/wp-content/plugins/wp-migrate-db/class/wpmdb-replace.php

https://gitlab.com/haque.mdmanzurul/wp-harpar-carolyn · PHP · 213 lines · 114 code · 28 blank · 71 comment · 15 complexity · 84fdbc5f8c36f1ed9e77459309b22230 MD5 · raw file

  1. <?php
  2. final class WPMDB_Replace {
  3. protected $search;
  4. protected $replace;
  5. protected $subdomain_replaces_on;
  6. protected $wpmdb;
  7. private $table;
  8. private $column;
  9. private $row;
  10. function __construct( $table, $search, $replace, $wpmdb ) {
  11. $this->table = $table;
  12. $this->search = $search;
  13. $this->replace = $replace;
  14. $this->wpmdb = $wpmdb;
  15. }
  16. /**
  17. * Determine whether to apply a subdomain replace over each value in the database.
  18. *
  19. * @return bool
  20. */
  21. function is_subdomain_replaces_on() {
  22. if ( ! isset( $this->subdomain_replaces_on ) ) {
  23. $this->subdomain_replaces_on = ( is_multisite() && defined( 'SUBDOMAIN_INSTALL' ) && SUBDOMAIN_INSTALL && apply_filters( 'wpmdb_subdomain_replace', true ) );
  24. }
  25. return $this->subdomain_replaces_on;
  26. }
  27. /**
  28. * Automatically replace URLs for subdomain based multisite installations
  29. * e.g. //site1.example.com -> //site1.example.local for site with domain example.com
  30. * NB: only handles the current network site, does not work for additional networks / mapped domains
  31. *
  32. * @param $new
  33. *
  34. * @return mixed
  35. */
  36. function subdomain_replaces( $new ) {
  37. $domain_replace = $this->wpmdb->get_domain_replace();
  38. if ( empty( $domain_replace ) ) {
  39. return $new;
  40. }
  41. $pattern = '|//(.*?)\\.' . preg_quote( $this->wpmdb->get_domain_current_site(), '|' ) . '|';
  42. $replacement = '//$1.' . trim( $domain_replace );
  43. $new = preg_replace( $pattern, $replacement, $new );
  44. return $new;
  45. }
  46. /**
  47. * Applies find/replace pairs to a given string.
  48. *
  49. * @param string $subject
  50. *
  51. * @return string
  52. */
  53. function apply_replaces( $subject ) {
  54. $new = str_ireplace( $this->search, $this->replace, $subject, $count );
  55. if ( $this->is_subdomain_replaces_on() ) {
  56. $new = $this->subdomain_replaces( $new );
  57. }
  58. return $new;
  59. }
  60. /**
  61. * Take a serialized array and unserialize it replacing elements as needed and
  62. * unserialising any subordinate arrays and performing the replace on those too.
  63. *
  64. * Mostly from https://github.com/interconnectit/Search-Replace-DB
  65. *
  66. * @param array $data Used to pass any subordinate arrays back to in.
  67. * @param bool $serialized Does the array passed via $data need serialising.
  68. * @param bool $parent_serialized Passes whether the original data passed in was serialized
  69. *
  70. * @return array The original array with all elements replaced as needed.
  71. */
  72. function recursive_unserialize_replace( $data, $serialized = false, $parent_serialized = false ) {
  73. $pre = apply_filters( 'wpmdb_pre_recursive_unserialize_replace', false, $data, $this );
  74. if ( false !== $pre ) {
  75. return $pre;
  76. }
  77. $is_json = false;
  78. // some unserialized data cannot be re-serialized eg. SimpleXMLElements
  79. try {
  80. if ( is_string( $data ) && ( $unserialized = @unserialize( $data ) ) !== false ) {
  81. // PHP currently has a bug that doesn't allow you to clone the DateInterval / DatePeriod classes.
  82. // We skip them here as they probably won't need data to be replaced anyway
  83. if ( is_object( $unserialized ) ) {
  84. if ( $unserialized instanceof DateInterval || $unserialized instanceof DatePeriod ) {
  85. return $data;
  86. }
  87. }
  88. $data = $this->recursive_unserialize_replace( $unserialized, true, true );
  89. } elseif ( is_array( $data ) ) {
  90. $_tmp = array();
  91. foreach ( $data as $key => $value ) {
  92. $_tmp[ $key ] = $this->recursive_unserialize_replace( $value, false, $parent_serialized );
  93. }
  94. $data = $_tmp;
  95. unset( $_tmp );
  96. } elseif ( is_object( $data ) ) { // Submitted by Tina Matter
  97. $_tmp = clone $data;
  98. foreach ( $data as $key => $value ) {
  99. $_tmp->$key = $this->recursive_unserialize_replace( $value, false, $parent_serialized );
  100. }
  101. $data = $_tmp;
  102. unset( $_tmp );
  103. } elseif ( $this->wpmdb->is_json( $data, true ) ) {
  104. $_tmp = array();
  105. $data = json_decode( $data, true );
  106. foreach ( $data as $key => $value ) {
  107. $_tmp[ $key ] = $this->recursive_unserialize_replace( $value, false, $parent_serialized );
  108. }
  109. $data = $_tmp;
  110. unset( $_tmp );
  111. $is_json = true;
  112. } elseif ( is_string( $data ) ) {
  113. list( $data, $do_replace ) = apply_filters( 'wpmdb_replace_custom_data', array( $data, true ), $this );
  114. if ( $do_replace ) {
  115. $data = $this->apply_replaces( $data );
  116. }
  117. }
  118. if ( $serialized ) {
  119. return serialize( $data );
  120. }
  121. if ( $is_json ) {
  122. return json_encode( $data );
  123. }
  124. } catch ( Exception $error ) {
  125. $error_msg = __( 'Failed attempting to do the recursive unserialize replace. Please contact support.', 'wp-migrate-db' );
  126. $error_details = $error->getMessage() . "\n\n";
  127. $error_details .= var_export( $data, true );
  128. $this->wpmdb->log_error( $error_msg, $error_details );
  129. }
  130. return $data;
  131. }
  132. /**
  133. * Getter for the $table class property.
  134. *
  135. * @return string Name of the table currently being processed in the migration.
  136. */
  137. public function get_table() {
  138. return $this->table;
  139. }
  140. /**
  141. * Getter for the $column class property.
  142. *
  143. * @return string Name of the column currently being processed in the migration.
  144. */
  145. public function get_column() {
  146. return $this->column;
  147. }
  148. /**
  149. * Getter for the $row class property.
  150. *
  151. * @return string Name of the row currently being processed in the migration.
  152. */
  153. public function get_row() {
  154. return $this->row;
  155. }
  156. /**
  157. * Setter for the $column class property.
  158. *
  159. * @param string $column Name of the column currently being processed in the migration.
  160. */
  161. public function set_column( $column ) {
  162. $this->column = $column;
  163. }
  164. /**
  165. * Setter for the $row class property.
  166. *
  167. * @param string $row Name of the row currently being processed in the migration.
  168. */
  169. public function set_row( $row ) {
  170. $this->row = $row;
  171. }
  172. /**
  173. * Multsite safe way of comparing the table currently being processed in the migration against a desired table.
  174. *
  175. * The table prefix should be omitted, example:
  176. *
  177. * $is_posts = $this->table_is( 'posts' );
  178. *
  179. * @param string $desired_table Name of the desired table, table prefix omitted.
  180. * @return boolean Whether or not the desired table is the table currently being processed.
  181. */
  182. public function table_is( $desired_table ) {
  183. return $this->wpmdb->table_is( $desired_table, $this->table );
  184. }
  185. }