/wp-content/plugins/the-events-calendar/src/Tribe/Aggregator/Record/Activity.php

https://github.com/livinglab/openlab · PHP · 358 lines · 148 code · 55 blank · 155 comment · 22 complexity · a8c187dadc21e5164200e2a9410ec129 MD5 · raw file

  1. <?php
  2. // Don't load directly
  3. defined( 'WPINC' ) or die;
  4. class Tribe__Events__Aggregator__Record__Activity {
  5. /**
  6. * The below constants are meant to be used to set a status on the activity.
  7. * The reasons, check and management of said status are up to the client
  8. * object and not managed by the activity instance.
  9. *
  10. * @see Tribe__Events__Aggregator__Record__Activity::set_last_status()
  11. * @see Tribe__Events__Aggregator__Record__Activity::get_last_status()
  12. *
  13. */
  14. const STATUS_SUCCESS = 'success';
  15. const STATUS_FAIL = 'fail';
  16. const STATUS_PARTIAL = 'partial';
  17. const STATUS_NULL = 'null';
  18. /**
  19. * Holds a Log of what has been done on This Queue
  20. * @var array
  21. */
  22. protected $items = [];
  23. /**
  24. * The status of the last processing operation.
  25. *
  26. * @var string
  27. */
  28. protected $last_status;
  29. /**
  30. * Allows easier quick shortcodes to access activity
  31. * @var array
  32. */
  33. private $map = [];
  34. public $total = 0;
  35. /**
  36. * Creates an easy way to test valid Actions
  37. * @var array
  38. */
  39. private static $actions = [
  40. 'created' => [],
  41. 'updated' => [],
  42. 'skipped' => [],
  43. 'scheduled' => [],
  44. ];
  45. public function __construct() {
  46. // The items are registered on the wakeup to avoid saving unnecessary data
  47. $this->__wakeup();
  48. }
  49. /**
  50. * Register the Activities Tracked
  51. */
  52. public function __wakeup() {
  53. // Entry for Events CPT
  54. $this->register( Tribe__Events__Main::POSTTYPE, array( 'event', 'events' ) );
  55. // Entry for Organizers CPT
  56. $this->register( Tribe__Events__Organizer::POSTTYPE, array( 'organizer', 'organizers' ) );
  57. // Entry for Venues CPT
  58. $this->register( Tribe__Events__Venue::POSTTYPE, array( 'venue', 'venues' ) );
  59. // Entry for Terms in Events Cat
  60. $this->register( Tribe__Events__Main::TAXONOMY, array( 'category', 'categories', 'cat', 'cats' ) );
  61. // Entry for Tags
  62. $this->register( 'post_tag', array( 'tag', 'tags' ) );
  63. // Entry for Attachment
  64. $this->register( 'attachment', array( 'attachments', 'image', 'images' ) );
  65. /**
  66. * Fires during record activity wakeup to allow other plugins to inject/register activity entries
  67. * for other custom post types
  68. *
  69. * @param Tribe__Events__Aggregator__Record__Activity $this
  70. */
  71. do_action( 'tribe_aggregator_record_activity_wakeup', $this );
  72. }
  73. /**
  74. * Prevents Mapping to be saved on the DB object
  75. * @return array
  76. */
  77. public function __sleep() {
  78. return array( 'items', 'last_status' );
  79. }
  80. /**
  81. * Register a Specific Activity and it's mappings
  82. *
  83. * @param string $slug Name of this Activity
  84. * @param array $map (optional) Other names in which you can access this activity
  85. *
  86. * @return boolean [description]
  87. */
  88. public function register( $slug, $map = array() ) {
  89. if ( empty( $this->items[ $slug ] ) ) {
  90. // Clone the Default action values
  91. $this->items[ $slug ] = (object) self::$actions;
  92. } else {
  93. $this->items[ $slug ] = (object) array_merge( (array) self::$actions, (array) $this->items[ $slug ] );
  94. }
  95. // Add the base mapping
  96. $this->map[ $slug ] = $slug;
  97. // Allow short names for the activities
  98. foreach ( $map as $to ) {
  99. $this->map[ $to ] = $slug;
  100. }
  101. $this->prevent_duplicates_between_item_actions( $slug );
  102. return true;
  103. }
  104. /**
  105. * Logs an Activity
  106. *
  107. * @param string $slug Name of this Activity
  108. * @param string|array $items Type of activity
  109. * @param array $ids items inside of the action
  110. *
  111. * @return boolean
  112. */
  113. public function add( $slug, $items, $ids = array() ) {
  114. if ( ! $this->exists( $slug ) ) {
  115. return false;
  116. }
  117. if ( ! isset( $this->map[ $slug ] ) ) {
  118. return false;
  119. }
  120. // Map the Slug
  121. $slug = $this->map[ $slug ];
  122. if ( is_scalar( $items ) ) {
  123. // If it's a scalar and it's not one of the registered actions we skip it
  124. if ( ! isset( self::$actions[ $items ] ) ) {
  125. return false;
  126. }
  127. // Make the actual Array of items
  128. $items = array( $items => $ids );
  129. } else {
  130. $items = (object) $items;
  131. // Doesn't contain any of the Possible Actions
  132. if ( 0 === count( array_intersect_key( self::$actions, (array) $items ) ) ) {
  133. return false;
  134. }
  135. }
  136. foreach ( $items as $action => $ids ) {
  137. // Skip Empty ids
  138. if ( empty( $ids ) ) {
  139. continue;
  140. }
  141. $this->items[ $slug ]->{ $action } = array_unique( array_filter( array_merge( $this->items[ $slug ]->{ $action }, (array) $ids ) ) );
  142. }
  143. return true;
  144. }
  145. /**
  146. * Returns the merged version of two Activities classes
  147. *
  148. * @param self $activity Which activity should be merged here
  149. *
  150. * @return self
  151. */
  152. public function merge( self $activity ) {
  153. $items = $activity->get();
  154. foreach ( $items as $slug => $data ) {
  155. $this->add( $slug, $data );
  156. }
  157. return $this;
  158. }
  159. /**
  160. * Removes a activity from the Registered ones
  161. *
  162. * @param string $slug The Slug of the Activity
  163. *
  164. * @return boolean
  165. */
  166. public function remove( $slug ) {
  167. if ( ! $this->exists( $slug ) ) {
  168. return false;
  169. }
  170. if ( ! isset( $this->map[ $slug ] ) ) {
  171. return false;
  172. }
  173. // Map the Slug
  174. $slug = $this->map[ $slug ];
  175. // Remove it
  176. unset( $this->items[ $slug ] );
  177. return true;
  178. }
  179. /**
  180. * Fetches a registered Activity
  181. *
  182. * @param string $slug (optional) The Slug of the Activity
  183. * @param string $action (optional) Which action
  184. *
  185. * @return null|array|object
  186. */
  187. public function get( $slug = null, $action = null ) {
  188. if ( is_null( $slug ) ) {
  189. return $this->items;
  190. }
  191. if ( ! isset( $this->map[ $slug ] ) ) {
  192. return null;
  193. }
  194. // Map the Slug
  195. $slug = $this->map[ $slug ];
  196. // Check if it actually exists
  197. if ( empty( $this->items[ $slug ] ) ) {
  198. return null;
  199. }
  200. $actions = $this->items[ $slug ];
  201. // If we trying to get a specific action and
  202. if ( is_null( $action ) ) {
  203. return $this->items[ $slug ];
  204. } elseif ( ! empty( $actions->{ $action } ) ) {
  205. return $actions->{ $action };
  206. } else {
  207. return null;
  208. }
  209. }
  210. /**
  211. * Fetches a registered Activity counter
  212. *
  213. * @param string $slug (optional) The Slug of the Activity
  214. * @param string $action (optional) Which action
  215. *
  216. * @return int
  217. */
  218. public function count( $slug = null, $action = null ) {
  219. $actions = $this->get( $slug );
  220. if ( empty( $actions ) ) {
  221. return 0;
  222. }
  223. // Sum all of the Actions
  224. if ( is_null( $action ) ) {
  225. // recursively convert to associative array
  226. $actions = json_decode( json_encode( $actions ), true );
  227. return array_sum( array_map( 'count', $actions ) );
  228. } elseif ( ! empty( $actions->{ $action } ) ) {
  229. return count( $actions->{ $action } );
  230. }
  231. return 0;
  232. }
  233. /**
  234. * Checks if a given Activity type exists
  235. *
  236. * @param string $slug The Slug of the Tab
  237. *
  238. * @return boolean
  239. */
  240. public function exists( $slug ) {
  241. if ( is_null( $slug ) ) {
  242. return false;
  243. }
  244. if ( ! isset( $this->map[ $slug ] ) ) {
  245. return false;
  246. }
  247. // Map the Slug
  248. $slug = $this->map[ $slug ];
  249. // Check if it actually exists
  250. return ! empty( $this->items[ $slug ] ) ;
  251. }
  252. /**
  253. * Checks the activities for a slug to make sure there are no incoherent duplicate entries due to concurring processes.
  254. *
  255. * @since 4.5.12
  256. *
  257. * @param string $slug
  258. */
  259. protected function prevent_duplicates_between_item_actions( $slug ) {
  260. // sanity check the updated elements: elements cannot be created AND updated
  261. if ( ! empty( $this->items[ $slug ]->updated ) && ! empty( $this->items[ $slug ]->created ) ) {
  262. $this->items[ $slug ]->updated = array_diff( $this->items[ $slug ]->updated, $this->items[ $slug ]->created );
  263. }
  264. }
  265. /**
  266. * Returns the raw items from the activity.
  267. *
  268. * @since 4.6.15
  269. *
  270. * @return array
  271. */
  272. public function get_items() {
  273. return $this->items;
  274. }
  275. /**
  276. * Sets the last status on the activity object.
  277. *
  278. * Ideally set to one of the `STATUS_` constants defined by the class
  279. * but allowing arbitrary stati by design. It's up to the client to set
  280. * and consume this information.
  281. *
  282. * @since 4.6.15
  283. *
  284. * @param string $status
  285. */
  286. public function set_last_status( $status ) {
  287. $this->last_status = $status;
  288. }
  289. /**
  290. * Gets the last status on the activity object.
  291. *
  292. * Ideally set to one of the `STATUS_` constants defined by the class
  293. * but allowing arbitrary stati by design. It's up to the client to set
  294. * and consume this information.
  295. *
  296. * @since 4.6.15
  297. *
  298. * @return string
  299. */
  300. public function get_last_status() {
  301. return $this->last_status;
  302. }
  303. }