PageRenderTime 70ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/all-in-one-event-calendar/app/helper/class-ai1ec-importer-helper.php

https://gitlab.com/endomorphosis/jeffersonsmithmayor
PHP | 255 lines | 133 code | 31 blank | 91 comment | 19 complexity | ec09ade9fece3377e69f18ee1ab372a4 MD5 | raw file
  1. <?php
  2. //
  3. // class-ai1ec-importer-helper.php
  4. // all-in-one-event-calendar
  5. //
  6. // Created by The Seed Studio on 2011-07-13.
  7. //
  8. /**
  9. * Ai1ec_Importer_Helper class
  10. *
  11. * @package Helpers
  12. * @author The Seed Studio
  13. **/
  14. class Ai1ec_Importer_Helper {
  15. /**
  16. * _instance class variable
  17. *
  18. * Class instance
  19. *
  20. * @var null | object
  21. **/
  22. private static $_instance = NULL;
  23. /**
  24. * Constructor
  25. *
  26. * Default constructor
  27. **/
  28. private function __construct() { }
  29. /**
  30. * get_instance function
  31. *
  32. * Return singleton instance
  33. *
  34. * @return object
  35. **/
  36. static function get_instance() {
  37. if( self::$_instance === NULL ) {
  38. self::$_instance = new self();
  39. }
  40. return self::$_instance;
  41. }
  42. /**
  43. * time_array_to_timestamp function
  44. *
  45. * Converts time array to time string.
  46. * Passed array: Array( 'year', 'month', 'day', ['hour', 'min', 'sec', ['tz']] )
  47. * Return int: UNIX timestamp in GMT
  48. *
  49. * @param array $t iCalcreator's time property array (*full* format expected)
  50. * @param string $def_timezone Default time zone in case not defined in $t
  51. *
  52. * @return int UNIX timestamp
  53. **/
  54. function time_array_to_timestamp( $t, $def_timezone ) {
  55. $ret = $t['value']['year'] .
  56. '-' . $t['value']['month'] .
  57. '-' . $t['value']['day'];
  58. if( isset( $t['value']['hour'] ) )
  59. $ret .= ' ' . $t['value']['hour'] .
  60. ':' . $t['value']['min'] .
  61. ':' . $t['value']['sec'];
  62. $timezone = '';
  63. if( isset( $t['value']['tz'] ) && $t['value']['tz'] == 'Z' )
  64. $timezone = 'Z';
  65. elseif( isset( $t['params']['TZID'] ) )
  66. $timezone = $t['params']['TZID'];
  67. if( empty( $timezone ) ) $timezone = $def_timezone;
  68. if( $timezone )
  69. $ret .= ' ' . $timezone;
  70. return strtotime( $ret );
  71. }
  72. /**
  73. * Gets and parses an iCalendar feed into an array of Ai1ec_Event objects
  74. *
  75. * @param object $feed Row from the ai1ec_event_feeds table
  76. *
  77. * @return int Number of events imported
  78. */
  79. function parse_ics_feed( &$feed )
  80. {
  81. global $ai1ec_events_helper;
  82. $count = 0;
  83. // include ical parser
  84. if( version_compare( PHP_VERSION, '5.3.0' ) >= 0 ) {
  85. // Parser that requires PHP v5.3.0 or up
  86. require_once( AI1EC_LIB_PATH . '/iCalcreator-2.10.23/iCalcreator.class.php' );
  87. require_once( AI1EC_LIB_PATH . '/iCalcreator-2.10.23//iCalUtilityFunctions.class.php' );
  88. } else {
  89. // Parser that works on PHP versions below 5.3.0
  90. require_once( AI1EC_LIB_PATH . '/iCalcreator-2.10/iCalcreator.class.php' );
  91. require_once( AI1EC_LIB_PATH . '/iCalcreator-2.10/iCalUtilityFunctions.class.php' );
  92. }
  93. // set unique id, required if any component UID is missing
  94. $config = array( 'unique_id' => 'ai1ec' );
  95. // create new instance
  96. $v = new vcalendar( array(
  97. 'unique_id' => $feed->feed_url,
  98. 'url' => $feed->feed_url,
  99. ) );
  100. // actual parse of the feed
  101. if( $v->parse() )
  102. {
  103. $v->sort();
  104. // Reverse the sort order, so that RECURRENCE-IDs are listed before the
  105. // defining recurrence events, and therefore take precedence during
  106. // caching.
  107. $v->components = array_reverse( $v->components );
  108. // TODO: select only VEVENT components that occur after, say, 1 month ago.
  109. // Maybe use $v->selectComponents(), which takes into account recurrence
  110. // Fetch default timezone in case individual properties don't define it
  111. $timezone = $v->getProperty( 'X-WR-TIMEZONE' );
  112. $timezone = $timezone[1];
  113. // go over each event
  114. while( $e = $v->getComponent( 'vevent' ) )
  115. {
  116. $start = $e->getProperty( 'dtstart', 1, true );
  117. $end = $e->getProperty( 'dtend', 1, true );
  118. // If end can't be found, check for duration property
  119. if( empty( $end ) )
  120. $end = $e->getProperty( 'duration', 1, true, true );
  121. // Event is all-day if no time components are defined
  122. $allday = ! isset( $start['value']['hour'] );
  123. // convert times to GMT UNIX timestamps
  124. $start = $this->time_array_to_timestamp( $start, $timezone );
  125. $end = $this->time_array_to_timestamp( $end, $timezone );
  126. // If all-day, and start and end times are equal, then this event has
  127. // invalid end time (happens sometimes with poorly implemented iCalendar
  128. // exports, such as in The Event Calendar), so set end time to 1 day
  129. // after start time.
  130. if( $allday && $start === $end )
  131. $end += 24 * 60 * 60;
  132. // Due to potential time zone differences (WP time zone vs. feed time
  133. // zone), must convert all-day event start/end dates to date only (the
  134. // *intended* local date, non-GMT-ified)
  135. if( $allday ) {
  136. $start = $ai1ec_events_helper->gmt_to_local( $start );
  137. $start = $ai1ec_events_helper->gmgetdate( $start );
  138. $start = gmmktime( 0, 0, 0, $start['mon'], $start['mday'], $start['year'] );
  139. $start = $ai1ec_events_helper->local_to_gmt( $start );
  140. $end = $ai1ec_events_helper->gmt_to_local( $end );
  141. $end = $ai1ec_events_helper->gmgetdate( $end );
  142. $end = gmmktime( 0, 0, 0, $end['mon'], $end['mday'], $end['year'] );
  143. $end = $ai1ec_events_helper->local_to_gmt( $end );
  144. }
  145. if( $rrule = $e->createRrule() )
  146. $rrule = trim( end( explode( ':', $rrule ) ) );
  147. if( $exrule = $e->createExrule() )
  148. $exrule = trim( end( explode( ':', $exrule ) ) );
  149. if( $rdate = $e->createRdate() )
  150. $rdate = trim( end( explode( ':', $rdate ) ) );
  151. if( $exdate = $e->createExdate() )
  152. $exdate = trim( end( explode( ':', $exdate ) ) );
  153. $data = array(
  154. 'start' => $start,
  155. 'end' => $end,
  156. 'allday' => $allday,
  157. 'recurrence_rules' => $rrule,
  158. 'exception_rules' => $exrule,
  159. 'recurrence_dates' => $rdate,
  160. 'exception_dates' => $exdate,
  161. 'venue' => $e->getProperty( 'location' ),
  162. 'ical_feed_url' => $feed->feed_url,
  163. 'ical_source_url' => $e->getProperty( 'url' ),
  164. 'ical_organizer' => $e->getProperty( 'organizer' ),
  165. 'ical_contact' => $e->getProperty( 'contact' ),
  166. 'ical_uid' => $e->getProperty( 'uid' ),
  167. 'categories' => $feed->feed_category,
  168. 'tags' => $feed->feed_tags,
  169. 'feed' => $feed,
  170. 'post' => array(
  171. 'post_status' => 'publish',
  172. 'post_type' => AI1EC_POST_TYPE,
  173. 'post_author' => 1,
  174. 'post_title' => $e->getProperty( 'summary' ),
  175. 'post_content' => stripslashes( str_replace( '\n', "\n", $e->getProperty( 'description' ) ) ),
  176. ),
  177. );
  178. $event = new Ai1ec_Event( $data );
  179. // TODO: when singular events change their times in an ICS feed from one
  180. // import to another, the matching_event_id is null, which is wrong. We
  181. // want to match that event that previously had a different time.
  182. // However, we also want the function to NOT return a matching event in
  183. // the case of recurring events, and different events with different
  184. // RECURRENCE-IDs... ponder how to solve this.. may require saving the
  185. // RECURRENCE-ID as another field in the database.
  186. $matching_event_id = $ai1ec_events_helper->get_matching_event_id(
  187. $event->ical_uid,
  188. $event->ical_feed_url,
  189. $event->start,
  190. ! empty( $event->recurrence_rules )
  191. );
  192. if( is_null( $matching_event_id ) )
  193. {
  194. // =================================================
  195. // = Event was not found, so store it and the post =
  196. // =================================================
  197. $event->save();
  198. }
  199. else
  200. {
  201. // ======================================================
  202. // = Event was found, let's store the new event details =
  203. // ======================================================
  204. // Update the post
  205. $post = get_post( $matching_event_id );
  206. $post->post_title = $event->post->post_title;
  207. $post->post_content = $event->post->post_content;
  208. wp_update_post( $post );
  209. // Update the event
  210. $event->post_id = $matching_event_id;
  211. $event->post = $post;
  212. $event->save( true );
  213. // Delete event's cache
  214. $ai1ec_events_helper->delete_event_cache( $matching_event_id );
  215. }
  216. // Regenerate event's cache
  217. $ai1ec_events_helper->cache_event( $event );
  218. $count++;
  219. }
  220. }
  221. return $count;
  222. }
  223. }
  224. // END class