Pods_Term_Splitting

The Pods - Custom Content Types and Fields Pods Term Splitting class.

Defined (1)

The class is defined in the following location(s).

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