class-wpseo-options-backfill.php 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. <?php
  2. /**
  3. * WPSEO plugin file.
  4. *
  5. * @package WPSEO\Internals\Options
  6. */
  7. /**
  8. * Backfill the removed options.
  9. *
  10. * @since 7.0.2
  11. */
  12. class WPSEO_Options_Backfill implements WPSEO_WordPress_Integration {
  13. /**
  14. * Are the filters hooked or not.
  15. *
  16. * @var bool
  17. */
  18. protected $hooked = false;
  19. /**
  20. * Registers all hooks to WordPress.
  21. */
  22. public function register_hooks() {
  23. // Make sure we don't hook multiple times.
  24. if ( $this->hooked ) {
  25. return;
  26. }
  27. $this->hooked = true;
  28. // Backfill options that were removed.
  29. foreach ( $this->get_lookups() as $option ) {
  30. add_filter( 'pre_option_' . $option, [ $this, 'backfill_option' ], 10, 2 );
  31. }
  32. // Make sure renamed meta key is backfilled.
  33. add_filter( 'get_user_metadata', [ $this, 'backfill_usermeta' ], 10, 3 );
  34. // Extend the options that have removed items.
  35. add_filter( 'option_wpseo_titles', [ $this, 'extend_wpseo_titles' ], 10, 1 );
  36. add_filter( 'option_wpseo', [ $this, 'extend_wpseo' ], 10, 1 );
  37. }
  38. /**
  39. * Removes the option filters.
  40. */
  41. public function remove_hooks() {
  42. // Remove backfill options filter.
  43. foreach ( $this->get_lookups() as $option ) {
  44. remove_filter( 'pre_option_' . $option, [ $this, 'backfill_option' ], 10 );
  45. }
  46. // Remove user meta filter.
  47. remove_filter( 'get_user_metadata', [ $this, 'backfill_usermeta' ], 10 );
  48. // Remove option extending filters.
  49. remove_filter( 'option_wpseo_titles', [ $this, 'extend_wpseo_titles' ], 10 );
  50. remove_filter( 'option_wpseo', [ $this, 'extend_wpseo' ], 10 );
  51. $this->hooked = false;
  52. }
  53. /**
  54. * Retrieves the options that need to be backfilled.
  55. *
  56. * @since 7.0.2
  57. *
  58. * @return array List of options that need to be backfilled.
  59. */
  60. protected function get_lookups() {
  61. return [
  62. 'wpseo_internallinks',
  63. 'wpseo_rss',
  64. 'wpseo_xml',
  65. 'wpseo_permalinks',
  66. ];
  67. }
  68. /**
  69. * Retrieves the settings for the specified option.
  70. *
  71. * @since 7.0.2
  72. *
  73. * @param string $option The option to get the settings for.
  74. *
  75. * @return array The settings for the provided option.
  76. */
  77. protected function get_settings( $option ) {
  78. $settings = [
  79. 'wpseo' => [
  80. 'website_name' => 'website_name',
  81. 'alternate_website_name' => 'alternate_website_name',
  82. 'company_logo' => 'company_logo',
  83. 'company_name' => 'company_name',
  84. 'company_or_person' => 'company_or_person',
  85. 'person_name' => 'person_name',
  86. ],
  87. 'wpseo_internallinks' => [
  88. 'breadcrumbs-404crumb' => 'breadcrumbs-404crumb',
  89. 'breadcrumbs-blog-remove' => 'breadcrumbs-display-blog-page',
  90. 'breadcrumbs-boldlast' => 'breadcrumbs-boldlast',
  91. 'breadcrumbs-archiveprefix' => 'breadcrumbs-archiveprefix',
  92. 'breadcrumbs-enable' => 'breadcrumbs-enable',
  93. 'breadcrumbs-home' => 'breadcrumbs-home',
  94. 'breadcrumbs-prefix' => 'breadcrumbs-prefix',
  95. 'breadcrumbs-searchprefix' => 'breadcrumbs-searchprefix',
  96. 'breadcrumbs-sep' => 'breadcrumbs-sep',
  97. ],
  98. 'wpseo_rss' => [
  99. 'rssbefore' => 'rssbefore',
  100. 'rssafter' => 'rssafter',
  101. ],
  102. 'wpseo_xml' => [
  103. 'enablexmlsitemap' => 'enable_xml_sitemap',
  104. 'disable_author_sitemap' => 'noindex-author-wpseo',
  105. 'disable_author_noposts' => 'noindex-author-noposts-wpseo',
  106. ],
  107. 'wpseo_permalinks' => [
  108. 'redirectattachment' => 'disable-attachment',
  109. 'stripcategorybase' => 'stripcategorybase',
  110. ],
  111. ];
  112. if ( ! isset( $settings[ $option ] ) ) {
  113. return [];
  114. }
  115. return $settings[ $option ];
  116. }
  117. /**
  118. * Extends the WPSEO option with the removed option values.
  119. *
  120. * @since 7.0.2
  121. *
  122. * @param array $data The data of the option.
  123. *
  124. * @return array Modified data.
  125. */
  126. public function extend_wpseo( $data ) {
  127. // Make sure we don't get stuck in an infinite loop.
  128. static $running = false;
  129. // If we are already running, don't run again.
  130. if ( $running ) {
  131. return $data;
  132. }
  133. $running = true;
  134. foreach ( $this->get_settings( 'wpseo' ) as $old_key => $new_key ) {
  135. $data[ $old_key ] = WPSEO_Options::get( $new_key );
  136. }
  137. // Ended running.
  138. $running = false;
  139. return $data;
  140. }
  141. /**
  142. * Extends the WPSEO Title with removed attributes.
  143. *
  144. * @since 7.0.2
  145. *
  146. * @param array $data Data of the option.
  147. *
  148. * @return array Extended data.
  149. */
  150. public function extend_wpseo_titles( $data ) {
  151. // Make sure we don't get stuck in an infinite loop.
  152. static $running = false;
  153. // If we are already running, don't run again.
  154. if ( $running ) {
  155. return $data;
  156. }
  157. $running = true;
  158. $data['breadcrumbs-blog-remove'] = ! WPSEO_Options::get( 'breadcrumbs-display-blog-page' );
  159. $running = false;
  160. $data = $this->add_hideeditbox( $data );
  161. return $data;
  162. }
  163. /**
  164. * Backfills the options that have been removed with the current values.
  165. *
  166. * @since 7.0.2
  167. *
  168. * @param mixed $value Current value for the option.
  169. * @param string $option Name of the option.
  170. *
  171. * @return array Option data.
  172. */
  173. public function backfill_option( $value, $option ) {
  174. $output = [];
  175. foreach ( $this->get_settings( $option ) as $old_key => $new_key ) {
  176. $output[ $old_key ] = WPSEO_Options::get( $new_key );
  177. }
  178. $output = $this->apply_permalinks_settings( $output, $option );
  179. $output = $this->apply_xml_settings( $output, $option );
  180. return $output;
  181. }
  182. /**
  183. * Backfills removed user meta fields.
  184. *
  185. * @since 7.0.2
  186. *
  187. * @param mixed $value The current value.
  188. * @param int $object_id The user ID.
  189. * @param string $meta_key The meta key.
  190. *
  191. * @return mixed The backfilled value if applicable.
  192. */
  193. public function backfill_usermeta( $value, $object_id, $meta_key ) {
  194. if ( $meta_key !== 'wpseo_excludeauthorsitemap' ) {
  195. return $value;
  196. }
  197. return get_user_meta( $object_id, 'wpseo_noindex_author' );
  198. }
  199. /**
  200. * Extends the data of the option with the deprecated values.
  201. *
  202. * @since 7.0.2
  203. *
  204. * @param array $data Current data of the option.
  205. *
  206. * @return array Extended data.
  207. */
  208. protected function add_hideeditbox( $data ) {
  209. foreach ( $data as $key => $value ) {
  210. if ( strpos( $key, 'display-metabox-tax-' ) === 0 ) {
  211. $taxonomy = substr( $key, strlen( 'display-metabox-tax-' ) );
  212. $data[ 'hideeditbox-tax-' . $taxonomy ] = ! $value;
  213. continue;
  214. }
  215. if ( strpos( $key, 'display-metabox-pt-' ) === 0 ) {
  216. $post_type = substr( $key, strlen( 'display-metabox-pt-' ) );
  217. $data[ 'hideeditbox-' . $post_type ] = ! $value;
  218. continue;
  219. }
  220. }
  221. return $data;
  222. }
  223. /**
  224. * Adds the permalinks specific data to the option when requested.
  225. *
  226. * @since 7.0.2
  227. *
  228. * @param array $data Current data.
  229. * @param string $option The option that is being parsed.
  230. *
  231. * @return array Extended data.
  232. */
  233. protected function apply_permalinks_settings( $data, $option ) {
  234. if ( $option !== 'wpseo_permalinks' ) {
  235. return $data;
  236. }
  237. // Add defaults for completely removed settings in the option.
  238. return array_merge(
  239. $data,
  240. [
  241. 'cleanpermalinks' => false,
  242. 'cleanpermalink-extravars' => '',
  243. 'cleanpermalink-googlecampaign' => false,
  244. 'cleanpermalink-googlesitesearch' => false,
  245. 'cleanreplytocom' => false,
  246. 'cleanslugs' => false,
  247. 'trailingslash' => false,
  248. ]
  249. );
  250. }
  251. /**
  252. * Adds the XML specific data to the option when requested.
  253. *
  254. * @since 7.0.2
  255. *
  256. * @param array $data Current data.
  257. * @param string $option The option that is being parsed.
  258. *
  259. * @return array Extended data.
  260. */
  261. protected function apply_xml_settings( $data, $option ) {
  262. if ( $option !== 'wpseo_xml' ) {
  263. return $data;
  264. }
  265. // Add dynamic implementations for settings that are not in any option anymore.
  266. return array_merge(
  267. $data,
  268. [
  269. 'entries-per-page' => (int) apply_filters( 'wpseo_sitemap_entries_per_page', 1000 ),
  270. 'excluded-posts' => apply_filters( 'wpseo_exclude_from_sitemap_by_post_ids', [] ),
  271. ]
  272. );
  273. }
  274. }