aioseo-validate-data-action.php
8.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
<?php
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Given it's a very specific case.
namespace Yoast\WP\SEO\Actions\Importing\Aioseo;
use wpdb;
use Yoast\WP\SEO\Actions\Importing\Abstract_Aioseo_Importing_Action;
use Yoast\WP\SEO\Exceptions\Importing\Aioseo_Validation_Exception;
use Yoast\WP\SEO\Helpers\Options_Helper;
/**
* Importing action for validating AIOSEO data before the import occurs.
*/
class Aioseo_Validate_Data_Action extends Abstract_Aioseo_Importing_Action {
/**
* The plugin of the action.
*/
const PLUGIN = 'aioseo';
/**
* The type of the action.
*/
const TYPE = 'validate_data';
/**
* The WordPress database instance.
*
* @var wpdb
*/
protected $wpdb;
/**
* The Post Importing action.
*
* @var Aioseo_Posts_Importing_Action
*/
protected $post_importing_action;
/**
* The settings importing actions.
*
* @var array
*/
protected $settings_importing_actions;
/**
* Class constructor.
*
* @param wpdb $wpdb The WordPress database instance.
* @param Options_Helper $options The options helper.
* @param Aioseo_Custom_Archive_Settings_Importing_Action $custom_archive_action The Custom Archive Settings importing action.
* @param Aioseo_Default_Archive_Settings_Importing_Action $default_archive_action The Default Archive Settings importing action.
* @param Aioseo_General_Settings_Importing_Action $general_settings_action The General Settings importing action.
* @param Aioseo_Posttype_Defaults_Settings_Importing_Action $posttype_defaults_settings_action The Posttype Defaults Settings importing action.
* @param Aioseo_Taxonomy_Settings_Importing_Action $taxonomy_settings_action The Taxonomy Settings importing action.
* @param Aioseo_Posts_Importing_Action $post_importing_action The Post importing action.
*/
public function __construct(
wpdb $wpdb,
Options_Helper $options,
Aioseo_Custom_Archive_Settings_Importing_Action $custom_archive_action,
Aioseo_Default_Archive_Settings_Importing_Action $default_archive_action,
Aioseo_General_Settings_Importing_Action $general_settings_action,
Aioseo_Posttype_Defaults_Settings_Importing_Action $posttype_defaults_settings_action,
Aioseo_Taxonomy_Settings_Importing_Action $taxonomy_settings_action,
Aioseo_Posts_Importing_Action $post_importing_action
) {
$this->wpdb = $wpdb;
$this->options = $options;
$this->post_importing_action = $post_importing_action;
$this->settings_importing_actions = [
$custom_archive_action,
$default_archive_action,
$general_settings_action,
$posttype_defaults_settings_action,
$taxonomy_settings_action,
];
}
/**
* Just checks if the action has been completed in the past.
*
* @return int 1 if it hasn't been completed in the past, 0 if it has.
*/
public function get_total_unindexed() {
return ( ! $this->get_completed() ) ? 1 : 0;
}
/**
* Just checks if the action has been completed in the past.
*
* @param int $limit The maximum number of unimported objects to be returned. Not used, exists to comply with the interface.
*
* @return int 1 if it hasn't been completed in the past, 0 if it has.
*/
public function get_limited_unindexed_count( $limit ) {
return ( ! $this->get_completed() ) ? 1 : 0;
}
/**
* Validates AIOSEO data.
*
* @return array An array of validated data or false if aioseo data did not pass validation.
*
* @throws Aioseo_Validation_Exception If the validation fails.
*/
public function index() {
if ( $this->get_completed() ) {
return [];
}
$validated_aioseo_table = $this->validate_aioseo_table();
$validated_aioseo_settings = $this->validate_aioseo_settings();
$validated_robot_settings = $this->validate_robot_settings();
if ( $validated_aioseo_table === false || $validated_aioseo_settings === false || $validated_robot_settings === false ) {
throw new Aioseo_Validation_Exception();
}
$this->set_completed( true );
return [
'validated_aioseo_table' => $validated_aioseo_table,
'validated_aioseo_settings' => $validated_aioseo_settings,
'validated_robot_settings' => $validated_robot_settings,
];
}
/**
* Validates the AIOSEO indexable table.
*
* @return bool Whether the AIOSEO table exists and has the structure we expect.
*/
public function validate_aioseo_table() {
if ( ! $this->aioseo_helper->aioseo_exists() ) {
return false;
}
$table = $this->aioseo_helper->get_table();
$needed_data = $this->post_importing_action->get_needed_data();
$aioseo_columns = $this->wpdb->get_col(
"SHOW COLUMNS FROM {$table}", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Reason: There is no unescaped user input.
0
);
return $needed_data === \array_intersect( $needed_data, $aioseo_columns );
}
/**
* Validates the AIOSEO settings from the options table.
*
* @return bool Whether the AIOSEO settings from the options table exist and have the structure we expect.
*/
public function validate_aioseo_settings() {
foreach ( $this->settings_importing_actions as $settings_import_action ) {
$aioseo_settings = \json_decode( \get_option( $settings_import_action->get_source_option_name(), '' ), true );
if ( ! $settings_import_action->isset_settings_tab( $aioseo_settings ) ) {
return false;
}
}
return true;
}
/**
* Validates the AIOSEO robots settings from the options table.
*
* @return bool Whether the AIOSEO robots settings from the options table exist and have the structure we expect.
*/
public function validate_robot_settings() {
if ( $this->validate_post_robot_settings() && $this->validate_default_robot_settings() ) {
return true;
}
return false;
}
/**
* Validates the post AIOSEO robots settings from the options table.
*
* @return bool Whether the post AIOSEO robots settings from the options table exist and have the structure we expect.
*/
public function validate_post_robot_settings() {
$post_robot_mapping = $this->post_importing_action->enhance_mapping();
// We're gonna validate against posttype robot settings only for posts, assuming the robot settings stay the same for other post types.
$post_robot_mapping['subtype'] = 'post';
// Let's get both the aioseo_options and the aioseo_options_dynamic options.
$aioseo_global_settings = $this->aioseo_helper->get_global_option();
$aioseo_posts_settings = \json_decode( \get_option( $post_robot_mapping['option_name'], '' ), true );
$needed_robots_data = $this->post_importing_action->get_needed_robot_data();
\array_push( $needed_robots_data, 'default', 'noindex' );
foreach ( $needed_robots_data as $robot_setting ) {
// Validate against global settings.
if ( ! isset( $aioseo_global_settings['searchAppearance']['advanced']['globalRobotsMeta'][ $robot_setting ] ) ) {
return false;
}
// Validate against posttype settings.
if ( ! isset( $aioseo_posts_settings['searchAppearance'][ $post_robot_mapping['type'] ][ $post_robot_mapping['subtype'] ]['advanced']['robotsMeta'][ $robot_setting ] ) ) {
return false;
}
}
return true;
}
/**
* Validates the default AIOSEO robots settings for search appearance settings from the options table.
*
* @return bool Whether the AIOSEO robots settings for search appearance settings from the options table exist and have the structure we expect.
*/
public function validate_default_robot_settings() {
foreach ( $this->settings_importing_actions as $settings_import_action ) {
$robot_setting_map = $settings_import_action->pluck_robot_setting_from_mapping();
// Some actions return empty robot settings, let's not validate against those.
if ( ! empty( $robot_setting_map ) ) {
$aioseo_settings = \json_decode( \get_option( $robot_setting_map['option_name'], '' ), true );
if ( ! isset( $aioseo_settings['searchAppearance'][ $robot_setting_map['type'] ][ $robot_setting_map['subtype'] ]['advanced']['robotsMeta']['default'] ) ) {
return false;
}
}
}
return true;
}
/**
* Used nowhere. Exists to comply with the interface.
*
* @return int The limit.
*/
public function get_limit() {
/**
* Filter 'wpseo_aioseo_cleanup_limit' - Allow filtering the number of validations during each action pass.
*
* @api int The maximum number of validations.
*/
$limit = \apply_filters( 'wpseo_aioseo_validation_limit', 25 );
if ( ! \is_int( $limit ) || $limit < 1 ) {
$limit = 25;
}
return $limit;
}
}