PluginProbe ʕ •ᴥ•ʔ
Pods – Custom Content Types and Fields / 2.9.19.4
Pods – Custom Content Types and Fields v2.9.19.4
2.7.31.4 2.8.23.5 2.9.19.5 3.0.10.5 3.1.4.3 3.2.8.4 3.3.9.2 2.8.23.4 2.9.19.4 3.0.10.4 3.1.4.2 3.2.8.3 3.3.9.1 trunk 1.14.8 2.7.31.3 2.8.23.3 2.9.19.3 3.0.10.3 3.1.4.1 3.2.0 3.2.1 3.2.1.1 3.2.2 3.2.4 3.2.5 3.2.6 3.2.7 3.2.7.1 3.2.8 3.2.8.1 3.2.8.2 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.3.8 3.3.9
pods / tribe-common / src / Tribe / Tracker.php
pods / tribe-common / src / Tribe Last commit date
Admin 2 weeks ago Ajax 2 weeks ago Asset 2 weeks ago Context 2 weeks ago Customizer 2 weeks ago Debug_Bar 2 weeks ago Dialog 2 weeks ago Documentation 2 weeks ago Duplicate 2 weeks ago Editor 2 weeks ago Image 2 weeks ago JSON_LD 2 weeks ago Languages 2 weeks ago Log 2 weeks ago Meta 2 weeks ago Models 2 weeks ago PUE 2 weeks ago Process 2 weeks ago Promoter 2 weeks ago REST 2 weeks ago Repository 2 weeks ago Service_Providers 2 weeks ago Shortcode 2 weeks ago Support 2 weeks ago Tabbed_View 2 weeks ago Tooltip 2 weeks ago Traits 2 weeks ago Utils 2 weeks ago Validator 2 weeks ago Widget 2 weeks ago Abstract_Deactivation.php 2 weeks ago Abstract_Plugin_Register.php 2 weeks ago App_Shop.php 2 weeks ago Assets.php 2 weeks ago Assets_Pipeline.php 2 weeks ago Autoloader.php 2 weeks ago Cache.php 2 weeks ago Cache_Listener.php 2 weeks ago Changelog_Reader.php 2 weeks ago Container.php 2 weeks ago Context.php 2 weeks ago Cost_Utils.php 2 weeks ago Credits.php 2 weeks ago Customizer.php 2 weeks ago DB_Lock.php 2 weeks ago Data.php 2 weeks ago Date_Utils.php 2 weeks ago Db.php 2 weeks ago Debug.php 2 weeks ago Dependency.php 2 weeks ago Deprecation.php 2 weeks ago Editor.php 2 weeks ago Error.php 2 weeks ago Exception.php 2 weeks ago Extension.php 2 weeks ago Extension_Loader.php 2 weeks ago Feature_Detection.php 2 weeks ago Field.php 2 weeks ago Field_Conditional.php 2 weeks ago Freemius.php 2 weeks ago Log.php 2 weeks ago Main.php 2 weeks ago Notices.php 2 weeks ago Plugin_Meta_Links.php 2 weeks ago Plugins.php 2 weeks ago Plugins_API.php 2 weeks ago Post_History.php 2 weeks ago Post_Transient.php 2 weeks ago Promise.php 2 weeks ago Repository.php 2 weeks ago Rewrite.php 2 weeks ago Settings.php 2 weeks ago Settings_Manager.php 2 weeks ago Settings_Tab.php 2 weeks ago Simple_Table.php 2 weeks ago Support.php 2 weeks ago Tabbed_View.php 2 weeks ago Template.php 2 weeks ago Template_Factory.php 2 weeks ago Template_Part_Cache.php 2 weeks ago Templates.php 2 weeks ago Terms.php 2 weeks ago Timezones.php 2 weeks ago Tracker.php 2 weeks ago Updater.php 2 weeks ago Validate.php 2 weeks ago View_Helpers.php 2 weeks ago
Tracker.php
468 lines
1 <?php
2
3 /**
4 * Class Tribe__Tracker
5 *
6 * Tracks changes of post attributes.
7 */
8 class Tribe__Tracker {
9 /**
10 * @var string The meta field used to track changes.
11 */
12 public static $field_key = '_tribe_modified_fields';
13
14 /**
15 * @var bool Whether the class is tracking terms or not.
16 */
17 protected $track_terms = true;
18
19 /**
20 * @var array An array of the tracked post types.
21 */
22 protected $tracked_post_types = [];
23
24 /**
25 * @var array An array of the tracked taxonomies.
26 */
27 protected $tracked_taxonomies = [];
28
29 /**
30 * Hooks up the methods that will actually track the fields we are looking for.
31 */
32 public function hook() {
33 // Track the Meta Updates for Meta That came from the correct Post Types
34 add_filter( 'update_post_metadata', [ $this, 'filter_watch_updated_meta' ], PHP_INT_MAX - 1, 5 );
35
36 // After a meta is added we mark that is has been modified
37 add_action( 'added_post_meta', [ $this, 'register_added_deleted_meta' ], PHP_INT_MAX - 1, 3 );
38
39 // Before a meta is removed we mark that is has been modified
40 add_action( 'delete_post_meta', [ $this, 'register_added_deleted_meta' ], PHP_INT_MAX - 1, 3 );
41
42 // Track the Post Fields Updates for Meta in the correct Post Types
43 add_action( 'post_updated', [ $this, 'filter_watch_post_fields' ], 10, 3 );
44
45 // Track the Post term updates
46 add_action( 'set_object_terms', [ $this, 'track_taxonomy_term_changes' ], 10, 6 );
47
48 // Clean up modified fields if the post is removed.
49 add_action( 'delete_post', [ $this, 'cleanup_meta_fields' ] );
50 }
51
52 /**
53 * Determines if a post value has been changed
54 *
55 * @param string $field Field to compare against
56 * @param array $new New data
57 * @param array $old WP_Post pre-update
58 *
59 * @return boolean
60 */
61 public function has_field_changed( $field, $new, $old ) {
62 if ( ! is_object( $new ) ) {
63 $new = (object) $new;
64 }
65
66 if ( ! is_object( $old ) ) {
67 $old = (object) $old;
68 }
69
70 if ( ! isset( $new->$field ) ) {
71 return false;
72 }
73
74 if ( isset( $new->$field ) && ! isset( $old->$field ) ) {
75 return true;
76 }
77
78 if ( $new->$field !== $old->$field ) {
79 return true;
80 }
81
82 return false;
83 }
84
85 /**
86 * Get the date(timestamp) of last modification for a tracked field.
87 *
88 * @since 4.12.3
89 *
90 * @param string $meta_key The key for the meta field we're interested in.
91 * @param int $post_id The ID of the post to check.
92 *
93 * @return boolean|string The change timestamp or false if the field is not found/empty.
94 */
95 public function get_modified_date( $meta_key, $post_id ) {
96 $modified = get_post_meta( $post_id, self::$field_key, true );
97
98 // If the key is missing or empty/null return false - no recorded change.
99 return Tribe__Utils__Array::get( $modified, $meta_key, false );
100 }
101
102 /**
103 * Easy way to see currently which post types are being tracked by our code.
104 *
105 * @return array
106 */
107 public function get_post_types() {
108 // By default we are not tracking anything
109 $tracked_post_types = [];
110
111 /**
112 * Adds a way for Developers to add and remove which post types will be tracked
113 *
114 * Note: Removing any of the default methods will affect how we deal with fields
115 * affected by the authority settings defined on this installation
116 *
117 * @var array
118 */
119 $tracked_post_types = (array) apply_filters( 'tribe_tracker_post_types', $this->tracked_post_types );
120
121 return $tracked_post_types;
122 }
123
124 /**
125 * Easy way to see currenlty which meta values are been tracked by our code
126 *
127 * @return array
128 */
129 public function get_excluded_meta_keys() {
130 // By default we are not tracking anything
131 $excluded_keys = [
132 '_edit_lock',
133 self::$field_key,
134 ];
135
136 /**
137 * Adds a way for Developers remove Meta Keys that shouldn't be tracked
138 *
139 * Note: Removing any of the default methods will affect how we deal with fields
140 * affected by the authority settings defined on this installation
141 *
142 * @var array
143 */
144 $excluded_keys = (array) apply_filters( 'tribe_tracker_excluded_meta_keys', $excluded_keys );
145
146 return $excluded_keys;
147 }
148
149 /**
150 * Make sure we are tracking all meta fields related on the correct Post Types
151 *
152 * @since 4.5
153 *
154 * @param int $meta_id Meta ID
155 * @param int $post_id Post ID.
156 * @param string $meta_key Meta key.
157 */
158 public function register_added_deleted_meta( $meta_id, $post_id, $meta_key ) {
159 /**
160 * Allows toggling the Modified fields tracking
161 * @var bool
162 */
163 $is_tracking_modified_fields = (bool) apply_filters( 'tribe_tracker_enabled', true );
164
165 // Bail if we shouldn't be tracking modifications
166 if ( false === $is_tracking_modified_fields ) {
167 return;
168 }
169
170 // Try to fetch the post object
171 $post = get_post( $post_id );
172
173 // We only go forward if we have the Post Object
174 if ( ! $post instanceof WP_Post ) {
175 return;
176 }
177
178 // Fetch from a unified method which meta keys are been excluded
179 $excluded_keys = $this->get_excluded_meta_keys();
180
181 // Bail when this meta is set to be excluded
182 if ( in_array( $meta_key, $excluded_keys ) ) {
183 return;
184 }
185
186 // Fetch from a unified method which post types are been tracked
187 $tracked_post_types = $this->get_post_types();
188
189 // Only track if the meta is from a post that is been tracked
190 if ( ! in_array( $post->post_type, $tracked_post_types ) ) {
191 return;
192 }
193
194 // Gets the Current Timestamp
195 $now = current_time( 'timestamp' );
196
197 // Fetch the current data from the modified fields
198 $modified = get_post_meta( $post->ID, self::$field_key, true );
199 if ( ! is_array( $modified ) ) {
200 $modified = [];
201 }
202
203 // If we got here we will update the Modified Meta
204 $modified[ $meta_key ] = $now;
205
206 // Actually do the Update
207 update_post_meta( $post->ID, self::$field_key, $modified );
208 }
209
210 /**
211 * Make sure we are tracking all meta fields related to the correct Post Types
212 *
213 * @since 4.5
214 *
215 * @param null|bool $check Whether to allow updating metadata for the given type.
216 * @param int $post_id Post ID.
217 * @param string $meta_key Meta key.
218 * @param mixed $meta_value Meta value. Must be serializable if non-scalar.
219 * @param mixed $prev_value Previous Value of the Meta, allowing to check the data
220 *
221 * @return null|bool This should be ignored, only used to not break the WordPress filters
222 */
223 public function filter_watch_updated_meta( $check, $post_id, $meta_key, $meta_value, $prev_value = null ) {
224 /**
225 * Allows toggling the Modified fields tracking
226 * @var bool
227 */
228 $is_tracking_modified_fields = (bool) apply_filters( 'tribe_tracker_enabled', true );
229
230 // Bail if we shouldn't be tracking modifications
231 if ( false === $is_tracking_modified_fields ) {
232 return $check;
233 }
234
235 // Matching the WordPress filter, we actually don't care about Check at all!
236 if ( null !== $check ) {
237 return (bool) $check;
238 }
239
240 // Try to fetch the post object
241 $post = get_post( $post_id );
242
243 // We only go forward if we have the Post Object
244 if ( ! $post instanceof WP_Post ) {
245 return $check;
246 }
247
248 // Fetch from a unified method which meta keys are been excluded
249 $excluded_keys = $this->get_excluded_meta_keys();
250
251 // Bail when this meta is set to be excluded
252 if ( in_array( $meta_key, $excluded_keys ) ) {
253 return $check;
254 }
255
256 // Fetch from a unified method which post types are been tracked
257 $tracked_post_types = $this->get_post_types();
258
259 // Only track if the meta is from a post that is been tracked
260 if ( ! in_array( $post->post_type, $tracked_post_types ) ) {
261 return $check;
262 }
263
264 if ( empty( $prev_value ) ) {
265 $prev_value = get_post_meta( $post->ID, $meta_key, true );
266 }
267
268 // We don't care if the value didn't actually change
269 if ( $prev_value == $meta_value ) {
270 return $check;
271 }
272
273 // Gets the Current Timestamp
274 $now = current_time( 'timestamp' );
275
276 // Fetch the current data from the modified fields
277 $modified = get_post_meta( $post->ID, self::$field_key, true );
278 if ( ! is_array( $modified ) ) {
279 $modified = [];
280 }
281
282 // If we got here we will update the Modified Meta
283 $modified[ $meta_key ] = $now;
284
285 // Actually do the Update
286 update_post_meta( $post->ID, self::$field_key, $modified );
287
288 // We need to return this, because we are still on a filter
289 return $check;
290 }
291
292 /**
293 * Tracks fields that are changed when an event is updated
294 *
295 * @param int $post_id Post ID
296 * @param WP_Post $post_after New post object
297 * @param WP_Post $post_before Old post object
298 */
299 public function filter_watch_post_fields( $post_id, $post_after, $post_before ) {
300 /**
301 * Allows toggling the Modified fields tracking
302 * @var bool
303 */
304 $is_tracking_modified_fields = (bool) apply_filters( 'tribe_tracker_enabled', true );
305
306 // Bail if we shouldn't be tracking modifications
307 if ( false === $is_tracking_modified_fields ) {
308 return;
309 }
310
311 // Fetch from a unified method which post types are been tracked
312 $tracked_post_types = $this->get_post_types();
313
314 // Only track if the meta is from a post that is been tracked
315 if ( ! in_array( $post_before->post_type, $tracked_post_types ) ) {
316 return;
317 }
318
319 // Fetch the current Time
320 $now = current_time( 'timestamp' );
321
322 if ( ! $modified = get_post_meta( $post_id, self::$field_key, true ) ) {
323 $modified = [];
324 }
325
326 $fields_to_check_for_changes = [
327 'post_title',
328 'post_content',
329 'post_excerpt',
330 'post_status',
331 'post_type',
332 'post_parent',
333 ];
334
335 foreach ( $fields_to_check_for_changes as $field ) {
336 if ( ! $this->has_field_changed( $field, $post_after, $post_before ) ) {
337 continue;
338 }
339
340 $modified[ $field ] = $now;
341 }
342
343 if ( $modified ) {
344 update_post_meta( $post_id, self::$field_key, $modified );
345 }
346 }
347
348 /**
349 * Track term changes for the tracked post types and terms.
350 *
351 * Meant to run on the `set_object_terms` action.
352 *
353 * @see wp_set_object_terms()
354 *
355 * @param $object_id
356 * @param $terms
357 * @param $tt_ids
358 * @param $taxonomy
359 * @param $append
360 * @param $old_tt_ids
361 *
362 * @return bool `true` if the post type and taxonomy are tracked, `false` otherwise.
363 */
364 public function track_taxonomy_term_changes( $object_id, $terms, $tt_ids, $taxonomy, $append, $old_tt_ids ) {
365 /**
366 * Allows toggling the post taxonomy terms tracking
367 *
368 * @var bool $track_terms Whether the class is currently tracking terms or not.
369 */
370 $is_tracking_taxonomy_terms = (bool) apply_filters( 'tribe_tracker_enabled_for_terms', $this->track_terms );
371
372 if ( false === $is_tracking_taxonomy_terms ) {
373 return false;
374 }
375
376 $tracked_post_types = $this->get_post_types();
377
378 $post_id = tribe_post_exists( $object_id );
379
380 if (
381 empty( $post_id )
382 || ! ( $post = get_post( $post_id ) )
383 || ! in_array( $post->post_type, $tracked_post_types )
384 ) {
385 return false;
386 }
387
388 $tracked_taxonomies = $this->get_taxonomies();
389
390 if ( ! in_array( $taxonomy, $tracked_taxonomies ) ) {
391 return false;
392 }
393
394 if ( ! $modified = get_post_meta( $post->ID, self::$field_key, true ) ) {
395 $modified = [];
396 }
397
398 if ( $tt_ids == $old_tt_ids ) {
399 // nothing to update, still we did the job
400 return true;
401 }
402
403 $modified[ $taxonomy ] = time();
404 update_post_meta( $post->ID, self::$field_key, $modified );
405
406 return true;
407 }
408
409 /**
410 * Easy way to see currently which taxonomies are been tracked by our code.
411 *
412 * @return array
413 */
414 public function get_taxonomies() {
415 /**
416 * Adds a way for Developers to add and remove which taxonomies will be tracked
417 *
418 * Note: Removing any of the default methods will affect how we deal with fields
419 * affected by the authority settings defined on this installation
420 *
421 * @var array $tracked_taxonomies An array of the tracker taxonomies names.
422 */
423 $tracked_taxonomies = (array) apply_filters( 'tribe_tracker_taxonomies', $this->tracked_taxonomies );
424
425 return $tracked_taxonomies;
426 }
427
428 /**
429 * Whether taxonomy term changes should be tracked or not by the class.
430 *
431 * @param bool $track_terms
432 */
433 public function should_track_terms( $track_terms ) {
434 $this->track_terms = $track_terms;
435 }
436
437 /**
438 * Sets the taxonomies the tracker should track.
439 *
440 * @param array $tracked_taxonomies
441 */
442 public function set_tracked_taxonomies( array $tracked_taxonomies ) {
443 $this->tracked_taxonomies = $tracked_taxonomies;
444 }
445
446 /**
447 * Sets the post types the tracker should track.
448 *
449 * @param array $tracked_post_types
450 */
451 public function set_tracked_post_types( array $tracked_post_types ) {
452 $this->tracked_post_types = $tracked_post_types;
453 }
454
455 /**
456 * Make sure to remove the changed field if the event is deleted to ensure there are no left meta fields when
457 * the event is deleted.
458 *
459 * @since 4.7.6
460 *
461 * @param int Post ID
462 * @return bool
463 */
464 public function cleanup_meta_fields( $post_id ) {
465 return delete_post_meta( (int) $post_id, self::$field_key );
466 }
467 }
468