This repository has been archived on 2026-10-23. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
aktiv-web/wp-content/plugins/google-calendar-events/inc/gce-feed.php
T

248 lines
7.6 KiB
PHP

<?php
class GCE_Feed{
private $feed_id = 1;
private $feed_title = '';
private $feed_url = '';
private $max_events = 25;
private $cache_duration = 43200;
private $date_format = '';
private $time_format = '';
private $timezone = '';
private $display_opts = array();
private $multi_day = false;
private $feed_start = 0;
private $feed_end = 2145916800;
private $use_builder = true;
private $builder = '';
private $events = array();
private $error = false;
function init() {
require_once 'gce-event.php';
//Break the feed URL up into its parts (scheme, host, path, query)
$url_parts = parse_url( $this->feed_url );
$scheme_and_host = $url_parts['scheme'] . '://' . $url_parts['host'];
//Remove the exisitng projection from the path, and replace it with '/full-noattendees'
$path = substr( $url_parts['path'], 0, strrpos( $url_parts['path'], '/' ) ) . '/full-noattendees';
//Add the default parameters to the querystring (retrieving JSON, not XML)
$query = '?alt=json&singleevents=true&sortorder=ascending&orderby=starttime';
$gmt_offset = get_option( 'gmt_offset' ) * 3600;
//Append the feed specific parameters to the querystring
$query .= '&start-min=' . date( 'Y-m-d\TH:i:s', $this->feed_start - $gmt_offset );
$query .= '&start-max=' . date( 'Y-m-d\TH:i:s', $this->feed_end - $gmt_offset );
$query .= '&max-results=' . $this->max_events;
if ( ! empty( $this->timezone ) )
$query .= '&ctz=' . $this->timezone;
//If enabled, use experimental 'fields' parameter of Google Data API, so that only necessary data is retrieved. This *significantly* reduces amount of data to retrieve and process
$general_options = get_option( GCE_GENERAL_OPTIONS_NAME );
if ( $general_options['fields'] )
$query .= '&fields=entry(title,link[@rel="alternate"],content,gd:where,gd:when,gCal:uid)';
//Put the URL back together
$url = $scheme_and_host . $path . $query;
//Attempt to retrieve the cached feed data
$this->events = get_transient( 'gce_feed_' . $this->feed_id );
//If the cached feed data isn't valid any more (has expired), or the URL has changed (settings have changed), then the feed data needs to be retrieved and decoded again
if ( false === $this->events || 0 == $this->cache_duration || get_transient( 'gce_feed_' . $this->feed_id . '_url' ) != $url ) {
$this->events = array();
//Retrieve the feed data
$raw_data = wp_remote_get( $url, array(
'sslverify' => false, //sslverify is set to false to ensure https URLs work reliably. Data source is Google's servers, so is trustworthy
'timeout' => 10 //Increase timeout from the default 5 seconds to ensure even large feeds are retrieved successfully
) );
//If $raw_data is a WP_Error, something went wrong
if ( ! is_wp_error( $raw_data ) ) {
//If response code isn't 200, something went wrong
if ( 200 == $raw_data['response']['code'] ) {
//Attempt to convert the returned JSON into an array
$raw_data = json_decode( $raw_data['body'], true );
//If decoding was successful
if ( ! empty( $raw_data ) ) {
//If there are some entries (events) to process
if ( isset( $raw_data['feed']['entry'] ) ) {
//Loop through each event, extracting the relevant information
foreach ( $raw_data['feed']['entry'] as $event ) {
$id = esc_html( substr( $event['gCal$uid']['value'], 0, strpos( $event['gCal$uid']['value'], '@' ) ) );
$title = esc_html( $event['title']['$t'] );
$description = esc_html( $event['content']['$t'] );
$link = esc_url( $event['link'][0]['href'] );
$location = esc_html( $event['gd$where'][0]['valueString'] );
$start_time = $this->iso_to_ts( $event['gd$when'][0]['startTime'] );
$end_time = $this->iso_to_ts( $event['gd$when'][0]['endTime'] );
//Create a GCE_Event using the above data. Add it to the array of events
$this->events[] = new GCE_Event( $id, $title, $description, $location, $start_time, $end_time, $link );
}
}
if ( 0 != $this->cache_duration ) {
//Cache the feed data
set_transient( 'gce_feed_' . $this->feed_id, $this->events, $this->cache_duration );
set_transient( 'gce_feed_' . $this->feed_id . '_url', $url, $this->cache_duration );
}
} else {
//json_decode failed
$this->error = __( 'Some data was retrieved, but could not be parsed successfully. Please ensure your feed URL is correct.', GCE_TEXT_DOMAIN );
}
} else {
//The response code wasn't 200, so generate a helpful(ish) error message depending on error code
switch ( $raw_data['response']['code'] ) {
case 404:
$this->error = __( 'The feed could not be found (404). Please ensure your feed URL is correct.', GCE_TEXT_DOMAIN );
break;
case 403:
$this->error = __( 'Access to this feed was denied (403). Please ensure you have public sharing enabled for your calendar.', GCE_TEXT_DOMAIN );
break;
default:
$this->error = sprintf( __( 'The feed data could not be retrieved. Error code: %s. Please ensure your feed URL is correct.', GCE_TEXT_DOMAIN ), $raw_data['response']['code'] );
}
}
}else{
//Generate an error message from the returned WP_Error
$this->error = $raw_data->get_error_message() . ' Please ensure your feed URL is correct.';
}
}
//Makes sure each event knows it came from this feed
foreach ( $this->events as $event ) {
$event->set_feed( $this );
}
}
//Convert an ISO date/time to a UNIX timestamp
function iso_to_ts( $iso ) {
sscanf( $iso, "%u-%u-%uT%u:%u:%uZ", $year, $month, $day, $hour, $minute, $second );
return mktime( $hour, $minute, $second, $month, $day, $year );
}
//Return error message, or false if no error occurred
function error() {
return $this->error;
}
//Setters
function set_feed_id( $v ) {
$this->feed_id = $v;
}
function set_feed_title( $v ) {
$this->feed_title = $v;
}
function set_feed_url( $v ) {
$this->feed_url = $v;
}
function set_max_events( $v ) {
$this->max_events = $v;
}
function set_cache_duration( $v ) {
$this->cache_duration = $v;
}
function set_date_format( $v ) {
$this->date_format = $v;
}
function set_time_format( $v ) {
$this->time_format = $v;
}
function set_timezone( $v ) {
$this->timezone = $v;
}
function set_display_options( $v ) {
$this->display_opts = $v;
}
function set_multi_day( $v ) {
$this->multi_day = $v;
}
function set_feed_start( $v ) {
$this->feed_start = $v;
}
function set_feed_end( $v ) {
$this->feed_end = $v;
}
function set_use_builder( $v ) {
$this->use_builder = $v;
}
function set_builder( $v ) {
$this->builder = $v;
}
//Getters
function get_events() {
return $this->events;
}
function get_feed_id() {
return $this->feed_id;
}
function get_feed_title() {
return $this->feed_title;
}
function get_feed_url() {
return $this->feed_url;
}
function get_date_format() {
return $this->date_format;
}
function get_time_format() {
return $this->time_format;
}
function get_display_options() {
return $this->display_opts;
}
function get_multi_day() {
return $this->multi_day;
}
function get_feed_start() {
return $this->feed_start;
}
function get_feed_end() {
return $this->feed_end;
}
function get_timezone() {
return $this->timezone;
}
function get_use_builder() {
return $this->use_builder;
}
function get_builder() {
return $this->builder;
}
}
?>