/wp-content/plugins/the-events-calendar/src/Tribe/Aggregator/API/Origins.php

https://github.com/livinglab/openlab · PHP · 275 lines · 157 code · 42 blank · 76 comment · 21 complexity · 3440f22ce86d4ab6a73ec1e7f08ddb90 MD5 · raw file

  1. <?php
  2. // Don't load directly
  3. defined( 'WPINC' ) or die;
  4. class Tribe__Events__Aggregator__API__Origins extends Tribe__Events__Aggregator__API__Abstract {
  5. /**
  6. * @since 4.9.6
  7. */
  8. const VERSION = '1.1.0';
  9. /**
  10. * @var array
  11. */
  12. public $origins;
  13. /**
  14. * @var bool Whether EA is enabled or not.
  15. * While EA might be ready to work on a license and functional level
  16. * the user might disable it; this flag tracks that choice.
  17. */
  18. protected $is_ea_disabled = true;
  19. /**
  20. * @var array An array of origins that will still be available when EA has
  21. * been disabled by the user.
  22. */
  23. protected $available_when_disabled = [ 'csv' ];
  24. public function __construct() {
  25. parent::__construct();
  26. $this->origins = [
  27. 'csv' => (object) [
  28. 'id' => 'csv',
  29. 'name' => __( 'CSV File', 'the-events-calendar' ),
  30. 'disabled' => false,
  31. ],
  32. 'eventbrite' => (object) [
  33. 'id' => 'eventbrite',
  34. 'name' => __( 'Eventbrite', 'the-events-calendar' ),
  35. 'disabled' => true,
  36. 'upsell' => true,
  37. ],
  38. 'gcal' => (object) [
  39. 'id' => 'gcal',
  40. 'name' => __( 'Google Calendar', 'the-events-calendar' ),
  41. 'disabled' => true,
  42. 'upsell' => true,
  43. ],
  44. 'ical' => (object) [
  45. 'id' => 'ical',
  46. 'name' => __( 'iCalendar', 'the-events-calendar' ),
  47. 'disabled' => true,
  48. 'upsell' => true,
  49. ],
  50. 'ics' => (object) [
  51. 'id' => 'ics',
  52. 'name' => __( 'ICS File', 'the-events-calendar' ),
  53. 'disabled' => true,
  54. 'upsell' => true,
  55. ],
  56. 'meetup' => (object) [
  57. 'id' => 'meetup',
  58. 'name' => __( 'Meetup', 'the-events-calendar' ),
  59. 'disabled' => true,
  60. 'upsell' => true,
  61. ],
  62. 'url' => (object) [
  63. 'id' => 'url',
  64. 'name' => __( 'Other URL', 'the-events-calendar' ),
  65. 'disabled' => true,
  66. 'upsell' => true,
  67. ],
  68. ];
  69. $this->is_ea_disabled = tribe_get_option( 'tribe_aggregator_disable', false );
  70. }
  71. /**
  72. * Get event-aggregator origins
  73. *
  74. * @return array
  75. */
  76. public function get() {
  77. if ( tribe( 'events-aggregator.main' )->is_service_active() ) {
  78. $this->enable_service_origins();
  79. }
  80. $origins = $this->origins;
  81. $origins = array_filter( $origins, [ $this, 'is_origin_available' ] );
  82. /**
  83. * The origins (sources) that EA can import from
  84. *
  85. * @param array $origins The origins
  86. */
  87. $origins = apply_filters( 'tribe_aggregator_origins', $origins );
  88. return $origins;
  89. }
  90. /**
  91. * Get event-aggregator origins from the service or cache
  92. *
  93. * @return array
  94. */
  95. private function enable_service_origins() {
  96. $cached_origins = get_transient( "{$this->cache_group}_origins" );
  97. $cached_version = ! empty( $cached_origins->version )
  98. ? $cached_origins->version
  99. : '1.0.0';
  100. if ( $cached_origins && version_compare( $cached_version, static::VERSION, '=' ) ) {
  101. $this->origins = $cached_origins;
  102. return $this->origins;
  103. }
  104. $service_origins = $this->fetch_origin_data();
  105. if ( is_wp_error( $service_origins ) ) {
  106. return $this->origins;
  107. }
  108. if ( empty( $service_origins->origin ) ) {
  109. return $this->origins;
  110. }
  111. // enable the options for any that come back from the Service
  112. foreach ( $service_origins->origin as $origin ) {
  113. if ( ! empty( $this->origins[ $origin->id ] ) ) {
  114. $this->origins[ $origin->id ]->disabled = false;
  115. }
  116. }
  117. // use the specified expiration if available
  118. if ( isset( $this->origins->expiration ) ) {
  119. $expiration = $this->origins->expiration;
  120. unset( $this->origins->expiration );
  121. } else {
  122. $expiration = 6 * HOUR_IN_SECONDS;
  123. }
  124. set_transient( "{$this->cache_group}_origins", $this->origins, $expiration );
  125. return $this->origins;
  126. }
  127. /**
  128. * Fetches origin data from the service and sets necessary transients
  129. */
  130. private function fetch_origin_data() {
  131. $request_cached = tribe_get_var( 'events-aggregator.origins-data' );
  132. if ( empty( $request_cached ) ) {
  133. // Try to see if we have a lock in place.
  134. $lock = get_transient( "{$this->cache_group}_fetch_lock" );
  135. }
  136. if ( ! empty( $lock ) ) {
  137. return $request_cached;
  138. }
  139. list( $origin_data, $error ) = $this->service->get_origins( true );
  140. $origin_data = (object) $origin_data;
  141. $version = ! empty( $origin_data->version ) ? $origin_data->version : '1.0.0';
  142. if ( empty( $error ) ) {
  143. // Refresh some accessory transients and embed the version in them.
  144. $oauth_data = $origin_data->oauth;
  145. $limit_data = $origin_data->limit;
  146. $oauth_data->version = $limit_data->version = $version;
  147. set_transient( "{$this->cache_group}_origin_oauth", $oauth_data, 6 * HOUR_IN_SECONDS );
  148. set_transient( "{$this->cache_group}_origin_limit", $limit_data, 6 * HOUR_IN_SECONDS );
  149. } elseif ( 403 == wp_remote_retrieve_response_code( $error ) ) {
  150. // Store the origins data for 5' only.
  151. $origin_data->expiration = 300;
  152. // And avoid bugging the service for 5'.
  153. set_transient( "{$this->cache_group}_fetch_lock", $origin_data, 300 );
  154. }
  155. tribe_set_var( 'events-aggregator.origins-data', $origin_data );
  156. return $origin_data;
  157. }
  158. /**
  159. * Returns whether oauth for a given origin is enabled.
  160. *
  161. * The OAuth status for the origin is enabled on EA Service side.
  162. *
  163. * @param string $origin The origin to check the OAuth status for.
  164. *
  165. * @return boolean Whether OAuth is enabled for the origin or not.
  166. */
  167. public function is_oauth_enabled( $origin ) {
  168. if ( 'eventbrite' !== $origin && ! tribe( 'events-aggregator.main' )->is_service_active() ) {
  169. return false;
  170. }
  171. if ( 'eventbrite' === $origin && class_exists( 'Tribe__Events__Tickets__Eventbrite__Main' ) ) {
  172. return true;
  173. }
  174. $oauth = $this->get_data( 'oauth' );
  175. return ! empty( $oauth->{$origin} ) && (bool) $oauth->{$origin};
  176. }
  177. /**
  178. * Get origin limit values for an operation.
  179. *
  180. * @param string $type Type of operation limit to retrieve; defaults to `import`.
  181. *
  182. * @return int The numeric limit (how many times) applied to the operation.
  183. */
  184. public function get_limit( $type = 'import' ) {
  185. $limits = $this->get_data( 'limit' );
  186. return ! empty( $limits->{$type} ) ? (int) $limits->{$type} : false;
  187. }
  188. public function get_name( $id ) {
  189. $this->get();
  190. if ( empty( $this->origins[ $id ] ) ) {
  191. return __( 'Event Aggregator', 'the-events-calendar' );
  192. }
  193. return $this->origins[ $id ]->name;
  194. }
  195. /**
  196. * Whether an origin is available or not in respect to the user possibility
  197. * to disable EA functions.
  198. *
  199. * @param stdClass|string $origin The origin to check for availability as an object
  200. * or a slug.
  201. *
  202. * @return bool
  203. */
  204. public function is_origin_available( $origin ) {
  205. if ( is_object( $origin ) ) {
  206. $origin = $origin->id;
  207. }
  208. return $this->is_ea_disabled ? in_array( $origin, $this->available_when_disabled ) : true;
  209. }
  210. /**
  211. * Gets the data for an internal Origins data key.
  212. *
  213. * The result might be cached from a previous request.
  214. *
  215. * @since 4.9.6
  216. *
  217. * @param string|null $key The key to fetch the data for.
  218. *
  219. * @return mixed|object|bool The data associated with the key if any and available, `false` otherwise.
  220. */
  221. public function get_data( $key ) {
  222. if ( null === $key ) {
  223. return $this->fetch_origin_data();
  224. }
  225. $data = get_transient( "{$this->cache_group}_origin_{$key}" );
  226. $cached_version = isset( $data->version ) ? $data->version : '1.0.0';
  227. if ( ! version_compare( $cached_version, static::VERSION, '=' ) ) {
  228. $origin_data = $this->fetch_origin_data();
  229. $data = ! empty( $origin_data->{$key} ) ? $origin_data->{$key} : false;
  230. }
  231. return $data;
  232. }
  233. }