-
-
Save Jany-M/af50d5c4a0eec2692734d76383ed4dd8 to your computer and use it in GitHub Desktop.
<?php | |
/* | |
For a better understanding of ics requirements and time formats | |
please check https://gist.github.com/jakebellacera/635416 | |
*/ | |
// UTILS | |
// Check if string is a timestamp | |
function isValidTimeStamp($timestamp) { | |
//if($timestamp == '') return; | |
return ((string) (int) $timestamp === $timestamp) | |
&& ($timestamp <= PHP_INT_MAX) | |
&& ($timestamp >= ~PHP_INT_MAX); | |
} | |
// Escapes a string of characters | |
function escapeString($string) { | |
return preg_replace('/([\,;])/','\\\$1', $string); | |
} | |
// Shorten a string to desidered characters lenght - eg. shorter_version($string, 100); | |
function shorter_version($string, $lenght) { | |
if (strlen($string) >= $lenght) { | |
return substr($string, 0, $lenght); | |
} else { | |
return $string; | |
} | |
} | |
// Add a custom endpoint "calendar" | |
function add_calendar_feed(){ | |
add_feed('calendar', 'export_ics'); | |
// Only uncomment these 2 lines the first time you load this script, to update WP rewrite rules, or in case you see a 404 | |
/*global $wp_rewrite; | |
$wp_rewrite->flush_rules( false );*/ | |
} | |
add_action('init', 'add_calendar_feed'); | |
// Calendar function | |
function export_ics(){ | |
// Query the event | |
$the_event = new WP_Query(array( | |
'p' => $_REQUEST['id'], | |
'post_type' => 'any', | |
)); | |
if($the_event->have_posts()) : | |
while($the_event->have_posts()) : $the_event->the_post(); | |
// If your version of WP < 5.3.0 use the code below | |
/* The correct date format, for ALL dates is date_i18n('Ymd\THis\Z',time(), true) | |
So if your date is not in this format, use that function */ | |
$start_date = date_i18n("Ymd\THis\Z", get_post_meta( get_the_ID(), 'custom-field-of-start-date', true )); // EDIT THIS WITH YOUR OWN VALUE | |
$end_date = date_i18n("Ymd\THis\Z", get_post_meta( get_the_ID(), 'custom-field-of-end-date', true )); // EDIT THIS WITH YOUR OWN VALUE | |
$deadline = date_i18n("Ymd\THis\Z", get_post_meta( get_the_ID(), 'custom-field-of-deadline-date', true )); // EDIT THIS WITH YOUR OWN VALUE | |
// Otherwise, if your version of WP >= 5.3.0 use this code | |
$start_date = get_post_meta( get_the_ID(), 'custom-field-of-start-date', true ); // EDIT THIS WITH YOUR OWN VALUE | |
$end_date = get_post_meta( get_the_ID(), 'custom-field-of-end-date', true ); // EDIT THIS WITH YOUR OWN VALUE | |
if($start_date != '' && !isValidTimeStamp($start_date)) { | |
$start_date = strtotime($start_date); | |
$start_date = wp_date("Ymd\THis", $start_date); | |
} | |
if($end_date != '' && !isValidTimeStamp($end_date)) { | |
$end_date = strtotime($end_date); | |
$end_date = wp_date('Ymd\THis', $end_date); | |
} else { | |
$end_date = wp_date("Ymd\THis", $start_date + (1 * 60 * 60)); // 1 hour after | |
} | |
$deadline = date_i18n("Ymd\THis\Z", get_post_meta( get_the_ID(), 'custom-field-of-deadline-date', true )); // EDIT THIS WITH YOUR OWN VALUE | |
// The rest is the same for any version | |
$timestamp = date_i18n('Ymd\THis\Z',time(), true); | |
$uid = get_the_ID(); | |
$created_date = get_post_time('Ymd\THis\Z', true, $uid ); | |
$organiser = get_bloginfo('name'); // EDIT THIS WITH YOUR OWN VALUE | |
$address = ''; // EDIT THIS WITH YOUR OWN VALUE | |
$url = get_the_permalink(); | |
$summary = get_the_excerpt(); | |
$content = html_entity_decode(trim(preg_replace('/\s\s+/', ' ', get_the_content()))); // removes newlines and double spaces | |
$title = html_entity_decode(get_the_title()); | |
//Give the iCal export a filename | |
$filename = urlencode( $title.'-ical-' . date('Y-m-d') . '.ics' ); | |
$eol = "\r\n"; | |
//Collect output | |
ob_start(); | |
// Set the correct headers for this file | |
header("Content-Description: File Transfer"); | |
header("Content-Disposition: attachment; filename=".$filename); | |
header('Content-type: text/calendar; charset=utf-8'); | |
header("Pragma: 0"); | |
header("Expires: 0"); | |
// The below ics structure MUST NOT have spaces before each line | |
// Credit for the .ics structure goes to https://gist.github.com/jakebellacera/635416 | |
?> | |
BEGIN:VCALENDAR | |
VERSION:2.0 | |
PRODID:-//<?php echo get_bloginfo('name'); ?> //NONSGML Events //EN | |
CALSCALE:GREGORIAN | |
X-WR-CALNAME:<?php echo get_bloginfo('name').$eol;?> | |
BEGIN:VEVENT | |
CREATED:<?php echo $created_date.$eol;?> | |
UID:<?php echo $uid.$eol;?> | |
DTEND;VALUE=DATE:<?php echo $end_date.$eol; ?> | |
DTSTART;VALUE=DATE:<?php echo $start_date.$eol; ?> | |
DTSTAMP:<?php echo $timestamp.$eol; ?> | |
LOCATION:<?php echo escapeString($address).$eol; ?> | |
DESCRIPTION:<?php echo $content.$eol; ?> | |
SUMMARY:<?php echo $title.$eol; ?> | |
ORGANIZER:<?php echo escapeString($organiser).$eol;?> | |
URL;VALUE=URI:<?php echo escapeString($url).$eol; ?> | |
TRANSP:OPAQUE | |
BEGIN:VALARM | |
ACTION:DISPLAY | |
TRIGGER;VALUE=DATE-TIME:<?php echo $deadline.$eol; ?> | |
DESCRIPTION:Reminder for <?php echo escapeString(get_the_title()); echo $eol; ?> | |
END:VALARM | |
END:VEVENT | |
<?php | |
endwhile; | |
?> | |
END:VCALENDAR | |
<?php | |
//Collect output and echo | |
$eventsical = ob_get_contents(); | |
ob_end_clean(); | |
echo $eventsical; | |
exit(); | |
endif; | |
} | |
?> | |
USAGE in TEMPLATE | |
<a href="<?php echo get_feed_link('calendar'); ?>?id=<?php echo get_the_ID(); ?>"> Download the ics/ical </a> |
Hello thank you for the ical solution but like @LVilaj i'm getting this url http://localhost:8888/feed/calendar/?id=71 but no downloadable file and yes I did change line 5 and line 20 to the event custom post type
Excellent! However, changes in the export_icns() are not being taken. Any need to reregister it or anything?
Changing
$start_date = date_i18n("Ymd\THis\Z", get_post_meta( get_the_ID(), 'custom-field-of-start-date', true )); // EDIT THIS WITH YOUR OWN VALUE
to
$start_date = $eventDate['event_start']; // EDIT THIS WITH YOUR OWN VALUE
after the initial upload does not result in any changes in the .icf files.
Even deleting the whole content of export_ics() does still generate .ics-files.
Any idea?
Thanks!
Just realized that this is only affecting already generated .ics'. When clicking/generating a new one, that's fine. So I guess I only have to find and delete the already generated files?
Sorry just saw most of these comments, not getting any notifications. Please make sure you @ me, in case.
I have updated the script to work with wp_date()
since as of WP >= 5.3.0 date_i18n()
isn't working as expected.
@BumblebeeGames the script doesnt cache any file, so it would have to be either your host or your site's setup.
@ghost I had fixed that at the time, thanks!
@marvilmedia try to add AddType application/octet-stream .ics
in your .htaccess
(it could also be a browser or OS config though)
@Jany-M
I get a error like @marvilmedia i get send to http://localhost/wordpress/feed/calendar/?id=237 doesnt create a file but there is a error that says: error on line 3 at column 1: Extra content at the end of the document. What could this be as i just copied the code and changed the stuff that was needed also tried a clean copy of the code without changes but still get this error can you please help me with this.
Thank you!
@erikvanblitterswijk it's possible that the issue isn't with this script, but something else. Try with WP's default theme first, if issue is still there, reactivate your theme and disable all plugins and try again.. then try enabling them one by one. The script is fine, I've used it on several sites.
Check your error log too, just in case.
@Jany-M oke i will try that and come back if i have something. Already checked the error log but there is nothing there also the error says Below is a rendering of the page up to the first error. but there is nothing there but i will try what you said Tnx!
@Jany-M Here again tried everything but nothing worked but i got a Internal server error it says at the log now what could this be you think because nothing is changed to the code or am i missing things in my files can you figure something out by this information because i dont really know whats wrong the image is what i see when i click the link
An error 500 is the default php fatal error when no custom error pages have been set. Do you have errors set to log and display?
You could try to simply echo everything in a test page, so you could see if it's the script or something else with your setup, without having to click on link/generate the cap dynamically. I can't really help without more specific details.
@Jany-M i dont really know what you mean by your setup but i wil try and echo everything into a page and see what happens. Dont really understand why only i am having this problem and what could cause it because i pretty much didnt changed anything in my plugins and pages
@Jany-M I think i have some more information about the error here is what the debug says:
[28-Jan-2020 12:48:49 UTC] PHP Notice: Undefined index: id in C:\xampp\htdocs\wordpress\wp-content\themes\astra\functions.php on line 185
[28-Jan-2020 12:48:49 UTC] PHP Fatal error: Uncaught Error: Call to undefined function get_field() in C:\xampp\htdocs\wordpress\wp-content\themes\astra\functions.php:217
Stack trace:
#0 C:\xampp\htdocs\wordpress\wp-includes\class-wp-hook.php(288): export_ics(false, 'calendar')
#1 C:\xampp\htdocs\wordpress\wp-includes\class-wp-hook.php(312): WP_Hook->apply_filters('', Array)
#2 C:\xampp\htdocs\wordpress\wp-includes\plugin.php(478): WP_Hook->do_action(Array)
#3 C:\xampp\htdocs\wordpress\wp-includes\functions.php(1543): do_action('do_feed_calenda...', false, 'calendar')
#4 C:\xampp\htdocs\wordpress\wp-includes\template-loader.php(40): do_feed()
#5 C:\xampp\htdocs\wordpress\wp-blog-header.php(19): require_once('C:\xampp\htdocs...')
#6 C:\xampp\htdocs\wordpress\index.php(17): require('C:\xampp\htdocs...')
#7 {main}
thrown in C:\xampp\htdocs\wordpress\wp-content\themes\astra\functions.php on line 217
Something about the undefined get field is this useful?
Are you not using ACF? It seems like you aren't, so you will need to use a different function than get_field() to retrieve custom fields and that should fix it :)
Thank you so much for saying this i downloaded the plugin and it worked the only thing is that it didnt put the right info in the ics so that i have to figure out think i have some things wrong in the code so if i need any help i will come back to you but thank you so much for helping!
@Jany-M i have 1 last question i hope the only thing showing in the ics file is the description and i have some problems with the start time end time and the title from the event and as last the address how can i get this to work my meta keys are : _event_title , _event_address , _event_start_date , _event_send_date and as last i want to add the start time and end time to it but dont know how.
i am sorry that i ask so many question but i am kinda new to this so i need some help with it already thanks for helping me so much
@Jany-M Could you please help me out with this were i have to put the meta-keys or something i cant figure it out what i have to do exactly it still doesnt show the title, address, start time and end time
@Jany-M Can you please help me or help me where i can find the exact names of the tables so i can fill them in where you say to fill them in so i can finish this part of the website because i still cant figure out where to find the table names as when i fill in the meta-keys that the plugin says the field doesnt gets filled in when i download the ics file.
@erikvanblitterswijk sorry but I really don't have time at the moment for one on one tutoring on WP or PHP. There are many guides and tutorials out there, besides the WP codex, that will teach you exactly how to get $post title and $post metas.
Oke thanks for telling then i hope i can figure it out what i have to fill in in the 'edit with own value spots to make it work because the its not the meta keys thats for sure and i already looked into the db but there is nothing there about the names so i hope i will figure it out thanks for helping as much as you could
Hi @Jany-M,
A couple of things:
- It would be nice to document the code a little better. For example, there is no mention that ACF is required where you use
get_field()
, and it’s especially confusing since in your comments you mention the WP version, which has nothing to do with it (i. e. in the WP < 5.3.0 section you useget_post_meta()
and in the WP >= 5.3.0 you useget_field()
. - The function
shorter_version()
is being defined but never used. You could mention that it’s optional (I suppose for summary and content?). - I’m getting an error “Uncaught Error: Call to undefined function isValidTimeStamp()” – yeah, where is that function defined in the first place? Or am I missing anything that the other people before me didn’t?
- The variable
$timestamp
you are using on line 108 is defined on line 50 within the section after the WP < 5.3.0 comment, so if you remove that because you’re using a version greater than 5.3.0 an error occurs. What’s the alternative for later versions? - The variable
$deadline_txt
is used on line 90 but never defined before. On the other hand, there is a variable$summary
defined on line 56 but never used. Is that simply an oversight?
- I removed ACF
get_field
, in favor of the standard WPget_post_meta
- I left it there in case anyone needed it, function's name is pretty self_explanatory, but I've added a better explanation
- You're right! Added it to script (I had it defined elsewhere)
$timestamp
should be ok as is, I've moved below it so it's not confusing- Correct. In my original script there's more about deadline, which uses ACF true/false and conditional functions in case one is set. I've removed the reference here.
Keep in mind this is a script I used in a real project and added it here mostly for myself, I removed most of project-specific references, it's possible that small parts are not perfect... So, good observations, but remember this isn't a paid php or wp tutorial service, it's just a snippet that other developers can use and manipulate according to need and if they can't figure out the small changes needed, maybe they should hire a dev ;)
On line 66 there is a "g" missing in the function name
On line 66 there is a "g" missing in the function name
Fixed, thank you!
Have you change the line 5 like as sacrista said? @LVilaj