PluginProbe ʕ •ᴥ•ʔ
Pods – Custom Content Types and Fields / 2.7.31.4
Pods – Custom Content Types and Fields v2.7.31.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 / classes / PodsTermSplitting.php
pods / classes Last commit date
cli 4 days ago fields 4 days ago widgets 4 days ago Pods.php 4 days ago PodsAPI.php 4 days ago PodsAdmin.php 4 days ago PodsArray.php 4 days ago PodsComponent.php 4 days ago PodsComponents.php 4 days ago PodsData.php 4 days ago PodsField.php 4 days ago PodsForm.php 4 days ago PodsI18n.php 4 days ago PodsInit.php 4 days ago PodsMeta.php 4 days ago PodsMigrate.php 4 days ago PodsRESTFields.php 4 days ago PodsRESTHandlers.php 4 days ago PodsTermSplitting.php 4 days ago PodsUI.php 4 days ago PodsView.php 4 days ago
PodsTermSplitting.php
505 lines
1 <?php
2
3 /**
4 * @package Pods
5 */
6 class Pods_Term_Splitting {
7
8 /** @var int ID of the formerly shared term */
9 private $term_id;
10
11 /** @var int ID of the new term created for the $term_taxonomy_id */
12 private $new_term_id;
13
14 /** @var string Taxonomy for the split term */
15 private $taxonomy;
16
17 /** @var string */
18 private $progress_option_name;
19
20 /** @var array */
21 private $previous_progress = array();
22
23 /**
24 * @param int $term_id ID of the formerly shared term.
25 * @param int $new_term_id ID of the new term created for the $term_taxonomy_id.
26 * @param string $taxonomy Taxonomy for the split term.
27 */
28 public function __construct( $term_id, $new_term_id, $taxonomy ) {
29
30 $this->term_id = $term_id;
31 $this->new_term_id = $new_term_id;
32 $this->taxonomy = $taxonomy;
33
34 $this->progress_option_name = "_pods_term_split_{$term_id}_{$taxonomy}";
35
36 }
37
38 /**
39 *
40 */
41 public function split_shared_term() {
42
43 // Stash any previous progress
44 $this->previous_progress = $this->get_progress();
45 if ( empty( $this->previous_progress ) ) {
46 $this->append_progress( 'started' );
47 $this->append_progress( "new term ID: {$this->new_term_id}" );
48 }
49
50 // Get the Pod information if the taxonomy is a Pod
51 $taxonomy_pod = $this->get_pod_info();
52
53 // Is the taxonomy a Pod?
54 if ( is_array( $taxonomy_pod ) ) {
55 $this->update_podsrel_taxonomy( $taxonomy_pod['id'] );
56
57 // Update the Pods table if the taxonomy is a table based Pod
58 if ( 'table' === $taxonomy_pod['storage'] ) {
59 $this->update_pod_table( $taxonomy_pod['pod_table'] );
60 }
61 }
62
63 // Track down all fields related to the target taxonomy and update stored term IDs as necessary
64 $this->update_relationships_to_term();
65
66 // Clean up
67 $this->delete_progress();
68
69 }
70
71 /**
72 * Return the Pod information for the specified taxonomy, or null if the taxonomy isn't a Pod
73 *
74 * @return array|bool|mixed|null
75 */
76 private function get_pod_info() {
77
78 $pod_info = null;
79
80 if ( pods_api()->pod_exists( $this->taxonomy ) ) {
81
82 // Load the taxonomy Pod
83 $params = array(
84 'name' => $this->taxonomy,
85 'table_info' => true,
86 );
87 $pod_info = pods_api()->load_pod( $params, false );
88 }
89
90 return $pod_info;
91
92 }
93
94 /**
95 * @param int $pod_id
96 */
97 private function update_podsrel_taxonomy( $pod_id ) {
98
99 /** @global wpdb $wpdb */
100 global $wpdb;
101
102 $task = "update_podsrel_taxonomy_{$pod_id}";
103 if ( ! $this->have_done( $task ) ) {
104
105 // UPDATE {$wpdb->prefix}podsrel SET item_id = {$new_term_id} WHERE pod_id = {$pod_id} AND item_id = {$term_id}
106 $table = "{$wpdb->prefix}podsrel";
107 $data = array( 'item_id' => $this->new_term_id );
108 $where = array(
109 'pod_id' => $pod_id,
110 'item_id' => $this->term_id,
111 );
112 $format = '%d';
113 $where_format = '%d';
114
115 $wpdb->update( $table, $data, $where, $format, $where_format );
116
117 $this->append_progress( $task );
118 }
119
120 }
121
122 /**
123 * @param string $pod_table
124 */
125 private function update_pod_table( $pod_table ) {
126
127 /** @global wpdb $wpdb */
128 global $wpdb;
129
130 $task = "update_pod_table_{$pod_table}";
131 if ( ! $this->have_done( $task ) ) {
132
133 // Prime the values and update
134 $data = array( 'id' => $this->new_term_id );
135 $where = array( 'id' => $this->term_id );
136 $format = '%d';
137 $where_format = '%d';
138 $wpdb->update( $pod_table, $data, $where, $format, $where_format );
139
140 $this->append_progress( $task );
141 }
142
143 }
144
145 /**
146 * Track down all fields related to the target taxonomy and update stored term IDs as necessary
147 */
148 private function update_relationships_to_term() {
149
150 // Loop through all Pods
151 $all_pods = pods_api()->load_pods();
152
153 if ( ! is_array( $all_pods ) ) {
154 return;
155 }
156
157 foreach ( $all_pods as $this_pod_id => $this_pod ) {
158
159 // Loop through all fields in this Pod
160 foreach ( $this_pod['fields'] as $this_field_name => $this_field ) {
161
162 // Ignore everything except relationship fields to this taxonomy
163 if ( 'pick' !== $this_field['type'] || 'taxonomy' !== $this_field['pick_object'] || $this->taxonomy != $this_field['pick_val'] ) {
164 continue;
165 }
166
167 // Update the term ID in podsrel everywhere it is the value for this field
168 $this->update_podsrel_related_term( $this_field['id'] );
169
170 // Fix-up any special-case relationships that store term IDs in their own meta table and/or serialized
171 switch ( $this_pod['type'] ) {
172
173 case 'post_type':
174 $this->update_postmeta( $this_pod['name'], $this_field_name );
175 break;
176
177 case 'comment':
178 $this->update_commentmeta( $this_field_name );
179 break;
180
181 case 'user':
182 $this->update_usermeta( $this_field_name );
183 break;
184
185 case 'settings':
186 $this->update_setting_meta( $this_pod['name'], $this_field_name );
187 break;
188 }
189 }//end foreach
190 }//end foreach
191
192 }
193
194 /**
195 * @param int $field_id
196 */
197 private function update_podsrel_related_term( $field_id ) {
198
199 /** @global wpdb $wpdb */
200 global $wpdb;
201
202 $task = "update_podsrel_related_term_{$field_id}";
203 if ( ! $this->have_done( $task ) ) {
204
205 // UPDATE {$wpdb->prefix}podsrel SET related_item_id = {$new_term_id} WHERE field_id = {$field_id} AND related_item_id = {$term_id}
206 $table = "{$wpdb->prefix}podsrel";
207 $data = array(
208 'related_item_id' => $this->new_term_id,
209 );
210 $where = array(
211 'field_id' => $field_id,
212 'related_item_id' => $this->term_id,
213 );
214 $format = '%d';
215 $where_format = '%d';
216 $wpdb->update( $table, $data, $where, $format, $where_format );
217
218 $this->append_progress( $task );
219 }
220
221 }
222
223 /**
224 * Called for all fields related to the target taxonomy that are in a post_type
225 *
226 * @param string $pod_name
227 * @param string $field_name
228 */
229 private function update_postmeta( $pod_name, $field_name ) {
230
231 /** @global wpdb $wpdb */
232 global $wpdb;
233
234 // Fix up the unserialized data
235 $task = "update_postmeta_{$pod_name}_{$field_name}_unserialized";
236 if ( ! $this->have_done( $task ) ) {
237
238 $wpdb->query(
239 $wpdb->prepare(
240 "
241 UPDATE
242 {$wpdb->postmeta} AS meta
243 LEFT JOIN {$wpdb->posts} AS t
244 ON meta.post_id = t.ID
245 SET
246 meta_value = %s
247 WHERE
248 meta_key = %s
249 AND meta_value = %s
250 AND t.post_type = %s
251 ", $this->new_term_id, $field_name, $this->term_id, $pod_name
252 )
253 );
254
255 $this->append_progress( $task );
256 }//end if
257
258 // Fix up the serialized data
259 $task = "update_postmeta_{$pod_name}_{$field_name}_serialized";
260 if ( ! $this->have_done( $task ) ) {
261
262 $meta_key = sprintf( '_pods_%s', $field_name );
263 $target_serialized = sprintf( ';i:%s;', $this->term_id );
264 $replace_serialized = sprintf( ';i:%s;', $this->new_term_id );
265
266 $wpdb->query(
267 $wpdb->prepare(
268 "
269 UPDATE
270 {$wpdb->postmeta} AS meta
271 LEFT JOIN {$wpdb->posts} AS t
272 ON meta.post_id = t.ID
273 SET
274 meta.meta_value = REPLACE( meta.meta_value, %s, %s )
275 WHERE
276 meta.meta_key = %s
277 AND t.post_type = %s
278 AND meta_value LIKE '%%%s%%'
279 ", $target_serialized, $replace_serialized, $meta_key, $pod_name, pods_sanitize_like( $target_serialized )
280 )
281 );
282
283 $this->append_progress( $task );
284 }//end if
285
286 }
287
288 /**
289 * Called for all fields related to the target taxonomy that are in a comment Pod
290 *
291 * @param string $field_name
292 */
293 private function update_commentmeta( $field_name ) {
294
295 /** @global wpdb $wpdb */
296 global $wpdb;
297
298 // Fix up the unserialized data
299 $task = "update_commentmeta_{$field_name}_unserialized";
300 if ( ! $this->have_done( $task ) ) {
301
302 $table = $wpdb->commentmeta;
303 $data = array( 'meta_value' => $this->new_term_id );
304 $where = array(
305 'meta_key' => $field_name,
306 'meta_value' => $this->term_id,
307 );
308 $format = '%s';
309 $where_format = array( '%s', '%s' );
310 $wpdb->update( $table, $data, $where, $format, $where_format );
311
312 $this->append_progress( $task );
313 }
314
315 // Fix up the serialized data
316 $task = "update_commentmeta_{$field_name}_serialized";
317 if ( ! $this->have_done( $task ) ) {
318
319 $meta_key = sprintf( '_pods_%s', $field_name );
320 $target_serialized = sprintf( ';i:%s;', $this->term_id );
321 $replace_serialized = sprintf( ';i:%s;', $this->new_term_id );
322
323 $wpdb->query(
324 $wpdb->prepare(
325 "
326 UPDATE
327 {$wpdb->commentmeta}
328 SET
329 meta_value = REPLACE( meta_value, %s, %s )
330 WHERE
331 meta_key = %s
332 AND meta_value LIKE '%%%s%%'
333 ", $target_serialized, $replace_serialized, $meta_key, pods_sanitize_like( $target_serialized )
334 )
335 );
336
337 $this->append_progress( $task );
338 }//end if
339
340 }
341
342 /**
343 * Called for all fields related to the target taxonomy that are in a user Pod
344 *
345 * @param string $field_name
346 */
347 private function update_usermeta( $field_name ) {
348
349 /** @global wpdb $wpdb */
350 global $wpdb;
351
352 // Fix up the unserialized data
353 $task = "update_usermeta_{$field_name}_unserialized";
354 if ( ! $this->have_done( $task ) ) {
355
356 $table = $wpdb->usermeta;
357 $data = array( 'meta_value' => $this->new_term_id );
358 $where = array(
359 'meta_key' => $field_name,
360 'meta_value' => $this->term_id,
361 );
362 $format = '%s';
363 $where_format = array( '%s', '%s' );
364 $wpdb->update( $table, $data, $where, $format, $where_format );
365
366 $this->append_progress( $task );
367 }
368
369 // Fix up the serialized data
370 $task = "update_usermeta_{$field_name}_serialized";
371 if ( ! $this->have_done( $task ) ) {
372
373 $meta_key = sprintf( '_pods_%s', $field_name );
374 $target_serialized = sprintf( ';i:%s;', $this->term_id );
375 $replace_serialized = sprintf( ';i:%s;', $this->new_term_id );
376
377 $wpdb->query(
378 $wpdb->prepare(
379 "
380 UPDATE
381 {$wpdb->usermeta}
382 SET
383 meta_value = REPLACE( meta_value, %s, %s )
384 WHERE
385 meta_key = %s
386 AND meta_value LIKE '%%%s%%'
387 ", $target_serialized, $replace_serialized, $meta_key, pods_sanitize_like( $target_serialized )
388 )
389 );
390
391 $this->append_progress( $task );
392 }//end if
393
394 }
395
396 /**
397 * Called for all fields related to the target taxonomy that are in a user Pod
398 *
399 * @param string $pod_name
400 * @param string $field_name
401 */
402 private function update_setting_meta( $pod_name, $field_name ) {
403
404 /** @global wpdb $wpdb */
405 global $wpdb;
406
407 $option_name = "{$pod_name}_{$field_name}";
408
409 // Fix up the unserialized data
410 $task = "update_setting_meta_{$pod_name}_{$field_name}_unserialized";
411 if ( ! $this->have_done( $task ) ) {
412
413 // UPDATE {$wpdb->options} SET option_value = '{$new_term_id}' WHERE option_name = '{$pod_name}_{$field_name}' AND option_value = '{$term_id}'
414 $table = $wpdb->options;
415 $data = array( 'option_value' => $this->new_term_id );
416 $where = array(
417 'option_name' => $option_name,
418 'option_value' => $this->term_id,
419 );
420 $format = '%s';
421 $where_format = array( '%s', '%s' );
422 $wpdb->update( $table, $data, $where, $format, $where_format );
423
424 $this->append_progress( $task );
425 }
426
427 // Fix up the serialized data
428 $task = "update_setting_meta_{$pod_name}_{$field_name}_serialized";
429 if ( ! $this->have_done( $task ) ) {
430
431 $target_serialized = sprintf( ';i:%s;', $this->term_id );
432 $replace_serialized = sprintf( ';i:%s;', $this->new_term_id );
433
434 $wpdb->query(
435 $wpdb->prepare(
436 "
437 UPDATE
438 {$wpdb->options}
439 SET
440 option_value = REPLACE( option_value, %s, %s )
441 WHERE
442 option_name = %s
443 AND option_value LIKE '%%%s%%'
444 ", $target_serialized, $replace_serialized, $option_name, pods_sanitize_like( $target_serialized )
445 )
446 );
447
448 $this->append_progress( $task );
449 }//end if
450
451 }
452
453 /**
454 * @param string $task_name
455 *
456 * @return bool
457 */
458 private function have_done( $task_name ) {
459
460 return in_array( $task_name, $this->previous_progress );
461
462 }
463
464 /**
465 * @return array
466 */
467 private function get_progress() {
468
469 return get_option( $this->progress_option_name, array() );
470 }
471
472 /**
473 * @param $data
474 */
475 private function append_progress( $data ) {
476
477 // Get the current progress array
478 $current_progress = $this->get_progress();
479 if ( ! is_array( $current_progress ) ) {
480 $current_progress = array();
481 }
482
483 // Tack on the new data
484 $updated_progress = array_merge( $current_progress, array( $data ) );
485
486 // Note: we don't want autoload set and you cannot specify autoload via update_option
487 if ( ! empty( $current_progress ) && is_array( $current_progress ) ) {
488 update_option( $this->progress_option_name, $updated_progress );
489 } else {
490 add_option( $this->progress_option_name, $updated_progress, '', false );
491 }
492
493 }
494
495 /**
496 *
497 */
498 private function delete_progress() {
499
500 delete_option( $this->progress_option_name );
501
502 }
503
504 }
505