This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
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; |
||
0 ignored issues
–
show
|
|||
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} |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
36% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
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; |
||
0 ignored issues
–
show
Compatibility
Best Practice
introduced
by
Use of
global functionality is not recommended; it makes your code harder to test, and less reusable.
Instead of relying on 1. Pass all data via parametersfunction myFunction($a, $b) {
// Do something
}
2. Create a class that maintains your stateclass MyClass {
private $a;
private $b;
public function __construct($a, $b) {
$this->a = $a;
$this->b = $b;
}
public function myFunction() {
// Do something
}
}
![]() |
|||
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; |
||
0 ignored issues
–
show
Compatibility
Best Practice
introduced
by
Use of
global functionality is not recommended; it makes your code harder to test, and less reusable.
Instead of relying on 1. Pass all data via parametersfunction myFunction($a, $b) {
// Do something
}
2. Create a class that maintains your stateclass MyClass {
private $a;
private $b;
public function __construct($a, $b) {
$this->a = $a;
$this->b = $b;
}
public function myFunction() {
// Do something
}
}
![]() |
|||
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} |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
36% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
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; |
||
0 ignored issues
–
show
Compatibility
Best Practice
introduced
by
Use of
global functionality is not recommended; it makes your code harder to test, and less reusable.
Instead of relying on 1. Pass all data via parametersfunction myFunction($a, $b) {
// Do something
}
2. Create a class that maintains your stateclass MyClass {
private $a;
private $b;
public function __construct($a, $b) {
$this->a = $a;
$this->b = $b;
}
public function myFunction() {
// Do something
}
}
![]() |
|||
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; |
||
0 ignored issues
–
show
Compatibility
Best Practice
introduced
by
Use of
global functionality is not recommended; it makes your code harder to test, and less reusable.
Instead of relying on 1. Pass all data via parametersfunction myFunction($a, $b) {
// Do something
}
2. Create a class that maintains your stateclass MyClass {
private $a;
private $b;
public function __construct($a, $b) {
$this->a = $a;
$this->b = $b;
}
public function myFunction() {
// Do something
}
}
![]() |
|||
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 ); |
||
0 ignored issues
–
show
|
|||
304 | $where = array( |
||
305 | 'meta_key' => $field_name, |
||
0 ignored issues
–
show
|
|||
306 | 'meta_value' => $this->term_id, |
||
0 ignored issues
–
show
|
|||
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; |
||
0 ignored issues
–
show
Compatibility
Best Practice
introduced
by
Use of
global functionality is not recommended; it makes your code harder to test, and less reusable.
Instead of relying on 1. Pass all data via parametersfunction myFunction($a, $b) {
// Do something
}
2. Create a class that maintains your stateclass MyClass {
private $a;
private $b;
public function __construct($a, $b) {
$this->a = $a;
$this->b = $b;
}
public function myFunction() {
// Do something
}
}
![]() |
|||
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 ); |
||
0 ignored issues
–
show
|
|||
358 | $where = array( |
||
359 | 'meta_key' => $field_name, |
||
0 ignored issues
–
show
|
|||
360 | 'meta_value' => $this->term_id, |
||
0 ignored issues
–
show
|
|||
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; |
||
0 ignored issues
–
show
Compatibility
Best Practice
introduced
by
Use of
global functionality is not recommended; it makes your code harder to test, and less reusable.
Instead of relying on 1. Pass all data via parametersfunction myFunction($a, $b) {
// Do something
}
2. Create a class that maintains your stateclass MyClass {
private $a;
private $b;
public function __construct($a, $b) {
$this->a = $a;
$this->b = $b;
}
public function myFunction() {
// Do something
}
}
![]() |
|||
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 |
Instead of relying on
global
state, we recommend one of these alternatives:1. Pass all data via parameters
2. Create a class that maintains your state