PluginProbe
Parse.ly / 3.14.1
Parse.ly v3.14.1
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 3.20.2 3.20.3 All 105 releases
← All changes | src/class-parsely.php +31 -196 3.17.03.14.1 View file →
@@ -9,14 +9,10 @@
9 9 declare(strict_types=1);
10 10
11 11 namespace Parsely;
12 12
13 -use Parsely\REST_API\REST_API_Controller;
14 -use Parsely\Services\Content_API\Content_API_Service;
15 -use Parsely\Services\Suggestions_API\Suggestions_API_Service;
16 13 use Parsely\UI\Metadata_Renderer;
17 14 use Parsely\UI\Settings_Page;
18 -use Parsely\Utils\Utils;
19 15 use WP_Post;
20 16
21 17 /**
22 18 * Holds most of the logic for the plugin.
@@ -30,9 +26,8 @@
30 26 * api_secret: string,
31 27 * use_top_level_cats: bool,
32 28 * custom_taxonomy_section: string,
33 29 * cats_as_tags: bool,
34 - * content_helper: Parsely_Options_Content_Helper,
35 30 * track_authenticated_users: bool,
36 31 * lowercase_tags: bool,
37 32 * force_https_canonicals: bool,
38 33 * track_post_types: string[],
@@ -37,9 +32,9 @@
37 32 * force_https_canonicals: bool,
38 33 * track_post_types: string[],
39 34 * track_page_types: string[],
40 35 * track_post_types_as?: array<string, string>,
41 - * full_metadata_in_non_posts: bool,
36 + * full_metadata_in_non_posts: ?bool,
42 37 * disable_javascript: bool,
43 38 * disable_amp: bool,
44 39 * meta_type: string,
45 40 * logo: string,
@@ -47,27 +42,15 @@
47 42 * disable_autotrack: bool,
48 43 * plugin_version: string,
49 44 * }
50 45 *
51 - * @phpstan-type Parsely_Options_Content_Helper array{
52 - * ai_features_enabled: bool,
53 - * smart_linking: Parsely_Options_Content_Helper_Feature,
54 - * title_suggestions: Parsely_Options_Content_Helper_Feature,
55 - * excerpt_suggestions: Parsely_Options_Content_Helper_Feature,
56 - * }
57 - *
58 - * @phpstan-type Parsely_Options_Content_Helper_Feature array{
59 - * enabled: bool,
60 - * allowed_user_roles: string[],
61 - * }
62 - *
63 46 * @phpstan-type WP_HTTP_Request_Args array{
64 - * method?: string,
65 - * timeout?: float,
66 - * blocking?: bool,
67 - * headers?: array<string, string>,
68 - * body?: string,
69 - * data_format?: string,
47 + * method: string,
48 + * timeout: float,
49 + * blocking: bool,
50 + * headers: array<string, string>,
51 + * body: string,
52 + * data_format: string,
70 53 * }
71 54 *
72 55 * @phpstan-import-type Metadata_Attributes from Metadata
73 56 */
@@ -74,36 +57,17 @@
74 57 class Parsely {
75 58 /**
76 59 * Declare our constants
77 60 */
78 - public const VERSION = PARSELY_VERSION;
79 - public const MENU_SLUG = 'parsely'; // The page param passed to options-general.php.
80 - public const OPTIONS_KEY = 'parsely'; // The key used to store options in the WP database.
81 - public const CAPABILITY = 'manage_options'; // The capability required to administer settings.
82 - public const DASHBOARD_BASE_URL = 'https://dash.parsely.com';
61 + public const VERSION = PARSELY_VERSION;
62 + public const MENU_SLUG = 'parsely'; // The page param passed to options-general.php.
63 + public const OPTIONS_KEY = 'parsely'; // The key used to store options in the WP database.
64 + public const CAPABILITY = 'manage_options'; // The capability required to administer settings.
65 + public const DASHBOARD_BASE_URL = 'https://dash.parsely.com';
66 + public const PUBLIC_API_BASE_URL = 'https://api.parsely.com/v2';
67 + public const PUBLIC_SUGGESTIONS_API_BASE_URL = 'https://content-suggestions-api.parsely.net/prod';
83 68
84 69 /**
85 - * The Content API service.
86 - *
87 - * @var ?Content_API_Service $content_api_service
88 - */
89 - private $content_api_service;
90 -
91 - /**
92 - * The Suggestions API service.
93 - *
94 - * @var ?Suggestions_API_Service $suggestions_api_service
95 - */
96 - private $suggestions_api_service;
97 -
98 - /**
99 - * The Parse.ly internal REST API controller.
100 - *
101 - * @var REST_API_Controller|null $rest_api_controller
102 - */
103 - private $rest_api_controller;
104 -
105 - /**
106 70 * Declare some class properties
107 71 *
108 72 * @var Parsely_Options $option_defaults The defaults we need for the class.
109 73 */
@@ -113,23 +77,8 @@
113 77 'api_secret' => '',
114 78 'use_top_level_cats' => false,
115 79 'custom_taxonomy_section' => 'category',
116 80 'cats_as_tags' => false,
117 - 'content_helper' => array(
118 - 'ai_features_enabled' => true,
119 - 'smart_linking' => array(
120 - 'enabled' => true,
121 - 'allowed_user_roles' => array( 'administrator' ),
122 - ),
123 - 'title_suggestions' => array(
124 - 'enabled' => true,
125 - 'allowed_user_roles' => array( 'administrator' ),
126 - ),
127 - 'excerpt_suggestions' => array(
128 - 'enabled' => true,
129 - 'allowed_user_roles' => array( 'administrator' ),
130 - ),
131 - ),
132 81 'track_authenticated_users' => false,
133 82 'lowercase_tags' => true,
134 83 'force_https_canonicals' => false,
135 84 'track_post_types' => array(),
@@ -232,34 +181,8 @@
232 181 $this->allow_parsely_remote_requests();
233 182 }
234 183
235 184 /**
236 - * Gets the allowed post statuses for tracking.
237 - *
238 - * Uses the `wp_parsely_trackable_statuses` filter to determine which post statuses are allowed to be tracked.
239 - *
240 - * @since 3.17.0
241 - *
242 - * @param WP_Post|int|null $post The post object.
243 - * @return array<string> The allowed post statuses.
244 - */
245 - public static function get_trackable_statuses( $post = null ): array {
246 - /**
247 - * Filters the statuses that are permitted to be tracked.
248 - *
249 - * By default, the only status tracked is 'publish'. Use this filter if
250 - * you have other published content that has a different (custom) status.
251 - *
252 - * @since 2.5.0
253 - * @since 3.17.0 Filter extracted to a separate method.
254 - *
255 - * @param string[] $trackable_statuses The list of post statuses that are allowed to be tracked.
256 - * @param WP_Post|int|null $post Which post object or ID is being checked.
257 - */
258 - return apply_filters( 'wp_parsely_trackable_statuses', array( 'publish' ), $post );
259 - }
260 -
261 - /**
262 185 * Registers action and filter hook callbacks, and immediately upgrades
263 186 * options if needed.
264 187 */
265 188 public function run(): void {
@@ -285,59 +208,8 @@
285 208 add_action( 'save_post', array( $this, 'update_metadata_endpoint' ) );
286 209 }
287 210
288 211 /**
289 - * Returns the Content API service.
290 - *
291 - * This method returns the Content API service, which is used to interact with the Parse.ly Content API.
292 - *
293 - * @since 3.17.0
294 - *
295 - * @return Content_API_Service
296 - */
297 - public function get_content_api(): Content_API_Service {
298 - if ( ! isset( $this->content_api_service ) ) {
299 - $this->content_api_service = new Content_API_Service( $this );
300 - }
301 -
302 - return $this->content_api_service;
303 - }
304 -
305 - /**
306 - * Returns the Suggestions API service.
307 - *
308 - * This method returns the Suggestions API service, which is used to interact with the Parse.ly Suggestions API.
309 - *
310 - * @since 3.17.0
311 - *
312 - * @return Suggestions_API_Service
313 - */
314 - public function get_suggestions_api(): Suggestions_API_Service {
315 - if ( ! isset( $this->suggestions_api_service ) ) {
316 - $this->suggestions_api_service = new Suggestions_API_Service( $this );
317 - }
318 -
319 - return $this->suggestions_api_service;
320 - }
321 -
322 - /**
323 - * Gets the REST API controller.
324 - *
325 - * If the controller is not set, a new instance is created.
326 - *
327 - * @since 3.17.0
328 - *
329 - * @return REST_API_Controller
330 - */
331 - public function get_rest_api_controller(): REST_API_Controller {
332 - if ( ! isset( $this->rest_api_controller ) ) {
333 - $this->rest_api_controller = new REST_API_Controller( $this );
334 - }
335 -
336 - return $this->rest_api_controller;
337 - }
338 -
339 - /**
340 212 * Gets the full URL of the JavaScript tracker file for the site. If an API
341 213 * key is not set, return an empty string.
342 214 *
343 215 * @since 3.2.0
@@ -419,9 +291,20 @@
419 291 $cache[ $post_id ] = false;
420 292 return false;
421 293 }
422 294
423 - $statuses = self::get_trackable_statuses( $post );
295 + /**
296 + * Filters the statuses that are permitted to be tracked.
297 + *
298 + * By default, the only status tracked is 'publish'. Use this filter if
299 + * you have other published content that has a different (custom) status.
300 + *
301 + * @since 2.5.0
302 + *
303 + * @param string[] $trackable_statuses The list of post statuses that are allowed to be tracked.
304 + * @param int|WP_Post $post Which post object or ID is being checked.
305 + */
306 + $statuses = apply_filters( 'wp_parsely_trackable_statuses', array( 'publish' ), $post );
424 307 $cache[ $post_id ] = in_array( get_post_status( $post ), $statuses, true );
425 308 return $cache[ $post_id ];
426 309 }
427 310
@@ -471,10 +354,9 @@
471 354 'authors' => $metadata['creator'] ?? '',
472 355 'tags' => $metadata['keywords'] ?? '',
473 356 );
474 357
475 - $parsely_api_base_url = Content_API_Service::get_base_url();
476 - $parsely_api_endpoint = $parsely_api_base_url . '/metadata/posts';
358 + $parsely_api_endpoint = self::PUBLIC_API_BASE_URL . '/metadata/posts';
477 359 $parsely_metadata_secret = $parsely_options['metadata_secret'];
478 360
479 361 $headers = array( 'Content-Type' => 'application/json' );
480 362 $body = wp_json_encode(
@@ -522,21 +404,12 @@
522 404 * @var Parsely_Options|null
523 405 */
524 406 $options = get_option( self::OPTIONS_KEY, null );
525 407
526 - // @phpstan-ignore isset.offset, booleanAnd.alwaysFalse
527 408 if ( is_array( $options ) && ! isset( $options['full_metadata_in_non_posts'] ) ) {
528 - // Existing plugin installation without full metadata option.
529 409 $this->set_default_full_metadata_in_non_posts();
530 410 }
531 411
532 - // @phpstan-ignore isset.offset, booleanAnd.alwaysFalse
533 - if ( is_array( $options ) && ! isset( $options['content_helper'] ) ) {
534 - // Existing plugin installation without Content Helper options.
535 - $this->set_default_content_helper_settings_values();
536 - }
537 -
538 - // New plugin installation that hasn't saved its options yet.
539 412 if ( ! is_array( $options ) ) {
540 413 $this->set_default_track_as_values();
541 414 $this->set_default_full_metadata_in_non_posts();
542 415 $options = $this->option_defaults;
@@ -555,30 +428,8 @@
555 428 );
556 429 }
557 430
558 431 /**
559 - * Returns the value of a nested option.
560 - *
561 - * @since 3.16.0
562 - *
563 - * @param string $option The option to get.
564 - * @param Parsely_Options $options The options to get the value from.
565 - * @return mixed The value of the nested option.
566 - */
567 - public static function get_nested_option_value( $option, $options ) {
568 - $keys = explode( '[', str_replace( ']', '', $option ) );
569 - $value = $options;
570 -
571 - foreach ( $keys as $key ) {
572 - if ( isset( $value[ $key ] ) ) {
573 - $value = $value[ $key ];
574 - }
575 - }
576 -
577 - return $value;
578 - }
579 -
580 - /**
581 432 * Sets the default values for the track_post_types and track_page_types
582 433 * options.
583 434 *
584 435 * @since 3.9.0
@@ -631,24 +482,8 @@
631 482 }
632 483 }
633 484
634 485 /**
635 - * Sets the default values for Content Helper options.
636 - *
637 - * Gives PCH access to all users having the edit_posts capability, to keep
638 - * consistent behavior with plugin versions prior to 3.16.0.
639 - *
640 - * @since 3.16.0
641 - */
642 - public function set_default_content_helper_settings_values(): void {
643 - $this->option_defaults['content_helper'] =
644 - Permissions::build_pch_permissions_settings_array(
645 - true,
646 - array_keys( Permissions::get_user_roles_with_edit_posts_cap() )
647 - );
648 - }
649 -
650 - /**
651 486 * Gets the URL of the plugin's settings page.
652 487 *
653 488 * @param int|null $_blog_id The Blog ID for the multisite subsite to use
654 489 * for context (Default null for current).
@@ -653,9 +488,9 @@
653 488 * @param int|null $_blog_id The Blog ID for the multisite subsite to use
654 489 * for context (Default null for current).
655 490 * @return string
656 491 */
657 - public static function get_settings_url( ?int $_blog_id = null ): string {
492 + public static function get_settings_url( int $_blog_id = null ): string {
658 493 return get_admin_url( $_blog_id, 'options-general.php?page=' . self::MENU_SLUG );
659 494 }
660 495
661 496 /**
@@ -1026,10 +861,10 @@
1026 861 */
1027 862 private function allow_parsely_remote_requests(): void {
1028 863 $allowed_urls = array(
1029 864 self::DASHBOARD_BASE_URL,
1030 - Content_API_Service::get_base_url(),
1031 - Suggestions_API_Service::get_base_url(),
865 + self::PUBLIC_API_BASE_URL,
866 + self::PUBLIC_SUGGESTIONS_API_BASE_URL,
1032 867 );
1033 868
1034 869 add_filter(
1035 870 'http_request_host_is_external',
@@ -1035,9 +870,9 @@
1035 870 'http_request_host_is_external',
1036 871 function ( $external, $host, $url ) use ( $allowed_urls ) {
1037 872 // Check if the URL matches any URLs on the allowed list.
1038 873 foreach ( $allowed_urls as $allowed_url ) {
1039 - if ( Utils::str_starts_with( $url, $allowed_url ) ) {
874 + if ( \Parsely\Utils\str_starts_with( $url, $allowed_url ) ) {
1040 875 return true;
1041 876 }
1042 877 }
1043 878 return $external;