PluginProbe
Parse.ly / 3.24.2
Parse.ly v3.24.2
3.24.3 3.24.2 3.24.1 3.24.0 3.23.7 3.23.6 3.23.5 3.23.4 3.23.3 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.17.0 3.18.0 3.18.1 3.19.0 3.19.1 3.19.2 3.19.3 3.2.0 3.2.1 3.20.0 3.20.1 All 107 releases
← All changes | wp-parsely.php +198 -205 3.16.4 → 3.24.2 View file →
@@ -10,9 +10,9 @@
10 10 * @wordpress-plugin
11 11 * Plugin Name: Parse.ly
12 12 * Plugin URI: https://docs.parse.ly/wordpress
13 13 * Description: This plugin makes it a snap to add Parse.ly tracking code and metadata to your WordPress blog.
14 - * Version: 3.16.4
14 + * Version: 3.24.2
15 15 * Author: Parse.ly
16 16 * Author URI: https://www.parse.ly
17 17 * Text Domain: wp-parsely
18 18 * License: GPL-2.0-or-later
@@ -17,10 +17,10 @@
17 17 * Text Domain: wp-parsely
18 18 * License: GPL-2.0-or-later
19 19 * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
20 20 * GitHub Plugin URI: https://github.com/Parsely/wp-parsely
21 - * Requires PHP: 7.2
22 - * Requires WP: 5.0.0
21 + * Requires PHP: 7.4
22 + * Requires WP: 6.1.0
23 23 */
24 24
25 25 declare(strict_types=1);
26 26
@@ -27,36 +27,18 @@
27 27 namespace Parsely;
28 28
29 29 use Parsely\Content_Helper\Dashboard_Widget;
30 30 use Parsely\Content_Helper\Editor_Sidebar;
31 -use Parsely\Content_Helper\Excerpt_Generator;
32 31 use Parsely\Content_Helper\Post_List_Stats;
33 -use Parsely\Endpoints\Analytics_Post_Detail_API_Proxy;
34 -use Parsely\Endpoints\Analytics_Posts_API_Proxy;
35 -use Parsely\Endpoints\Content_Helper\Smart_Linking_Endpoint;
36 -use Parsely\Endpoints\ContentSuggestions\Suggest_Brief_API_Proxy;
37 -use Parsely\Endpoints\ContentSuggestions\Suggest_Headline_API_Proxy;
38 -use Parsely\Endpoints\ContentSuggestions\Suggest_Linked_Reference_API_Proxy;
39 32 use Parsely\Endpoints\GraphQL_Metadata;
40 -use Parsely\Endpoints\Referrers_Post_Detail_API_Proxy;
41 -use Parsely\Endpoints\Related_API_Proxy;
42 33 use Parsely\Endpoints\Rest_Metadata;
43 -use Parsely\Endpoints\User_Meta\Dashboard_Widget_Settings_Endpoint;
44 -use Parsely\Endpoints\User_Meta\Editor_Sidebar_Settings_Endpoint;
34 +use Parsely\Headline_Testing;
45 35 use Parsely\Integrations\Amp;
46 36 use Parsely\Integrations\Google_Web_Stories;
47 37 use Parsely\Integrations\Integrations;
48 -use Parsely\RemoteAPI\Analytics_Post_Detail_API;
49 -use Parsely\RemoteAPI\Analytics_Posts_API;
50 -use Parsely\RemoteAPI\ContentSuggestions\Suggest_Brief_API;
51 -use Parsely\RemoteAPI\ContentSuggestions\Suggest_Headline_API;
52 -use Parsely\RemoteAPI\ContentSuggestions\Suggest_Linked_Reference_API;
53 -use Parsely\RemoteAPI\Referrers_Post_Detail_API;
54 -use Parsely\RemoteAPI\Related_API;
55 -use Parsely\RemoteAPI\Remote_API_Cache;
56 -use Parsely\RemoteAPI\WordPress_Cache;
57 38 use Parsely\UI\Admin_Bar;
58 39 use Parsely\UI\Admin_Warning;
40 +use Parsely\UI\Dashboard_Page;
59 41 use Parsely\UI\Metadata_Renderer;
60 42 use Parsely\UI\Network_Admin_Sites_List;
61 43 use Parsely\UI\Plugins_Actions;
62 44 use Parsely\UI\Recommended_Widget;
@@ -63,81 +45,72 @@
63 45 use Parsely\UI\Row_Actions;
64 46 use Parsely\UI\Settings_Page;
65 47 use Parsely\UI\Site_Health;
66 48
67 -require_once __DIR__ . '/src/Utils/utils.php';
68 -
69 49 if ( class_exists( Parsely::class ) ) {
70 50 return;
71 51 }
72 52
73 -const PARSELY_VERSION = '3.16.4';
74 -const PARSELY_FILE = __FILE__;
53 +const PARSELY_VERSION = '3.24.2';
54 +const PARSELY_FILE = __FILE__;
55 +const PARSELY_DATA_SCHEMA_VERSION = '1';
56 +const PARSELY_CACHE_GROUP = 'wp-parsely';
75 57
76 -require_once __DIR__ . '/src/Models/class-base-model.php';
77 -require_once __DIR__ . '/src/Models/class-smart-link.php';
78 -require_once __DIR__ . '/src/Models/class-inbound-smart-link.php';
58 +if ( file_exists( __DIR__ . '/vendor/autoload.php' ) ) {
59 + require_once __DIR__ . '/vendor/autoload.php';
60 +}
79 61
80 -require_once __DIR__ . '/src/class-parsely.php';
81 -require_once __DIR__ . '/src/class-permissions.php';
82 -require_once __DIR__ . '/src/class-scripts.php';
83 -require_once __DIR__ . '/src/class-dashboard-link.php';
84 -require_once __DIR__ . '/src/class-validator.php';
85 -require_once __DIR__ . '/src/UI/class-admin-bar.php';
86 -require_once __DIR__ . '/src/UI/class-metadata-renderer.php';
87 -require_once __DIR__ . '/src/Endpoints/class-metadata-endpoint.php';
88 -require_once __DIR__ . '/src/Endpoints/class-graphql-metadata.php';
62 +// Load Telemetry classes.
89 63 require_once __DIR__ . '/src/Telemetry/telemetry-init.php';
90 64
91 -require_once __DIR__ . '/src/class-metadata.php';
92 -require_once __DIR__ . '/src/Metadata/class-metadata-builder.php';
93 -require_once __DIR__ . '/src/Metadata/class-author-archive-builder.php';
94 -require_once __DIR__ . '/src/Metadata/class-category-builder.php';
95 -require_once __DIR__ . '/src/Metadata/class-date-builder.php';
96 -require_once __DIR__ . '/src/Metadata/class-front-page-builder.php';
97 -require_once __DIR__ . '/src/Metadata/class-page-builder.php';
98 -require_once __DIR__ . '/src/Metadata/class-page-for-posts-builder.php';
99 -require_once __DIR__ . '/src/Metadata/class-paginated-front-page-builder.php';
100 -require_once __DIR__ . '/src/Metadata/class-post-builder.php';
101 -require_once __DIR__ . '/src/Metadata/class-tag-builder.php';
65 +/**
66 + * Gets the Parsely object.
67 + *
68 + * @since 3.19.0
69 + *
70 + * @return Parsely The Parsely object.
71 + */
72 +function get_parsely(): Parsely {
73 + if ( ! isset( $GLOBALS['parsely'] ) ) {
74 + $GLOBALS['parsely'] = new Parsely();
75 + }
102 76
77 + return $GLOBALS['parsely'];
78 +}
79 +
103 80 add_action( 'plugins_loaded', __NAMESPACE__ . '\\parsely_initialize_plugin' );
104 81 /**
105 82 * Registers the basic classes to initialize the plugin.
106 83 */
107 84 function parsely_initialize_plugin(): void {
108 - $GLOBALS['parsely'] = new Parsely();
109 - $GLOBALS['parsely']->run();
85 + $parsely = get_parsely();
86 + $parsely->run();
110 87
111 88 if ( class_exists( 'WPGraphQL' ) ) {
112 - $graphql = new GraphQL_Metadata( $GLOBALS['parsely'] );
89 + $graphql = new GraphQL_Metadata( $parsely );
113 90 $graphql->run();
114 91 }
115 92
116 - $scripts = new Scripts( $GLOBALS['parsely'] );
93 + $scripts = new Scripts( $parsely );
117 94 $scripts->run();
118 95
119 - $admin_bar = new Admin_Bar( $GLOBALS['parsely'] );
96 + $admin_bar = new Admin_Bar( $parsely );
120 97 $admin_bar->run();
121 98
122 - $metadata_renderer = new Metadata_Renderer( $GLOBALS['parsely'] );
99 + $metadata_renderer = new Metadata_Renderer( $parsely );
123 100 $metadata_renderer->run();
101 +
102 + // Initialize Headline Testing feature.
103 + $headline_testing = new Headline_Testing( $parsely );
104 + $headline_testing->run();
124 105 }
125 106
126 -require_once __DIR__ . '/src/content-helper/common/class-content-helper-feature.php';
127 -require_once __DIR__ . '/src/content-helper/post-list-stats/class-post-list-stats.php';
128 -require_once __DIR__ . '/src/UI/class-admin-warning.php';
129 -require_once __DIR__ . '/src/UI/class-plugins-actions.php';
130 -require_once __DIR__ . '/src/UI/class-row-actions.php';
131 -require_once __DIR__ . '/src/UI/class-site-health.php';
132 -require_once __DIR__ . '/src/content-helper/dashboard-widget/class-dashboard-widget.php';
133 -
134 107 add_action( 'admin_init', __NAMESPACE__ . '\\parsely_admin_init_register' );
135 108 /**
136 109 * Registers the Parse.ly wp-admin warnings, plugin actions and row actions.
137 110 */
138 111 function parsely_admin_init_register(): void {
139 - $parsely = $GLOBALS['parsely'];
112 + $parsely = get_parsely();
140 113
141 114 ( new Admin_Warning( $parsely ) )->run();
142 115 ( new Plugins_Actions() )->run();
143 116 ( new Row_Actions( $parsely ) )->run();
@@ -145,11 +118,56 @@
145 118 ( new Site_Health( $parsely ) )->run();
146 119 ( new Dashboard_Widget( $parsely ) )->run();
147 120 }
148 121
149 -require_once __DIR__ . '/src/UI/class-settings-page.php';
150 -require_once __DIR__ . '/src/UI/class-network-admin-sites-list.php';
122 +add_action( 'admin_init', __NAMESPACE__ . '\\create_engagement_boost_changeset_post' );
123 +/**
124 + * Creates a predefined changeset post in order to make the Engagement Boost
125 + * preview work for non-administrator user roles.
126 + *
127 + * When the Engagement Boost preview iframe is loaded, it calls the WordPress
128 + * Customizer in the `iFrameSrc()` function. The Customizer requires the current
129 + * user to have the `customize` capability (available to Administrators), or the
130 + * passed UUID to have a corresponding changeset post in the database. Otherwise
131 + * it fails with -1 ("Non-existent changeset UUID") around line 561 in
132 + * `class-wp-customize-manager.php` and prevents preview, displaying "-1".
133 + *
134 + * By creating a predefined changeset post with a known UUID that we use in
135 + * `iFrameSrc()`, we guarantee that the preview will work for all authorized
136 + * user roles.
137 + *
138 + * @since 3.20.7
139 + */
140 +function create_engagement_boost_changeset_post(): void {
141 + if ( ! function_exists( 'post_exists' ) ) {
142 + return;
143 + }
151 144
145 + $parsely = get_parsely();
146 +
147 + if ( ! $parsely->api_secret_is_set() || ! Permissions::current_user_can_use_pch_feature(
148 + 'traffic_boost',
149 + $parsely->get_options()['content_helper']
150 + ) ) {
151 + return;
152 + }
153 +
154 + // Needs to match the UUID in `iFrameSrc()` in `preview-iframe.tsx`.
155 + $uuid = '905b130b-4129-4416-919c-9e31433a6f65';
156 + $post_id = post_exists( "wp-parsely-$uuid", '', '', 'customize_changeset', 'private' );
157 +
158 + if ( 0 === $post_id ) {
159 + wp_insert_post(
160 + array(
161 + 'post_type' => 'customize_changeset',
162 + 'post_name' => $uuid,
163 + 'post_title' => "wp-parsely-$uuid",
164 + 'post_status' => 'private',
165 + )
166 + );
167 + }
168 +}
169 +
152 170 add_action( 'init', __NAMESPACE__ . '\\parsely_wp_admin_early_register' );
153 171 /**
154 172 * Registers the additions the Parse.ly wp-admin settings page and Multisite
155 173 * Network Admin Sites List table.
@@ -154,51 +172,26 @@
154 172 * Registers the additions the Parse.ly wp-admin settings page and Multisite
155 173 * Network Admin Sites List table.
156 174 */
157 175 function parsely_wp_admin_early_register(): void {
158 - $GLOBALS['parsely_settings_page'] = new Settings_Page( $GLOBALS['parsely'] );
176 + $parsely = get_parsely();
177 +
178 + // Plugin dashboard page.
179 + $GLOBALS['parsely_dashboard_page'] = new Dashboard_Page( $parsely );
180 + $GLOBALS['parsely_dashboard_page']->run();
181 +
182 + // Plugin settings page.
183 + $GLOBALS['parsely_settings_page'] = new Settings_Page( $parsely );
159 184 $GLOBALS['parsely_settings_page']->run();
160 185
161 - $network_admin_sites_list = new Network_Admin_Sites_List( $GLOBALS['parsely'] );
186 + $network_admin_sites_list = new Network_Admin_Sites_List( $parsely );
162 187 $network_admin_sites_list->run();
188 +
189 + // Initialize the REST API Controller.
190 + $rest_api_controller = $parsely->get_rest_api_controller();
191 + $rest_api_controller->init();
163 192 }
164 193
165 -// Endpoint base classes.
166 -require_once __DIR__ . '/src/Endpoints/class-base-endpoint.php';
167 -require_once __DIR__ . '/src/Endpoints/class-base-api-proxy.php';
168 -require_once __DIR__ . '/src/Endpoints/user-meta/class-base-endpoint-user-meta.php';
169 -
170 -// Endpoint classes.
171 -require_once __DIR__ . '/src/Endpoints/class-analytics-post-detail-api-proxy.php';
172 -require_once __DIR__ . '/src/Endpoints/class-analytics-posts-api-proxy.php';
173 -require_once __DIR__ . '/src/Endpoints/class-referrers-post-detail-api-proxy.php';
174 -require_once __DIR__ . '/src/Endpoints/class-related-api-proxy.php';
175 -require_once __DIR__ . '/src/Endpoints/class-rest-metadata.php';
176 -require_once __DIR__ . '/src/Endpoints/content-suggestions/class-suggest-brief-api-proxy.php';
177 -require_once __DIR__ . '/src/Endpoints/content-suggestions/class-suggest-headline-api-proxy.php';
178 -require_once __DIR__ . '/src/Endpoints/content-suggestions/class-suggest-linked-reference-api-proxy.php';
179 -require_once __DIR__ . '/src/Endpoints/user-meta/class-dashboard-widget-settings-endpoint.php';
180 -require_once __DIR__ . '/src/Endpoints/user-meta/class-editor-sidebar-settings-endpoint.php';
181 -require_once __DIR__ . '/src/Endpoints/content-helper/class-smart-linking-endpoint.php';
182 -
183 -// RemoteAPI base classes.
184 -require_once __DIR__ . '/src/RemoteAPI/interface-cache.php';
185 -require_once __DIR__ . '/src/RemoteAPI/interface-remote-api.php';
186 -require_once __DIR__ . '/src/RemoteAPI/class-remote-api-cache.php';
187 -require_once __DIR__ . '/src/RemoteAPI/class-wordpress-cache.php';
188 -require_once __DIR__ . '/src/RemoteAPI/class-base-endpoint-remote.php';
189 -require_once __DIR__ . '/src/RemoteAPI/content-suggestions/class-content-suggestions-base-api.php';
190 -
191 -// RemoteAPI classes.
192 -require_once __DIR__ . '/src/RemoteAPI/class-analytics-post-detail-api.php';
193 -require_once __DIR__ . '/src/RemoteAPI/class-analytics-posts-api.php';
194 -require_once __DIR__ . '/src/RemoteAPI/class-referrers-post-detail-api.php';
195 -require_once __DIR__ . '/src/RemoteAPI/class-related-api.php';
196 -require_once __DIR__ . '/src/RemoteAPI/class-validate-api.php';
197 -require_once __DIR__ . '/src/RemoteAPI/content-suggestions/class-suggest-brief-api.php';
198 -require_once __DIR__ . '/src/RemoteAPI/content-suggestions/class-suggest-headline-api.php';
199 -require_once __DIR__ . '/src/RemoteAPI/content-suggestions/class-suggest-linked-reference-api.php';
200 -
201 194 add_action( 'rest_api_init', __NAMESPACE__ . '\\parsely_rest_api_init' );
202 195 /**
203 196 * Registers REST Endpoints that act as a proxy to the Parse.ly API.
204 197 * This is needed to get around CORS issues with Firefox.
@@ -205,64 +198,14 @@
205 198 *
206 199 * @since 3.2.0
207 200 */
208 201 function parsely_rest_api_init(): void {
209 - $wp_cache = new WordPress_Cache();
210 - $rest = new Rest_Metadata( $GLOBALS['parsely'] );
202 + $parsely = get_parsely();
203 +
204 + $rest = new Rest_Metadata( $parsely );
211 205 $rest->run();
212 -
213 - // Content Helper settings endpoints.
214 - ( new Dashboard_Widget_Settings_Endpoint( $GLOBALS['parsely'] ) )->run();
215 - ( new Editor_Sidebar_Settings_Endpoint( $GLOBALS['parsely'] ) )->run();
216 -
217 - // Internal Content Helper endpoints.
218 - ( new Smart_Linking_Endpoint( $GLOBALS['parsely'] ) )->run();
219 -
220 - parsely_run_rest_api_endpoint(
221 - Related_API::class,
222 - Related_API_Proxy::class,
223 - $wp_cache
224 - );
225 -
226 - parsely_run_rest_api_endpoint(
227 - Analytics_Posts_API::class,
228 - Analytics_Posts_API_Proxy::class,
229 - $wp_cache
230 - );
231 -
232 - parsely_run_rest_api_endpoint(
233 - Analytics_Post_Detail_API::class,
234 - Analytics_Post_Detail_API_Proxy::class,
235 - $wp_cache
236 - );
237 -
238 - parsely_run_rest_api_endpoint(
239 - Referrers_Post_Detail_API::class,
240 - Referrers_Post_Detail_API_Proxy::class,
241 - $wp_cache
242 - );
243 -
244 - parsely_run_rest_api_endpoint(
245 - Suggest_Headline_API::class,
246 - Suggest_Headline_API_Proxy::class,
247 - $wp_cache
248 - );
249 -
250 - parsely_run_rest_api_endpoint(
251 - Suggest_Brief_API::class,
252 - Suggest_Brief_API_Proxy::class,
253 - $wp_cache
254 - );
255 -
256 - parsely_run_rest_api_endpoint(
257 - Suggest_Linked_Reference_API::class,
258 - Suggest_Linked_Reference_API_Proxy::class,
259 - $wp_cache
260 - );
261 206 }
262 207
263 -require_once __DIR__ . '/src/blocks/recommendations/class-recommendations-block.php';
264 -
265 208 add_action( 'init', __NAMESPACE__ . '\\init_recommendations_block' );
266 209 /**
267 210 * Registers the Recommendations Block.
268 211 */
@@ -270,10 +213,8 @@
270 213 $recommendations_block = new Recommendations_Block();
271 214 $recommendations_block->run();
272 215 }
273 216
274 -require_once __DIR__ . '/src/content-helper/editor-sidebar/class-editor-sidebar.php';
275 -
276 217 add_action( 'enqueue_block_editor_assets', __NAMESPACE__ . '\\init_content_helper_editor_sidebar' );
277 218 /**
278 219 * Inserts the PCH Editor Sidebar.
279 220 *
@@ -283,13 +224,24 @@
283 224 function init_content_helper_editor_sidebar(): void {
284 225 $GLOBALS['parsely_editor_sidebar']->run();
285 226 }
286 227
287 -require_once __DIR__ . '/src/content-helper/excerpt-generator/class-excerpt-generator.php';
228 +add_action( 'enqueue_block_assets', __NAMESPACE__ . '\\init_content_helper_canvas_styles' );
229 +/**
230 + * Inserts the PCH Editor Sidebar styles that need to reach the Editor canvas.
231 + *
232 + * @since 3.24.0
233 + */
234 +function init_content_helper_canvas_styles(): void {
235 + if ( ! isset( $GLOBALS['parsely_editor_sidebar'] ) ) {
236 + return;
237 + }
288 238
239 + $GLOBALS['parsely_editor_sidebar']->run_canvas_styles();
240 +}
241 +
289 242 add_action( 'admin_init', __NAMESPACE__ . '\\parsely_content_helper_editor_sidebar_features' );
290 243 add_action( 'rest_api_init', __NAMESPACE__ . '\\parsely_content_helper_editor_sidebar_features' );
291 -
292 244 /**
293 245 * Initializes the PCH Editor Sidebar features.
294 246 *
295 247 * @since 3.16.0
@@ -301,39 +253,25 @@
301 253 *
302 254 * @since 3.16.0
303 255 * @var Editor_Sidebar $GLOBALS['parsely_editor_sidebar']
304 256 */
305 - $GLOBALS['parsely_editor_sidebar'] = new Editor_Sidebar( $GLOBALS['parsely'] );
257 + $parsely = get_parsely();
258 +
259 + $GLOBALS['parsely_editor_sidebar'] = new Editor_Sidebar( $parsely );
306 260 $GLOBALS['parsely_editor_sidebar']->init_features();
307 261 }
308 262 }
309 263
310 -// The priority of 9 is used to ensure that the Excerpt Generator is loaded before the PCH Editor Sidebar (10).
311 -add_action( 'enqueue_block_editor_assets', __NAMESPACE__ . '\\init_content_helper_excerpt_generator', 9 );
312 -/**
313 - * Initializes and inserts the PCH Excerpt Generator.
314 - *
315 - * @since 3.13.0
316 - */
317 -function init_content_helper_excerpt_generator(): void {
318 - ( new Excerpt_Generator( $GLOBALS['parsely'] ) )->run();
319 -}
320 -
321 -require_once __DIR__ . '/src/UI/class-recommended-widget.php';
322 -
323 264 add_action( 'widgets_init', __NAMESPACE__ . '\\parsely_recommended_widget_register' );
324 265 /**
325 266 * Registers the Parse.ly Recommended widget.
326 267 */
327 268 function parsely_recommended_widget_register(): void {
328 - register_widget( new Recommended_Widget( $GLOBALS['parsely'] ) );
269 + $parsely = get_parsely();
270 +
271 + register_widget( new Recommended_Widget( $parsely ) );
329 272 }
330 273
331 -require_once __DIR__ . '/src/Integrations/class-integration.php';
332 -require_once __DIR__ . '/src/Integrations/class-integrations.php';
333 -require_once __DIR__ . '/src/Integrations/class-amp.php';
334 -require_once __DIR__ . '/src/Integrations/class-google-web-stories.php';
335 -
336 274 add_action( 'init', __NAMESPACE__ . '\\parsely_integrations' ); // @phpstan-ignore-line
337 275 /**
338 276 * Instantiates Integrations collection and registers built-in integrations.
339 277 *
@@ -346,9 +284,9 @@
346 284 // If $parsely value is "", then this function is being called by the init
347 285 // hook and we can get the value from $GLOBALS. If $parsely is an instance
348 286 // of the Parsely object, then this function is being called by a test.
349 287 if ( ! is_object( $parsely ) || get_class( $parsely ) !== Parsely::class ) {
350 - $parsely = $GLOBALS['parsely'];
288 + $parsely = get_parsely();
351 289 }
352 290
353 291 $parsely_integrations = new Integrations( $parsely );
354 292 $parsely_integrations->register( 'amp', Amp::class );
@@ -358,34 +296,89 @@
358 296
359 297 return $parsely_integrations;
360 298 }
361 299
300 +add_action( 'admin_init', __NAMESPACE__ . '\\parsely_check_data_schema_updates', 999 );
362 301 /**
363 - * Instantiates and runs the specified API endpoint.
302 + * Checks and performs any data schema updates.
364 303 *
365 - * @since 3.6.0
366 - *
367 - * @param string $api_class_name The proxy class to instantiate.
368 - * @param string $proxy_api_class_name The API proxy class to instantiate and run.
369 - * @param WordPress_Cache $wp_cache The WordPress cache instance to be used.
304 + * @since 3.19.0 Handles the update from schema version 0 to 1.
370 305 */
371 -function parsely_run_rest_api_endpoint(
372 - string $api_class_name,
373 - string $proxy_api_class_name,
374 - WordPress_Cache &$wp_cache
375 -): void {
306 +function parsely_check_data_schema_updates(): void {
307 + $current_data_schema_version = get_option( 'parsely_data_schema_version' );
308 +
309 + if ( false === $current_data_schema_version ) {
310 + $current_data_schema_version = 0;
311 + }
312 +
313 + if ( PARSELY_DATA_SCHEMA_VERSION <= $current_data_schema_version ) {
314 + return;
315 + }
316 +
376 317 /**
377 - * Internal Variable.
318 + * Updates the smart links to have the Smart Link Status terms,
319 + * and checks the _smart_link_applied meta, if it exists.
378 320 *
379 - * @var RemoteAPI\Base_Endpoint_Remote
321 + * Schema version 1.
322 + *
323 + * @since 3.19.0
380 324 */
381 - $remote_api = new $api_class_name( $GLOBALS['parsely'] );
382 - $remote_api_cache = new Remote_API_Cache( $remote_api, $wp_cache );
325 + if ( 0 === $current_data_schema_version ) {
326 + // Get all the smart links that do not have any Smart Link Status terms.
327 + // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.get_posts_get_posts
328 + $smart_links_without_status = get_posts(
329 + array(
330 + 'post_type' => 'parsely_smart_link',
331 + 'posts_per_page' => -1, // phpcs:ignore WordPressVIPMinimum.Performance.NoPaging.posts_per_page_posts_per_page
332 + 'fields' => 'ids',
333 + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query
334 + 'tax_query' => array(
335 + array(
336 + 'taxonomy' => 'smart_link_status',
337 + 'field' => 'name',
338 + 'terms' => \Parsely\Models\Smart_Link_Status::get_all_statuses(),
339 + 'operator' => 'NOT IN',
340 + ),
341 + ),
342 + )
343 + );
383 344
384 - /**
385 - * Internal Variable.
386 - *
387 - * @var Endpoints\Base_API_Proxy
388 - */
389 - $remote_api_proxy = new $proxy_api_class_name( $GLOBALS['parsely'], $remote_api_cache );
390 - $remote_api_proxy->run();
345 + if ( count( $smart_links_without_status ) === 0 ) {
346 + update_option( 'parsely_data_schema_version', PARSELY_DATA_SCHEMA_VERSION );
347 + return;
348 + }
349 +
350 + // Loop through the smart links and update them to have the Smart Link Status terms.
351 + foreach ( $smart_links_without_status as $post_id ) {
352 + $smart_link = \Parsely\Models\Smart_Link::get_smart_link_by_id( intval( $post_id ) );
353 +
354 + if ( false === $smart_link ) {
355 + continue;
356 + }
357 +
358 + $meta_exists = metadata_exists( 'post', $post_id, '_smart_link_applied' );
359 +
360 + // If there is no meta, it means that the smart link is considered applied,
361 + // for backwards compatibility with Parse.ly < 3.18.0.
362 + if ( ! $meta_exists ) {
363 + $smart_link->set_status( \Parsely\Models\Smart_Link_Status::APPLIED, true );
364 + continue;
365 + }
366 +
367 + // Get the value of the _smart_link_applied meta.
368 + $meta_value = get_post_meta( $post_id, '_smart_link_applied', true );
369 +
370 + // If the meta value is true, then the smart link is considered applied.
371 + if ( 'true' === $meta_value || true === $meta_value ) {
372 + $smart_link->set_status( \Parsely\Models\Smart_Link_Status::APPLIED, true );
373 + } else {
374 + // If the meta value is not true, then the smart link is considered pending.
375 + $smart_link->set_status( \Parsely\Models\Smart_Link_Status::PENDING, true );
376 + }
377 +
378 + // Flush the cache for the smart link.
379 + $smart_link->flush_all_cache();
380 + }
381 +
382 + update_option( 'parsely_data_schema_version', PARSELY_DATA_SCHEMA_VERSION );
383 + }
391 384 }