0

I have a 'single' page for individual workshop events and i'm tying to create an 'add to calendar' functionality. Right now i have a link setup, which passes the current post ID in a query string to the PHP file that generates the iCal file. I'm pretty sure I should be able to generate such a file from a wp_query, but i know my code is probably grotesquely incorrect. I've been working on this all day and can't seem to make any other post i've found on the matter work. Any help would really be appreciated. I'm semi-new to wordpress so be gentle!

Here's the file:

//allow access to the wp_query method:
$parse_uri = explode( 'wp-content', $_SERVER['SCRIPT_FILENAME'] );
require_once( $parse_uri[0] . 'wp-blog-header.php' );

//get the post ID from the incoming query string:
$workshop_id = @$_GET['workshop_id'];

$args = array(
'p' => $workshop_id,
'post_type' => 'any');

$the_query = new WP_Query($args);

// The Loop
if ( $the_query->have_posts() ) :

while ( $the_query->have_posts() ) :
        $the_query->the_post();

$workshop = array(
    'workshop_title' => get_field('workshop');
);

header("Content-Type: text/Calendar");
header("Content-Disposition: inline; filename=calendar.ics");
echo "BEGIN:VCALENDAR\n";
echo "VERSION:2.0\n";
echo "PRODID:-//Foobar Corporation//NONSGML Foobar//EN\n";
echo "METHOD:REQUEST\n"; // requied by Outlook
echo "BEGIN:VEVENT\n";
echo "UID:".date('Ymd').'T'.date('His')."-".rand()."-example.com\n"; // required by Outlok
echo "DTSTAMP:".date('Ymd').'T'.date('His')."\n"; // required by Outlook
echo "DTSTART:20080413T000000\n"; 
//  echo "SUMMARY:{$workshop['workshop_title']}\n";
echo "DESCRIPTION: this is just a test\n";
echo "END:VEVENT\n";
echo "END:VCALENDAR\n";

endwhile;

endif;

?>

2 Answers 2

0

Two things. Firstly, don't load WordPress yourself. Instead of linking directly to your plugin file, use your WordPress home URL:

<a href="<?php echo home_url( '?workshop_id=X' ) ?>">Download iCal</a>

...and then intercept the request:

function wpse_183197_send_ical() {
    if ( ! empty( $_GET['workshop_id'] ) && ! is_admin() ) {
         // Your code
         exit;
    }
}

add_action( 'init', 'wpse_183197_send_ical' );

As for the code itself, since you're only operating on one post, we can make it a lot leaner:

if ( ! $id = ( int ) $_GET['workshop_id'] )
    return; // Invalid parameter

if ( ! $post = get_post( $id ) )
    return; // Invalid post

if ( ! $title = get_field( 'workshop', $post->ID /* You can pass a post ID as a second arg to ACF get_field */ ) )
    return; // No workshop

if ( $post->post_status !== 'publish' )
    return; // Might want to protect access to drafts and the like

// Calendar headers
echo "SUMMARY:$title\n";
3
  • Great. I think I follow. ..or maybe not. If I link using the homeURL with a query string, how will wordpess know to find the code to generate the ical file? should the function live in my functions.php file? It looks like the wpse_183197_send_ical function should catch the query string... just not sure where the incerception is happening.
    – Brian C
    Apr 5, 2015 at 1:09
  • Yes place the code in your functions.php Apr 5, 2015 at 18:18
  • All Set! worked like a charm. I ended up using 'get_post' in my function after I made the changes, which allowed me to pull all my custom fields when i passed the workshop_id from the query string. Thanks for the help!
    – Brian C
    Apr 6, 2015 at 0:34
0

Please check if you are getting valid values. If headers are set in while loop, it may cause some error. Create calendar file after while loop, if possible.

There may be problem with '\n'. Instead of it, try to echo entire string as follows,

 $UID = date('Ymd').'T'.date('His')."-".rand()."-example.com";
 $date_stamp = date('Ymd').'T'.date('His');

 echo "BEGIN:VCALENDAR
 VERSION:2.0
 PRODID:-//Foobar Corporation//NONSGML Foobar//EN
 BEGIN:VEVENT
 UID:{$UID}
 DTSTAMP:{$date_stamp}
 DTSTART:20080413T000000
 DESCRIPTION: this is just a test
 END:VEVENT
 END:VCALENDAR";

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.