PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / trunk
Yoast SEO – Advanced SEO with real-time guidance and built-in AI vtrunk
28.5 28.4 28.3 28.2 28.1 28.0 27.9 27.8 27.7 27.6 27.5 trunk 18.0 18.1 18.2 18.3 18.4 18.4.1 18.5 18.5.1 18.6 18.7 18.8 18.9 19.0 All 129 releases
wordpress-seo / admin / import / plugins / class-import-aioseo-v4.php

class-import-aioseo-v4.php in Yoast SEO – Advanced SEO with real-time guidance and built-in AI trunk, at admin/import/plugins/class-import-aioseo-v4.php

242 lines 9.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * File with the class to handle data from All in One SEO Pack, versions 4 and up.
4 *
5 * @package WPSEO\Admin\Import\Plugins
6 */
7
8 use Yoast\WP\SEO\Actions\Importing\Aioseo\Aioseo_Cleanup_Action;
9 use Yoast\WP\SEO\Actions\Importing\Aioseo\Aioseo_Posts_Importing_Action;
10
11 /**
12 * Class with functionality to import & clean All in One SEO Pack post metadata, versions 4 and up.
13 */
14 class WPSEO_Import_AIOSEO_V4 extends WPSEO_Plugin_Importer {
15
16 /**
17 * The plugin name.
18 *
19 * @var string
20 */
21 protected $plugin_name = 'All In One SEO Pack';
22
23 /**
24 * Meta key, used in SQL LIKE clause for delete query.
25 *
26 * @var string
27 */
28 protected $meta_key = '_aioseo_%';
29
30 /**
31 * Array of meta keys to detect and import.
32 *
33 * @var array
34 */
35 protected $clone_keys = [
36 [
37 'old_key' => '_aioseo_title',
38 'new_key' => 'title',
39 ],
40 [
41 'old_key' => '_aioseo_description',
42 'new_key' => 'metadesc',
43 ],
44 [
45 'old_key' => '_aioseo_og_title',
46 'new_key' => 'opengraph-title',
47 ],
48 [
49 'old_key' => '_aioseo_og_description',
50 'new_key' => 'opengraph-description',
51 ],
52 [
53 'old_key' => '_aioseo_twitter_title',
54 'new_key' => 'twitter-title',
55 ],
56 [
57 'old_key' => '_aioseo_twitter_description',
58 'new_key' => 'twitter-description',
59 ],
60 ];
61
62 /**
63 * Mapping between the AiOSEO replace vars and the Yoast replace vars.
64 *
65 * @see https://yoast.com/help/list-available-snippet-variables-yoast-seo/
66 *
67 * @var array
68 */
69 protected $replace_vars = [
70 // They key is the AiOSEO replace var, the value is the Yoast replace var (see class-wpseo-replace-vars).
71 '#author_first_name' => '%%author_first_name%%',
72 '#author_last_name' => '%%author_last_name%%',
73 '#author_name' => '%%name%%',
74 '#categories' => '%%category%%',
75 '#current_date' => '%%currentdate%%',
76 '#current_day' => '%%currentday%%',
77 '#current_month' => '%%currentmonth%%',
78 '#current_year' => '%%currentyear%%',
79 '#permalink' => '%%permalink%%',
80 '#post_content' => '%%post_content%%',
81 '#post_date' => '%%date%%',
82 '#post_day' => '%%post_day%%',
83 '#post_month' => '%%post_month%%',
84 '#post_title' => '%%title%%',
85 '#post_year' => '%%post_year%%',
86 '#post_excerpt_only' => '%%excerpt_only%%',
87 '#post_excerpt' => '%%excerpt%%',
88 '#separator_sa' => '%%sep%%',
89 '#site_title' => '%%sitename%%',
90 '#tagline' => '%%sitedesc%%',
91 '#taxonomy_title' => '%%category_title%%',
92 ];
93
94 /**
95 * Replaces the AiOSEO variables in our temporary table with Yoast variables (replace vars).
96 *
97 * @param array $replace_values Key value pair of values to replace with other values. This is only used in the base class but not here.
98 * That is because this class doesn't have any `convert` keys in `$clone_keys`.
99 * For that reason, we're overwriting the base class' `meta_key_clone_replace()` function without executing that base functionality.
100 *
101 * @return void
102 */
103 protected function meta_key_clone_replace( $replace_values ) {
104 global $wpdb;
105
106 // At this point we're already looping through all the $clone_keys (this happens in meta_keys_clone() in the abstract class).
107 // Now, we'll also loop through the replace_vars array, which holds the mappings between the AiOSEO variables and the Yoast variables.
108 // We'll replace all the AiOSEO variables in the temporary table with their Yoast equivalents.
109 foreach ( $this->replace_vars as $aioseo_variable => $yoast_variable ) {
110 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: We need this query and this is done at many other places as well, for example class-import-rankmath.
111 $wpdb->query(
112 $wpdb->prepare(
113 'UPDATE tmp_meta_table SET meta_value = REPLACE( meta_value, %s, %s )',
114 $aioseo_variable,
115 $yoast_variable,
116 ),
117 );
118 }
119
120 // The AiOSEO custom fields take the form of `#custom_field-myfield`.
121 // These should be mapped to %%cf_myfield%%.
122 $meta_values_with_custom_fields = $this->get_meta_values_with_custom_field_or_taxonomy( $wpdb, 'custom_field' );
123 $unique_custom_fields = $this->get_unique_custom_fields_or_taxonomies( $meta_values_with_custom_fields, 'custom_field' );
124 $this->replace_custom_field_or_taxonomy_replace_vars( $unique_custom_fields, $wpdb, 'custom_field', 'cf' );
125
126 // Map `#tax_name-{tax-slug}` to `%%ct_{tax-slug}%%``.
127 $meta_values_with_custom_taxonomies = $this->get_meta_values_with_custom_field_or_taxonomy( $wpdb, 'tax_name' );
128 $unique_custom_taxonomies = $this->get_unique_custom_fields_or_taxonomies( $meta_values_with_custom_taxonomies, 'tax_name' );
129 $this->replace_custom_field_or_taxonomy_replace_vars( $unique_custom_taxonomies, $wpdb, 'tax_name', 'ct' );
130 }
131
132 /**
133 * Filters out all unique custom fields/taxonomies/etc. used in an AiOSEO replace var.
134 *
135 * @param string[] $meta_values An array of all the meta values that
136 * contain one or more AIOSEO custom field replace vars
137 * (in the form `#custom_field-xyz`).
138 * @param string $aioseo_prefix The AiOSEO prefix to use
139 * (e.g. `custom-field` for custom fields or `tax_name` for custom taxonomies).
140 *
141 * @return string[] An array of all the unique custom fields/taxonomies/etc. used in the replace vars.
142 * E.g. `xyz` in the above example.
143 */
144 protected function get_unique_custom_fields_or_taxonomies( $meta_values, $aioseo_prefix ) {
145 $unique_custom_fields_or_taxonomies = [];
146
147 foreach ( $meta_values as $meta_value ) {
148 // Find all custom field replace vars, store them in `$matches`.
149 preg_match_all(
150 "/#$aioseo_prefix-([\w-]+)/",
151 $meta_value,
152 $matches,
153 );
154
155 /*
156 * `$matches[1]` contain the captured matches of the
157 * first capturing group (the `([\w-]+)` in the regex above).
158 */
159 $custom_fields_or_taxonomies = $matches[1];
160
161 foreach ( $custom_fields_or_taxonomies as $custom_field_or_taxonomy ) {
162 $unique_custom_fields_or_taxonomies[ trim( $custom_field_or_taxonomy ) ] = 1;
163 }
164 }
165
166 return array_keys( $unique_custom_fields_or_taxonomies );
167 }
168
169 /**
170 * Replaces every AIOSEO custom field/taxonomy/etc. replace var with the Yoast version.
171 *
172 * E.g. `#custom_field-xyz` becomes `%%cf_xyz%%`.
173 *
174 * @param string[] $unique_custom_fields_or_taxonomies An array of unique custom fields to replace the replace vars of.
175 * @param wpdb $wpdb The WordPress database object.
176 * @param string $aioseo_prefix The AiOSEO prefix to use
177 * (e.g. `custom-field` for custom fields or `tax_name` for custom taxonomies).
178 * @param string $yoast_prefix The Yoast prefix to use (e.g. `cf` for custom fields).
179 *
180 * @return void
181 */
182 protected function replace_custom_field_or_taxonomy_replace_vars( $unique_custom_fields_or_taxonomies, $wpdb, $aioseo_prefix, $yoast_prefix ) {
183 foreach ( $unique_custom_fields_or_taxonomies as $unique_custom_field_or_taxonomy ) {
184 $aioseo_variable = "#{$aioseo_prefix}-{$unique_custom_field_or_taxonomy}";
185 $yoast_variable = "%%{$yoast_prefix}_{$unique_custom_field_or_taxonomy}%%";
186
187 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
188 $wpdb->query(
189 $wpdb->prepare(
190 'UPDATE tmp_meta_table SET meta_value = REPLACE( meta_value, %s, %s )',
191 $aioseo_variable,
192 $yoast_variable,
193 ),
194 );
195 }
196 }
197
198 // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
199
200 /**
201 * Retrieve all the meta values from the temporary meta table that contain
202 * at least one AiOSEO custom field replace var.
203 *
204 * @param wpdb $wpdb The WordPress database object.
205 * @param string $aioseo_prefix The AiOSEO prefix to use
206 * (e.g. `custom-field` for custom fields or `tax_name` for custom taxonomies).
207 *
208 * @return string[] All meta values that contain at least one AioSEO custom field replace var.
209 */
210 protected function get_meta_values_with_custom_field_or_taxonomy( $wpdb, $aioseo_prefix ) {
211 return $wpdb->get_col(
212 $wpdb->prepare(
213 'SELECT meta_value FROM tmp_meta_table WHERE meta_value LIKE %s',
214 "%#$aioseo_prefix-%",
215 ),
216 );
217 }
218
219 // phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
220
221 /**
222 * Detects whether there is AIOSEO data to import by looking whether the AIOSEO data have been cleaned up.
223 *
224 * @return bool Boolean indicating whether there is something to import.
225 */
226 protected function detect() {
227 $aioseo_cleanup_action = YoastSEO()->classes->get( Aioseo_Cleanup_Action::class );
228 return ( $aioseo_cleanup_action->get_total_unindexed() > 0 );
229 }
230
231 /**
232 * Import AIOSEO post data from their custom indexable table. Not currently used.
233 *
234 * @return void
235 */
236 protected function import() {
237 // This is overriden from the import.js and never run.
238 $aioseo_posts_import_action = YoastSEO()->classes->get( Aioseo_Posts_Importing_Action::class );
239 $aioseo_posts_import_action->index();
240 }
241 }
242