From b50f12402fb9ed84d8e1359d97b6447ef884c74c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jul 2024 14:05:24 +0000 Subject: [PATCH 001/282] build(deps-dev): bump typescript from 5.4.5 to 5.5.3 Bumps [typescript](https://github.com/Microsoft/TypeScript) from 5.4.5 to 5.5.3. - [Release notes](https://github.com/Microsoft/TypeScript/releases) - [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml) - [Commits](https://github.com/Microsoft/TypeScript/compare/v5.4.5...v5.5.3) --- updated-dependencies: - dependency-name: typescript dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 9 ++++----- package.json | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index d7cfc8d6b..bb6e32c96 100644 --- a/package-lock.json +++ b/package-lock.json @@ -52,7 +52,7 @@ "husky": "^9.0.11", "prettier": "^3.3.2", "ts-loader": "^9.5.1", - "typescript": "^5.4.5" + "typescript": "^5.5.3" }, "engines": { "node": ">=18.12.0", @@ -30744,11 +30744,10 @@ } }, "node_modules/typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", + "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", "dev": true, - "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/package.json b/package.json index e3bd9b0f5..88be599cb 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,7 @@ "husky": "^9.0.11", "prettier": "^3.3.2", "ts-loader": "^9.5.1", - "typescript": "^5.4.5" + "typescript": "^5.5.3" }, "devDependenciesComments": { "@wordpress/babel-preset-default": "Don't upgrade to v8 or greater until the plugin requires WordPress 6.6. See https://github.com/WordPress/gutenberg/pull/62265/files", From 137b50d9118ef3b99e6de2a8045d68b70c387eeb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Jul 2024 14:11:53 +0000 Subject: [PATCH 002/282] build(deps): bump actions/setup-node from 4.0.2 to 4.0.3 (#2623) --- .github/workflows/e2e-tests.yml | 2 +- .github/workflows/node.js.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 1202e6e67..067b83af5 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -24,7 +24,7 @@ jobs: uses: actions/checkout@v4 - name: Use desired version of NodeJS - uses: actions/setup-node@v4.0.2 + uses: actions/setup-node@v4.0.3 with: node-version: 16 cache: npm diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index d12a2b370..02e0a54fa 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -28,7 +28,7 @@ jobs: run: echo "NODE_VERSION=$(cat .nvmrc)" >> $GITHUB_ENV - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@v4.0.2 + uses: actions/setup-node@v4.0.3 with: node-version: ${{ env.NODE_VERSION }} cache: npm From 72c377672337b9b4483177060de5352e451e01eb Mon Sep 17 00:00:00 2001 From: Alex Cicovic <23142906+acicovic@users.noreply.github.com> Date: Wed, 24 Jul 2024 11:11:11 +0300 Subject: [PATCH 003/282] ESLint: Use method-signature-style rule --- .eslintrc | 5 +++-- src/@types/gutenberg/types.ts | 41 +++++++++++++++++------------------ 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/.eslintrc b/.eslintrc index 3d30bfcdf..1627ecffb 100644 --- a/.eslintrc +++ b/.eslintrc @@ -42,10 +42,11 @@ } ], "@typescript-eslint/ban-ts-comment": "off", - "@typescript-eslint/prefer-nullish-coalescing": ["error"], + "@typescript-eslint/method-signature-style": "error", // Can be removed after we've updated to wp-scripts v28 or greater. + "@typescript-eslint/prefer-nullish-coalescing": "error", // Enabling TS rule and disabling Base rule as it can report incorrect errors. "no-shadow": "off", - "@typescript-eslint/no-shadow": ["error"], + "@typescript-eslint/no-shadow": "error", // Allow usage of Gutenberg experimental components. "@wordpress/no-unsafe-wp-apis": "off", // Allow link tag in JSDocs. diff --git a/src/@types/gutenberg/types.ts b/src/@types/gutenberg/types.ts index 287a8670d..01fa4093f 100644 --- a/src/@types/gutenberg/types.ts +++ b/src/@types/gutenberg/types.ts @@ -11,27 +11,26 @@ import { dispatch } from '@wordpress/data'; * @since 3.12.0 */ export interface GutenbergFunction { - editPost( edits: Record ): void; - getBlock( clientId: string ): BlockInstance | null; - getBlockParents( clientId: string ): string[]; - getBlocks(): BlockInstance[]; - getCurrentPostAttribute( attribute: string ): string; - getCurrentPostId(): number | undefined; - getEditedPostAttribute( attribute: string ): string; - getEditedPostContent(): string; - getPermalink(): string | null; - getPermalink(): string | null; - getSelectedBlock(): BlockInstance | null; - hasMetaBoxes(): boolean; - isAutosavingPost(): boolean; - isSavingPost(): boolean; - lockPostSaving( lockName: string ): void; - lockPostAutosaving( lockName: string ): void; - unlockPostAutosaving( lockName: string ): void; - removeEditorPanel( panelName: string ): void; - selectBlock( clientId: string, initialPosition?: number ): void; - unlockPostSaving( lockName: string ): void; - updateBlockAttributes( clientId: string, attributes: Record ): void; + editPost: ( edits: Record ) => void; + getBlock: ( clientId: string ) => BlockInstance | null; + getBlockParents: ( clientId: string ) => string[]; + getBlocks: () => BlockInstance[]; + getCurrentPostAttribute: ( attribute: string ) => string; + getCurrentPostId: () => number | undefined; + getEditedPostAttribute: ( attribute: string ) => string; + getEditedPostContent: () => string; + getPermalink: () => string | null; + getSelectedBlock: () => BlockInstance | null; + hasMetaBoxes: () => boolean; + isAutosavingPost: () => boolean; + isSavingPost: () => boolean; + lockPostSaving: ( lockName: string ) => void; + lockPostAutosaving: ( lockName: string ) => void; + unlockPostAutosaving: ( lockName: string ) => void; + removeEditorPanel: ( panelName: string ) => void; + selectBlock: ( clientId: string, initialPosition?: number ) => void; + unlockPostSaving: ( lockName: string ) => void; + updateBlockAttributes: ( clientId: string, attributes: Record ) => void; } /** From 0cbc98356ef4881929cb89eea460b8a98ef54f1c Mon Sep 17 00:00:00 2001 From: Alex Cicovic <23142906+acicovic@users.noreply.github.com> Date: Wed, 24 Jul 2024 12:56:56 +0300 Subject: [PATCH 004/282] Add .stylelintrc --- .stylelintrc | 22 +++++++++++++++++++ src/content-helper/common/css/common.scss | 1 - .../dashboard-widget/dashboard-widget.scss | 1 - .../editor-sidebar/editor-sidebar.scss | 5 ----- .../performance-stats/performance-stats.scss | 1 - .../related-posts/related-posts.scss | 3 --- .../smart-linking/smart-linking.scss | 2 -- .../title-suggestions/title-suggestions.scss | 2 -- src/css/admin-settings.scss | 4 ---- src/css/recommended-widget.scss | 1 - 10 files changed, 22 insertions(+), 20 deletions(-) create mode 100644 .stylelintrc diff --git a/.stylelintrc b/.stylelintrc new file mode 100644 index 000000000..af105d1a6 --- /dev/null +++ b/.stylelintrc @@ -0,0 +1,22 @@ +{ + "extends": [ + "@wordpress/stylelint-config/scss" + ], + "reportInvalidScopeDisables": true, + "reportNeedlessDisables": true, + "rules": { + "media-feature-parentheses-space-inside": "never", + "rule-empty-line-before": [ + "always-multi-line", + { + "except": [ + "first-nested" + ], + "ignore": [ + "after-comment" + ] + } + ], + "selector-class-pattern": null + } +} diff --git a/src/content-helper/common/css/common.scss b/src/content-helper/common/css/common.scss index 86e6e7117..25c1182d0 100644 --- a/src/content-helper/common/css/common.scss +++ b/src/content-helper/common/css/common.scss @@ -118,7 +118,6 @@ } .components-panel__body { - &.is-opened { padding: 0; } diff --git a/src/content-helper/dashboard-widget/dashboard-widget.scss b/src/content-helper/dashboard-widget/dashboard-widget.scss index dffc9eead..98fd5bfb4 100644 --- a/src/content-helper/dashboard-widget/dashboard-widget.scss +++ b/src/content-helper/dashboard-widget/dashboard-widget.scss @@ -66,7 +66,6 @@ } @media only screen and (max-width: 380px) { - &::before { content: ""; padding-right: 0; diff --git a/src/content-helper/editor-sidebar/editor-sidebar.scss b/src/content-helper/editor-sidebar/editor-sidebar.scss index 3d48c1025..b566f4638 100644 --- a/src/content-helper/editor-sidebar/editor-sidebar.scss +++ b/src/content-helper/editor-sidebar/editor-sidebar.scss @@ -4,7 +4,6 @@ // Set the colors of the sidebar icon. .components-button[aria-controls="wp-parsely-block-editor-sidebar:wp-parsely-content-helper"] { - &:hover { background-color: #fff; } @@ -38,7 +37,6 @@ p.content-helper-error-message-hint { // Notice components with errors that appear within Sidebar panels. .wp-parsely-content-helper-error.components-notice { - .components-notice__content { margin: 0; @@ -53,7 +51,6 @@ p.content-helper-error-message-hint { } .wp-parsely-content-helper { - .wp-parsely-sidebar-header { display: flex; flex-direction: column; @@ -70,7 +67,6 @@ p.content-helper-error-message-hint { } .wp-parsely-sidebar-main-panel { - // Settings button for panels. .components-panel button.panel-settings-button, .components-panel .panel-settings-button > button { @@ -86,7 +82,6 @@ p.content-helper-error-message-hint { } .components-tab-panel__tabs { - // Individual tab. button { display: flex; diff --git a/src/content-helper/editor-sidebar/performance-stats/performance-stats.scss b/src/content-helper/editor-sidebar/performance-stats/performance-stats.scss index 38947302b..5d48d96aa 100644 --- a/src/content-helper/editor-sidebar/performance-stats/performance-stats.scss +++ b/src/content-helper/editor-sidebar/performance-stats/performance-stats.scss @@ -49,7 +49,6 @@ /** Level 3 heading */ &.level-3 { - h3 { margin-bottom: 0; line-height: to_rem(16px); diff --git a/src/content-helper/editor-sidebar/related-posts/related-posts.scss b/src/content-helper/editor-sidebar/related-posts/related-posts.scss index 8b83c7b2c..b49d45604 100644 --- a/src/content-helper/editor-sidebar/related-posts/related-posts.scss +++ b/src/content-helper/editor-sidebar/related-posts/related-posts.scss @@ -106,7 +106,6 @@ } .related-posts-wrapper { - .related-posts-descr { font-size: to_rem(13px); font-style: normal; @@ -203,13 +202,11 @@ } .wp-parsely-icon { - path { fill: #1e1e1e; } &:hover { - path { fill: #0073aa; } diff --git a/src/content-helper/editor-sidebar/smart-linking/smart-linking.scss b/src/content-helper/editor-sidebar/smart-linking/smart-linking.scss index 94fe35d64..e4509d056 100644 --- a/src/content-helper/editor-sidebar/smart-linking/smart-linking.scss +++ b/src/content-helper/editor-sidebar/smart-linking/smart-linking.scss @@ -269,7 +269,6 @@ align-self: stretch; .smart-linking-review-sidebar-tabs { - .components-tab-panel__tabs { margin-bottom: var(--grid-unit-20); @@ -488,7 +487,6 @@ } .wp-parsely-preview-editor { - .editor-styles-wrapper { padding-bottom: 0; font-size: var(--font-size--medium); diff --git a/src/content-helper/editor-sidebar/title-suggestions/title-suggestions.scss b/src/content-helper/editor-sidebar/title-suggestions/title-suggestions.scss index e866a5f4a..17a5e7c94 100644 --- a/src/content-helper/editor-sidebar/title-suggestions/title-suggestions.scss +++ b/src/content-helper/editor-sidebar/title-suggestions/title-suggestions.scss @@ -7,7 +7,6 @@ flex-direction: column; .title-suggestions-settings { - display: flex; padding: to_rem(6px) 0 var(--grid-unit-20) 0; flex-direction: column; @@ -69,7 +68,6 @@ // Accepted Title view. // TODO: Remove, unused? .parsely-write-titles-accepted-title-container { - .parsely-write-titles-accepted-title { font-weight: 600; font-size: to_rem(16px); diff --git a/src/css/admin-settings.scss b/src/css/admin-settings.scss index 0b6c4bbe7..265cb34e7 100644 --- a/src/css/admin-settings.scss +++ b/src/css/admin-settings.scss @@ -5,7 +5,6 @@ --padding-default: 15px; fieldset.user-role-permissions { - label { margin-right: to_rem(16px) !important; } @@ -14,7 +13,6 @@ .disabled-before-posting, fieldset:disabled, tr:has(fieldset:disabled) { - label:not(.prevent-disable), p, th { @@ -75,9 +73,7 @@ } @media only screen and (max-width: 380px) { - #track-post-types { - th, td { padding-left: 10px; diff --git a/src/css/recommended-widget.scss b/src/css/recommended-widget.scss index c42bfd13e..293250eb6 100644 --- a/src/css/recommended-widget.scss +++ b/src/css/recommended-widget.scss @@ -56,7 +56,6 @@ } @supports (display: grid) { - .parsely-recommended-widget-entry::after { display: none; clear: initial; From c38025fd7a30ca4eec3b1c840bce07c8f5d609cf Mon Sep 17 00:00:00 2001 From: Alex Cicovic <23142906+acicovic@users.noreply.github.com> Date: Fri, 26 Jul 2024 11:46:09 +0300 Subject: [PATCH 005/282] Refactor some integration tests --- .../Integration/BaseUserMetaEndpointTest.php | 4 +- .../Integration/ContentHelperFeatureTest.php | 285 +++++++++++++++--- .../AnalyticsPostsProxyEndpointTest.php | 6 +- .../EditorSidebarSettingsEndpointTest.php | 2 +- .../ReferrersPostDetailProxyEndpointTest.php | 6 +- .../StatsPostDetailProxyEndpointTest.php | 6 +- tests/Integration/ProxyEndpointTest.php | 4 +- .../RemoteAPI/AnalyticsPostsRemoteAPITest.php | 6 +- tests/Integration/ScriptsTest.php | 6 +- tests/Integration/TestCase.php | 59 +++- .../ContentHelperDashboardWidgetTest.php | 60 ++-- .../ContentHelperEditorSidebarTest.php | 46 +-- .../ContentHelperPostListStatsTest.php | 47 ++- 13 files changed, 398 insertions(+), 139 deletions(-) diff --git a/tests/Integration/BaseUserMetaEndpointTest.php b/tests/Integration/BaseUserMetaEndpointTest.php index a32e32cc3..d2c082b2f 100644 --- a/tests/Integration/BaseUserMetaEndpointTest.php +++ b/tests/Integration/BaseUserMetaEndpointTest.php @@ -48,7 +48,7 @@ abstract protected function generate_json( * @since 3.13.0 */ public function run_test_endpoint_returns_value_on_get_request(): void { - $this->set_admin_user(); + $this->set_current_user_to_admin(); $value = rest_do_request( new WP_REST_Request( @@ -136,7 +136,7 @@ public function provide_put_requests_data(): iterable { * @return string The response returned by the endpoint. */ protected function send_put_request( string $data ): string { - $this->set_admin_user(); + $this->set_current_user_to_admin(); $result = $this->send_wp_rest_request( 'PUT', self::$route, $data ); if ( ! is_string( $result ) ) { diff --git a/tests/Integration/ContentHelperFeatureTest.php b/tests/Integration/ContentHelperFeatureTest.php index b250e2f86..02f0905a5 100644 --- a/tests/Integration/ContentHelperFeatureTest.php +++ b/tests/Integration/ContentHelperFeatureTest.php @@ -20,23 +20,61 @@ */ abstract class ContentHelperFeatureTest extends TestCase { /** - * Asserts the enqueueing status of the feature's assets according to the - * passed filter values. + * Asserts the enqueueing status of a feature's assets. * * @since 3.9.0 * - * @param mixed $global_filter_value The value of the global filter. - * @param mixed $feature_filter_value The value of the feature filter. - * @param bool $expected Whether the assets should be enqueued. - * @param mixed ...$additional_args Any required additional arguments. + * @param mixed $global_filter_value The value of the global filter. + * @param mixed $feature_filter_value The value of the feature filter. + * @param bool $expected Whether the assets should be enqueued. + * @param string $user_login The current user's login. + * @param string $user_role The current user's role. + * @param array $additional_args Any required additional arguments. */ abstract protected function assert_enqueued_status( $global_filter_value, $feature_filter_value, bool $expected, - ...$additional_args + string $user_login, + string $user_role, + array $additional_args = array() ): void; + /** + * Provides a default implementation for asserting the enqueueing status + * of a feature's assets. + * + * @since 3.17.0 + * + * @param Content_Helper_Feature $feature The feature to be tested. + * @param mixed $global_filter_value The value of the global filter. + * @param mixed $feature_filter_value The value of the feature filter. + * @param bool $expected Whether the assets should be enqueued. + * @param string $user_login The current user's login. + * @param string $user_role The current user's role. + */ + protected function assert_enqueued_status_default( + Content_Helper_Feature $feature, + $global_filter_value, + $feature_filter_value, + bool $expected, + string $user_login, + string $user_role + ): void { + $this->set_current_user_to( $user_login, $user_role ); + + self::set_filters( + $feature::get_feature_filter_name(), + $global_filter_value, + $feature_filter_value + ); + + self::deregister_feature_assets_and_run( $feature ); + + self::assertSame( $expected, wp_script_is( $feature::get_script_id() ) ); + self::assertSame( $expected, wp_style_is( $feature::get_style_id() ) ); + } + /** * Sets the global and feature filters according to the passed values. * @@ -77,6 +115,27 @@ function () use ( $feature_filter_value ) { } } + /** + * Deregisters a feature's assets and calls the feature's run method. + * + * @since 3.17.0 + * + * @param Content_Helper_Feature $feature The instance of the feature. + */ + protected static function deregister_feature_assets_and_run( + Content_Helper_Feature $feature + ): void { + $script_id = $feature::get_script_id(); + $style_id = $feature::get_style_id(); + + wp_dequeue_script( $script_id ); + wp_deregister_script( $script_id ); + wp_dequeue_style( $style_id ); + wp_deregister_style( $style_id ); + + $feature->run(); + } + /** * Verifies that the run() method enqueues the assets by default. * @@ -95,6 +154,12 @@ function () use ( $feature_filter_value ) { * @covers \Parsely\Content_Helper\Editor_Sidebar::get_script_id * @covers \Parsely\Content_Helper\Editor_Sidebar::get_style_id * @covers \Parsely\Content_Helper\Editor_Sidebar::run + * @covers \Parsely\Content_Helper\Excerpt_Generator::__construct + * @covers \Parsely\Content_Helper\Excerpt_Generator::can_enable_feature + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_feature_filter_name + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_script_id + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_style_id + * @covers \Parsely\Content_Helper\Excerpt_Generator::run * @covers \Parsely\Content_Helper\Post_List_Stats::__construct * @covers \Parsely\Content_Helper\Post_List_Stats::enqueue_parsely_stats_script_with_data * @covers \Parsely\Content_Helper\Post_List_Stats::enqueue_parsely_stats_styles @@ -105,18 +170,26 @@ function () use ( $feature_filter_value ) { * @covers \Parsely\Content_Helper\Post_List_Stats::is_tracked_as_post_type * @covers \Parsely\Content_Helper\Post_List_Stats::run * @covers \Parsely\Content_Helper\Post_List_Stats::set_current_screen + * @uses \Parsely\Content_Helper\Content_Helper_Feature::get_credentials_not_set_message + * @uses \Parsely\Content_Helper\Content_Helper_Feature::inject_inline_scripts + * @uses \Parsely\Endpoints\Base_Endpoint::__construct * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::get_managed_credentials * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::set_default_track_as_values + * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Endpoints\Base_Endpoint::__construct * @uses \Parsely\Utils\convert_endpoint_to_filter_key * @uses \Parsely\Utils\get_asset_info * * @group content-helper */ public function test_assets_get_enqueued_by_default(): void { - $this->assert_enqueued_status( null, null, true ); + $this->assert_enqueued_status( null, null, true, 'admin', 'administrator' ); } /** @@ -138,6 +211,12 @@ public function test_assets_get_enqueued_by_default(): void { * @covers \Parsely\Content_Helper\Editor_Sidebar::get_script_id * @covers \Parsely\Content_Helper\Editor_Sidebar::get_style_id * @covers \Parsely\Content_Helper\Editor_Sidebar::run + * @covers \Parsely\Content_Helper\Excerpt_Generator::__construct + * @covers \Parsely\Content_Helper\Excerpt_Generator::can_enable_feature + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_feature_filter_name + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_script_id + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_style_id + * @covers \Parsely\Content_Helper\Excerpt_Generator::run * @covers \Parsely\Content_Helper\Post_List_Stats::__construct * @covers \Parsely\Content_Helper\Post_List_Stats::enqueue_parsely_stats_script_with_data * @covers \Parsely\Content_Helper\Post_List_Stats::enqueue_parsely_stats_styles @@ -148,18 +227,26 @@ public function test_assets_get_enqueued_by_default(): void { * @covers \Parsely\Content_Helper\Post_List_Stats::is_tracked_as_post_type * @covers \Parsely\Content_Helper\Post_List_Stats::run * @covers \Parsely\Content_Helper\Post_List_Stats::set_current_screen + * @uses \Parsely\Content_Helper\Content_Helper_Feature::get_credentials_not_set_message + * @uses \Parsely\Content_Helper\Content_Helper_Feature::inject_inline_scripts + * @uses \Parsely\Endpoints\Base_Endpoint::__construct * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::get_managed_credentials * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::set_default_track_as_values + * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Endpoints\Base_Endpoint::__construct * @uses \Parsely\Utils\convert_endpoint_to_filter_key * @uses \Parsely\Utils\get_asset_info * * @group content-helper */ public function test_assets_get_enqueued_when_global_filter_is_true(): void { - $this->assert_enqueued_status( true, null, true ); + $this->assert_enqueued_status( true, null, true, 'admin', 'administrator' ); } /** @@ -181,21 +268,30 @@ public function test_assets_get_enqueued_when_global_filter_is_true(): void { * @covers \Parsely\Content_Helper\Editor_Sidebar::get_script_id * @covers \Parsely\Content_Helper\Editor_Sidebar::get_style_id * @covers \Parsely\Content_Helper\Editor_Sidebar::run + * @covers \Parsely\Content_Helper\Excerpt_Generator::__construct + * @covers \Parsely\Content_Helper\Excerpt_Generator::can_enable_feature + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_feature_filter_name + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_script_id + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_style_id + * @covers \Parsely\Content_Helper\Excerpt_Generator::run * @covers \Parsely\Content_Helper\Post_List_Stats::__construct * @covers \Parsely\Content_Helper\Post_List_Stats::get_feature_filter_name * @covers \Parsely\Content_Helper\Post_List_Stats::run + * @uses \Parsely\Endpoints\Base_Endpoint::__construct * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::are_credentials_managed * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Endpoints\Base_Endpoint::__construct * @uses \Parsely\Utils\convert_endpoint_to_filter_key * @uses \Parsely\Utils\get_asset_info * * @group content-helper */ public function test_assets_do_not_get_enqueued_when_global_filter_is_false(): void { - $this->assert_enqueued_status( false, null, false ); + $this->assert_enqueued_status( false, null, false, 'admin', 'administrator' ); } /** @@ -217,14 +313,23 @@ public function test_assets_do_not_get_enqueued_when_global_filter_is_false(): v * @covers \Parsely\Content_Helper\Editor_Sidebar::get_script_id * @covers \Parsely\Content_Helper\Editor_Sidebar::get_style_id * @covers \Parsely\Content_Helper\Editor_Sidebar::run + * @covers \Parsely\Content_Helper\Excerpt_Generator::__construct + * @covers \Parsely\Content_Helper\Excerpt_Generator::can_enable_feature + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_feature_filter_name + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_script_id + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_style_id + * @covers \Parsely\Content_Helper\Excerpt_Generator::run * @covers \Parsely\Content_Helper\Post_List_Stats::__construct * @covers \Parsely\Content_Helper\Post_List_Stats::get_feature_filter_name * @covers \Parsely\Content_Helper\Post_List_Stats::run + * @uses \Parsely\Endpoints\Base_Endpoint::__construct * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::are_credentials_managed * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Endpoints\Base_Endpoint::__construct * @uses \Parsely\Utils\convert_endpoint_to_filter_key * @uses \Parsely\Utils\get_asset_info * @@ -232,7 +337,7 @@ public function test_assets_do_not_get_enqueued_when_global_filter_is_false(): v */ public function test_assets_do_not_get_enqueued_when_global_filter_is_invalid(): void { // We expect the filter to be boolean true. - $this->assert_enqueued_status( 1, null, false ); + $this->assert_enqueued_status( 1, null, false, 'admin', 'administrator' ); } /** @@ -254,6 +359,12 @@ public function test_assets_do_not_get_enqueued_when_global_filter_is_invalid(): * @covers \Parsely\Content_Helper\Editor_Sidebar::get_script_id * @covers \Parsely\Content_Helper\Editor_Sidebar::get_style_id * @covers \Parsely\Content_Helper\Editor_Sidebar::run + * @covers \Parsely\Content_Helper\Excerpt_Generator::__construct + * @covers \Parsely\Content_Helper\Excerpt_Generator::can_enable_feature + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_feature_filter_name + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_script_id + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_style_id + * @covers \Parsely\Content_Helper\Excerpt_Generator::run * @covers \Parsely\Content_Helper\Post_List_Stats::__construct * @covers \Parsely\Content_Helper\Post_List_Stats::enqueue_parsely_stats_script_with_data * @covers \Parsely\Content_Helper\Post_List_Stats::enqueue_parsely_stats_styles @@ -264,18 +375,26 @@ public function test_assets_do_not_get_enqueued_when_global_filter_is_invalid(): * @covers \Parsely\Content_Helper\Post_List_Stats::is_tracked_as_post_type * @covers \Parsely\Content_Helper\Post_List_Stats::run * @covers \Parsely\Content_Helper\Post_List_Stats::set_current_screen + * @uses \Parsely\Content_Helper\Content_Helper_Feature::get_credentials_not_set_message + * @uses \Parsely\Content_Helper\Content_Helper_Feature::inject_inline_scripts + * @uses \Parsely\Endpoints\Base_Endpoint::__construct * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::get_managed_credentials * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::set_default_track_as_values + * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Endpoints\Base_Endpoint::__construct * @uses \Parsely\Utils\convert_endpoint_to_filter_key * @uses \Parsely\Utils\get_asset_info * * @group content-helper */ public function test_assets_get_enqueued_when_feature_filter_is_true(): void { - $this->assert_enqueued_status( null, true, true ); + $this->assert_enqueued_status( null, true, true, 'admin', 'administrator' ); } /** @@ -297,21 +416,30 @@ public function test_assets_get_enqueued_when_feature_filter_is_true(): void { * @covers \Parsely\Content_Helper\Editor_Sidebar::get_script_id * @covers \Parsely\Content_Helper\Editor_Sidebar::get_style_id * @covers \Parsely\Content_Helper\Editor_Sidebar::run + * @covers \Parsely\Content_Helper\Excerpt_Generator::__construct + * @covers \Parsely\Content_Helper\Excerpt_Generator::can_enable_feature + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_feature_filter_name + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_script_id + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_style_id + * @covers \Parsely\Content_Helper\Excerpt_Generator::run * @covers \Parsely\Content_Helper\Post_List_Stats::__construct * @covers \Parsely\Content_Helper\Post_List_Stats::get_feature_filter_name * @covers \Parsely\Content_Helper\Post_List_Stats::run + * @uses \Parsely\Endpoints\Base_Endpoint::__construct * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::are_credentials_managed * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Endpoints\Base_Endpoint::__construct * @uses \Parsely\Utils\convert_endpoint_to_filter_key * @uses \Parsely\Utils\get_asset_info * * @group content-helper */ public function test_assets_do_not_get_enqueued_when_feature_filter_is_false(): void { - $this->assert_enqueued_status( null, false, false ); + $this->assert_enqueued_status( null, false, false, 'admin', 'administrator' ); } /** @@ -333,21 +461,30 @@ public function test_assets_do_not_get_enqueued_when_feature_filter_is_false(): * @covers \Parsely\Content_Helper\Editor_Sidebar::get_script_id * @covers \Parsely\Content_Helper\Editor_Sidebar::get_style_id * @covers \Parsely\Content_Helper\Editor_Sidebar::run + * @covers \Parsely\Content_Helper\Excerpt_Generator::__construct + * @covers \Parsely\Content_Helper\Excerpt_Generator::can_enable_feature + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_feature_filter_name + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_script_id + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_style_id + * @covers \Parsely\Content_Helper\Excerpt_Generator::run * @covers \Parsely\Content_Helper\Post_List_Stats::__construct * @covers \Parsely\Content_Helper\Post_List_Stats::get_feature_filter_name * @covers \Parsely\Content_Helper\Post_List_Stats::run + * @uses \Parsely\Endpoints\Base_Endpoint::__construct * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::are_credentials_managed * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Endpoints\Base_Endpoint::__construct * @uses \Parsely\Utils\convert_endpoint_to_filter_key * @uses \Parsely\Utils\get_asset_info * * @group content-helper */ public function test_assets_do_not_get_enqueued_when_feature_filter_is_invalid(): void { - $this->assert_enqueued_status( null, array(), false ); + $this->assert_enqueued_status( null, array(), false, 'admin', 'administrator' ); } /** @@ -369,6 +506,12 @@ public function test_assets_do_not_get_enqueued_when_feature_filter_is_invalid() * @covers \Parsely\Content_Helper\Editor_Sidebar::get_script_id * @covers \Parsely\Content_Helper\Editor_Sidebar::get_style_id * @covers \Parsely\Content_Helper\Editor_Sidebar::run + * @covers \Parsely\Content_Helper\Excerpt_Generator::__construct + * @covers \Parsely\Content_Helper\Excerpt_Generator::can_enable_feature + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_feature_filter_name + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_script_id + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_style_id + * @covers \Parsely\Content_Helper\Excerpt_Generator::run * @covers \Parsely\Content_Helper\Post_List_Stats::__construct * @covers \Parsely\Content_Helper\Post_List_Stats::enqueue_parsely_stats_script_with_data * @covers \Parsely\Content_Helper\Post_List_Stats::enqueue_parsely_stats_styles @@ -379,18 +522,26 @@ public function test_assets_do_not_get_enqueued_when_feature_filter_is_invalid() * @covers \Parsely\Content_Helper\Post_List_Stats::is_tracked_as_post_type * @covers \Parsely\Content_Helper\Post_List_Stats::run * @covers \Parsely\Content_Helper\Post_List_Stats::set_current_screen + * @uses \Parsely\Content_Helper\Content_Helper_Feature::get_credentials_not_set_message + * @uses \Parsely\Content_Helper\Content_Helper_Feature::inject_inline_scripts + * @uses \Parsely\Endpoints\Base_Endpoint::__construct * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::get_managed_credentials * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::set_default_track_as_values + * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Endpoints\Base_Endpoint::__construct * @uses \Parsely\Utils\convert_endpoint_to_filter_key * @uses \Parsely\Utils\get_asset_info * * @group content-helper */ public function test_assets_get_enqueued_when_both_filters_are_true(): void { - $this->assert_enqueued_status( true, true, true ); + $this->assert_enqueued_status( true, true, true, 'admin', 'administrator' ); } /** @@ -412,6 +563,12 @@ public function test_assets_get_enqueued_when_both_filters_are_true(): void { * @covers \Parsely\Content_Helper\Editor_Sidebar::get_script_id * @covers \Parsely\Content_Helper\Editor_Sidebar::get_style_id * @covers \Parsely\Content_Helper\Editor_Sidebar::run + * @covers \Parsely\Content_Helper\Excerpt_Generator::__construct + * @covers \Parsely\Content_Helper\Excerpt_Generator::can_enable_feature + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_feature_filter_name + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_script_id + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_style_id + * @covers \Parsely\Content_Helper\Excerpt_Generator::run * @covers \Parsely\Content_Helper\Post_List_Stats::__construct * @covers \Parsely\Content_Helper\Post_List_Stats::enqueue_parsely_stats_script_with_data * @covers \Parsely\Content_Helper\Post_List_Stats::enqueue_parsely_stats_styles @@ -422,18 +579,21 @@ public function test_assets_get_enqueued_when_both_filters_are_true(): void { * @covers \Parsely\Content_Helper\Post_List_Stats::is_tracked_as_post_type * @covers \Parsely\Content_Helper\Post_List_Stats::run * @covers \Parsely\Content_Helper\Post_List_Stats::set_current_screen + * @uses \Parsely\Endpoints\Base_Endpoint::__construct * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::are_credentials_managed * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Endpoints\Base_Endpoint::__construct * @uses \Parsely\Utils\convert_endpoint_to_filter_key * @uses \Parsely\Utils\get_asset_info * * @group content-helper */ public function test_assets_do_not_get_enqueued_when_both_filters_are_false(): void { - $this->assert_enqueued_status( false, false, false ); + $this->assert_enqueued_status( false, false, false, 'admin', 'administrator' ); } /** @@ -455,21 +615,30 @@ public function test_assets_do_not_get_enqueued_when_both_filters_are_false(): v * @covers \Parsely\Content_Helper\Editor_Sidebar::get_script_id * @covers \Parsely\Content_Helper\Editor_Sidebar::get_style_id * @covers \Parsely\Content_Helper\Editor_Sidebar::run + * @covers \Parsely\Content_Helper\Excerpt_Generator::__construct + * @covers \Parsely\Content_Helper\Excerpt_Generator::can_enable_feature + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_feature_filter_name + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_script_id + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_style_id + * @covers \Parsely\Content_Helper\Excerpt_Generator::run * @covers \Parsely\Content_Helper\Post_List_Stats::__construct * @covers \Parsely\Content_Helper\Post_List_Stats::get_feature_filter_name * @covers \Parsely\Content_Helper\Post_List_Stats::run + * @uses \Parsely\Endpoints\Base_Endpoint::__construct * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::are_credentials_managed * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Endpoints\Base_Endpoint::__construct * @uses \Parsely\Utils\convert_endpoint_to_filter_key * @uses \Parsely\Utils\get_asset_info * * @group content-helper */ public function test_assets_do_not_get_enqueued_when_both_filters_are_invalid(): void { - $this->assert_enqueued_status( 'string', 'string', false ); + $this->assert_enqueued_status( 'string', 'string', false, 'admin', 'administrator' ); } /** @@ -491,21 +660,30 @@ public function test_assets_do_not_get_enqueued_when_both_filters_are_invalid(): * @covers \Parsely\Content_Helper\Editor_Sidebar::get_script_id * @covers \Parsely\Content_Helper\Editor_Sidebar::get_style_id * @covers \Parsely\Content_Helper\Editor_Sidebar::run + * @covers \Parsely\Content_Helper\Excerpt_Generator::__construct + * @covers \Parsely\Content_Helper\Excerpt_Generator::can_enable_feature + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_feature_filter_name + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_script_id + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_style_id + * @covers \Parsely\Content_Helper\Excerpt_Generator::run * @covers \Parsely\Content_Helper\Post_List_Stats::__construct * @covers \Parsely\Content_Helper\Post_List_Stats::get_feature_filter_name * @covers \Parsely\Content_Helper\Post_List_Stats::run + * @uses \Parsely\Endpoints\Base_Endpoint::__construct * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::are_credentials_managed * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Endpoints\Base_Endpoint::__construct * @uses \Parsely\Utils\convert_endpoint_to_filter_key * @uses \Parsely\Utils\get_asset_info * * @group content-helper */ public function test_assets_do_not_get_enqueued_when_global_filter_is_true_and_feature_filter_is_false(): void { - $this->assert_enqueued_status( true, false, false ); + $this->assert_enqueued_status( true, false, false, 'admin', 'administrator' ); } /** @@ -527,6 +705,12 @@ public function test_assets_do_not_get_enqueued_when_global_filter_is_true_and_f * @covers \Parsely\Content_Helper\Editor_Sidebar::get_script_id * @covers \Parsely\Content_Helper\Editor_Sidebar::get_style_id * @covers \Parsely\Content_Helper\Editor_Sidebar::run + * @covers \Parsely\Content_Helper\Excerpt_Generator::__construct + * @covers \Parsely\Content_Helper\Excerpt_Generator::can_enable_feature + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_feature_filter_name + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_script_id + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_style_id + * @covers \Parsely\Content_Helper\Excerpt_Generator::run * @covers \Parsely\Content_Helper\Post_List_Stats::__construct * @covers \Parsely\Content_Helper\Post_List_Stats::enqueue_parsely_stats_script_with_data * @covers \Parsely\Content_Helper\Post_List_Stats::enqueue_parsely_stats_styles @@ -537,18 +721,26 @@ public function test_assets_do_not_get_enqueued_when_global_filter_is_true_and_f * @covers \Parsely\Content_Helper\Post_List_Stats::is_tracked_as_post_type * @covers \Parsely\Content_Helper\Post_List_Stats::run * @covers \Parsely\Content_Helper\Post_List_Stats::set_current_screen + * @uses \Parsely\Content_Helper\Content_Helper_Feature::get_credentials_not_set_message + * @uses \Parsely\Content_Helper\Content_Helper_Feature::inject_inline_scripts + * @uses \Parsely\Endpoints\Base_Endpoint::__construct * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::get_managed_credentials * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::set_default_track_as_values + * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Endpoints\Base_Endpoint::__construct * @uses \Parsely\Utils\convert_endpoint_to_filter_key * @uses \Parsely\Utils\get_asset_info * * @group content-helper */ public function test_assets_get_enqueued_when_global_filter_is_false_and_feature_filter_is_true(): void { - $this->assert_enqueued_status( false, true, true ); + $this->assert_enqueued_status( false, true, true, 'admin', 'administrator' ); } /** @@ -571,21 +763,30 @@ public function test_assets_get_enqueued_when_global_filter_is_false_and_feature * @covers \Parsely\Content_Helper\Editor_Sidebar::get_script_id * @covers \Parsely\Content_Helper\Editor_Sidebar::get_style_id * @covers \Parsely\Content_Helper\Editor_Sidebar::run + * @covers \Parsely\Content_Helper\Excerpt_Generator::__construct + * @covers \Parsely\Content_Helper\Excerpt_Generator::can_enable_feature + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_feature_filter_name + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_script_id + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_style_id + * @covers \Parsely\Content_Helper\Excerpt_Generator::run * @covers \Parsely\Content_Helper\Post_List_Stats::__construct * @covers \Parsely\Content_Helper\Post_List_Stats::get_feature_filter_name * @covers \Parsely\Content_Helper\Post_List_Stats::run + * @uses \Parsely\Endpoints\Base_Endpoint::__construct * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::are_credentials_managed * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Endpoints\Base_Endpoint::__construct * @uses \Parsely\Utils\convert_endpoint_to_filter_key * @uses \Parsely\Utils\get_asset_info * * @group content-helper */ public function test_assets_do_not_get_enqueued_when_global_filter_is_true_and_feature_filter_is_invalid(): void { - $this->assert_enqueued_status( true, array(), false ); + $this->assert_enqueued_status( true, array(), false, 'admin', 'administrator' ); } /** @@ -607,6 +808,12 @@ public function test_assets_do_not_get_enqueued_when_global_filter_is_true_and_f * @covers \Parsely\Content_Helper\Editor_Sidebar::get_script_id * @covers \Parsely\Content_Helper\Editor_Sidebar::get_style_id * @covers \Parsely\Content_Helper\Editor_Sidebar::run + * @covers \Parsely\Content_Helper\Excerpt_Generator::__construct + * @covers \Parsely\Content_Helper\Excerpt_Generator::can_enable_feature + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_feature_filter_name + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_script_id + * @covers \Parsely\Content_Helper\Excerpt_Generator::get_style_id + * @covers \Parsely\Content_Helper\Excerpt_Generator::run * @covers \Parsely\Content_Helper\Post_List_Stats::__construct * @covers \Parsely\Content_Helper\Post_List_Stats::enqueue_parsely_stats_script_with_data * @covers \Parsely\Content_Helper\Post_List_Stats::enqueue_parsely_stats_styles @@ -617,17 +824,25 @@ public function test_assets_do_not_get_enqueued_when_global_filter_is_true_and_f * @covers \Parsely\Content_Helper\Post_List_Stats::is_tracked_as_post_type * @covers \Parsely\Content_Helper\Post_List_Stats::run * @covers \Parsely\Content_Helper\Post_List_Stats::set_current_screen + * @uses \Parsely\Content_Helper\Content_Helper_Feature::get_credentials_not_set_message + * @uses \Parsely\Content_Helper\Content_Helper_Feature::inject_inline_scripts + * @uses \Parsely\Endpoints\Base_Endpoint::__construct * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::get_managed_credentials * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::set_default_track_as_values + * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Endpoints\Base_Endpoint::__construct * @uses \Parsely\Utils\convert_endpoint_to_filter_key * @uses \Parsely\Utils\get_asset_info * * @group content-helper */ public function test_assets_get_enqueued_when_global_filter_is_invalid_and_feature_filter_is_true(): void { - $this->assert_enqueued_status( 'string', true, true ); + $this->assert_enqueued_status( 'string', true, true, 'admin', 'administrator' ); } } diff --git a/tests/Integration/Endpoints/AnalyticsPostsProxyEndpointTest.php b/tests/Integration/Endpoints/AnalyticsPostsProxyEndpointTest.php index 19d6170ff..4c490be8c 100644 --- a/tests/Integration/Endpoints/AnalyticsPostsProxyEndpointTest.php +++ b/tests/Integration/Endpoints/AnalyticsPostsProxyEndpointTest.php @@ -113,7 +113,7 @@ public function test_access_of_analytics_posts_endpoint_is_forbidden(): void { * @uses \Parsely\Endpoints\Base_API_Proxy::register_endpoint */ public function test_get_items_fails_when_site_id_is_not_set(): void { - $this->set_admin_user(); + $this->set_current_user_to_admin(); parent::run_test_get_items_fails_without_site_id_set(); } @@ -135,7 +135,7 @@ public function test_get_items_fails_when_site_id_is_not_set(): void { * @uses \Parsely\Endpoints\Base_API_Proxy::register_endpoint */ public function test_get_items_fails_when_api_secret_is_not_set(): void { - $this->set_admin_user(); + $this->set_current_user_to_admin(); parent::run_test_get_items_fails_without_api_secret_set(); } @@ -184,7 +184,7 @@ public function test_user_is_allowed_to_make_proxy_api_call_if_endpoint_specific * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_request_options */ public function test_get_items(): void { - $this->set_admin_user(); + $this->set_current_user_to_admin(); TestCase::set_options( array( 'apikey' => 'example.com', diff --git a/tests/Integration/Endpoints/EditorSidebarSettingsEndpointTest.php b/tests/Integration/Endpoints/EditorSidebarSettingsEndpointTest.php index 4eef9d0d7..99f74b3fe 100644 --- a/tests/Integration/Endpoints/EditorSidebarSettingsEndpointTest.php +++ b/tests/Integration/Endpoints/EditorSidebarSettingsEndpointTest.php @@ -225,7 +225,7 @@ public function test_endpoint_correctly_handles_put_requests( * @uses \Parsely\Utils\convert_endpoint_to_filter_key() */ public function test_valid_nested_performance_stats_settings_period(): void { - $this->set_admin_user(); + $this->set_current_user_to_admin(); $value = $this->send_put_request( $this->generate_json( diff --git a/tests/Integration/Endpoints/ReferrersPostDetailProxyEndpointTest.php b/tests/Integration/Endpoints/ReferrersPostDetailProxyEndpointTest.php index eac7f0429..b0eafdb76 100644 --- a/tests/Integration/Endpoints/ReferrersPostDetailProxyEndpointTest.php +++ b/tests/Integration/Endpoints/ReferrersPostDetailProxyEndpointTest.php @@ -83,7 +83,7 @@ public function test_verify_that_route_is_not_registered_when_proxy_is_disabled( * @uses \Parsely\Endpoints\Base_Endpoint::__construct */ public function test_get_items_fails_when_site_id_is_not_set(): void { - $this->set_admin_user(); + $this->set_current_user_to_admin(); parent::run_test_get_items_fails_without_site_id_set(); } @@ -105,7 +105,7 @@ public function test_get_items_fails_when_site_id_is_not_set(): void { * @uses \Parsely\Endpoints\Base_Endpoint::__construct */ public function test_get_items_fails_when_api_secret_is_not_set(): void { - $this->set_admin_user(); + $this->set_current_user_to_admin(); parent::run_test_get_items_fails_without_api_secret_set(); } @@ -153,7 +153,7 @@ public function test_user_is_allowed_to_make_proxy_api_call_if_endpoint_specific * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_request_options */ public function test_get_items(): void { - $this->set_admin_user(); + $this->set_current_user_to_admin(); TestCase::set_options( array( 'apikey' => 'example.com', diff --git a/tests/Integration/Endpoints/StatsPostDetailProxyEndpointTest.php b/tests/Integration/Endpoints/StatsPostDetailProxyEndpointTest.php index 67280bac2..321949374 100644 --- a/tests/Integration/Endpoints/StatsPostDetailProxyEndpointTest.php +++ b/tests/Integration/Endpoints/StatsPostDetailProxyEndpointTest.php @@ -83,7 +83,7 @@ public function test_verify_that_route_is_not_registered_when_proxy_is_disabled( * @uses \Parsely\Endpoints\Base_Endpoint::__construct */ public function test_get_items_fails_when_site_id_is_not_set(): void { - $this->set_admin_user(); + $this->set_current_user_to_admin(); parent::run_test_get_items_fails_without_site_id_set(); } @@ -105,7 +105,7 @@ public function test_get_items_fails_when_site_id_is_not_set(): void { * @uses \Parsely\Endpoints\Base_Endpoint::__construct */ public function test_get_items_fails_when_api_secret_is_not_set(): void { - $this->set_admin_user(); + $this->set_current_user_to_admin(); parent::run_test_get_items_fails_without_api_secret_set(); } @@ -151,7 +151,7 @@ public function test_user_is_allowed_to_make_proxy_api_call_if_endpoint_specific * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_request_options */ public function test_get_items(): void { - $this->set_admin_user(); + $this->set_current_user_to_admin(); TestCase::set_options( array( 'apikey' => 'example.com', diff --git a/tests/Integration/ProxyEndpointTest.php b/tests/Integration/ProxyEndpointTest.php index 030871970..708b0db80 100644 --- a/tests/Integration/ProxyEndpointTest.php +++ b/tests/Integration/ProxyEndpointTest.php @@ -210,7 +210,7 @@ private function run_test_get_items_fails( * Verifies default user capability filter. */ public function run_test_user_is_allowed_to_make_proxy_api_call_if_default_user_capability_is_changed(): void { - $this->login_as_contributor(); + $this->set_current_user_to_contributor(); add_filter( 'wp_parsely_user_capability_for_all_private_apis', function () { @@ -229,7 +229,7 @@ function () { public function run_test_user_is_allowed_to_make_proxy_api_call_if_endpoint_specific_user_capability_is_changed( $filter_key = null ): void { - $this->login_as_contributor(); + $this->set_current_user_to_contributor(); $filter_key = $filter_key ?? static::$filter_key; add_filter( diff --git a/tests/Integration/RemoteAPI/AnalyticsPostsRemoteAPITest.php b/tests/Integration/RemoteAPI/AnalyticsPostsRemoteAPITest.php index c3f75b3e3..c0e8dc7ea 100644 --- a/tests/Integration/RemoteAPI/AnalyticsPostsRemoteAPITest.php +++ b/tests/Integration/RemoteAPI/AnalyticsPostsRemoteAPITest.php @@ -53,7 +53,7 @@ public function data_api_url(): iterable { * @uses \Parsely\Utils\convert_endpoint_to_filter_key */ public function test_user_is_allowed_to_make_api_call_if_default_user_capability_is_changed(): void { - $this->login_as_contributor(); + $this->set_current_user_to_contributor(); add_filter( 'wp_parsely_user_capability_for_all_private_apis', function () { @@ -79,7 +79,7 @@ function () { * @uses \Parsely\Utils\convert_endpoint_to_filter_key */ public function test_user_is_allowed_to_make_api_call_if_endpoint_specific_user_capability_is_changed(): void { - $this->login_as_contributor(); + $this->set_current_user_to_contributor(); add_filter( 'wp_parsely_user_capability_for_analytics_posts_api', function () { @@ -105,7 +105,7 @@ function () { * @uses \Parsely\Utils\convert_endpoint_to_filter_key */ public function test_endpoint_specific_user_capability_filter_have_more_priority_than_default(): void { - $this->login_as_contributor(); + $this->set_current_user_to_contributor(); add_filter( 'wp_parsely_user_capability_for_all_private_apis', diff --git a/tests/Integration/ScriptsTest.php b/tests/Integration/ScriptsTest.php index a062999c9..8798f5507 100644 --- a/tests/Integration/ScriptsTest.php +++ b/tests/Integration/ScriptsTest.php @@ -176,7 +176,7 @@ public function test_enqueue_js_tracker(): void { * @group scripts */ public function test_should_not_enqueue_tracker_scripts_for_drafted_posts(): void { - $this->set_admin_user(); + $this->set_current_user_to_admin(); $this->go_to_new_post( 'draft' ); self::$scripts->register_scripts(); @@ -206,7 +206,7 @@ public function test_should_not_enqueue_tracker_scripts_for_drafted_posts(): voi public function test_should_not_enqueue_tracker_scripts_for_published_posts_in_preview_mode(): void { $post_id = $this->create_test_post(); - $this->set_admin_user(); + $this->set_current_user_to_admin(); $this->go_to( "/?p={$post_id}&preview=true" ); self::$scripts->register_scripts(); @@ -471,7 +471,7 @@ public function test_do_not_track_logged_in_users_by_default(): void { ( new Parsely() )->get_default_options() ); - $this->set_admin_user(); + $this->set_current_user_to_admin(); $this->go_to_new_post(); self::$scripts->register_scripts(); self::$scripts->enqueue_js_tracker(); diff --git a/tests/Integration/TestCase.php b/tests/Integration/TestCase.php index 50672a880..23882e042 100644 --- a/tests/Integration/TestCase.php +++ b/tests/Integration/TestCase.php @@ -421,21 +421,39 @@ public function go_to_new_post( string $post_status = 'publish' ): int { } /** - * Sets current user as admin. + * Changes the current user, creating the account if it doesn't exist. * - * @param int $admin_user_id User ID for the site administrator. - * Default is 1 which is assigned to first admin user while creating the site. + * @since 3.17.0 + * + * @param string $user_login The user's login. + * @param string $user_role The user's role. + */ + public function set_current_user_to( string $user_login, string $user_role ): void { + $user = get_user_by( 'login', $user_login ); + if ( false === $user ) { + $user_id = $this->create_test_user( $user_login, $user_role ); + $user = get_user_by( 'id', $user_id ); + } + + if ( false === $user ) { + $this::fail( 'Invalid user.' ); + } + + wp_set_current_user( $user->ID ); + } + + /** + * Changes the current user to the built-in admin account. */ - public function set_admin_user( int $admin_user_id = 1 ): void { - wp_set_current_user( $admin_user_id ); + public function set_current_user_to_admin(): void { + $this->set_current_user_to( 'admin', 'administrator' ); } /** - * Creates a user with role `contributor` and login. + * Changes the current user to a contributor account. */ - public function login_as_contributor(): void { - $user_id = $this->create_test_user( 'test_contributor', 'contributor' ); - wp_set_current_user( $user_id ); + public function set_current_user_to_contributor(): void { + $this->set_current_user_to( 'test_contributor', 'contributor' ); } /** @@ -683,4 +701,27 @@ public function send_wp_rest_request( return rest_do_request( $request )->get_data(); } + + /** + * Returns the requested string value from an associative array. If + * validation fails, the default value is returned. + * + * @since 3.17.0 + * + * @param array $data The array from which to get the string. + * @param string $key The key of the string in the array. + * @param string $default_value The value to return if validation fails. + * @return string The string, or the default value if validation fails. + */ + protected static function get_string_value_from_array( + array $data, + string $key, + string $default_value + ): string { + if ( ! isset( $data[ $key ] ) || ! is_string( $data[ $key ] ) ) { + return $default_value; + } + + return $data[ $key ]; + } } diff --git a/tests/Integration/content-helper/ContentHelperDashboardWidgetTest.php b/tests/Integration/content-helper/ContentHelperDashboardWidgetTest.php index 13032d131..39801809c 100644 --- a/tests/Integration/content-helper/ContentHelperDashboardWidgetTest.php +++ b/tests/Integration/content-helper/ContentHelperDashboardWidgetTest.php @@ -21,17 +21,18 @@ final class ContentHelperDashboardWidgetTest extends ContentHelperFeatureTest { */ public function set_up(): void { $GLOBALS['parsely'] = new Parsely(); - self::set_admin_user(); } /** * Asserts the enqueueing status of the feature's assets according to the * passed filter values. * - * @param mixed $global_filter_value The value of the global filter. - * @param mixed $feature_filter_value The value of the feature filter. - * @param bool $expected Whether the assets should be enqueued. - * @param mixed ...$additional_args Any required additional arguments. + * @param mixed $global_filter_value The value of the global filter. + * @param mixed $feature_filter_value The value of the feature filter. + * @param bool $expected Whether the assets should be enqueued. + * @param string $user_login The current user's login. + * @param string $user_role The current user's role. + * @param array $additional_args Any required additional arguments. * * @since 3.9.0 */ @@ -39,37 +40,34 @@ protected function assert_enqueued_status( $global_filter_value, $feature_filter_value, bool $expected, - ...$additional_args + string $user_login, + string $user_role, + array $additional_args = array() ): void { - /** - * The WordPress screen on which the test will run. - * - * @var string - */ - $screen = $additional_args[0] ?? 'dashboard'; - - $script_id = Dashboard_Widget::get_script_id(); - $style_id = Dashboard_Widget::get_style_id(); + $feature = new Dashboard_Widget( $GLOBALS['parsely'] ); + $this->set_current_user_to( $user_login, $user_role ); parent::set_filters( - Dashboard_Widget::get_feature_filter_name(), + $feature::get_feature_filter_name(), $global_filter_value, $feature_filter_value ); - // Dequeue and deregister assets. - wp_dequeue_script( $script_id ); - wp_deregister_script( $script_id ); - wp_dequeue_style( $style_id ); - wp_deregister_style( $style_id ); + set_current_screen( + self::get_string_value_from_array( + $additional_args, + 'screen', + 'dashboard' + ) + ); + + self::deregister_feature_assets_and_run( $feature ); // Force the feature's enqueueing code to run. - set_current_screen( $screen ); - ( new Dashboard_Widget( $GLOBALS['parsely'] ) )->run(); do_action( 'admin_enqueue_scripts' ); // phpcs:ignore - self::assertSame( $expected, wp_script_is( $script_id ) ); - self::assertSame( $expected, wp_style_is( $style_id ) ); + self::assertSame( $expected, wp_script_is( $feature::get_script_id() ) ); + self::assertSame( $expected, wp_style_is( $feature::get_script_id() ) ); } /** @@ -96,8 +94,7 @@ protected function assert_enqueued_status( * @group content-helper */ public function test_assets_do_not_get_enqueued_when_user_has_not_enough_capabilities(): void { - $this->login_as_contributor(); - self::assert_enqueued_status( null, null, false ); + self::assert_enqueued_status( null, null, false, 'test_contributor', 'contributor' ); } /** @@ -124,6 +121,13 @@ public function test_assets_do_not_get_enqueued_when_user_has_not_enough_capabil * @group content-helper */ public function test_assets_do_not_get_enqueued_when_page_is_not_dashboard(): void { - $this->assert_enqueued_status( null, null, false, 'edit-page' ); + $this->assert_enqueued_status( + null, + null, + false, + 'admin', + 'administrator', + array( 'screen' => 'edit-page' ) + ); } } diff --git a/tests/Integration/content-helper/ContentHelperEditorSidebarTest.php b/tests/Integration/content-helper/ContentHelperEditorSidebarTest.php index 282d2eae0..6934d6225 100644 --- a/tests/Integration/content-helper/ContentHelperEditorSidebarTest.php +++ b/tests/Integration/content-helper/ContentHelperEditorSidebarTest.php @@ -16,50 +16,34 @@ * Integration Tests for the PCH Editor Sidebar. */ final class ContentHelperEditorSidebarTest extends ContentHelperFeatureTest { - /** - * Setup method called before each test. - * - * @since 3.9.0 - */ - public function set_up(): void { - $GLOBALS['parsely'] = new Parsely(); - } - /** * Asserts the enqueueing status of the feature's assets according to the * passed filter values. * * @since 3.9.0 * - * @param mixed $global_filter_value The value of the global filter. - * @param mixed $feature_filter_value The value of the feature filter. - * @param bool $expected Whether the assets should be enqueued. - * @param mixed ...$additional_args Any required additional arguments. + * @param mixed $global_filter_value The value of the global filter. + * @param mixed $feature_filter_value The value of the feature filter. + * @param bool $expected Whether the assets should be enqueued. + * @param string $user_login The current user's login. + * @param string $user_role The current user's role. + * @param array $additional_args Any required additional arguments. */ protected function assert_enqueued_status( $global_filter_value, $feature_filter_value, bool $expected, - ...$additional_args + string $user_login, + string $user_role, + array $additional_args = array() ): void { - $script_id = Editor_Sidebar::get_script_id(); - $style_id = Editor_Sidebar::get_style_id(); - - parent::set_filters( - Editor_Sidebar::get_feature_filter_name(), + parent::assert_enqueued_status_default( + new Editor_Sidebar( new Parsely() ), $global_filter_value, - $feature_filter_value + $feature_filter_value, + $expected, + $user_login, + $user_role ); - - // Dequeue and deregister assets. - wp_dequeue_script( $script_id ); - wp_deregister_script( $script_id ); - wp_dequeue_style( $style_id ); - wp_deregister_style( $style_id ); - - ( new Editor_Sidebar( $GLOBALS['parsely'] ) )->run(); - - self::assertSame( $expected, wp_script_is( $script_id ) ); - self::assertSame( $expected, wp_style_is( $style_id ) ); } } diff --git a/tests/Integration/content-helper/ContentHelperPostListStatsTest.php b/tests/Integration/content-helper/ContentHelperPostListStatsTest.php index 7070e67eb..3bd358037 100644 --- a/tests/Integration/content-helper/ContentHelperPostListStatsTest.php +++ b/tests/Integration/content-helper/ContentHelperPostListStatsTest.php @@ -53,7 +53,7 @@ public function set_up(): void { parent::set_up(); $this->set_permalink_structure( '/%year%/%monthnum%/%day%/%postname%' ); - $this->set_admin_user(); + $this->set_current_user_to_admin(); } /** @@ -71,23 +71,22 @@ public function tear_down(): void { * * @since 3.9.0 * - * @param mixed $global_filter_value The value of the global filter. - * @param mixed $feature_filter_value The value of the feature filter. - * @param bool $expected Whether the assets should be enqueued. - * @param mixed ...$additional_args Any required additional arguments. + * @param mixed $global_filter_value The value of the global filter. + * @param mixed $feature_filter_value The value of the feature filter. + * @param bool $expected Whether the assets should be enqueued. + * @param string $user_login The current user's login. + * @param string $user_role The current user's role. + * @param array $additional_args Any required additional arguments. */ protected function assert_enqueued_status( $global_filter_value, $feature_filter_value, bool $expected, - ...$additional_args + string $user_login, + string $user_role, + array $additional_args = array() ): void { - /** - * The WordPress screen on which the test will run. - * - * @var string - */ - $screen = $additional_args[0] ?? 'edit-post'; + $this->set_current_user_to( $user_login, $user_role ); parent::set_filters( Post_List_Stats::get_feature_filter_name(), @@ -96,8 +95,18 @@ protected function assert_enqueued_status( ); $this->set_valid_conditions_for_parsely_stats(); - set_current_screen( $screen ); // Overrides screen set by previous function. + + // Override the screen set by previous function. + set_current_screen( + self::get_string_value_from_array( + $additional_args, + 'screen', + 'edit-post' + ) + ); + $this->mock_parsely_stats_response( array() ); + $this->assert_parsely_stats_admin_script( $expected ); $this->assert_parsely_stats_admin_styles( $expected ); } @@ -124,8 +133,7 @@ protected function assert_enqueued_status( * @group content-helper */ public function test_assets_do_not_get_enqueued_when_user_has_not_enough_capabilities(): void { - $this->login_as_contributor(); - self::assert_enqueued_status( null, null, false ); + self::assert_enqueued_status( null, null, false, 'test_contributor', 'contributor' ); } /** @@ -154,7 +162,14 @@ public function test_assets_do_not_get_enqueued_when_user_has_not_enough_capabil * @group content-helper */ public function test_assets_do_not_get_enqueued_when_page_is_not_post_list(): void { - $this->assert_enqueued_status( null, null, false, 'dashboard' ); + $this->assert_enqueued_status( + null, + null, + false, + 'admin', + 'administrator', + array( 'screen' => 'dashboard' ) + ); } /** From d0db110a68440cc9aa932e74723a2805e76bec68 Mon Sep 17 00:00:00 2001 From: Henrique Mouta Date: Fri, 26 Jul 2024 09:56:06 +0100 Subject: [PATCH 006/282] Fix deprecation warnings in the browser console in WordPress 6.6 (#2668) * Fix deprecation warnings in the browser console * Change how we detect WP >= 6.6 in the getActiveComplementaryArea call --- build/content-helper/editor-sidebar.asset.php | 2 +- build/content-helper/editor-sidebar.js | 40 +++++++++---------- .../excerpt-generator.asset.php | 2 +- build/content-helper/excerpt-generator.js | 4 +- src/@types/gutenberg/wrapper.ts | 40 +++++++++++++++++++ .../editor-sidebar/editor-sidebar.tsx | 11 ++++- .../components/excerpt-panel.tsx | 2 +- 7 files changed, 75 insertions(+), 26 deletions(-) create mode 100644 src/@types/gutenberg/wrapper.ts diff --git a/build/content-helper/editor-sidebar.asset.php b/build/content-helper/editor-sidebar.asset.php index b3eaddd98..026bd31ba 100644 --- a/build/content-helper/editor-sidebar.asset.php +++ b/build/content-helper/editor-sidebar.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-dom-ready', 'wp-edit-post', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-plugins', 'wp-primitives', 'wp-url'), 'version' => 'b8c0240b984732a6e310'); + array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-dom-ready', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-plugins', 'wp-primitives', 'wp-url'), 'version' => 'a27b03daab3cef0f4b98'); diff --git a/build/content-helper/editor-sidebar.js b/build/content-helper/editor-sidebar.js index ba7ebb91e..76ec74618 100644 --- a/build/content-helper/editor-sidebar.js +++ b/build/content-helper/editor-sidebar.js @@ -1,27 +1,27 @@ -!function(){"use strict";var e={20:function(e,t,n){var r=n(609),i=Symbol.for("react.element"),s=Symbol.for("react.fragment"),a=Object.prototype.hasOwnProperty,o=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function c(e,t,n){var r,s={},c=null,u=null;for(r in void 0!==n&&(c=""+n),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(u=t.ref),t)a.call(t,r)&&!l.hasOwnProperty(r)&&(s[r]=t[r]);if(e&&e.defaultProps)for(r in t=e.defaultProps)void 0===s[r]&&(s[r]=t[r]);return{$$typeof:i,type:e,key:c,ref:u,props:s,_owner:o.current}}t.Fragment=s,t.jsx=c,t.jsxs=c},848:function(e,t,n){e.exports=n(20)},609:function(e){e.exports=window.React}},t={};function n(r){var i=t[r];if(void 0!==i)return i.exports;var s=t[r]={exports:{}};return e[r](s,s.exports,n),s.exports}n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,{a:t}),t},n.d=function(e,t){for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},function(){n.d({},{_:function(){return Kn}});var e,t,r,i=n(848),s=window.wp.components,a=window.wp.data,o=window.wp.domReady,l=n.n(o),c=window.wp.editPost,u=window.wp.element,p=window.wp.i18n,d=window.wp.primitives,f=(0,i.jsx)(d.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,i.jsx)(d.Path,{fillRule:"evenodd",d:"M11.25 5h1.5v15h-1.5V5zM6 10h1.5v10H6V10zm12 4h-1.5v6H18v-6z",clipRule:"evenodd"})}),h=window.wp.plugins,v=function(){function e(){this._tkq=[],this.isLoaded=!1,this.isEnabled=!1,"undefined"!=typeof wpParselyTracksTelemetry&&(this.isEnabled=!0,this.loadTrackingLibrary())}return e.getInstance=function(){return window.wpParselyTelemetryInstance||Object.defineProperty(window,"wpParselyTelemetryInstance",{value:new e,writable:!1,configurable:!1,enumerable:!1}),window.wpParselyTelemetryInstance},e.prototype.loadTrackingLibrary=function(){var e=this,t=document.createElement("script");t.async=!0,t.src="//stats.wp.com/w.js",t.onload=function(){e.isLoaded=!0,e._tkq=window._tkq||[]},document.head.appendChild(t)},e.trackEvent=function(t){return n=this,r=arguments,s=function(t,n){var r;return void 0===n&&(n={}),function(e,t){var n,r,i,s,a={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return s={next:o(0),throw:o(1),return:o(2)},"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function o(o){return function(l){return function(o){if(n)throw new TypeError("Generator is already executing.");for(;s&&(s=0,o[0]&&(a=0)),a;)try{if(n=1,r&&(i=2&o[0]?r.return:o[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,o[1])).done)return i;switch(r=0,i&&(o=[2&o[0],i.value]),o[0]){case 0:case 1:i=o;break;case 4:return a.label++,{value:o[1],done:!1};case 5:a.label++,r=o[1],o=[0];continue;case 7:o=a.ops.pop(),a.trys.pop();continue;default:if(!((i=(i=a.trys).length>0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]=1e4&&(clearInterval(s),n("Telemetry library not loaded"))}),100);else n("Telemetry not enabled")}))},e.prototype.trackEvent=function(t,n){var r;this.isLoaded?(0!==t.indexOf(e.TRACKS_PREFIX)&&(t=e.TRACKS_PREFIX+t),this.isEventNameValid(t)?(n=this.prepareProperties(n),null===(r=this._tkq)||void 0===r||r.push(["recordEvent",t,n])):console.error("Error tracking event: Invalid event name")):console.error("Error tracking event: Telemetry not loaded")},e.prototype.isTelemetryEnabled=function(){return this.isEnabled},e.prototype.isProprietyValid=function(t){return e.PROPERTY_REGEX.test(t)},e.prototype.isEventNameValid=function(t){return e.EVENT_NAME_REGEX.test(t)},e.prototype.prepareProperties=function(e){return(e=this.sanitizeProperties(e)).parsely_version=wpParselyTracksTelemetry.version,wpParselyTracksTelemetry.user&&(e._ut=wpParselyTracksTelemetry.user.type,e._ui=wpParselyTracksTelemetry.user.id),wpParselyTracksTelemetry.vipgo_env&&(e.vipgo_env=wpParselyTracksTelemetry.vipgo_env),this.sanitizeProperties(e)},e.prototype.sanitizeProperties=function(e){var t=this,n={};return Object.keys(e).forEach((function(r){t.isProprietyValid(r)&&(n[r]=e[r])})),n},e.TRACKS_PREFIX="wpparsely_",e.EVENT_NAME_REGEX=/^(([a-z0-9]+)_){2}([a-z0-9_]+)$/,e.PROPERTY_REGEX=/^[a-z_][a-z0-9_]*$/,e}(),g=(v.trackEvent,function(){return(0,i.jsx)(s.SVG,{"aria-hidden":"true",version:"1.1",viewBox:"0 0 15 15",width:"15",height:"15",xmlns:"http://www.w3.org/2000/svg",children:(0,i.jsx)(s.Path,{d:"M0 14.0025V11.0025L7.5 3.5025L10.5 6.5025L3 14.0025H0ZM12 5.0025L13.56 3.4425C14.15 2.8525 14.15 1.9025 13.56 1.3225L12.68 0.4425C12.09 -0.1475 11.14 -0.1475 10.56 0.4425L9 2.0025L12 5.0025Z"})})}),y=function(e){var t=e.size,n=void 0===t?24:t,r=e.className,a=void 0===r?"wp-parsely-icon":r;return(0,i.jsxs)(s.SVG,{className:a,height:n,viewBox:"0 0 60 65",width:n,xmlns:"http://www.w3.org/2000/svg",children:[(0,i.jsx)(s.Path,{fill:"#5ba745",d:"M23.72,51.53c0-.18,0-.34-.06-.52a13.11,13.11,0,0,0-2.1-5.53A14.74,14.74,0,0,0,19.12,43c-.27-.21-.5-.11-.51.22l-.24,3.42c0,.33-.38.35-.49,0l-1.5-4.8a1.4,1.4,0,0,0-.77-.78,23.91,23.91,0,0,0-3.1-.84c-1.38-.24-3.39-.39-3.39-.39-.34,0-.45.21-.25.49l2.06,3.76c.2.27,0,.54-.29.33l-4.51-3.6a3.68,3.68,0,0,0-2.86-.48c-1,.16-2.44.46-2.44.46a.68.68,0,0,0-.39.25.73.73,0,0,0-.14.45S.41,43,.54,44a3.63,3.63,0,0,0,1.25,2.62L6.48,50c.28.2.09.49-.23.37l-4.18-.94c-.32-.12-.5,0-.4.37,0,0,.69,1.89,1.31,3.16a24,24,0,0,0,1.66,2.74,1.34,1.34,0,0,0,1,.52l5,.13c.33,0,.41.38.1.48L7.51,58c-.31.1-.34.35-.07.55a14.29,14.29,0,0,0,3.05,1.66,13.09,13.09,0,0,0,5.9.5,25.13,25.13,0,0,0,4.34-1,9.55,9.55,0,0,1-.08-1.2,9.32,9.32,0,0,1,3.07-6.91"}),(0,i.jsx)(s.Path,{fill:"#5ba745",d:"M59.7,41.53a.73.73,0,0,0-.14-.45.68.68,0,0,0-.39-.25s-1.43-.3-2.44-.46a3.64,3.64,0,0,0-2.86.48l-4.51,3.6c-.26.21-.49-.06-.29-.33l2.06-3.76c.2-.28.09-.49-.25-.49,0,0-2,.15-3.39.39a23.91,23.91,0,0,0-3.1.84,1.4,1.4,0,0,0-.77.78l-1.5,4.8c-.11.32-.48.3-.49,0l-.24-3.42c0-.33-.24-.43-.51-.22a14.74,14.74,0,0,0-2.44,2.47A13.11,13.11,0,0,0,36.34,51c0,.18,0,.34-.06.52a9.26,9.26,0,0,1,3,8.1,24.1,24.1,0,0,0,4.34,1,13.09,13.09,0,0,0,5.9-.5,14.29,14.29,0,0,0,3.05-1.66c.27-.2.24-.45-.07-.55l-3.22-1.17c-.31-.1-.23-.47.1-.48l5-.13a1.38,1.38,0,0,0,1-.52A24.6,24.6,0,0,0,57,52.92c.61-1.27,1.31-3.16,1.31-3.16.1-.33-.08-.49-.4-.37l-4.18.94c-.32.12-.51-.17-.23-.37l4.69-3.34A3.63,3.63,0,0,0,59.46,44c.13-1,.24-2.47.24-2.47"}),(0,i.jsx)(s.Path,{fill:"#5ba745",d:"M46.5,25.61c0-.53-.35-.72-.8-.43l-4.86,2.66c-.45.28-.56-.27-.23-.69l4.66-6.23a2,2,0,0,0,.28-1.68,36.51,36.51,0,0,0-2.19-4.89,34,34,0,0,0-2.81-3.94c-.33-.41-.74-.35-.91.16l-2.28,5.68c-.16.5-.6.48-.59-.05l.28-8.93a2.54,2.54,0,0,0-.66-1.64S35,4.27,33.88,3.27,30.78.69,30.78.69a1.29,1.29,0,0,0-1.54,0s-1.88,1.49-3.12,2.59-2.48,2.35-2.48,2.35A2.5,2.5,0,0,0,23,7.27l.27,8.93c0,.53-.41.55-.58.05l-2.29-5.69c-.17-.5-.57-.56-.91-.14a35.77,35.77,0,0,0-3,4.2,35.55,35.55,0,0,0-2,4.62,2,2,0,0,0,.27,1.67l4.67,6.24c.33.42.23,1-.22.69l-4.87-2.66c-.45-.29-.82-.1-.82.43a18.6,18.6,0,0,0,.83,5.07,20.16,20.16,0,0,0,5.37,7.77c3.19,3,5.93,7.8,7.45,11.08A9.6,9.6,0,0,1,30,49.09a9.31,9.31,0,0,1,2.86.45c1.52-3.28,4.26-8.11,7.44-11.09a20.46,20.46,0,0,0,5.09-7,19,19,0,0,0,1.11-5.82"}),(0,i.jsx)(s.Path,{fill:"#5ba745",d:"M36.12,58.44A6.12,6.12,0,1,1,30,52.32a6.11,6.11,0,0,1,6.12,6.12"})]})},m=function(){return m=Object.assign||function(e){for(var t,n=1,r=arguments.length;nhere.',"wp-parsely"):s.code===M.ParselySuggestionsApiOpenAiError||s.code===M.ParselySuggestionsApiOpenAiUnavailable?s.message=(0,p.__)("The Parse.ly API returned an internal server error. Please retry with a different input, or try again later.","wp-parsely"):s.code===M.HttpRequestFailed&&s.message.includes("cURL error 28")?s.message=(0,p.__)("The Parse.ly API did not respond in a timely manner. Please try again later.","wp-parsely"):s.code===M.ParselySuggestionsApiSchemaError?s.message=(0,p.__)("The Parse.ly API returned a validation error. Please try again with different parameters.","wp-parsely"):s.code===M.ParselySuggestionsApiNoData?s.message=(0,p.__)("The Parse.ly API couldn't find any relevant data to fulfill the request. Please retry with a different input.","wp-parsely"):s.code===M.ParselySuggestionsApiOpenAiSchema?s.message=(0,p.__)("The Parse.ly API returned an incorrect response. Please try again later.","wp-parsely"):s.code===M.ParselySuggestionsApiAuthUnavailable&&(s.message=(0,p.__)("The Parse.ly API is currently unavailable. Please try again later.","wp-parsely")),s}return W(t,e),t.prototype.Message=function(e){return void 0===e&&(e=null),[M.PluginCredentialsNotSetMessageDetected,M.PluginSettingsSiteIdNotSet,M.PluginSettingsApiSecretNotSet].includes(this.code)?F(e):(this.code===M.FetchError&&(this.hint=this.Hint((0,p.__)("This error can sometimes be caused by ad-blockers or browser tracking protections. Please add this site to any applicable allow lists and try again.","wp-parsely"))),this.code!==M.ParselyApiForbidden&&this.code!==M.ParselySuggestionsApiNoAuthentication||(this.hint=this.Hint((0,p.__)("Please ensure that the Site ID and API Secret given in the plugin's settings are correct.","wp-parsely"))),this.code===M.HttpRequestFailed&&(this.hint=this.Hint((0,p.__)("The Parse.ly API cannot be reached. Please verify that you are online.","wp-parsely"))),(0,i.jsx)(D,{className:null==e?void 0:e.className,testId:"error",children:"

".concat(this.message,"

").concat(this.hint?this.hint:"")}))},t.prototype.Hint=function(e){return'

'.concat((0,p.__)("Hint:","wp-parsely")," ").concat(e,"

")},t.prototype.createErrorSnackbar=function(){//.test(this.message)||(0,a.dispatch)("core/notices").createNotice("error",this.message,{type:"snackbar"})},t}(Error),K=function(e){var t=e.isDetectingEnabled,n=e.onLinkChange,r=e.onLinkRemove,i=e.onLinkAdd,s=e.debounceValue,o=void 0===s?500:s,l=(0,a.useSelect)((function(e){return{blocks:(0,e("core/block-editor").getBlocks)()}}),[]).blocks,c=(0,u.useRef)(l),p=(0,u.useRef)(t);return(0,u.useEffect)((function(){var e=(0,O.debounce)((function(){for(var t=[],s=0;s0)return r(e.innerBlocks,t[s].innerBlocks);if(JSON.stringify(e)!==JSON.stringify(t[s])){var a=t[s],o=i.parseFromString(e.attributes.content||"","text/html"),l=i.parseFromString((null==a?void 0:a.attributes.content)||"","text/html"),c=Array.from(o.querySelectorAll("a[data-smartlink]")),u=Array.from(l.querySelectorAll("a[data-smartlink]")),p=c.filter((function(e){return!u.some((function(t){return t.dataset.smartlink===e.dataset.smartlink}))})),d=u.filter((function(e){return!c.some((function(t){return t.dataset.smartlink===e.dataset.smartlink}))})),f=c.filter((function(e){var t=u.find((function(t){return t.dataset.smartlink===e.dataset.smartlink}));return t&&t.outerHTML!==e.outerHTML}));(p.length>0||d.length>0||f.length>0)&&n.push({block:e,prevBlock:a,addedLinks:p,removedLinks:d,changedLinks:f})}}}))};return r(e,t),n}(l,c.current);a.length>0&&(a.forEach((function(e){e.changedLinks.length>0&&n&&n(e),e.addedLinks.length>0&&i&&i(e),e.removedLinks.length>0&&r&&r(e)})),c.current=l)}),o);return e(t),function(){e.cancel()}}),[l,o,t,i,n,r]),null},Y=function(e){var t=e.value,n=e.onChange,r=e.max,a=e.min,o=e.suffix,l=e.size,c=e.label,u=e.initialPosition,p=e.disabled,d=e.className;return(0,i.jsxs)("div",{className:"parsely-inputrange-control ".concat(d||""),children:[(0,i.jsx)(s.__experimentalHeading,{className:"parsely-inputrange-control__label",level:3,children:c}),(0,i.jsxs)("div",{className:"parsely-inputrange-control__controls",children:[(0,i.jsx)(s.__experimentalNumberControl,{disabled:p,value:t,suffix:(0,i.jsx)(s.__experimentalInputControlSuffixWrapper,{children:o}),size:null!=l?l:"__unstable-large",min:a,max:r,onChange:function(e){var t=parseInt(e,10);isNaN(t)||n(t)}}),(0,i.jsx)(s.RangeControl,{disabled:p,value:t,showTooltip:!1,initialPosition:u,onChange:function(e){n(e)},withInputField:!1,min:a,max:r})]})]})},J=function(e,t,n,r){return new(n||(n=Promise))((function(i,s){function a(e){try{l(r.next(e))}catch(e){s(e)}}function o(e){try{l(r.throw(e))}catch(e){s(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,o)}l((r=r.apply(e,t||[])).next())}))},Q=function(e,t){var n,r,i,s,a={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return s={next:o(0),throw:o(1),return:o(2)},"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function o(o){return function(l){return function(o){if(n)throw new TypeError("Generator is already executing.");for(;s&&(s=0,o[0]&&(a=0)),a;)try{if(n=1,r&&(i=2&o[0]?r.return:o[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,o[1])).done)return i;switch(r=0,i&&(o=[2&o[0],i.value]),o[0]){case 0:case 1:i=o;break;case 4:return a.label++,{value:o[1],done:!1};case 5:a.label++,r=o[1],o=[0];continue;case 7:o=a.ops.pop(),a.trys.pop();continue;default:if(!((i=(i=a.trys).length>0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]

","\n\x3c!-- /wp:paragraph --\x3e");t&&y((0,H.parse)(n))}),[o]),(0,i.jsxs)("div",{className:"smart-linking-review-suggestion",children:[(0,i.jsx)(s.KeyboardShortcuts,{shortcuts:{left:l,right:c,up:l,down:c}}),(0,i.jsx)("div",{className:"review-suggestion-post-title",children:null===(t=o.post_data)||void 0===t?void 0:t.title}),(0,i.jsxs)("div",{className:"review-suggestion-preview",children:[!(null===(n=o.post_data)||void 0===n?void 0:n.is_first_paragraph)&&(0,i.jsx)(Re,{topOrBottom:"top"}),(0,i.jsx)(Oe,{block:g[0],link:o,useOriginalBlock:!0}),!(null===(r=o.post_data)||void 0===r?void 0:r.is_last_paragraph)&&(0,i.jsx)(Re,{topOrBottom:"bottom"})]}),(0,i.jsx)(s.__experimentalDivider,{}),(0,i.jsx)(Ie,{link:o}),(0,i.jsxs)("div",{className:"review-controls",children:[(0,i.jsx)(s.Tooltip,{shortcut:"←",text:(0,p.__)("Previous","wp-parsely"),children:(0,i.jsx)(s.Button,{disabled:!d,className:"wp-parsely-review-suggestion-previous",onClick:l,icon:Ee,children:(0,p.__)("Previous","wp-parsely")})}),(0,i.jsx)("div",{className:"reviews-controls-middle",children:(0,i.jsx)(s.Button,{target:"_blank",href:(null===(a=o.post_data)||void 0===a?void 0:a.edit_link)+"&smart-link="+o.uid,variant:"secondary",onClick:function(){v.trackEvent("smart_linking_open_in_editor_pressed",{type:"inbound",uid:o.uid})},children:(0,p.__)("Open in the Editor","wp-parsely")})}),(0,i.jsx)(s.Tooltip,{shortcut:"→",text:(0,p.__)("Next","wp-parsely"),children:(0,i.jsxs)(s.Button,{disabled:!f,onClick:c,className:"wp-parsely-review-suggestion-next",children:[(0,p.__)("Next","wp-parsely"),(0,i.jsx)(z,{icon:Ne})]})})]})]})},Me=function(e){var t=e.size,n=void 0===t?24:t,r=e.className,a=void 0===r?"wp-parsely-icon":r;return(0,i.jsxs)(s.SVG,{xmlns:"http://www.w3.org/2000/svg",className:a,width:n,height:n,viewBox:"0 0 24 24",fill:"none",children:[(0,i.jsx)(s.Path,{d:"M8.18983 5.90381L8.83642 7.54325L10.4758 8.18983L8.83642 8.8364L8.18983 10.4759L7.54324 8.8364L5.90381 8.18983L7.54324 7.54325L8.18983 5.90381Z"}),(0,i.jsx)(s.Path,{d:"M15.048 5.90381L15.9101 8.08972L18.0961 8.95186L15.9101 9.81397L15.048 11.9999L14.1859 9.81397L12 8.95186L14.1859 8.08972L15.048 5.90381Z"}),(0,i.jsx)(s.Path,{d:"M11.238 10.4761L12.3157 13.2085L15.048 14.2861L12.3157 15.3638L11.238 18.0962L10.1603 15.3638L7.42798 14.2861L10.1603 13.2085L11.238 10.4761Z"})]})},De=function(e,t,n){if(n||2===arguments.length)for(var r,i=0,s=t.length;ii.bottom)&&(n.scrollTop=r.offsetTop-n.offsetTop)}}}}),[t,d]);var h=function(){var e=document.querySelector(".smart-linking-review-sidebar-tabs [data-active-item]"),t=null==e?void 0:e.nextElementSibling;t||(t=document.querySelector('.smart-linking-review-sidebar-tabs [role="tab"]')),t&&t.click()},g=(0,i.jsxs)("span",{className:"smart-linking-menu-label",children:[(0,p.__)("NEW","wp-parsely"),(0,i.jsx)(Me,{})]}),y=[];n&&n.length>0&&y.push({name:"outbound",title:(0,p.__)("Outbound","wp-parsely")}),r&&r.length>0&&y.push({name:"inbound",title:(0,p.__)("Inbound","wp-parsely")});var m="outbound";return y=y.filter((function(e){return"outbound"===e.name&&r&&0===r.length&&(e.title=(0,p.__)("Outbound Smart Links","wp-parsely"),m="outbound"),"inbound"===e.name&&n&&0===n.length&&(e.title=(0,p.__)("Inbound Smart Links","wp-parsely"),m="inbound"),e})),(0,i.jsxs)("div",{className:"smart-linking-review-sidebar",ref:o,children:[(0,i.jsx)(s.KeyboardShortcuts,{shortcuts:{tab:function(){return h()},"shift+tab":function(){return h()}}}),(0,i.jsx)(s.TabPanel,{className:"smart-linking-review-sidebar-tabs",initialTabName:m,tabs:y,onSelect:function(e){var t,i;"outbound"===e&&n&&n.length>0&&a(n[0]),"inbound"===e&&r&&r.length>0&&a(r[0]),v.trackEvent("smart_linking_modal_tab_selected",{tab:e,total_inbound:null!==(t=null==r?void 0:r.length)&&void 0!==t?t:0,total_outbound:null!==(i=null==n?void 0:n.length)&&void 0!==i?i:0})},children:function(e){return(0,i.jsxs)(i.Fragment,{children:["outbound"===e.name&&(0,i.jsx)(i.Fragment,{children:n&&0!==n.length?n.map((function(e,n){return(0,i.jsxs)(s.MenuItem,{ref:function(e){l.current[n]=e},className:(null==t?void 0:t.uid)===e.uid?"is-selected":"",role:"menuitemradio",isSelected:(null==t?void 0:t.uid)===e.uid,onClick:function(){return a(e)},children:[(0,i.jsx)("span",{className:"smart-linking-menu-item",children:e.text}),!e.applied&&g]},e.uid)})):(0,i.jsxs)(i.Fragment,{children:[" ",(0,p.__)("No outbound links found.","wp-parsely")]})}),"inbound"===e.name&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)("div",{className:"review-sidebar-tip",children:(0,p.__)("This section shows external posts that link back to the current post.","wp-parsely")}),r&&0!==r.length?r.map((function(e,r){var o;return(0,i.jsx)(s.MenuItem,{ref:function(e){l.current[(n?n.length:0)+r]=e},className:(null==t?void 0:t.uid)===e.uid?"is-selected":"",role:"menuitemradio",isSelected:(null==t?void 0:t.uid)===e.uid,onClick:function(){return a(e)},children:(0,i.jsx)("span",{className:"smart-linking-menu-item",children:null===(o=e.post_data)||void 0===o?void 0:o.title})},e.uid)})):(0,i.jsxs)(i.Fragment,{children:[" ",(0,p.__)("No inbound links found.","wp-parsely")]})]})]})}})]})},Ve=(0,i.jsx)(d.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,i.jsx)(d.Path,{d:"M12 13.06l3.712 3.713 1.061-1.06L13.061 12l3.712-3.712-1.06-1.06L12 10.938 8.288 7.227l-1.061 1.06L10.939 12l-3.712 3.712 1.06 1.061L12 13.061z"})}),Ge=(0,i.jsx)(d.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,i.jsx)(d.Path,{d:"M16.7 7.1l-6.3 8.5-3.3-2.5-.9 1.2 4.5 3.4L17.9 8z"})}),He=function(e){var t,n,r,s,o=null===(t=e.link.match)||void 0===t?void 0:t.blockId,l=(0,a.useSelect)((function(e){var t=e("core/block-editor"),n=t.getBlock,r=t.getBlockParents;return o?{block:n(o),parents:r(o).map((function(e){return n(e)})).filter((function(e){return void 0!==e}))}:{block:void 0,parents:[]}}),[o]),c=l.block,u=l.parents;return c?(0,i.jsxs)("div",{className:"review-suggestions-breadcrumbs",children:[u.map((function(e,t){var n;return(0,i.jsxs)("span",{children:[(0,i.jsx)("span",{className:"breadcrumbs-parent-block",children:null===(n=(0,H.getBlockType)(e.name))||void 0===n?void 0:n.title}),(0,i.jsx)("span",{className:"breadcrumbs-parent-separator",children:" / "})]},t)})),(0,i.jsxs)("span",{className:"breadcrumbs-current-block",children:[(0,i.jsx)("span",{className:"breadcrumbs-current-block-type",children:null===(n=(0,H.getBlockType)(c.name))||void 0===n?void 0:n.title}),(null===(s=null===(r=c.attributes)||void 0===r?void 0:r.metadata)||void 0===s?void 0:s.name)&&(0,i.jsx)("span",{className:"breadcrumbs-current-block-name",children:c.attributes.metadata.name})]})]}):(0,i.jsx)(i.Fragment,{})},ze=function(e){var t,n=e.link,r=(0,u.useState)(n.href),o=r[0],l=r[1],c=(0,u.useState)(null===(t=n.destination)||void 0===t?void 0:t.post_type),d=c[0],f=c[1],h=(0,u.useRef)(null),v=(0,a.useDispatch)(ge).updateSmartLink;return(0,u.useEffect)((function(){n.destination?f(n.destination.post_type):(f((0,p.__)("External","wp-parsely")),Pe.getInstance().getPostTypeByURL(n.href).then((function(e){e&&f(e.post_type),n.destination=e,v(n)})))}),[n,v]),(0,u.useEffect)((function(){var e=function(){if(h.current){var e=h.current.offsetWidth,t=Math.floor(e/8);l(function(e,t){var n=e.replace(/(^\w+:|^)\/\//,"").replace(/^www\./,"");if(!t||n.length<=t)return n;var r=n.split("/")[0],i=n.substring(r.length);t-=r.length;var s=Math.floor((t-3)/2),a=i.substring(0,s),o=i.substring(i.length-s);return"".concat(r).concat(a,"...").concat(o)}(n.href,t))}};return e(),window.addEventListener("resize",e),function(){window.removeEventListener("resize",e)}}),[n]),(0,i.jsx)(s.MenuItem,{ref:h,info:o,iconPosition:"left",icon:Le,shortcut:d,className:"block-editor-link-control__search-item wp-parsely-link-suggestion-link-details",children:n.title})},Ue=function(e){var t=e.link,n=e.onNext,r=e.onPrevious,o=e.onAccept,l=e.onReject,c=e.onRemove,u=e.onSelectInEditor,d=e.hasPrevious,f=e.hasNext;if(t&&void 0!==t.post_data)return(0,i.jsx)(Be,{link:t,onNext:n,onPrevious:r,onAccept:o,onReject:l,onRemove:c,onSelectInEditor:u,hasPrevious:d,hasNext:f});if(!(null==t?void 0:t.match))return(0,i.jsx)(i.Fragment,{children:(0,p.__)("This Smart Link does not have any matches in the current content.","wp-parsely")});var h=t.match.blockId,v=(0,a.select)("core/block-editor").getBlock(h),g=t.applied;return v?(0,i.jsxs)("div",{className:"smart-linking-review-suggestion",children:[(0,i.jsx)(s.KeyboardShortcuts,{shortcuts:{left:r,right:n,up:r,down:n,a:function(){t&&!t.applied&&o()},r:function(){t&&(t.applied?c():l())}}}),(0,i.jsx)(He,{link:t}),(0,i.jsx)("div",{className:"review-suggestion-preview",children:(0,i.jsx)(Oe,{block:v,link:t})}),(0,i.jsx)(s.__experimentalDivider,{}),(0,i.jsx)(ze,{link:t}),(0,i.jsxs)("div",{className:"review-controls",children:[(0,i.jsx)(s.Tooltip,{shortcut:"←",text:(0,p.__)("Previous","wp-parsely"),children:(0,i.jsx)(s.Button,{disabled:!d,className:"wp-parsely-review-suggestion-previous",onClick:r,icon:Ee,children:(0,p.__)("Previous","wp-parsely")})}),(0,i.jsxs)("div",{className:"reviews-controls-middle",children:[!g&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(s.Tooltip,{shortcut:"R",text:(0,p.__)("Reject","wp-parsely"),children:(0,i.jsx)(s.Button,{className:"wp-parsely-review-suggestion-reject",icon:Ve,onClick:l,variant:"secondary",children:(0,p.__)("Reject","wp-parsely")})}),(0,i.jsx)(s.Tooltip,{shortcut:"A",text:(0,p.__)("Accept","wp-parsely"),children:(0,i.jsx)(s.Button,{className:"wp-parsely-review-suggestion-accept",icon:Ge,onClick:o,variant:"secondary",children:(0,p.__)("Accept","wp-parsely")})})]}),g&&(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(s.Tooltip,{shortcut:"R",text:(0,p.__)("Remove","wp-parsely"),children:(0,i.jsx)(s.Button,{className:"wp-parsely-review-suggestion-reject",icon:Ve,onClick:c,variant:"secondary",children:(0,p.__)("Remove","wp-parsely")})}),(0,i.jsx)(s.Button,{className:"wp-parsely-review-suggestion-accept",onClick:u,variant:"secondary",children:(0,p.__)("Select in Editor","wp-parsely")})]})]}),(0,i.jsx)(s.Tooltip,{shortcut:"→",text:(0,p.__)("Next","wp-parsely"),children:(0,i.jsxs)(s.Button,{disabled:!f,onClick:n,className:"wp-parsely-review-suggestion-next",children:[(0,p.__)("Next","wp-parsely"),(0,i.jsx)(z,{icon:Ne})]})})]})]}):(0,i.jsx)(i.Fragment,{children:(0,p.__)("No block is selected.","wp-parsely")})},qe=function(e,t,n,r){return new(n||(n=Promise))((function(i,s){function a(e){try{l(r.next(e))}catch(e){s(e)}}function o(e){try{l(r.throw(e))}catch(e){s(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,o)}l((r=r.apply(e,t||[])).next())}))},Ze=function(e,t){var n,r,i,s,a={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return s={next:o(0),throw:o(1),return:o(2)},"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function o(o){return function(l){return function(o){if(n)throw new TypeError("Generator is already executing.");for(;s&&(s=0,o[0]&&(a=0)),a;)try{if(n=1,r&&(i=2&o[0]?r.return:o[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,o[1])).done)return i;switch(r=0,i&&(o=[2&o[0],i.value]),o[0]){case 0:case 1:i=o;break;case 4:return a.label++,{value:o[1],done:!1};case 5:a.label++,r=o[1],o=[0];continue;case 7:o=a.ops.pop(),a.trys.pop();continue;default:if(!((i=(i=a.trys).length>0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0&&(o=a[0],(l=o.parentNode)&&(c=document.createTextNode(null!==(u=o.textContent)&&void 0!==u?u:""),l.replaceChild(c,o),q.updateBlockAttributes(n,{content:s.innerHTML}))),[4,E(t.uid)]):[2]):[2];case 1:return p.sent(),[2]}}))}))},C=(0,u.useCallback)((function(){h(!1),x().filter((function(e){return!e.applied})).length>0?c(!0):(Z.unlockPostAutosaving("smart-linking-review-modal"),t())}),[x,t]),A=function(e){c(!1),e?(h(!1),T().then((function(){C()}))):h(!0)},O=function(){if(ee(S)){var e=w.indexOf(S);if(!w[t=e+1])return;P(w[t])}else{var t;if(e=m.indexOf(S),!m[t=e+1])return;P(m[t])}},R=function(){if(ee(S)){var e=w.indexOf(S);if(!w[t=e-1])return;P(w[t])}else{var t;if(e=m.indexOf(S),!m[t=e-1])return;P(m[t])}};return(0,u.useEffect)((function(){f?Z.lockPostAutosaving("smart-linking-review-modal"):f&&0===y.length&&C()}),[f,t,y,C]),(0,u.useEffect)((function(){h(n)}),[n]),(0,i.jsxs)(i.Fragment,{children:[f&&(0,i.jsx)(s.Modal,{title:(0,p.__)("Review Smart Links","wp-parsely"),className:"wp-parsely-smart-linking-review-modal",onRequestClose:C,shouldCloseOnClickOutside:!1,shouldCloseOnEsc:!1,children:(0,i.jsxs)("div",{className:"smart-linking-modal-body",children:[(0,i.jsx)(Fe,{outboundLinks:m,inboundLinks:w,activeLink:S,setSelectedLink:P}),S&&(ee(S)?(0,i.jsx)(Be,{link:S,onNext:O,onPrevious:R,hasNext:w.indexOf(S)0}):(0,i.jsx)(Ue,{link:S,hasNext:_().indexOf(S)<_().length-1,hasPrevious:_().indexOf(S)>0,onNext:O,onPrevious:R,onAccept:function(){return qe(void 0,void 0,void 0,(function(){var e,t;return Ze(this,(function(n){switch(n.label){case 0:return S.match?(r(S),[4,(i=S.match.blockId,s=S,qe(void 0,void 0,void 0,(function(){var e,t;return Ze(this,(function(n){switch(n.label){case 0:return(e=document.createElement("a")).href=s.href,e.title=s.title,e.setAttribute("data-smartlink",s.uid),(t=(0,a.select)("core/block-editor").getBlock(i))?(ne(t,s,e),s.applied=!0,[4,L(s)]):[2];case 1:return n.sent(),[2]}}))})))]):[2];case 1:return n.sent(),v.trackEvent("smart_linking_link_accepted",{link:S.href,title:S.title,text:S.text,uid:S.uid}),0===b().length?(C(),[2]):(e=m.indexOf(S),m[t=e+1]?P(m[t]):P(m[0]),[2])}var i,s}))}))},onReject:function(){return qe(void 0,void 0,void 0,(function(){var e,t;return Ze(this,(function(n){switch(n.label){case 0:return e=m.indexOf(S),m[t=e+1]?P(m[t]):m[0]?P(m[0]):C(),[4,E(S.uid)];case 1:return n.sent(),v.trackEvent("smart_linking_link_rejected",{link:S.href,title:S.title,text:S.text,uid:S.uid}),[2]}}))}))},onRemove:function(){return qe(void 0,void 0,void 0,(function(){var e,t,n,r;return Ze(this,(function(i){switch(i.label){case 0:return S.match?(e=(0,a.select)("core/block-editor").getBlock(S.match.blockId))?(t=_(),n=t.indexOf(S),r=n-1,[4,N(e,S)]):[3,2]:[2];case 1:if(i.sent(),v.trackEvent("smart_linking_link_removed",{link:S.href,title:S.title,text:S.text,uid:S.uid}),0===(t=_()).length&&w.length>0)return P(w[0]),[2];if(0===t.length&&0===w.length)return C(),[2];if(t[r])return P(t[r]),[2];P(t[0]),i.label=2;case 2:return[2]}}))}))},onSelectInEditor:function(){if(S.match){var e=(0,a.select)("core/block-editor").getBlock(S.match.blockId);if(e){q.selectBlock(e.clientId);var t=document.querySelector('[data-block="'.concat(e.clientId,'"]'));t&&de(t,S.uid),v.trackEvent("smart_linking_select_in_editor_pressed",{type:"outbound",uid:S.uid}),C()}}}}))]})}),l&&(0,i.jsxs)(s.Modal,{title:(0,p.__)("Review Smart Links","wp-parsely"),onRequestClose:function(){return A(!1)},className:"wp-parsely-smart-linking-close-dialog",children:[(0,p.__)("Are you sure you want to close? All un-accepted smart links will not be added.","wp-parsely"),(0,i.jsxs)("div",{className:"smart-linking-close-dialog-actions",children:[(0,i.jsx)(s.Button,{variant:"secondary",onClick:function(){return A(!1)},children:(0,p.__)("Go Back","wp-parsely")}),(0,i.jsx)(s.Button,{variant:"primary",onClick:function(){return A(!0)},children:(0,p.__)("Close","wp-parsely")})]})]})]})})),$e=function(){return $e=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0&&S("success",/* translators: %d: number of smart links applied */ /* translators: %d: number of smart links applied */ -(0,p.sprintf)((0,p.__)("%s smart links successfully applied.","wp-parsely"),w),{type:"snackbar"}):b(0)}),[x]),(0,u.useEffect)((function(){if(!(Object.keys(B).length>0)){var e={maxLinksPerPost:d.SmartLinking.MaxLinks};pe(e)}}),[pe,d]);var ke=(0,a.useSelect)((function(e){var t=e("core/block-editor"),r=t.getSelectedBlock,i=t.getBlock,s=t.getBlocks,a=e("core/editor"),o=a.getEditedPostContent,l=a.getCurrentPostAttribute;return{allBlocks:s(),selectedBlock:n?i(n):r(),postContent:o(),postPermalink:l("link")}}),[n]),Se=ke.allBlocks,Le=ke.selectedBlock,Ee=ke.postContent,Ne=ke.postPermalink,Ce=function(e){return Ke(void 0,void 0,void 0,(function(){var t,n,r,i,s;return Ye(this,(function(a){switch(a.label){case 0:t=[],a.label=1;case 1:return a.trys.push([1,4,,9]),[4,de((n=N||!Le)?ue.All:ue.Selected)];case 2:return a.sent(),o=Ne.replace(/^https?:\/\//i,""),r=["http://"+o,"https://"+o],i=function(e){return e.map((function(e){return e.href}))}(G),r.push.apply(r,i),[4,Pe.getInstance().generateSmartLinks(Le&&!n?(0,H.getBlockContent)(Le):Ee,I,r)];case 3:return t=a.sent(),[3,9];case 4:if((s=a.sent()).code&&s.code===M.ParselyAborted)throw s.numRetries=3-e,s;return e>0&&s.retryFetch?(console.error(s),[4,he(!0)]):[3,8];case 5:return a.sent(),[4,ve()];case 6:return a.sent(),[4,Ce(e-1)];case 7:return[2,a.sent()];case 8:throw s;case 9:return[2,t]}var o}))}))},Ae=function(){for(var e=[],t=0;t[type="button"]').forEach((function(e){e.setAttribute("disabled","disabled")}))},Ie=function(){document.querySelectorAll('.edit-post-header__settings>[type="button"]').forEach((function(e){e.removeAttribute("disabled")})),Z.unlockPostSaving("wp-parsely-block-overlay")};return(0,i.jsxs)("div",{className:"wp-parsely-smart-linking",children:[(0,i.jsx)(K,{isDetectingEnabled:!E,onLinkRemove:function(e){!function(e){J(this,void 0,void 0,(function(){var t,n,r;return Q(this,(function(i){switch(i.label){case 0:return[4,le((0,H.getBlockContent)(e),e.clientId)];case 1:return t=i.sent(),n=t.missingSmartLinks,r=t.didAnyFixes,n.forEach((function(e){(0,a.dispatch)(ge).removeSmartLink(e.uid)})),[2,r]}}))}))}(e.block)}}),(0,i.jsxs)(s.PanelRow,{className:t,children:[(0,i.jsxs)("div",{className:"smart-linking-text",children:[(0,p.__)("Automatically insert links to your most relevant, top performing content.","wp-parsely"),(0,i.jsxs)(s.Button,{href:"https://docs.parse.ly/plugin-content-helper/#h-smart-linking-beta",target:"_blank",variant:"link",children:[(0,p.__)("Learn more about Parse.ly AI","wp-parsely"),(0,i.jsx)(z,{icon:U,size:18,className:"parsely-external-link-icon"})]})]}),A&&(0,i.jsx)(s.Notice,{status:"info",onRemove:function(){return te(null)},className:"wp-parsely-content-helper-error",children:A.Message()}),x&&w>0&&(0,i.jsx)(s.Notice,{status:"success",onRemove:function(){return k(!1)},className:"wp-parsely-smart-linking-suggested-links",children:(0,p.sprintf)(/* translators: 1 - number of smart links generated */ /* translators: 1 - number of smart links generated */ -(0,p.__)("Successfully added %s smart links.","wp-parsely"),w>0?w:R.length)}),(0,i.jsx)(me,{disabled:L,selectedBlock:null==Le?void 0:Le.clientId,onSettingChange:function(e,t){var n;y({SmartLinking:$e($e({},d.SmartLinking),(n={},n[e]=t,n))}),"MaxLinks"===e&&fe(t)}}),(0,i.jsx)("div",{className:"smart-linking-generate",children:(0,i.jsx)(s.Button,{onClick:function(){return Ke(void 0,void 0,void 0,(function(){var e,t,n,r,i,s,a,l,c;return Ye(this,(function(u){switch(u.label){case 0:return[4,ee(!0)];case 1:return u.sent(),[4,be()];case 2:return u.sent(),[4,te(null)];case 3:return u.sent(),k(!1),v.trackEvent("smart_linking_generate_pressed",{is_full_content:N,selected_block:null!==(a=null==Le?void 0:Le.name)&&void 0!==a?a:"none",context:o}),e=Se.some((function(e){return"core/freeform"===e.name})),"core/freeform"===(null==Le?void 0:Le.name)&&!N||e&&N?(S("error",(0,p.__)("Smart Linking is not supported for the Freeform block.","wp-parsely"),{type:"snackbar"}),ee(!1),[2]):[4,Ae(N?"all":null==Le?void 0:Le.clientId)];case 4:u.sent(),t=setTimeout((function(){var e;ee(!1),v.trackEvent("smart_linking_generate_timeout",{is_full_content:N,selected_block:null!==(e=null==Le?void 0:Le.name)&&void 0!==e?e:"none",context:o}),Oe(N?"all":null==Le?void 0:Le.clientId)}),18e4),n=D,u.label=5;case 5:return u.trys.push([5,11,13,18]),[4,Ce(3)];case 6:return r=u.sent(),[4,(d=r,Ke(void 0,void 0,void 0,(function(){var e;return Ye(this,(function(t){switch(t.label){case 0:return d=d.filter((function(e){return!G.some((function(t){return t.uid===e.uid&&t.applied}))})),e=Ne.replace(/^https?:\/\//,"").replace(/\/+$/,""),d=(d=d.filter((function(t){return!t.href.includes(e)||(console.warn("PCH Smart Linking: Skipping self-reference link: ".concat(t.href)),!1)}))).filter((function(e){return!G.some((function(t){return t.href===e.href?(console.warn("PCH Smart Linking: Skipping duplicate link: ".concat(e.href)),!0):t.text===e.text&&t.offset!==e.offset&&(console.warn("PCH Smart Linking: Skipping duplicate link text: ".concat(e.text)),!0)}))})),d=(d=se(N?Se:[Le],d,{}).filter((function(e){return e.match}))).filter((function(e){if(!e.match)return!1;var t=e.match.blockLinkPosition,n=t+e.text.length;return!G.some((function(r){if(!r.match)return!1;if(e.match.blockId!==r.match.blockId)return!1;var i=r.match.blockLinkPosition,s=i+r.text.length;return t>=i&&n<=s}))})),[4,ne(d)];case 1:return t.sent(),[2]}}))})))];case 7:return u.sent(),0!==G.length?[3,9]:(s=new $((0,p.__)("No smart links were generated.","wp-parsely"),M.ParselyApiReturnedNoData,""),[4,te(s)]);case 8:return u.sent(),s.createErrorSnackbar(),[3,10];case 9:_e(!0),u.label=10;case 10:return[3,18];case 11:return i=u.sent(),s=new $(null!==(l=i.message)&&void 0!==l?l:"An unknown error has occurred.",null!==(c=i.code)&&void 0!==c?c:M.UnknownError),i.code&&i.code===M.ParselyAborted&&(s.message=(0,p.sprintf)(/* translators: %d: number of retry attempts, %s: attempt plural */ /* translators: %d: number of retry attempts, %s: attempt plural */ -(0,p.__)("The Smart Linking process was cancelled after %1$d %2$s.","wp-parsely"),i.numRetries,(0,p._n)("attempt","attempts",i.numRetries,"wp-parsely"))),console.error(i),[4,te(s)];case 12:return u.sent(),s.createErrorSnackbar(),[3,18];case 13:return[4,ee(!1)];case 14:return u.sent(),[4,de(n)];case 15:return u.sent(),[4,he(!1)];case 16:return u.sent(),[4,Oe(N?"all":null==Le?void 0:Le.clientId)];case 17:return u.sent(),clearTimeout(t),[7];case 18:return[2]}var d}))}))},variant:"primary",isBusy:L,disabled:L,children:F?(0,p.sprintf)(/* translators: %1$d: number of retry attempts, %2$d: maximum number of retries */ /* translators: %1$d: number of retry attempts, %2$d: maximum number of retries */ -(0,p.__)("Retrying… Attempt %1$d of %2$d","wp-parsely"),V,3):L?(0,p.__)("Generating Smart Links…","wp-parsely"):(0,p.__)("Add Smart Links","wp-parsely")})}),(W.length>0||q.length>0)&&(0,i.jsx)("div",{className:"smart-linking-manage",children:(0,i.jsx)(s.Button,{onClick:function(){return Ke(void 0,void 0,void 0,(function(){var e,t;return Ye(this,(function(n){switch(n.label){case 0:return[4,ce()];case 1:return e=n.sent(),t=ae(),[4,ne(t)];case 2:return n.sent(),_e(!0),v.trackEvent("smart_linking_review_pressed",{num_smart_links:G.length,has_fixed_links:e,context:o}),[2]}}))}))},variant:"secondary",disabled:L,children:(0,p.__)("Review Smart Links","wp-parsely")})})]}),E&&(0,i.jsx)(We,{isOpen:E,onAppliedLink:function(){b((function(e){return e+1}))},onClose:function(){k(!0),_e(!1)}})]})},Xe=function(){return Xe=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0)&&(t(),e())}))}))]}))},new((n=void 0)||(n=Promise))((function(i,s){function a(e){try{l(r.next(e))}catch(e){s(e)}}function o(e){try{l(r.throw(e))}catch(e){s(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,o)}l((r=r.apply(e,t||[])).next())}));var e,t,n,r}().then((function(){var t=document.querySelector(".wp-block-post-content");de(t,e)}))})))},ut=(0,i.jsx)(d.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,i.jsx)(d.Path,{d:"M7 11.5h10V13H7z"})}),pt=(0,i.jsx)(d.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,i.jsx)(d.Path,{d:"M13 19h-2v-2h2v2zm0-6h-2v-2h2v2zm0-6h-2V5h2v2z"})}),dt=function(e){var t=e.title,n=e.icon,r=e.subtitle,a=e.level,o=void 0===a?2:a,l=e.children,c=e.controls,u=e.onClick,d=e.isOpen,f=e.isLoading,h=e.dropdownChildren;return(0,i.jsxs)("div",{className:"performance-stat-panel",children:[(0,i.jsxs)(s.__experimentalHStack,{className:"panel-header level-"+o,children:[(0,i.jsx)(s.__experimentalHeading,{level:o,children:t}),r&&!d&&(0,i.jsx)("span",{className:"panel-subtitle",children:r}),c&&!h&&(0,i.jsx)(s.DropdownMenu,{icon:n,label:(0,p.__)("Settings","wp-parsely"),className:"panel-settings-button",controls:c}),h&&(0,i.jsx)(s.DropdownMenu,{icon:n,label:(0,p.__)("Settings","wp-parsely"),className:"panel-settings-button",children:h}),n&&!h&&!c&&(0,i.jsx)(s.Button,{icon:n,className:"panel-settings-button",isPressed:d,onClick:u})]}),(0,i.jsx)("div",{className:"panel-body",children:f?(0,i.jsx)("div",{className:"parsely-spinner-wrapper","data-testid":"parsely-spinner-wrapper",children:(0,i.jsx)(s.Spinner,{})}):l})]})};function ft(e,t,n){void 0===t&&(t=1),void 0===n&&(n="");var r=parseInt(e.replace(/\D/g,""),10);if(r<1e3)return e;r<1e4&&(t=1);var i=r,s=r.toString(),a="",o=0;return Object.entries({1e3:"k","1,000,000":"M","1,000,000,000":"B","1,000,000,000,000":"T","1,000,000,000,000,000":"Q"}).forEach((function(e){var n=e[0],l=e[1],c=parseInt(n.replace(/\D/g,""),10);if(r>=c){var u=t;(i=r/c)%1>1/o&&(u=i>10?1:2),u=parseFloat(i.toFixed(2))===parseFloat(i.toFixed(0))?0:u,s=i.toFixed(u),a=l}o=c})),s+n+a}var ht=function(e){var n=e.data,r=e.isLoading,a=(0,u.useState)(t.Views),o=a[0],l=a[1],c=(0,u.useState)(!1),d=c[0],f=c[1];r||delete n.referrers.types.totals;var h=function(e){switch(e){case"social":return(0,p.__)("Social","wp-parsely");case"search":return(0,p.__)("Search","wp-parsely");case"other":return(0,p.__)("Other","wp-parsely");case"internal":return(0,p.__)("Internal","wp-parsely");case"direct":return(0,p.__)("Direct","wp-parsely")}return e},v=(0,p.sprintf)((0,p.__)("By %s","wp-parsely"),N(o)); -/* translators: %s: metric description */return(0,i.jsxs)(dt,{title:(0,p.__)("Categories","wp-parsely"),level:3,subtitle:v,isOpen:d,onClick:function(){return f(!d)},children:[d&&(0,i.jsx)("div",{className:"panel-settings",children:(0,i.jsx)(s.SelectControl,{value:o,prefix:(0,p.__)("By: ","wp-parsely"),onChange:function(e){L(e,t)&&l(e)},children:Object.values(t).map((function(e){return(0,i.jsxs)("option",{value:e,disabled:"avg_engaged"===e,children:[N(e),"avg_engaged"===e&&(0,p.__)(" (coming soon)","wp-parsely")]},e)}))})}),r?(0,i.jsx)("div",{className:"parsely-spinner-wrapper","data-testid":"parsely-spinner-wrapper",children:(0,i.jsx)(s.Spinner,{})}):(0,i.jsxs)("div",{children:[(0,i.jsx)("div",{className:"multi-percentage-bar",children:Object.entries(n.referrers.types).map((function(e){var t=e[0],n=e[1],r=(0,p.sprintf)(/* translators: 1: Referrer type, 2: Percentage value, %%: Escaped percent sign */ /* translators: 1: Referrer type, 2: Percentage value, %%: Escaped percent sign */ -(0,p.__)("%1$s: %2$s%%","wp-parsely"),h(t),n.viewsPercentage);return(0,i.jsx)(s.Tooltip +!function(){"use strict";var e={20:function(e,t,n){var r=n(609),i=Symbol.for("react.element"),s=Symbol.for("react.fragment"),a=Object.prototype.hasOwnProperty,o=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function c(e,t,n){var r,s={},c=null,u=null;for(r in void 0!==n&&(c=""+n),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(u=t.ref),t)a.call(t,r)&&!l.hasOwnProperty(r)&&(s[r]=t[r]);if(e&&e.defaultProps)for(r in t=e.defaultProps)void 0===s[r]&&(s[r]=t[r]);return{$$typeof:i,type:e,key:c,ref:u,props:s,_owner:o.current}}t.Fragment=s,t.jsx=c,t.jsxs=c},848:function(e,t,n){e.exports=n(20)},609:function(e){e.exports=window.React}},t={};function n(r){var i=t[r];if(void 0!==i)return i.exports;var s=t[r]={exports:{}};return e[r](s,s.exports,n),s.exports}n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,{a:t}),t},n.d=function(e,t){for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},function(){n.d({},{_:function(){return sr}});var e,t,r,i,s,a,o,l,c,u,p,d=n(848),f=window.wp.components,h=window.wp.data,v=window.wp.domReady,g=n.n(v);void 0!==window.wp&&(null!==(t=null===(e=window.wp.editor)||void 0===e?void 0:e.PluginDocumentSettingPanel)&&void 0!==t||(null!==(i=null===(r=window.wp.editPost)||void 0===r?void 0:r.PluginDocumentSettingPanel)&&void 0!==i||(null===(s=window.wp.editSite)||void 0===s||s.PluginDocumentSettingPanel)),p=null!==(o=null===(a=window.wp.editor)||void 0===a?void 0:a.PluginSidebar)&&void 0!==o?o:null!==(c=null===(l=window.wp.editPost)||void 0===l?void 0:l.PluginSidebar)&&void 0!==c?c:null===(u=window.wp.editSite)||void 0===u?void 0:u.PluginSidebar);var y,m,w,b=window.wp.element,_=window.wp.i18n,x=window.wp.primitives,k=(0,d.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,d.jsx)(x.Path,{fillRule:"evenodd",d:"M11.25 5h1.5v15h-1.5V5zM6 10h1.5v10H6V10zm12 4h-1.5v6H18v-6z",clipRule:"evenodd"})}),S=window.wp.plugins,P=function(){function e(){this._tkq=[],this.isLoaded=!1,this.isEnabled=!1,"undefined"!=typeof wpParselyTracksTelemetry&&(this.isEnabled=!0,this.loadTrackingLibrary())}return e.getInstance=function(){return window.wpParselyTelemetryInstance||Object.defineProperty(window,"wpParselyTelemetryInstance",{value:new e,writable:!1,configurable:!1,enumerable:!1}),window.wpParselyTelemetryInstance},e.prototype.loadTrackingLibrary=function(){var e=this,t=document.createElement("script");t.async=!0,t.src="//stats.wp.com/w.js",t.onload=function(){e.isLoaded=!0,e._tkq=window._tkq||[]},document.head.appendChild(t)},e.trackEvent=function(t){return n=this,r=arguments,s=function(t,n){var r;return void 0===n&&(n={}),function(e,t){var n,r,i,s,a={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return s={next:o(0),throw:o(1),return:o(2)},"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function o(o){return function(l){return function(o){if(n)throw new TypeError("Generator is already executing.");for(;s&&(s=0,o[0]&&(a=0)),a;)try{if(n=1,r&&(i=2&o[0]?r.return:o[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,o[1])).done)return i;switch(r=0,i&&(o=[2&o[0],i.value]),o[0]){case 0:case 1:i=o;break;case 4:return a.label++,{value:o[1],done:!1};case 5:a.label++,r=o[1],o=[0];continue;case 7:o=a.ops.pop(),a.trys.pop();continue;default:if(!((i=(i=a.trys).length>0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]=1e4&&(clearInterval(s),n("Telemetry library not loaded"))}),100);else n("Telemetry not enabled")}))},e.prototype.trackEvent=function(t,n){var r;this.isLoaded?(0!==t.indexOf(e.TRACKS_PREFIX)&&(t=e.TRACKS_PREFIX+t),this.isEventNameValid(t)?(n=this.prepareProperties(n),null===(r=this._tkq)||void 0===r||r.push(["recordEvent",t,n])):console.error("Error tracking event: Invalid event name")):console.error("Error tracking event: Telemetry not loaded")},e.prototype.isTelemetryEnabled=function(){return this.isEnabled},e.prototype.isProprietyValid=function(t){return e.PROPERTY_REGEX.test(t)},e.prototype.isEventNameValid=function(t){return e.EVENT_NAME_REGEX.test(t)},e.prototype.prepareProperties=function(e){return(e=this.sanitizeProperties(e)).parsely_version=wpParselyTracksTelemetry.version,wpParselyTracksTelemetry.user&&(e._ut=wpParselyTracksTelemetry.user.type,e._ui=wpParselyTracksTelemetry.user.id),wpParselyTracksTelemetry.vipgo_env&&(e.vipgo_env=wpParselyTracksTelemetry.vipgo_env),this.sanitizeProperties(e)},e.prototype.sanitizeProperties=function(e){var t=this,n={};return Object.keys(e).forEach((function(r){t.isProprietyValid(r)&&(n[r]=e[r])})),n},e.TRACKS_PREFIX="wpparsely_",e.EVENT_NAME_REGEX=/^(([a-z0-9]+)_){2}([a-z0-9_]+)$/,e.PROPERTY_REGEX=/^[a-z_][a-z0-9_]*$/,e}(),j=(P.trackEvent,function(){return(0,d.jsx)(f.SVG,{"aria-hidden":"true",version:"1.1",viewBox:"0 0 15 15",width:"15",height:"15",xmlns:"http://www.w3.org/2000/svg",children:(0,d.jsx)(f.Path,{d:"M0 14.0025V11.0025L7.5 3.5025L10.5 6.5025L3 14.0025H0ZM12 5.0025L13.56 3.4425C14.15 2.8525 14.15 1.9025 13.56 1.3225L12.68 0.4425C12.09 -0.1475 11.14 -0.1475 10.56 0.4425L9 2.0025L12 5.0025Z"})})}),T=function(e){var t=e.size,n=void 0===t?24:t,r=e.className,i=void 0===r?"wp-parsely-icon":r;return(0,d.jsxs)(f.SVG,{className:i,height:n,viewBox:"0 0 60 65",width:n,xmlns:"http://www.w3.org/2000/svg",children:[(0,d.jsx)(f.Path,{fill:"#5ba745",d:"M23.72,51.53c0-.18,0-.34-.06-.52a13.11,13.11,0,0,0-2.1-5.53A14.74,14.74,0,0,0,19.12,43c-.27-.21-.5-.11-.51.22l-.24,3.42c0,.33-.38.35-.49,0l-1.5-4.8a1.4,1.4,0,0,0-.77-.78,23.91,23.91,0,0,0-3.1-.84c-1.38-.24-3.39-.39-3.39-.39-.34,0-.45.21-.25.49l2.06,3.76c.2.27,0,.54-.29.33l-4.51-3.6a3.68,3.68,0,0,0-2.86-.48c-1,.16-2.44.46-2.44.46a.68.68,0,0,0-.39.25.73.73,0,0,0-.14.45S.41,43,.54,44a3.63,3.63,0,0,0,1.25,2.62L6.48,50c.28.2.09.49-.23.37l-4.18-.94c-.32-.12-.5,0-.4.37,0,0,.69,1.89,1.31,3.16a24,24,0,0,0,1.66,2.74,1.34,1.34,0,0,0,1,.52l5,.13c.33,0,.41.38.1.48L7.51,58c-.31.1-.34.35-.07.55a14.29,14.29,0,0,0,3.05,1.66,13.09,13.09,0,0,0,5.9.5,25.13,25.13,0,0,0,4.34-1,9.55,9.55,0,0,1-.08-1.2,9.32,9.32,0,0,1,3.07-6.91"}),(0,d.jsx)(f.Path,{fill:"#5ba745",d:"M59.7,41.53a.73.73,0,0,0-.14-.45.68.68,0,0,0-.39-.25s-1.43-.3-2.44-.46a3.64,3.64,0,0,0-2.86.48l-4.51,3.6c-.26.21-.49-.06-.29-.33l2.06-3.76c.2-.28.09-.49-.25-.49,0,0-2,.15-3.39.39a23.91,23.91,0,0,0-3.1.84,1.4,1.4,0,0,0-.77.78l-1.5,4.8c-.11.32-.48.3-.49,0l-.24-3.42c0-.33-.24-.43-.51-.22a14.74,14.74,0,0,0-2.44,2.47A13.11,13.11,0,0,0,36.34,51c0,.18,0,.34-.06.52a9.26,9.26,0,0,1,3,8.1,24.1,24.1,0,0,0,4.34,1,13.09,13.09,0,0,0,5.9-.5,14.29,14.29,0,0,0,3.05-1.66c.27-.2.24-.45-.07-.55l-3.22-1.17c-.31-.1-.23-.47.1-.48l5-.13a1.38,1.38,0,0,0,1-.52A24.6,24.6,0,0,0,57,52.92c.61-1.27,1.31-3.16,1.31-3.16.1-.33-.08-.49-.4-.37l-4.18.94c-.32.12-.51-.17-.23-.37l4.69-3.34A3.63,3.63,0,0,0,59.46,44c.13-1,.24-2.47.24-2.47"}),(0,d.jsx)(f.Path,{fill:"#5ba745",d:"M46.5,25.61c0-.53-.35-.72-.8-.43l-4.86,2.66c-.45.28-.56-.27-.23-.69l4.66-6.23a2,2,0,0,0,.28-1.68,36.51,36.51,0,0,0-2.19-4.89,34,34,0,0,0-2.81-3.94c-.33-.41-.74-.35-.91.16l-2.28,5.68c-.16.5-.6.48-.59-.05l.28-8.93a2.54,2.54,0,0,0-.66-1.64S35,4.27,33.88,3.27,30.78.69,30.78.69a1.29,1.29,0,0,0-1.54,0s-1.88,1.49-3.12,2.59-2.48,2.35-2.48,2.35A2.5,2.5,0,0,0,23,7.27l.27,8.93c0,.53-.41.55-.58.05l-2.29-5.69c-.17-.5-.57-.56-.91-.14a35.77,35.77,0,0,0-3,4.2,35.55,35.55,0,0,0-2,4.62,2,2,0,0,0,.27,1.67l4.67,6.24c.33.42.23,1-.22.69l-4.87-2.66c-.45-.29-.82-.1-.82.43a18.6,18.6,0,0,0,.83,5.07,20.16,20.16,0,0,0,5.37,7.77c3.19,3,5.93,7.8,7.45,11.08A9.6,9.6,0,0,1,30,49.09a9.31,9.31,0,0,1,2.86.45c1.52-3.28,4.26-8.11,7.44-11.09a20.46,20.46,0,0,0,5.09-7,19,19,0,0,0,1.11-5.82"}),(0,d.jsx)(f.Path,{fill:"#5ba745",d:"M36.12,58.44A6.12,6.12,0,1,1,30,52.32a6.11,6.11,0,0,1,6.12,6.12"})]})},L=function(){return L=Object.assign||function(e){for(var t,n=1,r=arguments.length;nhere.',"wp-parsely"):s.code===W.ParselySuggestionsApiOpenAiError||s.code===W.ParselySuggestionsApiOpenAiUnavailable?s.message=(0,_.__)("The Parse.ly API returned an internal server error. Please retry with a different input, or try again later.","wp-parsely"):s.code===W.HttpRequestFailed&&s.message.includes("cURL error 28")?s.message=(0,_.__)("The Parse.ly API did not respond in a timely manner. Please try again later.","wp-parsely"):s.code===W.ParselySuggestionsApiSchemaError?s.message=(0,_.__)("The Parse.ly API returned a validation error. Please try again with different parameters.","wp-parsely"):s.code===W.ParselySuggestionsApiNoData?s.message=(0,_.__)("The Parse.ly API couldn't find any relevant data to fulfill the request. Please retry with a different input.","wp-parsely"):s.code===W.ParselySuggestionsApiOpenAiSchema?s.message=(0,_.__)("The Parse.ly API returned an incorrect response. Please try again later.","wp-parsely"):s.code===W.ParselySuggestionsApiAuthUnavailable&&(s.message=(0,_.__)("The Parse.ly API is currently unavailable. Please try again later.","wp-parsely")),s}return re(t,e),t.prototype.Message=function(e){return void 0===e&&(e=null),[W.PluginCredentialsNotSetMessageDetected,W.PluginSettingsSiteIdNotSet,W.PluginSettingsApiSecretNotSet].includes(this.code)?K(e):(this.code===W.FetchError&&(this.hint=this.Hint((0,_.__)("This error can sometimes be caused by ad-blockers or browser tracking protections. Please add this site to any applicable allow lists and try again.","wp-parsely"))),this.code!==W.ParselyApiForbidden&&this.code!==W.ParselySuggestionsApiNoAuthentication||(this.hint=this.Hint((0,_.__)("Please ensure that the Site ID and API Secret given in the plugin's settings are correct.","wp-parsely"))),this.code===W.HttpRequestFailed&&(this.hint=this.Hint((0,_.__)("The Parse.ly API cannot be reached. Please verify that you are online.","wp-parsely"))),(0,d.jsx)($,{className:null==e?void 0:e.className,testId:"error",children:"

".concat(this.message,"

").concat(this.hint?this.hint:"")}))},t.prototype.Hint=function(e){return'

'.concat((0,_.__)("Hint:","wp-parsely")," ").concat(e,"

")},t.prototype.createErrorSnackbar=function(){//.test(this.message)||(0,h.dispatch)("core/notices").createNotice("error",this.message,{type:"snackbar"})},t}(Error),se=function(e){var t=e.isDetectingEnabled,n=e.onLinkChange,r=e.onLinkRemove,i=e.onLinkAdd,s=e.debounceValue,a=void 0===s?500:s,o=(0,h.useSelect)((function(e){return{blocks:(0,e("core/block-editor").getBlocks)()}}),[]).blocks,l=(0,b.useRef)(o),c=(0,b.useRef)(t);return(0,b.useEffect)((function(){var e=(0,z.debounce)((function(){for(var t=[],s=0;s0)return r(e.innerBlocks,t[s].innerBlocks);if(JSON.stringify(e)!==JSON.stringify(t[s])){var a=t[s],o=i.parseFromString(e.attributes.content||"","text/html"),l=i.parseFromString((null==a?void 0:a.attributes.content)||"","text/html"),c=Array.from(o.querySelectorAll("a[data-smartlink]")),u=Array.from(l.querySelectorAll("a[data-smartlink]")),p=c.filter((function(e){return!u.some((function(t){return t.dataset.smartlink===e.dataset.smartlink}))})),d=u.filter((function(e){return!c.some((function(t){return t.dataset.smartlink===e.dataset.smartlink}))})),f=c.filter((function(e){var t=u.find((function(t){return t.dataset.smartlink===e.dataset.smartlink}));return t&&t.outerHTML!==e.outerHTML}));(p.length>0||d.length>0||f.length>0)&&n.push({block:e,prevBlock:a,addedLinks:p,removedLinks:d,changedLinks:f})}}}))};return r(e,t),n}(o,l.current);a.length>0&&(a.forEach((function(e){e.changedLinks.length>0&&n&&n(e),e.addedLinks.length>0&&i&&i(e),e.removedLinks.length>0&&r&&r(e)})),l.current=o)}),a);return e(t),function(){e.cancel()}}),[o,a,t,i,n,r]),null},ae=function(e){var t=e.value,n=e.onChange,r=e.max,i=e.min,s=e.suffix,a=e.size,o=e.label,l=e.initialPosition,c=e.disabled,u=e.className;return(0,d.jsxs)("div",{className:"parsely-inputrange-control ".concat(u||""),children:[(0,d.jsx)(f.__experimentalHeading,{className:"parsely-inputrange-control__label",level:3,children:o}),(0,d.jsxs)("div",{className:"parsely-inputrange-control__controls",children:[(0,d.jsx)(f.__experimentalNumberControl,{disabled:c,value:t,suffix:(0,d.jsx)(f.__experimentalInputControlSuffixWrapper,{children:s}),size:null!=a?a:"__unstable-large",min:i,max:r,onChange:function(e){var t=parseInt(e,10);isNaN(t)||n(t)}}),(0,d.jsx)(f.RangeControl,{disabled:c,value:t,showTooltip:!1,initialPosition:l,onChange:function(e){n(e)},withInputField:!1,min:i,max:r})]})]})},oe=function(e,t,n,r){return new(n||(n=Promise))((function(i,s){function a(e){try{l(r.next(e))}catch(e){s(e)}}function o(e){try{l(r.throw(e))}catch(e){s(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,o)}l((r=r.apply(e,t||[])).next())}))},le=function(e,t){var n,r,i,s,a={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return s={next:o(0),throw:o(1),return:o(2)},"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function o(o){return function(l){return function(o){if(n)throw new TypeError("Generator is already executing.");for(;s&&(s=0,o[0]&&(a=0)),a;)try{if(n=1,r&&(i=2&o[0]?r.return:o[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,o[1])).done)return i;switch(r=0,i&&(o=[2&o[0],i.value]),o[0]){case 0:case 1:i=o;break;case 4:return a.label++,{value:o[1],done:!1};case 5:a.label++,r=o[1],o=[0];continue;case 7:o=a.ops.pop(),a.trys.pop();continue;default:if(!((i=(i=a.trys).length>0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]

","\n\x3c!-- /wp:paragraph --\x3e");t&&h((0,Q.parse)(n))}),[s]),(0,d.jsxs)("div",{className:"smart-linking-review-suggestion",children:[(0,d.jsx)(f.KeyboardShortcuts,{shortcuts:{left:a,right:o,up:a,down:o}}),(0,d.jsx)("div",{className:"review-suggestion-post-title",children:null===(t=s.post_data)||void 0===t?void 0:t.title}),(0,d.jsxs)("div",{className:"review-suggestion-preview",children:[!(null===(n=s.post_data)||void 0===n?void 0:n.is_first_paragraph)&&(0,d.jsx)(Ue,{topOrBottom:"top"}),(0,d.jsx)(ze,{block:p[0],link:s,useOriginalBlock:!0}),!(null===(r=s.post_data)||void 0===r?void 0:r.is_last_paragraph)&&(0,d.jsx)(Ue,{topOrBottom:"bottom"})]}),(0,d.jsx)(f.__experimentalDivider,{}),(0,d.jsx)(qe,{link:s}),(0,d.jsxs)("div",{className:"review-controls",children:[(0,d.jsx)(f.Tooltip,{shortcut:"←",text:(0,_.__)("Previous","wp-parsely"),children:(0,d.jsx)(f.Button,{disabled:!l,className:"wp-parsely-review-suggestion-previous",onClick:a,icon:Fe,children:(0,_.__)("Previous","wp-parsely")})}),(0,d.jsx)("div",{className:"reviews-controls-middle",children:(0,d.jsx)(f.Button,{target:"_blank",href:(null===(i=s.post_data)||void 0===i?void 0:i.edit_link)+"&smart-link="+s.uid,variant:"secondary",onClick:function(){P.trackEvent("smart_linking_open_in_editor_pressed",{type:"inbound",uid:s.uid})},children:(0,_.__)("Open in the Editor","wp-parsely")})}),(0,d.jsx)(f.Tooltip,{shortcut:"→",text:(0,_.__)("Next","wp-parsely"),children:(0,d.jsxs)(f.Button,{disabled:!c,onClick:o,className:"wp-parsely-review-suggestion-next",children:[(0,_.__)("Next","wp-parsely"),(0,d.jsx)(X,{icon:Ve})]})})]})]})},We=function(e){var t=e.size,n=void 0===t?24:t,r=e.className,i=void 0===r?"wp-parsely-icon":r;return(0,d.jsxs)(f.SVG,{xmlns:"http://www.w3.org/2000/svg",className:i,width:n,height:n,viewBox:"0 0 24 24",fill:"none",children:[(0,d.jsx)(f.Path,{d:"M8.18983 5.90381L8.83642 7.54325L10.4758 8.18983L8.83642 8.8364L8.18983 10.4759L7.54324 8.8364L5.90381 8.18983L7.54324 7.54325L8.18983 5.90381Z"}),(0,d.jsx)(f.Path,{d:"M15.048 5.90381L15.9101 8.08972L18.0961 8.95186L15.9101 9.81397L15.048 11.9999L14.1859 9.81397L12 8.95186L14.1859 8.08972L15.048 5.90381Z"}),(0,d.jsx)(f.Path,{d:"M11.238 10.4761L12.3157 13.2085L15.048 14.2861L12.3157 15.3638L11.238 18.0962L10.1603 15.3638L7.42798 14.2861L10.1603 13.2085L11.238 10.4761Z"})]})},$e=function(e,t,n){if(n||2===arguments.length)for(var r,i=0,s=t.length;ii.bottom)&&(n.scrollTop=r.offsetTop-n.offsetTop)}}}}),[t,l]);var u=function(){var e=document.querySelector(".smart-linking-review-sidebar-tabs [data-active-item]"),t=null==e?void 0:e.nextElementSibling;t||(t=document.querySelector('.smart-linking-review-sidebar-tabs [role="tab"]')),t&&t.click()},p=(0,d.jsxs)("span",{className:"smart-linking-menu-label",children:[(0,_.__)("NEW","wp-parsely"),(0,d.jsx)(We,{})]}),h=[];n&&n.length>0&&h.push({name:"outbound",title:(0,_.__)("Outbound","wp-parsely")}),r&&r.length>0&&h.push({name:"inbound",title:(0,_.__)("Inbound","wp-parsely")});var v="outbound";return h=h.filter((function(e){return"outbound"===e.name&&r&&0===r.length&&(e.title=(0,_.__)("Outbound Smart Links","wp-parsely"),v="outbound"),"inbound"===e.name&&n&&0===n.length&&(e.title=(0,_.__)("Inbound Smart Links","wp-parsely"),v="inbound"),e})),(0,d.jsxs)("div",{className:"smart-linking-review-sidebar",ref:s,children:[(0,d.jsx)(f.KeyboardShortcuts,{shortcuts:{tab:function(){return u()},"shift+tab":function(){return u()}}}),(0,d.jsx)(f.TabPanel,{className:"smart-linking-review-sidebar-tabs",initialTabName:v,tabs:h,onSelect:function(e){var t,s;"outbound"===e&&n&&n.length>0&&i(n[0]),"inbound"===e&&r&&r.length>0&&i(r[0]),P.trackEvent("smart_linking_modal_tab_selected",{tab:e,total_inbound:null!==(t=null==r?void 0:r.length)&&void 0!==t?t:0,total_outbound:null!==(s=null==n?void 0:n.length)&&void 0!==s?s:0})},children:function(e){return(0,d.jsxs)(d.Fragment,{children:["outbound"===e.name&&(0,d.jsx)(d.Fragment,{children:n&&0!==n.length?n.map((function(e,n){return(0,d.jsxs)(f.MenuItem,{ref:function(e){a.current[n]=e},className:(null==t?void 0:t.uid)===e.uid?"is-selected":"",role:"menuitemradio",isSelected:(null==t?void 0:t.uid)===e.uid,onClick:function(){return i(e)},children:[(0,d.jsx)("span",{className:"smart-linking-menu-item",children:e.text}),!e.applied&&p]},e.uid)})):(0,d.jsxs)(d.Fragment,{children:[" ",(0,_.__)("No outbound links found.","wp-parsely")]})}),"inbound"===e.name&&(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)("div",{className:"review-sidebar-tip",children:(0,_.__)("This section shows external posts that link back to the current post.","wp-parsely")}),r&&0!==r.length?r.map((function(e,r){var s;return(0,d.jsx)(f.MenuItem,{ref:function(e){a.current[(n?n.length:0)+r]=e},className:(null==t?void 0:t.uid)===e.uid?"is-selected":"",role:"menuitemradio",isSelected:(null==t?void 0:t.uid)===e.uid,onClick:function(){return i(e)},children:(0,d.jsx)("span",{className:"smart-linking-menu-item",children:null===(s=e.post_data)||void 0===s?void 0:s.title})},e.uid)})):(0,d.jsxs)(d.Fragment,{children:[" ",(0,_.__)("No inbound links found.","wp-parsely")]})]})]})}})]})},Ye=(0,d.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,d.jsx)(x.Path,{d:"M12 13.06l3.712 3.713 1.061-1.06L13.061 12l3.712-3.712-1.06-1.06L12 10.938 8.288 7.227l-1.061 1.06L10.939 12l-3.712 3.712 1.06 1.061L12 13.061z"})}),Je=(0,d.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,d.jsx)(x.Path,{d:"M16.7 7.1l-6.3 8.5-3.3-2.5-.9 1.2 4.5 3.4L17.9 8z"})}),Qe=function(e){var t,n,r,i,s=null===(t=e.link.match)||void 0===t?void 0:t.blockId,a=(0,h.useSelect)((function(e){var t=e("core/block-editor"),n=t.getBlock,r=t.getBlockParents;return s?{block:n(s),parents:r(s).map((function(e){return n(e)})).filter((function(e){return void 0!==e}))}:{block:void 0,parents:[]}}),[s]),o=a.block,l=a.parents;return o?(0,d.jsxs)("div",{className:"review-suggestions-breadcrumbs",children:[l.map((function(e,t){var n;return(0,d.jsxs)("span",{children:[(0,d.jsx)("span",{className:"breadcrumbs-parent-block",children:null===(n=(0,Q.getBlockType)(e.name))||void 0===n?void 0:n.title}),(0,d.jsx)("span",{className:"breadcrumbs-parent-separator",children:" / "})]},t)})),(0,d.jsxs)("span",{className:"breadcrumbs-current-block",children:[(0,d.jsx)("span",{className:"breadcrumbs-current-block-type",children:null===(n=(0,Q.getBlockType)(o.name))||void 0===n?void 0:n.title}),(null===(i=null===(r=o.attributes)||void 0===r?void 0:r.metadata)||void 0===i?void 0:i.name)&&(0,d.jsx)("span",{className:"breadcrumbs-current-block-name",children:o.attributes.metadata.name})]})]}):(0,d.jsx)(d.Fragment,{})},Xe=function(e){var t,n=e.link,r=(0,b.useState)(n.href),i=r[0],s=r[1],a=(0,b.useState)(null===(t=n.destination)||void 0===t?void 0:t.post_type),o=a[0],l=a[1],c=(0,b.useRef)(null),u=(0,h.useDispatch)(je).updateSmartLink;return(0,b.useEffect)((function(){n.destination?l(n.destination.post_type):(l((0,_.__)("External","wp-parsely")),Ie.getInstance().getPostTypeByURL(n.href).then((function(e){e&&l(e.post_type),n.destination=e,u(n)})))}),[n,u]),(0,b.useEffect)((function(){var e=function(){if(c.current){var e=c.current.offsetWidth,t=Math.floor(e/8);s(function(e,t){var n=e.replace(/(^\w+:|^)\/\//,"").replace(/^www\./,"");if(!t||n.length<=t)return n;var r=n.split("/")[0],i=n.substring(r.length);t-=r.length;var s=Math.floor((t-3)/2),a=i.substring(0,s),o=i.substring(i.length-s);return"".concat(r).concat(a,"...").concat(o)}(n.href,t))}};return e(),window.addEventListener("resize",e),function(){window.removeEventListener("resize",e)}}),[n]),(0,d.jsx)(f.MenuItem,{ref:c,info:i,iconPosition:"left",icon:De,shortcut:o,className:"block-editor-link-control__search-item wp-parsely-link-suggestion-link-details",children:n.title})},et=function(e){var t=e.link,n=e.onNext,r=e.onPrevious,i=e.onAccept,s=e.onReject,a=e.onRemove,o=e.onSelectInEditor,l=e.hasPrevious,c=e.hasNext;if(t&&void 0!==t.post_data)return(0,d.jsx)(Ze,{link:t,onNext:n,onPrevious:r,onAccept:i,onReject:s,onRemove:a,onSelectInEditor:o,hasPrevious:l,hasNext:c});if(!(null==t?void 0:t.match))return(0,d.jsx)(d.Fragment,{children:(0,_.__)("This Smart Link does not have any matches in the current content.","wp-parsely")});var u=t.match.blockId,p=(0,h.select)("core/block-editor").getBlock(u),v=t.applied;return p?(0,d.jsxs)("div",{className:"smart-linking-review-suggestion",children:[(0,d.jsx)(f.KeyboardShortcuts,{shortcuts:{left:r,right:n,up:r,down:n,a:function(){t&&!t.applied&&i()},r:function(){t&&(t.applied?a():s())}}}),(0,d.jsx)(Qe,{link:t}),(0,d.jsx)("div",{className:"review-suggestion-preview",children:(0,d.jsx)(ze,{block:p,link:t})}),(0,d.jsx)(f.__experimentalDivider,{}),(0,d.jsx)(Xe,{link:t}),(0,d.jsxs)("div",{className:"review-controls",children:[(0,d.jsx)(f.Tooltip,{shortcut:"←",text:(0,_.__)("Previous","wp-parsely"),children:(0,d.jsx)(f.Button,{disabled:!l,className:"wp-parsely-review-suggestion-previous",onClick:r,icon:Fe,children:(0,_.__)("Previous","wp-parsely")})}),(0,d.jsxs)("div",{className:"reviews-controls-middle",children:[!v&&(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(f.Tooltip,{shortcut:"R",text:(0,_.__)("Reject","wp-parsely"),children:(0,d.jsx)(f.Button,{className:"wp-parsely-review-suggestion-reject",icon:Ye,onClick:s,variant:"secondary",children:(0,_.__)("Reject","wp-parsely")})}),(0,d.jsx)(f.Tooltip,{shortcut:"A",text:(0,_.__)("Accept","wp-parsely"),children:(0,d.jsx)(f.Button,{className:"wp-parsely-review-suggestion-accept",icon:Je,onClick:i,variant:"secondary",children:(0,_.__)("Accept","wp-parsely")})})]}),v&&(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(f.Tooltip,{shortcut:"R",text:(0,_.__)("Remove","wp-parsely"),children:(0,d.jsx)(f.Button,{className:"wp-parsely-review-suggestion-reject",icon:Ye,onClick:a,variant:"secondary",children:(0,_.__)("Remove","wp-parsely")})}),(0,d.jsx)(f.Button,{className:"wp-parsely-review-suggestion-accept",onClick:o,variant:"secondary",children:(0,_.__)("Select in Editor","wp-parsely")})]})]}),(0,d.jsx)(f.Tooltip,{shortcut:"→",text:(0,_.__)("Next","wp-parsely"),children:(0,d.jsxs)(f.Button,{disabled:!c,onClick:n,className:"wp-parsely-review-suggestion-next",children:[(0,_.__)("Next","wp-parsely"),(0,d.jsx)(X,{icon:Ve})]})})]})]}):(0,d.jsx)(d.Fragment,{children:(0,_.__)("No block is selected.","wp-parsely")})},tt=function(e,t,n,r){return new(n||(n=Promise))((function(i,s){function a(e){try{l(r.next(e))}catch(e){s(e)}}function o(e){try{l(r.throw(e))}catch(e){s(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,o)}l((r=r.apply(e,t||[])).next())}))},nt=function(e,t){var n,r,i,s,a={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return s={next:o(0),throw:o(1),return:o(2)},"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function o(o){return function(l){return function(o){if(n)throw new TypeError("Generator is already executing.");for(;s&&(s=0,o[0]&&(a=0)),a;)try{if(n=1,r&&(i=2&o[0]?r.return:o[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,o[1])).done)return i;switch(r=0,i&&(o=[2&o[0],i.value]),o[0]){case 0:case 1:i=o;break;case 4:return a.label++,{value:o[1],done:!1};case 5:a.label++,r=o[1],o=[0];continue;case 7:o=a.ops.pop(),a.trys.pop();continue;default:if(!((i=(i=a.trys).length>0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0&&(o=a[0],(l=o.parentNode)&&(c=document.createTextNode(null!==(u=o.textContent)&&void 0!==u?u:""),l.replaceChild(c,o),te.updateBlockAttributes(n,{content:s.innerHTML}))),[4,E(t.uid)]):[2]):[2];case 1:return p.sent(),[2]}}))}))},C=(0,b.useCallback)((function(){c(!1),w().filter((function(e){return!e.applied})).length>0?a(!0):(ne.unlockPostAutosaving("smart-linking-review-modal"),t())}),[w,t]),A=function(e){a(!1),e?(c(!1),T().then((function(){C()}))):c(!0)},O=function(){if(ue(k)){var e=g.indexOf(k);if(!g[t=e+1])return;S(g[t])}else{var t;if(e=v.indexOf(k),!v[t=e+1])return;S(v[t])}},R=function(){if(ue(k)){var e=g.indexOf(k);if(!g[t=e-1])return;S(g[t])}else{var t;if(e=v.indexOf(k),!v[t=e-1])return;S(v[t])}};return(0,b.useEffect)((function(){l?ne.lockPostAutosaving("smart-linking-review-modal"):l&&0===p.length&&C()}),[l,t,p,C]),(0,b.useEffect)((function(){c(n)}),[n]),(0,d.jsxs)(d.Fragment,{children:[l&&(0,d.jsx)(f.Modal,{title:(0,_.__)("Review Smart Links","wp-parsely"),className:"wp-parsely-smart-linking-review-modal",onRequestClose:C,shouldCloseOnClickOutside:!1,shouldCloseOnEsc:!1,children:(0,d.jsxs)("div",{className:"smart-linking-modal-body",children:[(0,d.jsx)(Ke,{outboundLinks:v,inboundLinks:g,activeLink:k,setSelectedLink:S}),k&&(ue(k)?(0,d.jsx)(Ze,{link:k,onNext:O,onPrevious:R,hasNext:g.indexOf(k)0}):(0,d.jsx)(et,{link:k,hasNext:m().indexOf(k)0,onNext:O,onPrevious:R,onAccept:function(){return tt(void 0,void 0,void 0,(function(){var e,t;return nt(this,(function(n){switch(n.label){case 0:return k.match?(r(k),[4,(i=k.match.blockId,s=k,tt(void 0,void 0,void 0,(function(){var e,t;return nt(this,(function(n){switch(n.label){case 0:return(e=document.createElement("a")).href=s.href,e.title=s.title,e.setAttribute("data-smartlink",s.uid),(t=(0,h.select)("core/block-editor").getBlock(i))?(de(t,s,e),s.applied=!0,[4,L(s)]):[2];case 1:return n.sent(),[2]}}))})))]):[2];case 1:return n.sent(),P.trackEvent("smart_linking_link_accepted",{link:k.href,title:k.title,text:k.text,uid:k.uid}),0===y().length?(C(),[2]):(e=v.indexOf(k),v[t=e+1]?S(v[t]):S(v[0]),[2])}var i,s}))}))},onReject:function(){return tt(void 0,void 0,void 0,(function(){var e,t;return nt(this,(function(n){switch(n.label){case 0:return e=v.indexOf(k),v[t=e+1]?S(v[t]):v[0]?S(v[0]):C(),[4,E(k.uid)];case 1:return n.sent(),P.trackEvent("smart_linking_link_rejected",{link:k.href,title:k.title,text:k.text,uid:k.uid}),[2]}}))}))},onRemove:function(){return tt(void 0,void 0,void 0,(function(){var e,t,n,r;return nt(this,(function(i){switch(i.label){case 0:return k.match?(e=(0,h.select)("core/block-editor").getBlock(k.match.blockId))?(t=m(),n=t.indexOf(k),r=n-1,[4,N(e,k)]):[3,2]:[2];case 1:if(i.sent(),P.trackEvent("smart_linking_link_removed",{link:k.href,title:k.title,text:k.text,uid:k.uid}),0===(t=m()).length&&g.length>0)return S(g[0]),[2];if(0===t.length&&0===g.length)return C(),[2];if(t[r])return S(t[r]),[2];S(t[0]),i.label=2;case 2:return[2]}}))}))},onSelectInEditor:function(){if(k.match){var e=(0,h.select)("core/block-editor").getBlock(k.match.blockId);if(e){te.selectBlock(e.clientId);var t=document.querySelector('[data-block="'.concat(e.clientId,'"]'));t&&xe(t,k.uid),P.trackEvent("smart_linking_select_in_editor_pressed",{type:"outbound",uid:k.uid}),C()}}}}))]})}),s&&(0,d.jsxs)(f.Modal,{title:(0,_.__)("Review Smart Links","wp-parsely"),onRequestClose:function(){return A(!1)},className:"wp-parsely-smart-linking-close-dialog",children:[(0,_.__)("Are you sure you want to close? All un-accepted smart links will not be added.","wp-parsely"),(0,d.jsxs)("div",{className:"smart-linking-close-dialog-actions",children:[(0,d.jsx)(f.Button,{variant:"secondary",onClick:function(){return A(!1)},children:(0,_.__)("Go Back","wp-parsely")}),(0,d.jsx)(f.Button,{variant:"primary",onClick:function(){return A(!0)},children:(0,_.__)("Close","wp-parsely")})]})]})]})})),it=function(){return it=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0&&k("success",/* translators: %d: number of smart links applied */ /* translators: %d: number of smart links applied */ +(0,_.sprintf)((0,_.__)("%s smart links successfully applied.","wp-parsely"),g),{type:"snackbar"}):y(0)}),[w]),(0,b.useEffect)((function(){if(!(Object.keys(R).length>0)){var e={maxLinksPerPost:o.SmartLinking.MaxLinks};te(e)}}),[te,o]);var he=(0,h.useSelect)((function(e){var t=e("core/block-editor"),r=t.getSelectedBlock,i=t.getBlock,s=t.getBlocks,a=e("core/editor"),o=a.getEditedPostContent,l=a.getCurrentPostAttribute;return{allBlocks:s(),selectedBlock:n?i(n):r(),postContent:o(),postPermalink:l("link")}}),[n]),ye=he.allBlocks,_e=he.selectedBlock,xe=he.postContent,ke=he.postPermalink,Se=function(e){return st(void 0,void 0,void 0,(function(){var t,n,r,i,s;return at(this,(function(a){switch(a.label){case 0:t=[],a.label=1;case 1:return a.trys.push([1,4,,9]),[4,re((n=E||!_e)?be.All:be.Selected)];case 2:return a.sent(),o=ke.replace(/^https?:\/\//i,""),r=["http://"+o,"https://"+o],i=function(e){return e.map((function(e){return e.href}))}(F),r.push.apply(r,i),[4,Ie.getInstance().generateSmartLinks(_e&&!n?(0,Q.getBlockContent)(_e):xe,O,r)];case 3:return t=a.sent(),[3,9];case 4:if((s=a.sent()).code&&s.code===W.ParselyAborted)throw s.numRetries=3-e,s;return e>0&&s.retryFetch?(console.error(s),[4,ce(!0)]):[3,8];case 5:return a.sent(),[4,ue()];case 6:return a.sent(),[4,Se(e-1)];case 7:return[2,a.sent()];case 8:throw s;case 9:return[2,t]}var o}))}))},Pe=function(){for(var e=[],t=0;t[type="button"]').forEach((function(e){e.setAttribute("disabled","disabled")}))},Ae=function(){document.querySelectorAll('.edit-post-header__settings>[type="button"]').forEach((function(e){e.removeAttribute("disabled")})),ne.unlockPostSaving("wp-parsely-block-overlay")};return(0,d.jsxs)("div",{className:"wp-parsely-smart-linking",children:[(0,d.jsx)(se,{isDetectingEnabled:!L,onLinkRemove:function(e){!function(e){oe(this,void 0,void 0,(function(){var t,n,r;return le(this,(function(i){switch(i.label){case 0:return[4,me((0,Q.getBlockContent)(e),e.clientId)];case 1:return t=i.sent(),n=t.missingSmartLinks,r=t.didAnyFixes,n.forEach((function(e){(0,h.dispatch)(je).removeSmartLink(e.uid)})),[2,r]}}))}))}(e.block)}}),(0,d.jsxs)(f.PanelRow,{className:t,children:[(0,d.jsxs)("div",{className:"smart-linking-text",children:[(0,_.__)("Automatically insert links to your most relevant, top performing content.","wp-parsely"),(0,d.jsxs)(f.Button,{href:"https://docs.parse.ly/plugin-content-helper/#h-smart-linking-beta",target:"_blank",variant:"link",children:[(0,_.__)("Learn more about Parse.ly AI","wp-parsely"),(0,d.jsx)(X,{icon:ee,size:18,className:"parsely-external-link-icon"})]})]}),C&&(0,d.jsx)(f.Notice,{status:"info",onRemove:function(){return Z(null)},className:"wp-parsely-content-helper-error",children:C.Message()}),w&&g>0&&(0,d.jsx)(f.Notice,{status:"success",onRemove:function(){return x(!1)},className:"wp-parsely-smart-linking-suggested-links",children:(0,_.sprintf)(/* translators: 1 - number of smart links generated */ /* translators: 1 - number of smart links generated */ +(0,_.__)("Successfully added %s smart links.","wp-parsely"),g>0?g:A.length)}),(0,d.jsx)(Le,{disabled:T,selectedBlock:null==_e?void 0:_e.clientId,onSettingChange:function(e,t){var n;p({SmartLinking:it(it({},o.SmartLinking),(n={},n[e]=t,n))}),"MaxLinks"===e&&ae(t)}}),(0,d.jsx)("div",{className:"smart-linking-generate",children:(0,d.jsx)(f.Button,{onClick:function(){return st(void 0,void 0,void 0,(function(){var e,t,n,r,s,a,o,l,c;return at(this,(function(u){switch(u.label){case 0:return[4,q(!0)];case 1:return u.sent(),[4,pe()];case 2:return u.sent(),[4,Z(null)];case 3:return u.sent(),x(!1),P.trackEvent("smart_linking_generate_pressed",{is_full_content:E,selected_block:null!==(o=null==_e?void 0:_e.name)&&void 0!==o?o:"none",context:i}),e=ye.some((function(e){return"core/freeform"===e.name})),"core/freeform"===(null==_e?void 0:_e.name)&&!E||e&&E?(k("error",(0,_.__)("Smart Linking is not supported for the Freeform block.","wp-parsely"),{type:"snackbar"}),q(!1),[2]):[4,Pe(E?"all":null==_e?void 0:_e.clientId)];case 4:u.sent(),t=setTimeout((function(){var e;q(!1),P.trackEvent("smart_linking_generate_timeout",{is_full_content:E,selected_block:null!==(e=null==_e?void 0:_e.name)&&void 0!==e?e:"none",context:i}),Ne(E?"all":null==_e?void 0:_e.clientId)}),18e4),n=I,u.label=5;case 5:return u.trys.push([5,11,13,18]),[4,Se(3)];case 6:return r=u.sent(),[4,(p=r,st(void 0,void 0,void 0,(function(){var e;return at(this,(function(t){switch(t.label){case 0:return p=p.filter((function(e){return!F.some((function(t){return t.uid===e.uid&&t.applied}))})),e=ke.replace(/^https?:\/\//,"").replace(/\/+$/,""),p=(p=p.filter((function(t){return!t.href.includes(e)||(console.warn("PCH Smart Linking: Skipping self-reference link: ".concat(t.href)),!1)}))).filter((function(e){return!F.some((function(t){return t.href===e.href?(console.warn("PCH Smart Linking: Skipping duplicate link: ".concat(e.href)),!0):t.text===e.text&&t.offset!==e.offset&&(console.warn("PCH Smart Linking: Skipping duplicate link text: ".concat(e.text)),!0)}))})),p=(p=ve(E?ye:[_e],p,{}).filter((function(e){return e.match}))).filter((function(e){if(!e.match)return!1;var t=e.match.blockLinkPosition,n=t+e.text.length;return!F.some((function(r){if(!r.match)return!1;if(e.match.blockId!==r.match.blockId)return!1;var i=r.match.blockLinkPosition,s=i+r.text.length;return t>=i&&n<=s}))})),[4,$(p)];case 1:return t.sent(),[2]}}))})))];case 7:return u.sent(),0!==F.length?[3,9]:(a=new ie((0,_.__)("No smart links were generated.","wp-parsely"),W.ParselyApiReturnedNoData,""),[4,Z(a)]);case 8:return u.sent(),a.createErrorSnackbar(),[3,10];case 9:de(!0),u.label=10;case 10:return[3,18];case 11:return s=u.sent(),a=new ie(null!==(l=s.message)&&void 0!==l?l:"An unknown error has occurred.",null!==(c=s.code)&&void 0!==c?c:W.UnknownError),s.code&&s.code===W.ParselyAborted&&(a.message=(0,_.sprintf)(/* translators: %d: number of retry attempts, %s: attempt plural */ /* translators: %d: number of retry attempts, %s: attempt plural */ +(0,_.__)("The Smart Linking process was cancelled after %1$d %2$s.","wp-parsely"),s.numRetries,(0,_._n)("attempt","attempts",s.numRetries,"wp-parsely"))),console.error(s),[4,Z(a)];case 12:return u.sent(),a.createErrorSnackbar(),[3,18];case 13:return[4,q(!1)];case 14:return u.sent(),[4,re(n)];case 15:return u.sent(),[4,ce(!1)];case 16:return u.sent(),[4,Ne(E?"all":null==_e?void 0:_e.clientId)];case 17:return u.sent(),clearTimeout(t),[7];case 18:return[2]}var p}))}))},variant:"primary",isBusy:T,disabled:T,children:M?(0,_.sprintf)(/* translators: %1$d: number of retry attempts, %2$d: maximum number of retries */ /* translators: %1$d: number of retry attempts, %2$d: maximum number of retries */ +(0,_.__)("Retrying… Attempt %1$d of %2$d","wp-parsely"),D,3):T?(0,_.__)("Generating Smart Links…","wp-parsely"):(0,_.__)("Add Smart Links","wp-parsely")})}),(G.length>0||V.length>0)&&(0,d.jsx)("div",{className:"smart-linking-manage",children:(0,d.jsx)(f.Button,{onClick:function(){return st(void 0,void 0,void 0,(function(){var e,t;return at(this,(function(n){switch(n.label){case 0:return[4,we()];case 1:return e=n.sent(),t=ge(),[4,$(t)];case 2:return n.sent(),de(!0),P.trackEvent("smart_linking_review_pressed",{num_smart_links:F.length,has_fixed_links:e,context:i}),[2]}}))}))},variant:"secondary",disabled:T,children:(0,_.__)("Review Smart Links","wp-parsely")})})]}),L&&(0,d.jsx)(rt,{isOpen:L,onAppliedLink:function(){y((function(e){return e+1}))},onClose:function(){x(!0),de(!1)}})]})},ct=function(){return ct=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0)&&(t(),e())}))}))]}))},new((n=void 0)||(n=Promise))((function(i,s){function a(e){try{l(r.next(e))}catch(e){s(e)}}function o(e){try{l(r.throw(e))}catch(e){s(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,o)}l((r=r.apply(e,t||[])).next())}));var e,t,n,r}().then((function(){var t=document.querySelector(".wp-block-post-content");xe(t,e)}))})))},bt=(0,d.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,d.jsx)(x.Path,{d:"M7 11.5h10V13H7z"})}),_t=(0,d.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,d.jsx)(x.Path,{d:"M13 19h-2v-2h2v2zm0-6h-2v-2h2v2zm0-6h-2V5h2v2z"})}),xt=function(e){var t=e.title,n=e.icon,r=e.subtitle,i=e.level,s=void 0===i?2:i,a=e.children,o=e.controls,l=e.onClick,c=e.isOpen,u=e.isLoading,p=e.dropdownChildren;return(0,d.jsxs)("div",{className:"performance-stat-panel",children:[(0,d.jsxs)(f.__experimentalHStack,{className:"panel-header level-"+s,children:[(0,d.jsx)(f.__experimentalHeading,{level:s,children:t}),r&&!c&&(0,d.jsx)("span",{className:"panel-subtitle",children:r}),o&&!p&&(0,d.jsx)(f.DropdownMenu,{icon:n,label:(0,_.__)("Settings","wp-parsely"),className:"panel-settings-button",controls:o}),p&&(0,d.jsx)(f.DropdownMenu,{icon:n,label:(0,_.__)("Settings","wp-parsely"),className:"panel-settings-button",children:p}),n&&!p&&!o&&(0,d.jsx)(f.Button,{icon:n,className:"panel-settings-button",isPressed:c,onClick:l})]}),(0,d.jsx)("div",{className:"panel-body",children:u?(0,d.jsx)("div",{className:"parsely-spinner-wrapper","data-testid":"parsely-spinner-wrapper",children:(0,d.jsx)(f.Spinner,{})}):a})]})};function kt(e,t,n){void 0===t&&(t=1),void 0===n&&(n="");var r=parseInt(e.replace(/\D/g,""),10);if(r<1e3)return e;r<1e4&&(t=1);var i=r,s=r.toString(),a="",o=0;return Object.entries({1e3:"k","1,000,000":"M","1,000,000,000":"B","1,000,000,000,000":"T","1,000,000,000,000,000":"Q"}).forEach((function(e){var n=e[0],l=e[1],c=parseInt(n.replace(/\D/g,""),10);if(r>=c){var u=t;(i=r/c)%1>1/o&&(u=i>10?1:2),u=parseFloat(i.toFixed(2))===parseFloat(i.toFixed(0))?0:u,s=i.toFixed(u),a=l}o=c})),s+n+a}var St=function(e){var t=e.data,n=e.isLoading,r=(0,b.useState)(m.Views),i=r[0],s=r[1],a=(0,b.useState)(!1),o=a[0],l=a[1];n||delete t.referrers.types.totals;var c=function(e){switch(e){case"social":return(0,_.__)("Social","wp-parsely");case"search":return(0,_.__)("Search","wp-parsely");case"other":return(0,_.__)("Other","wp-parsely");case"internal":return(0,_.__)("Internal","wp-parsely");case"direct":return(0,_.__)("Direct","wp-parsely")}return e},u=(0,_.sprintf)((0,_.__)("By %s","wp-parsely"),V(i)); +/* translators: %s: metric description */return(0,d.jsxs)(xt,{title:(0,_.__)("Categories","wp-parsely"),level:3,subtitle:u,isOpen:o,onClick:function(){return l(!o)},children:[o&&(0,d.jsx)("div",{className:"panel-settings",children:(0,d.jsx)(f.SelectControl,{value:i,prefix:(0,_.__)("By: ","wp-parsely"),onChange:function(e){D(e,m)&&s(e)},children:Object.values(m).map((function(e){return(0,d.jsxs)("option",{value:e,disabled:"avg_engaged"===e,children:[V(e),"avg_engaged"===e&&(0,_.__)(" (coming soon)","wp-parsely")]},e)}))})}),n?(0,d.jsx)("div",{className:"parsely-spinner-wrapper","data-testid":"parsely-spinner-wrapper",children:(0,d.jsx)(f.Spinner,{})}):(0,d.jsxs)("div",{children:[(0,d.jsx)("div",{className:"multi-percentage-bar",children:Object.entries(t.referrers.types).map((function(e){var t=e[0],n=e[1],r=(0,_.sprintf)(/* translators: 1: Referrer type, 2: Percentage value, %%: Escaped percent sign */ /* translators: 1: Referrer type, 2: Percentage value, %%: Escaped percent sign */ +(0,_.__)("%1$s: %2$s%%","wp-parsely"),c(t),n.viewsPercentage);return(0,d.jsx)(f.Tooltip /* translators: %s: percentage value */,{ /* translators: %s: percentage value */ -text:"".concat(h(t)," - ").concat((0,p.sprintf)((0,p.__)("%s%%","wp-parsely"),n.viewsPercentage)),delay:150,children:(0,i.jsx)("div",{"aria-label":r,className:"bar-fill "+t,style:{width:n.viewsPercentage+"%"}})},t)}))}),(0,i.jsx)("div",{className:"percentage-bar-labels",children:Object.entries(n.referrers.types).map((function(e){var t=e[0],n=e[1];return(0,i.jsxs)("div",{className:"single-label "+t,children:[(0,i.jsx)("div",{className:"label-color "+t}),(0,i.jsx)("div",{className:"label-text",children:h(t)}),(0,i.jsx)("div",{className:"label-value",children:ft(n.views)})]},t)}))})]})]})},vt=(0,i.jsx)(d.SVG,{viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:(0,i.jsx)(d.Path,{d:"M3.99961 13C4.67043 13.3354 4.6703 13.3357 4.67017 13.3359L4.67298 13.3305C4.67621 13.3242 4.68184 13.3135 4.68988 13.2985C4.70595 13.2686 4.7316 13.2218 4.76695 13.1608C4.8377 13.0385 4.94692 12.8592 5.09541 12.6419C5.39312 12.2062 5.84436 11.624 6.45435 11.0431C7.67308 9.88241 9.49719 8.75 11.9996 8.75C14.502 8.75 16.3261 9.88241 17.5449 11.0431C18.1549 11.624 18.6061 12.2062 18.9038 12.6419C19.0523 12.8592 19.1615 13.0385 19.2323 13.1608C19.2676 13.2218 19.2933 13.2686 19.3093 13.2985C19.3174 13.3135 19.323 13.3242 19.3262 13.3305L19.3291 13.3359C19.3289 13.3357 19.3288 13.3354 19.9996 13C20.6704 12.6646 20.6703 12.6643 20.6701 12.664L20.6697 12.6632L20.6688 12.6614L20.6662 12.6563L20.6583 12.6408C20.6517 12.6282 20.6427 12.6108 20.631 12.5892C20.6078 12.5459 20.5744 12.4852 20.5306 12.4096C20.4432 12.2584 20.3141 12.0471 20.1423 11.7956C19.7994 11.2938 19.2819 10.626 18.5794 9.9569C17.1731 8.61759 14.9972 7.25 11.9996 7.25C9.00203 7.25 6.82614 8.61759 5.41987 9.9569C4.71736 10.626 4.19984 11.2938 3.85694 11.7956C3.68511 12.0471 3.55605 12.2584 3.4686 12.4096C3.42484 12.4852 3.39142 12.5459 3.36818 12.5892C3.35656 12.6108 3.34748 12.6282 3.34092 12.6408L3.33297 12.6563L3.33041 12.6614L3.32948 12.6632L3.32911 12.664C3.32894 12.6643 3.32879 12.6646 3.99961 13ZM11.9996 16C13.9326 16 15.4996 14.433 15.4996 12.5C15.4996 10.567 13.9326 9 11.9996 9C10.0666 9 8.49961 10.567 8.49961 12.5C8.49961 14.433 10.0666 16 11.9996 16Z"})}),gt=(0,i.jsx)(d.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,i.jsx)(d.Path,{d:"M15.5 9.5a1 1 0 100-2 1 1 0 000 2zm0 1.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5zm-2.25 6v-2a2.75 2.75 0 00-2.75-2.75h-4A2.75 2.75 0 003.75 15v2h1.5v-2c0-.69.56-1.25 1.25-1.25h4c.69 0 1.25.56 1.25 1.25v2h1.5zm7-2v2h-1.5v-2c0-.69-.56-1.25-1.25-1.25H15v-1.5h2.5A2.75 2.75 0 0120.25 15zM9.5 8.5a1 1 0 11-2 0 1 1 0 012 0zm1.5 0a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0z",fillRule:"evenodd"})}),yt=(0,i.jsx)(d.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,i.jsx)(d.Path,{d:"M12 4V2.2L9 4.8l3 2.5V5.5c3.6 0 6.5 2.9 6.5 6.5 0 2.9-1.9 5.3-4.5 6.2v.2l-.1-.2c-.4.1-.7.2-1.1.2l.2 1.5c.3 0 .6-.1 1-.2 3.5-.9 6-4 6-7.7 0-4.4-3.6-8-8-8zm-7.9 7l1.5.2c.1-1.2.5-2.3 1.2-3.2l-1.1-.9C4.8 8.2 4.3 9.6 4.1 11zm1.5 1.8l-1.5.2c.1.7.3 1.4.5 2 .3.7.6 1.3 1 1.8l1.2-.8c-.3-.5-.6-1-.8-1.5s-.4-1.1-.4-1.7zm1.5 5.5c1.1.9 2.4 1.4 3.8 1.6l.2-1.5c-1.1-.1-2.2-.5-3.1-1.2l-.9 1.1z"})}),mt=(0,i.jsx)(d.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,i.jsx)(d.Path,{d:"M11 13h2v-2h-2v2zm-6 0h2v-2H5v2zm12-2v2h2v-2h-2z"})}),wt=function(){return wt=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]1?[2,Promise.reject(new $((0,p.sprintf)(/* translators: URL of the published post */ /* translators: URL of the published post */ -(0,p.__)("Multiple results were returned for the post %s by the Parse.ly API.","wp-parsely"),t),M.ParselyApiReturnedTooManyResults))]:[2,n[0]]}}))}))},t.prototype.fetchReferrerDataFromWpEndpoint=function(e,t,n){return Ct(this,void 0,void 0,(function(){return At(this,(function(r){switch(r.label){case 0:return[4,this.fetch({path:(0,be.addQueryArgs)("/wp-parsely/v1/referrers/post/detail",Nt(Nt({},Lt(e)),{itm_source:this.itmSource,total_views:n,url:t}))})];case 1:return[2,r.sent()]}}))}))},t}(_e),Rt=function(){return Rt=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0&&e.retryFetch?[4,new Promise((function(e){return setTimeout(e,500)}))]:[3,3];case 1:return n.sent(),[4,t(r-1)];case 2:return n.sent(),[3,4];case 3:d(e),o(!1),n.label=4;case 4:return[2]}}))}))})),[2]}))}))};return o(!0),t(1),function(){d(void 0)}}),[n]),(0,i.jsxs)("div",{className:"wp-parsely-performance-panel",children:[(0,i.jsx)(dt,{title:(0,p.__)("Performance Stats","wp-parsely"),icon:pt,dropdownChildren:function(e){var t=e.onClose;return(0,i.jsx)(Vt,{onClose:t})},children:(0,i.jsx)("div",{className:"panel-settings",children:(0,i.jsx)(s.SelectControl,{size:"__unstable-large",value:m.PerformanceStats.Period,prefix:(0,i.jsx)(s.__experimentalInputControlPrefixWrapper,{children:(0,p.__)("Period: ","wp-parsely")}),onChange:function(t){L(t,e)&&(w({PerformanceStats:Rt(Rt({},m.PerformanceStats),{Period:t})}),v.trackEvent("editor_sidebar_performance_period_changed",{period:t}))},children:Object.values(e).map((function(e){return(0,i.jsx)("option",{value:e,children:E(e)},e)}))})})}),c?c.Message():(0,i.jsxs)(i.Fragment,{children:[Ft(m,"overview")&&(0,i.jsx)(jt,{data:h,isLoading:a}),Ft(m,"categories")&&(0,i.jsx)(ht,{data:h,isLoading:a}),Ft(m,"referrers")&&(0,i.jsx)(Tt,{data:h,isLoading:a})]}),window.wpParselyPostUrl&&(0,i.jsx)(s.Button,{className:"wp-parsely-view-post",variant:"primary",onClick:function(){v.trackEvent("editor_sidebar_view_post_pressed")},href:window.wpParselyPostUrl,rel:"noopener",target:"_blank",children:(0,p.__)("View this in Parse.ly","wp-parsely")})]})},Ht=function(e){var t=e.period;return(0,i.jsx)(s.Panel,{children:(0,i.jsx)(G,{children:(0,i.jsx)(Gt,{period:t})})})},zt=function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(r=Object.getOwnPropertySymbols(e);i=1&&(0,i.jsx)(s.__experimentalToggleGroupControlOption,{value:r.Tag,label:(0,p.__)("Tag","wp-parsely")}),a.categories.length>=1&&(0,i.jsx)(s.__experimentalToggleGroupControlOption,{value:r.Section,label:(0,p.__)("Section","wp-parsely")}),a.authors.length>=1&&(0,i.jsx)(s.__experimentalToggleGroupControlOption,{value:r.Author,label:(0,p.__)("Author","wp-parsely")})]})})},qt=function(e){var t=e.filter,n=e.label,a=e.postData,o=zt(e,["filter","label","postData"]);return(0,i.jsx)("div",{className:"related-posts-filter-values",children:(0,i.jsx)(s.ComboboxControl,{__next40pxDefaultSize:!0,allowReset:!0,label:n,onChange:function(e){return o.onFilterValueChange(e)},options:r.Tag===t.type?a.tags.map((function(e){return{value:e,label:e}})):r.Section===t.type?a.categories.map((function(e){return{value:e,label:e}})):r.Author===t.type?a.authors.map((function(e){return{value:e,label:e}})):[],value:t.value})})},Zt=function(e){var t=e.filter,n=e.postData,s=e.label,a=zt(e,["filter","postData","label"]),o=function(){return n.authors.length>0&&n.categories.length>0||n.authors.length>0&&n.tags.length>0||n.tags.length>0&&n.categories.length>0},l=function(){return r.Tag===t.type&&n.tags.length>1||r.Section===t.type&&n.categories.length>1||r.Author===t.type&&n.authors.length>1};return o()||l()?(0,i.jsxs)("div",{className:"related-posts-filter-settings",children:[o()&&(0,i.jsx)(Ut,{filter:t,label:s,onFilterTypeChange:a.onFilterTypeChange,postData:n}),l()&&(0,i.jsx)(qt,{filter:t,label:o()?void 0:s,onFilterValueChange:a.onFilterValueChange,postData:n})]}):null},Wt=(0,i.jsx)(d.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,i.jsx)(d.Path,{d:"M10 17.389H8.444A5.194 5.194 0 1 1 8.444 7H10v1.5H8.444a3.694 3.694 0 0 0 0 7.389H10v1.5ZM14 7h1.556a5.194 5.194 0 0 1 0 10.39H14v-1.5h1.556a3.694 3.694 0 0 0 0-7.39H14V7Zm-4.5 6h5v-1.5h-5V13Z"})}),$t=(0,i.jsx)(d.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,i.jsx)(d.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M5.625 5.5h9.75c.069 0 .125.056.125.125v9.75a.125.125 0 0 1-.125.125h-9.75a.125.125 0 0 1-.125-.125v-9.75c0-.069.056-.125.125-.125ZM4 5.625C4 4.728 4.728 4 5.625 4h9.75C16.273 4 17 4.728 17 5.625v9.75c0 .898-.727 1.625-1.625 1.625h-9.75A1.625 1.625 0 0 1 4 15.375v-9.75Zm14.5 11.656v-9H20v9C20 18.8 18.77 20 17.251 20H6.25v-1.5h11.001c.69 0 1.249-.528 1.249-1.219Z"})}),Kt=function(){return(0,i.jsx)(s.SVG,{xmlns:"http://www.w3.org/2000/svg",width:"1",height:"40",viewBox:"0 0 1 40",fill:"none",children:(0,i.jsx)(s.Rect,{width:"1",height:"40",fill:"#cccccc"})})};function Yt(e){var t=e.metric,n=e.post,r=e.avgEngagedIcon,s=e.viewsIcon;return"views"===t?(0,i.jsxs)("span",{className:"parsely-post-metric-data",children:[(0,i.jsx)("span",{className:"screen-reader-text",children:(0,p.__)("Number of Views","wp-parsely")}),s,ft(n.views.toString())]}):"avg_engaged"===t?(0,i.jsxs)("span",{className:"parsely-post-metric-data",children:[(0,i.jsx)("span",{className:"screen-reader-text",children:(0,p.__)("Average Time","wp-parsely")}),r,n.avgEngaged]}):(0,i.jsx)("span",{className:"parsely-post-metric-data",children:"-"})}var Jt,Qt=function(e){var t,n,r=e.metric,o=e.post,l=e.postContent,c=(0,a.useDispatch)("core/notices").createNotice,u=l&&(t=l,n=I(o.rawUrl),new RegExp("]*href=[\"'](http://|https://)?.*".concat(n,".*[\"'][^>]*>"),"i").test(t));return(0,i.jsxs)("div",{className:"related-post-single","data-testid":"related-post-single",children:[(0,i.jsx)("div",{className:"related-post-title",children:(0,i.jsxs)("a",{href:o.url,target:"_blank",rel:"noreferrer",children:[(0,i.jsx)("span",{className:"screen-reader-text",children:(0,p.__)("View on website (opens new tab)","wp-parsely")}),o.title]})}),(0,i.jsx)("div",{className:"related-post-actions",children:(0,i.jsxs)("div",{className:"related-post-info",children:[(0,i.jsxs)("div",{children:[(0,i.jsx)("div",{className:"related-post-metric",children:(0,i.jsx)(Yt,{metric:r,post:o,viewsIcon:(0,i.jsx)(z,{icon:vt}),avgEngagedIcon:(0,i.jsx)(s.Dashicon,{icon:"clock",size:24})})}),u&&(0,i.jsx)("div",{className:"related-post-linked",children:(0,i.jsx)(s.Tooltip,{text:(0,p.__)("This post is linked in the content","wp-parsely"),children:(0,i.jsx)(z,{icon:Wt,size:24})})})]}),(0,i.jsx)(Kt,{}),(0,i.jsxs)("div",{children:[(0,i.jsx)(s.Button,{icon:$t,iconSize:24,onClick:function(){navigator.clipboard.writeText(o.rawUrl).then((function(){c("success",(0,p.__)("URL copied to clipboard","wp-parsely"),{type:"snackbar"})}))},label:(0,p.__)("Copy URL to clipboard","wp-parsely")}),(0,i.jsx)(s.Button,{icon:(0,i.jsx)(y,{}),iconSize:18,href:o.dashUrl,target:"_blank",label:(0,p.__)("View in Parse.ly","wp-parsely")})]})]})})]})},Xt=window.wp.coreData,en=function(){var e=function(t,n){return e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},e(t,n)};return function(t,n){if("function"!=typeof n&&null!==n)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");function __(){this.constructor=t}e(t,n),t.prototype=null===n?Object.create(n):(__.prototype=n.prototype,new __)}}(),tn=function(){return tn=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]1?[2,Promise.reject(new ie((0,_.sprintf)(/* translators: URL of the published post */ /* translators: URL of the published post */ +(0,_.__)("Multiple results were returned for the post %s by the Parse.ly API.","wp-parsely"),t),W.ParselyApiReturnedTooManyResults))]:[2,n[0]]}}))}))},t.prototype.fetchReferrerDataFromWpEndpoint=function(e,t,n){return Gt(this,void 0,void 0,(function(){return Ht(this,(function(r){switch(r.label){case 0:return[4,this.fetch({path:(0,Ne.addQueryArgs)("/wp-parsely/v1/referrers/post/detail",Vt(Vt({},Dt(e)),{itm_source:this.itmSource,total_views:n,url:t}))})];case 1:return[2,r.sent()]}}))}))},t}(Ce),Ut=function(){return Ut=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0&&e.retryFetch?[4,new Promise((function(e){return setTimeout(e,500)}))]:[3,3];case 1:return t.sent(),[4,n(r-1)];case 2:return t.sent(),[3,4];case 3:o(e),i(!1),t.label=4;case 4:return[2]}}))}))})),[2]}))}))};return i(!0),n(1),function(){o(void 0)}}),[t]),(0,d.jsxs)("div",{className:"wp-parsely-performance-panel",children:[(0,d.jsx)(xt,{title:(0,_.__)("Performance Stats","wp-parsely"),icon:_t,dropdownChildren:function(e){var t=e.onClose;return(0,d.jsx)(Yt,{onClose:t})},children:(0,d.jsx)("div",{className:"panel-settings",children:(0,d.jsx)(f.SelectControl,{size:"__unstable-large",value:h.PerformanceStats.Period,prefix:(0,d.jsx)(f.__experimentalInputControlPrefixWrapper,{children:(0,_.__)("Period: ","wp-parsely")}),onChange:function(e){D(e,y)&&(v({PerformanceStats:Ut(Ut({},h.PerformanceStats),{Period:e})}),P.trackEvent("editor_sidebar_performance_period_changed",{period:e}))},children:Object.values(y).map((function(e){return(0,d.jsx)("option",{value:e,children:F(e)},e)}))})})}),a?a.Message():(0,d.jsxs)(d.Fragment,{children:[Kt(h,"overview")&&(0,d.jsx)(Bt,{data:c,isLoading:r}),Kt(h,"categories")&&(0,d.jsx)(St,{data:c,isLoading:r}),Kt(h,"referrers")&&(0,d.jsx)(Mt,{data:c,isLoading:r})]}),window.wpParselyPostUrl&&(0,d.jsx)(f.Button,{className:"wp-parsely-view-post",variant:"primary",onClick:function(){P.trackEvent("editor_sidebar_view_post_pressed")},href:window.wpParselyPostUrl,rel:"noopener",target:"_blank",children:(0,_.__)("View this in Parse.ly","wp-parsely")})]})},Qt=function(e){var t=e.period;return(0,d.jsx)(f.Panel,{children:(0,d.jsx)(J,{children:(0,d.jsx)(Jt,{period:t})})})},Xt=function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(r=Object.getOwnPropertySymbols(e);i=1&&(0,d.jsx)(f.__experimentalToggleGroupControlOption,{value:w.Tag,label:(0,_.__)("Tag","wp-parsely")}),r.categories.length>=1&&(0,d.jsx)(f.__experimentalToggleGroupControlOption,{value:w.Section,label:(0,_.__)("Section","wp-parsely")}),r.authors.length>=1&&(0,d.jsx)(f.__experimentalToggleGroupControlOption,{value:w.Author,label:(0,_.__)("Author","wp-parsely")})]})})},tn=function(e){var t=e.filter,n=e.label,r=e.postData,i=Xt(e,["filter","label","postData"]);return(0,d.jsx)("div",{className:"related-posts-filter-values",children:(0,d.jsx)(f.ComboboxControl,{__next40pxDefaultSize:!0,allowReset:!0,label:n,onChange:function(e){return i.onFilterValueChange(e)},options:w.Tag===t.type?r.tags.map((function(e){return{value:e,label:e}})):w.Section===t.type?r.categories.map((function(e){return{value:e,label:e}})):w.Author===t.type?r.authors.map((function(e){return{value:e,label:e}})):[],value:t.value})})},nn=function(e){var t=e.filter,n=e.postData,r=e.label,i=Xt(e,["filter","postData","label"]),s=function(){return n.authors.length>0&&n.categories.length>0||n.authors.length>0&&n.tags.length>0||n.tags.length>0&&n.categories.length>0},a=function(){return w.Tag===t.type&&n.tags.length>1||w.Section===t.type&&n.categories.length>1||w.Author===t.type&&n.authors.length>1};return s()||a()?(0,d.jsxs)("div",{className:"related-posts-filter-settings",children:[s()&&(0,d.jsx)(en,{filter:t,label:r,onFilterTypeChange:i.onFilterTypeChange,postData:n}),a()&&(0,d.jsx)(tn,{filter:t,label:s()?void 0:r,onFilterValueChange:i.onFilterValueChange,postData:n})]}):null},rn=(0,d.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,d.jsx)(x.Path,{d:"M10 17.389H8.444A5.194 5.194 0 1 1 8.444 7H10v1.5H8.444a3.694 3.694 0 0 0 0 7.389H10v1.5ZM14 7h1.556a5.194 5.194 0 0 1 0 10.39H14v-1.5h1.556a3.694 3.694 0 0 0 0-7.39H14V7Zm-4.5 6h5v-1.5h-5V13Z"})}),sn=(0,d.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,d.jsx)(x.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M5.625 5.5h9.75c.069 0 .125.056.125.125v9.75a.125.125 0 0 1-.125.125h-9.75a.125.125 0 0 1-.125-.125v-9.75c0-.069.056-.125.125-.125ZM4 5.625C4 4.728 4.728 4 5.625 4h9.75C16.273 4 17 4.728 17 5.625v9.75c0 .898-.727 1.625-1.625 1.625h-9.75A1.625 1.625 0 0 1 4 15.375v-9.75Zm14.5 11.656v-9H20v9C20 18.8 18.77 20 17.251 20H6.25v-1.5h11.001c.69 0 1.249-.528 1.249-1.219Z"})}),an=function(){return(0,d.jsx)(f.SVG,{xmlns:"http://www.w3.org/2000/svg",width:"1",height:"40",viewBox:"0 0 1 40",fill:"none",children:(0,d.jsx)(f.Rect,{width:"1",height:"40",fill:"#cccccc"})})};function on(e){var t=e.metric,n=e.post,r=e.avgEngagedIcon,i=e.viewsIcon;return"views"===t?(0,d.jsxs)("span",{className:"parsely-post-metric-data",children:[(0,d.jsx)("span",{className:"screen-reader-text",children:(0,_.__)("Number of Views","wp-parsely")}),i,kt(n.views.toString())]}):"avg_engaged"===t?(0,d.jsxs)("span",{className:"parsely-post-metric-data",children:[(0,d.jsx)("span",{className:"screen-reader-text",children:(0,_.__)("Average Time","wp-parsely")}),r,n.avgEngaged]}):(0,d.jsx)("span",{className:"parsely-post-metric-data",children:"-"})}var ln,cn=function(e){var t,n,r=e.metric,i=e.post,s=e.postContent,a=(0,h.useDispatch)("core/notices").createNotice,o=s&&(t=s,n=q(i.rawUrl),new RegExp("]*href=[\"'](http://|https://)?.*".concat(n,".*[\"'][^>]*>"),"i").test(t));return(0,d.jsxs)("div",{className:"related-post-single","data-testid":"related-post-single",children:[(0,d.jsx)("div",{className:"related-post-title",children:(0,d.jsxs)("a",{href:i.url,target:"_blank",rel:"noreferrer",children:[(0,d.jsx)("span",{className:"screen-reader-text",children:(0,_.__)("View on website (opens new tab)","wp-parsely")}),i.title]})}),(0,d.jsx)("div",{className:"related-post-actions",children:(0,d.jsxs)("div",{className:"related-post-info",children:[(0,d.jsxs)("div",{children:[(0,d.jsx)("div",{className:"related-post-metric",children:(0,d.jsx)(on,{metric:r,post:i,viewsIcon:(0,d.jsx)(X,{icon:Pt}),avgEngagedIcon:(0,d.jsx)(f.Dashicon,{icon:"clock",size:24})})}),o&&(0,d.jsx)("div",{className:"related-post-linked",children:(0,d.jsx)(f.Tooltip,{text:(0,_.__)("This post is linked in the content","wp-parsely"),children:(0,d.jsx)(X,{icon:rn,size:24})})})]}),(0,d.jsx)(an,{}),(0,d.jsxs)("div",{children:[(0,d.jsx)(f.Button,{icon:sn,iconSize:24,onClick:function(){navigator.clipboard.writeText(i.rawUrl).then((function(){a("success",(0,_.__)("URL copied to clipboard","wp-parsely"),{type:"snackbar"})}))},label:(0,_.__)("Copy URL to clipboard","wp-parsely")}),(0,d.jsx)(f.Button,{icon:(0,d.jsx)(T,{}),iconSize:18,href:i.dashUrl,target:"_blank",label:(0,_.__)("View in Parse.ly","wp-parsely")})]})]})})]})},un=window.wp.coreData,pn=function(){var e=function(t,n){return e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},e(t,n)};return function(t,n){if("function"!=typeof n&&null!==n)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");function __(){this.constructor=t}e(t,n),t.prototype=null===n?Object.create(n):(__.prototype=n.prototype,new __)}}(),dn=function(){return dn=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0&&u.every(Number.isInteger)?null!==(n=o("taxonomy","category",{include:u,context:"view"}))&&void 0!==n?n:void 0:null,tags:a=Array.isArray(p)&&p.length>0&&p.every(Number.isInteger)?null!==(r=o("taxonomy","post_tag",{include:p,context:"view"}))&&void 0!==r?r:void 0:null,isReady:void 0!==i&&void 0!==s&&void 0!==a}}),[]);return{authors:e.authors,categories:e.categories,tags:e.tags,isReady:e.isReady}}(),m=y.authors,w=y.categories,b=y.tags,_=y.isReady;(0,u.useEffect)((function(){if(_){var e=function(e){return function(e){return!(!Array.isArray(e)||0===e.length)&&e.every((function(e){return"name"in e&&"id"in e&&"slug"in e&&"description"in e&&"link"in e}))}(e)?e.map((function(e){return e.name})):[]};g({authors:e(m),categories:e(w),tags:e(b)})}}),[m,w,b,_]);var x=(0,u.useState)(!0),k=x[0],S=x[1],P=(0,u.useState)(),T=P[0],C=P[1],A=(0,u.useState)(),R=A[0],I=A[1],B=(0,u.useState)([]),M=B[0],D=B[1],F=(0,u.useState)({type:o.RelatedPosts.FilterBy,value:o.RelatedPosts.FilterValue}),V=F[0],G=F[1],H=(0,u.useState)(void 0),z=H[0],U=H[1],q=(0,O.useDebounce)(U,1e3);(0,a.useSelect)((function(e){if("undefined"==typeof jest){var t=e("core/editor").getEditedPostContent;q(t())}else q("Jest test is running")}),[q]);var Z=function(e,t){l({RelatedPosts:an(an({},o.RelatedPosts),{FilterBy:e,FilterValue:t})})};return(0,u.useEffect)((function(){var e,t,n=function(e){return on(void 0,void 0,void 0,(function(){return ln(this,(function(t){return sn.getInstance().getRelatedPosts(c,d,V).then((function(e){D(e.posts),I(e.message),S(!1)})).catch((function(t){return on(void 0,void 0,void 0,(function(){return ln(this,(function(r){switch(r.label){case 0:return e>0&&t.retryFetch?[4,new Promise((function(e){return setTimeout(e,500)}))]:[3,3];case 1:return r.sent(),[4,n(e-1)];case 2:return r.sent(),[3,4];case 3:S(!1),C(t),r.label=4;case 4:return[2]}}))}))})),[2]}))}))},i=r.Author===V.type,s=r.Tag===V.type,a=r.Section===V.type,o=r.Unavailable===V.type,l=0===h.authors.length,u=0===h.tags.length,p=0===h.categories.length,f=i&&!h.authors.includes(V.value),v=s&&!h.tags.includes(V.value),g=a&&!h.categories.includes(V.value);return S(!0),o||s&&u||a&&p||i&&l?Object.values(h).every((function(e){return 0===e.length}))||G((e="",t=r.Unavailable,h.tags.length>=1?(t=r.Tag,e=h.tags[0]):h.categories.length>=1?(t=r.Section,e=h.categories[0]):h.authors.length>=1&&(t=r.Author,e=h.authors[0]),{type:t,value:e})):v?G({type:r.Tag,value:h.tags[0]}):g?G({type:r.Section,value:h.categories[0]}):f?G({type:r.Author,value:h.authors[0]}):n(1),function(){S(!1),D([]),I(""),C(void 0)}}),[c,d,V,h]),0===h.authors.length&&0===h.categories.length&&0===h.tags.length&&_?(0,i.jsx)("div",{className:"wp-parsely-related-posts",children:(0,i.jsx)("div",{className:"related-posts-body",children:(0,p.__)("Error: No author, section, or tags could be found for this post.","wp-parsely")})}):(0,i.jsxs)("div",{className:"wp-parsely-related-posts",children:[(0,i.jsx)("div",{className:"related-posts-description",children:(0,p.__)("Find top-performing related posts based on a key metric.","wp-parsely")}),(0,i.jsxs)("div",{className:"related-posts-body",children:[(0,i.jsxs)("div",{className:"related-posts-settings",children:[(0,i.jsx)(s.SelectControl,{size:"__unstable-large",onChange:function(e){var n;L(n=e,t)&&(l({RelatedPosts:an(an({},o.RelatedPosts),{Metric:n})}),v.trackEvent("related_posts_metric_changed",{metric:n}))},prefix:(0,i.jsx)(s.__experimentalInputControlPrefixWrapper,{children:(0,p.__)("Metric: ","wp-parsely")}),value:d,children:Object.values(t).map((function(e){return(0,i.jsx)("option",{value:e,children:N(e)},e)}))}),(0,i.jsx)(s.SelectControl,{size:"__unstable-large",value:c,prefix:(0,i.jsxs)(s.__experimentalInputControlPrefixWrapper,{children:[(0,p.__)("Period: ","wp-parsely")," "]}),onChange:function(t){return function(t){L(t,e)&&(l({RelatedPosts:an(an({},o.RelatedPosts),{Period:t})}),v.trackEvent("related_posts_period_changed",{period:t}))}(t)},children:Object.values(e).map((function(e){return(0,i.jsx)("option",{value:e,children:E(e)},e)}))})]}),(0,i.jsx)(Zt,{label:(0,p.__)("Filter by","wp-parsely"),filter:V,onFilterTypeChange:function(e){if(L(e,r)){var t="",n=e;r.Tag===n&&(t=h.tags[0]),r.Section===n&&(t=h.categories[0]),r.Author===n&&(t=h.authors[0]),""!==t&&(Z(n,t),G({type:n,value:t}),v.trackEvent("related_posts_filter_type_changed",{filter_type:n}))}},onFilterValueChange:function(e){"string"==typeof e&&(Z(V.type,e),G(an(an({},V),{value:e})))},postData:h}),(0,i.jsxs)("div",{className:"related-posts-wrapper",children:[(0,i.jsx)("div",{children:(0,i.jsx)("p",{className:"related-posts-descr","data-testid":"parsely-related-posts-descr",children:r.Tag===V.type?(0,p.sprintf)(/* translators: 1: tag name, 2: period */ /* translators: 1: tag name, 2: period */ -(0,p.__)("Top related posts with the “%1$s” tag in the %2$s.","wp-parsely"),V.value,E(c,!0)):r.Section===V.type?(0,p.sprintf)(/* translators: 1: section name, 2: period */ /* translators: 1: section name, 2: period */ -(0,p.__)("Top related posts in the “%1$s” section in the %2$s.","wp-parsely"),V.value,E(c,!0)):r.Author===V.type?(0,p.sprintf)(/* translators: 1: author name, 2: period */ /* translators: 1: author name, 2: period */ -(0,p.__)("Top related posts by %1$s in the %2$s.","wp-parsely"),V.value,E(c,!0)):null!=R?R:""})}),T&&T.Message(),k&&(0,i.jsx)("div",{className:"related-posts-loading-message","data-testid":"parsely-related-posts-loading-message",children:(0,p.__)("Loading…","wp-parsely")}),!k&&!T&&0===M.length&&(0,i.jsx)("div",{className:"related-posts-empty","data-testid":"parsely-related-posts-empty",children:(0,p.__)("No related posts found.","wp-parsely")}),!k&&M.length>0&&(0,i.jsx)("div",{className:"related-posts-list",children:M.map((function(e){return(0,i.jsx)(Qt,{metric:d,post:e,postContent:z},e.id)}))})]})]})]})},un=(0,i.jsx)(d.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,i.jsx)(d.Path,{d:"m19 7-3-3-8.5 8.5-1 4 4-1L19 7Zm-7 11.5H5V20h7v-1.5Z"})}),pn=function(){return(0,i.jsx)(s.SVG,{xmlns:"http://www.w3.org/2000/svg",width:"18",height:"18",viewBox:"0 0 18 18",fill:"none",children:(0,i.jsx)(s.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M13.5034 7.91642L9 12.0104L4.49662 7.91642L5.25337 7.08398L8.99999 10.49L12.7466 7.08398L13.5034 7.91642Z",fill:"#1E1E1E"})})},dn={journalist:{label:(0,p.__)("Journalist","wp-parsely")},editorialWriter:{label:(0,p.__)("Editorial Writer","wp-parsely")},investigativeReporter:{label:(0,p.__)("Investigative Reporter","wp-parsely")},techAnalyst:{label:(0,p.__)("Tech Analyst","wp-parsely")},businessAnalyst:{label:(0,p.__)("Business Analyst","wp-parsely")},culturalCommentator:{label:(0,p.__)("Cultural Commentator","wp-parsely")},scienceCorrespondent:{label:(0,p.__)("Science Correspondent","wp-parsely")},politicalAnalyst:{label:(0,p.__)("Political Analyst","wp-parsely")},healthWellnessAdvocate:{label:(0,p.__)("Health and Wellness Advocate","wp-parsely")},environmentalJournalist:{label:(0,p.__)("Environmental Journalist","wp-parsely")},custom:{label:(0,p.__)("Custom Persona","wp-parsely"),icon:un}},fn=Object.keys(dn),hn=function(e){return"custom"===e||""===e?dn.custom.label:vn(e)?e:dn[e].label},vn=function(e){return!fn.includes(e)||"custom"===e},gn=function(e){var t=e.value,n=e.onChange,r=(0,u.useState)(""),a=r[0],o=r[1],l=(0,O.useDebounce)(n,500);return(0,i.jsx)("div",{className:"parsely-persona-selector-custom",children:(0,i.jsx)(s.TextControl,{value:a||t,placeholder:(0,p.__)("Enter a custom persona…","wp-parsely"),onChange:function(e){if(""===e)return n(""),void o("");e.length>32&&(e=e.slice(0,32)),l(e),o(e)}})})},yn=function(e){var t=e.persona,n=e.value,r=void 0===n?(0,p.__)("Select a persona…","wp-parsely"):n,a=e.label,o=void 0===a?(0,p.__)("Persona","wp-parsely"):a,l=e.onChange,c=e.onDropdownChange,u=e.disabled,d=void 0!==u&&u,f=e.allowCustom,h=void 0!==f&&f;return(0,i.jsxs)(s.Disabled,{isDisabled:d,children:[o&&(0,i.jsx)("div",{className:"wp-parsely-dropdown-label",children:o}),(0,i.jsx)(s.DropdownMenu,{label:(0,p.__)("Persona","wp-parsely"),className:"parsely-persona-selector-dropdown"+(d?" is-disabled":""),popoverProps:{className:"wp-parsely-popover"},toggleProps:{children:(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)("div",{className:"parsely-persona-selector-label",children:vn(t)?dn.custom.label:r}),(0,i.jsx)(pn,{})]})},children:function(e){var n=e.onClose;return(0,i.jsx)(s.MenuGroup,{label:(0,p.__)("Persona","wp-parsely"),children:(0,i.jsx)(i.Fragment,{children:fn.map((function(e){if(!h&&"custom"===e)return null;var r=dn[e],a=e===t||vn(t)&&"custom"===e;return(0,i.jsxs)(s.MenuItem,{isSelected:a,className:a?"is-selected":"",role:"menuitemradio",onClick:function(){null==c||c(e),l(e),n(),"custom"===e&&setTimeout((function(){var e=document.querySelector(".parsely-persona-selector-custom input");e&&e.focus()}),0)},children:[r.icon&&(0,i.jsx)(z,{icon:r.icon}),r.label]},e)}))})})}}),h&&vn(t)&&(0,i.jsx)(gn,{onChange:function(e){l(""!==e?e:"custom")},value:"custom"===t?"":t})]})},mn={neutral:{label:(0,p.__)("Neutral","wp-parsely")},formal:{label:(0,p.__)("Formal","wp-parsely")},humorous:{label:(0,p.__)("Humorous","wp-parsely")},confident:{label:(0,p.__)("Confident","wp-parsely")},provocative:{label:(0,p.__)("Provocative","wp-parsely")},serious:{label:(0,p.__)("Serious","wp-parsely")},inspirational:{label:(0,p.__)("Inspirational","wp-parsely")},skeptical:{label:(0,p.__)("Skeptical","wp-parsely")},conversational:{label:(0,p.__)("Conversational","wp-parsely")},analytical:{label:(0,p.__)("Analytical","wp-parsely")},custom:{label:(0,p.__)("Custom Tone","wp-parsely"),icon:un}},wn=Object.keys(mn),bn=function(e){return"custom"===e||""===e?mn.custom.label:xn(e)?e:mn[e].label},xn=function(e){return!wn.includes(e)||"custom"===e},kn=function(e){var t=e.value,n=e.onChange,r=(0,u.useState)(""),a=r[0],o=r[1],l=(0,O.useDebounce)(n,500);return(0,i.jsx)("div",{className:"parsely-tone-selector-custom",children:(0,i.jsx)(s.TextControl,{value:a||t,placeholder:(0,p.__)("Enter a custom tone","wp-parsely"),onChange:function(e){if(""===e)return n(""),void o("");e.length>32&&(e=e.slice(0,32)),l(e),o(e)}})})},Sn=function(e){var t=e.tone,n=e.value,r=void 0===n?(0,p.__)("Select a tone","wp-parsely"):n,a=e.label,o=void 0===a?(0,p.__)("Tone","wp-parsely"):a,l=e.onChange,c=e.onDropdownChange,u=e.disabled,d=void 0!==u&&u,f=e.allowCustom,h=void 0!==f&&f;return(0,i.jsxs)(s.Disabled,{isDisabled:d,children:[(0,i.jsx)("div",{className:"wp-parsely-dropdown-label",children:o}),(0,i.jsx)(s.DropdownMenu,{label:(0,p.__)("Tone","wp-parsely"),className:"parsely-tone-selector-dropdown"+(d?" is-disabled":""),popoverProps:{className:"wp-parsely-popover"},toggleProps:{children:(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)("div",{className:"parsely-tone-selector-label",children:xn(t)?mn.custom.label:r}),(0,i.jsx)(pn,{})]})},children:function(e){var n=e.onClose;return(0,i.jsx)(s.MenuGroup,{label:(0,p.__)("Select a tone","wp-parsely"),children:(0,i.jsx)(i.Fragment,{children:wn.map((function(e){if(!h&&"custom"===e)return null;var r=mn[e],a=e===t||xn(t)&&"custom"===e;return(0,i.jsxs)(s.MenuItem,{isSelected:a,className:a?"is-selected":"",role:"menuitemradio",onClick:function(){null==c||c(e),l(e),n(),"custom"===e&&setTimeout((function(){var e=document.querySelector(".parsely-tone-selector-custom input");e&&e.focus()}),0)},children:[r.icon&&(0,i.jsx)(z,{icon:r.icon}),r.label]},e)}))})})}}),h&&xn(t)&&(0,i.jsx)(kn,{onChange:function(e){l(""!==e?e:"custom")},value:"custom"===t?"":t})]})},Pn=(0,i.jsx)(d.SVG,{width:"24",height:"24",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:(0,i.jsx)(d.Path,{d:"M10.97 10.159a3.382 3.382 0 0 0-2.857.955l1.724 1.723-2.836 2.913L7 17h1.25l2.913-2.837 1.723 1.723a3.38 3.38 0 0 0 .606-.825c.33-.63.446-1.343.35-2.032L17 10.695 13.305 7l-2.334 3.159Z"})}),jn=(0,i.jsx)(d.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,i.jsx)(d.Path,{d:"M18.3 11.7c-.6-.6-1.4-.9-2.3-.9H6.7l2.9-3.3-1.1-1-4.5 5L8.5 16l1-1-2.7-2.7H16c.5 0 .9.2 1.3.5 1 1 1 3.4 1 4.5v.3h1.5v-.2c0-1.5 0-4.3-1.5-5.7z"})}),Tn=(0,i.jsx)(d.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,i.jsx)(d.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M12 5.5A2.25 2.25 0 0 0 9.878 7h4.244A2.251 2.251 0 0 0 12 5.5ZM12 4a3.751 3.751 0 0 0-3.675 3H5v1.5h1.27l.818 8.997a2.75 2.75 0 0 0 2.739 2.501h4.347a2.75 2.75 0 0 0 2.738-2.5L17.73 8.5H19V7h-3.325A3.751 3.751 0 0 0 12 4Zm4.224 4.5H7.776l.806 8.861a1.25 1.25 0 0 0 1.245 1.137h4.347a1.25 1.25 0 0 0 1.245-1.137l.805-8.861Z"})}),Ln=(0,i.jsx)(d.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,i.jsx)(d.Path,{d:"m21.5 9.1-6.6-6.6-4.2 5.6c-1.2-.1-2.4.1-3.6.7-.1 0-.1.1-.2.1-.5.3-.9.6-1.2.9l3.7 3.7-5.7 5.7v1.1h1.1l5.7-5.7 3.7 3.7c.4-.4.7-.8.9-1.2.1-.1.1-.2.2-.3.6-1.1.8-2.4.6-3.6l5.6-4.1zm-7.3 3.5.1.9c.1.9 0 1.8-.4 2.6l-6-6c.8-.4 1.7-.5 2.6-.4l.9.1L15 4.9 19.1 9l-4.9 3.6z"})}),En=function(){return En=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0?(0,i.jsx)("span",{className:"parsely-write-titles-text",children:(0,u.createInterpolateElement)( +message:(0,_.sprintf)((0,_.__)('by author "%1$s"',"wp-parsely"),n.value)};throw new ie((0,_.__)("No valid filter type has been specified.","wp-parsely"),W.CannotFormulateApiQuery)},t}(Ce),gn=function(){return gn=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0&&u.every(Number.isInteger)?null!==(n=o("taxonomy","category",{include:u,context:"view"}))&&void 0!==n?n:void 0:null,tags:a=Array.isArray(p)&&p.length>0&&p.every(Number.isInteger)?null!==(r=o("taxonomy","post_tag",{include:p,context:"view"}))&&void 0!==r?r:void 0:null,isReady:void 0!==i&&void 0!==s&&void 0!==a}}),[]);return{authors:e.authors,categories:e.categories,tags:e.tags,isReady:e.isReady}}(),c=l.authors,u=l.categories,p=l.tags,v=l.isReady;(0,b.useEffect)((function(){if(v){var e=function(e){return function(e){return!(!Array.isArray(e)||0===e.length)&&e.every((function(e){return"name"in e&&"id"in e&&"slug"in e&&"description"in e&&"link"in e}))}(e)?e.map((function(e){return e.name})):[]};o({authors:e(c),categories:e(u),tags:e(p)})}}),[c,u,p,v]);var g=(0,b.useState)(!0),x=g[0],k=g[1],S=(0,b.useState)(),j=S[0],T=S[1],L=(0,b.useState)(),E=L[0],N=L[1],C=(0,b.useState)([]),A=C[0],O=C[1],R=(0,b.useState)({type:t.RelatedPosts.FilterBy,value:t.RelatedPosts.FilterValue}),I=R[0],M=R[1],G=(0,b.useState)(void 0),H=G[0],U=G[1],q=(0,z.useDebounce)(U,1e3);(0,h.useSelect)((function(e){if("undefined"==typeof jest){var t=e("core/editor").getEditedPostContent;q(t())}else q("Jest test is running")}),[q]);var Z=function(e,r){n({RelatedPosts:gn(gn({},t.RelatedPosts),{FilterBy:e,FilterValue:r})})};return(0,b.useEffect)((function(){var e,t,n=function(e){return yn(void 0,void 0,void 0,(function(){return mn(this,(function(t){return vn.getInstance().getRelatedPosts(r,i,I).then((function(e){O(e.posts),N(e.message),k(!1)})).catch((function(t){return yn(void 0,void 0,void 0,(function(){return mn(this,(function(r){switch(r.label){case 0:return e>0&&t.retryFetch?[4,new Promise((function(e){return setTimeout(e,500)}))]:[3,3];case 1:return r.sent(),[4,n(e-1)];case 2:return r.sent(),[3,4];case 3:k(!1),T(t),r.label=4;case 4:return[2]}}))}))})),[2]}))}))},s=w.Author===I.type,o=w.Tag===I.type,l=w.Section===I.type,c=w.Unavailable===I.type,u=0===a.authors.length,p=0===a.tags.length,d=0===a.categories.length,f=s&&!a.authors.includes(I.value),h=o&&!a.tags.includes(I.value),v=l&&!a.categories.includes(I.value);return k(!0),c||o&&p||l&&d||s&&u?Object.values(a).every((function(e){return 0===e.length}))||M((e="",t=w.Unavailable,a.tags.length>=1?(t=w.Tag,e=a.tags[0]):a.categories.length>=1?(t=w.Section,e=a.categories[0]):a.authors.length>=1&&(t=w.Author,e=a.authors[0]),{type:t,value:e})):h?M({type:w.Tag,value:a.tags[0]}):v?M({type:w.Section,value:a.categories[0]}):f?M({type:w.Author,value:a.authors[0]}):n(1),function(){k(!1),O([]),N(""),T(void 0)}}),[r,i,I,a]),0===a.authors.length&&0===a.categories.length&&0===a.tags.length&&v?(0,d.jsx)("div",{className:"wp-parsely-related-posts",children:(0,d.jsx)("div",{className:"related-posts-body",children:(0,_.__)("Error: No author, section, or tags could be found for this post.","wp-parsely")})}):(0,d.jsxs)("div",{className:"wp-parsely-related-posts",children:[(0,d.jsx)("div",{className:"related-posts-description",children:(0,_.__)("Find top-performing related posts based on a key metric.","wp-parsely")}),(0,d.jsxs)("div",{className:"related-posts-body",children:[(0,d.jsxs)("div",{className:"related-posts-settings",children:[(0,d.jsx)(f.SelectControl,{size:"__unstable-large",onChange:function(e){var r;D(r=e,m)&&(n({RelatedPosts:gn(gn({},t.RelatedPosts),{Metric:r})}),P.trackEvent("related_posts_metric_changed",{metric:r}))},prefix:(0,d.jsx)(f.__experimentalInputControlPrefixWrapper,{children:(0,_.__)("Metric: ","wp-parsely")}),value:i,children:Object.values(m).map((function(e){return(0,d.jsx)("option",{value:e,children:V(e)},e)}))}),(0,d.jsx)(f.SelectControl,{size:"__unstable-large",value:r,prefix:(0,d.jsxs)(f.__experimentalInputControlPrefixWrapper,{children:[(0,_.__)("Period: ","wp-parsely")," "]}),onChange:function(e){return function(e){D(e,y)&&(n({RelatedPosts:gn(gn({},t.RelatedPosts),{Period:e})}),P.trackEvent("related_posts_period_changed",{period:e}))}(e)},children:Object.values(y).map((function(e){return(0,d.jsx)("option",{value:e,children:F(e)},e)}))})]}),(0,d.jsx)(nn,{label:(0,_.__)("Filter by","wp-parsely"),filter:I,onFilterTypeChange:function(e){if(D(e,w)){var t="",n=e;w.Tag===n&&(t=a.tags[0]),w.Section===n&&(t=a.categories[0]),w.Author===n&&(t=a.authors[0]),""!==t&&(Z(n,t),M({type:n,value:t}),P.trackEvent("related_posts_filter_type_changed",{filter_type:n}))}},onFilterValueChange:function(e){"string"==typeof e&&(Z(I.type,e),M(gn(gn({},I),{value:e})))},postData:a}),(0,d.jsxs)("div",{className:"related-posts-wrapper",children:[(0,d.jsx)("div",{children:(0,d.jsx)("p",{className:"related-posts-descr","data-testid":"parsely-related-posts-descr",children:w.Tag===I.type?(0,_.sprintf)(/* translators: 1: tag name, 2: period */ /* translators: 1: tag name, 2: period */ +(0,_.__)("Top related posts with the “%1$s” tag in the %2$s.","wp-parsely"),I.value,F(r,!0)):w.Section===I.type?(0,_.sprintf)(/* translators: 1: section name, 2: period */ /* translators: 1: section name, 2: period */ +(0,_.__)("Top related posts in the “%1$s” section in the %2$s.","wp-parsely"),I.value,F(r,!0)):w.Author===I.type?(0,_.sprintf)(/* translators: 1: author name, 2: period */ /* translators: 1: author name, 2: period */ +(0,_.__)("Top related posts by %1$s in the %2$s.","wp-parsely"),I.value,F(r,!0)):null!=E?E:""})}),j&&j.Message(),x&&(0,d.jsx)("div",{className:"related-posts-loading-message","data-testid":"parsely-related-posts-loading-message",children:(0,_.__)("Loading…","wp-parsely")}),!x&&!j&&0===A.length&&(0,d.jsx)("div",{className:"related-posts-empty","data-testid":"parsely-related-posts-empty",children:(0,_.__)("No related posts found.","wp-parsely")}),!x&&A.length>0&&(0,d.jsx)("div",{className:"related-posts-list",children:A.map((function(e){return(0,d.jsx)(cn,{metric:i,post:e,postContent:H},e.id)}))})]})]})]})},bn=(0,d.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,d.jsx)(x.Path,{d:"m19 7-3-3-8.5 8.5-1 4 4-1L19 7Zm-7 11.5H5V20h7v-1.5Z"})}),xn=function(){return(0,d.jsx)(f.SVG,{xmlns:"http://www.w3.org/2000/svg",width:"18",height:"18",viewBox:"0 0 18 18",fill:"none",children:(0,d.jsx)(f.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M13.5034 7.91642L9 12.0104L4.49662 7.91642L5.25337 7.08398L8.99999 10.49L12.7466 7.08398L13.5034 7.91642Z",fill:"#1E1E1E"})})},kn={journalist:{label:(0,_.__)("Journalist","wp-parsely")},editorialWriter:{label:(0,_.__)("Editorial Writer","wp-parsely")},investigativeReporter:{label:(0,_.__)("Investigative Reporter","wp-parsely")},techAnalyst:{label:(0,_.__)("Tech Analyst","wp-parsely")},businessAnalyst:{label:(0,_.__)("Business Analyst","wp-parsely")},culturalCommentator:{label:(0,_.__)("Cultural Commentator","wp-parsely")},scienceCorrespondent:{label:(0,_.__)("Science Correspondent","wp-parsely")},politicalAnalyst:{label:(0,_.__)("Political Analyst","wp-parsely")},healthWellnessAdvocate:{label:(0,_.__)("Health and Wellness Advocate","wp-parsely")},environmentalJournalist:{label:(0,_.__)("Environmental Journalist","wp-parsely")},custom:{label:(0,_.__)("Custom Persona","wp-parsely"),icon:bn}},Sn=Object.keys(kn),Pn=function(e){return"custom"===e||""===e?kn.custom.label:jn(e)?e:kn[e].label},jn=function(e){return!Sn.includes(e)||"custom"===e},Tn=function(e){var t=e.value,n=e.onChange,r=(0,b.useState)(""),i=r[0],s=r[1],a=(0,z.useDebounce)(n,500);return(0,d.jsx)("div",{className:"parsely-persona-selector-custom",children:(0,d.jsx)(f.TextControl,{value:i||t,placeholder:(0,_.__)("Enter a custom persona…","wp-parsely"),onChange:function(e){if(""===e)return n(""),void s("");e.length>32&&(e=e.slice(0,32)),a(e),s(e)}})})},Ln=function(e){var t=e.persona,n=e.value,r=void 0===n?(0,_.__)("Select a persona…","wp-parsely"):n,i=e.label,s=void 0===i?(0,_.__)("Persona","wp-parsely"):i,a=e.onChange,o=e.onDropdownChange,l=e.disabled,c=void 0!==l&&l,u=e.allowCustom,p=void 0!==u&&u;return(0,d.jsxs)(f.Disabled,{isDisabled:c,children:[s&&(0,d.jsx)("div",{className:"wp-parsely-dropdown-label",children:s}),(0,d.jsx)(f.DropdownMenu,{label:(0,_.__)("Persona","wp-parsely"),className:"parsely-persona-selector-dropdown"+(c?" is-disabled":""),popoverProps:{className:"wp-parsely-popover"},toggleProps:{children:(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)("div",{className:"parsely-persona-selector-label",children:jn(t)?kn.custom.label:r}),(0,d.jsx)(xn,{})]})},children:function(e){var n=e.onClose;return(0,d.jsx)(f.MenuGroup,{label:(0,_.__)("Persona","wp-parsely"),children:(0,d.jsx)(d.Fragment,{children:Sn.map((function(e){if(!p&&"custom"===e)return null;var r=kn[e],i=e===t||jn(t)&&"custom"===e;return(0,d.jsxs)(f.MenuItem,{isSelected:i,className:i?"is-selected":"",role:"menuitemradio",onClick:function(){null==o||o(e),a(e),n(),"custom"===e&&setTimeout((function(){var e=document.querySelector(".parsely-persona-selector-custom input");e&&e.focus()}),0)},children:[r.icon&&(0,d.jsx)(X,{icon:r.icon}),r.label]},e)}))})})}}),p&&jn(t)&&(0,d.jsx)(Tn,{onChange:function(e){a(""!==e?e:"custom")},value:"custom"===t?"":t})]})},En={neutral:{label:(0,_.__)("Neutral","wp-parsely")},formal:{label:(0,_.__)("Formal","wp-parsely")},humorous:{label:(0,_.__)("Humorous","wp-parsely")},confident:{label:(0,_.__)("Confident","wp-parsely")},provocative:{label:(0,_.__)("Provocative","wp-parsely")},serious:{label:(0,_.__)("Serious","wp-parsely")},inspirational:{label:(0,_.__)("Inspirational","wp-parsely")},skeptical:{label:(0,_.__)("Skeptical","wp-parsely")},conversational:{label:(0,_.__)("Conversational","wp-parsely")},analytical:{label:(0,_.__)("Analytical","wp-parsely")},custom:{label:(0,_.__)("Custom Tone","wp-parsely"),icon:bn}},Nn=Object.keys(En),Cn=function(e){return"custom"===e||""===e?En.custom.label:An(e)?e:En[e].label},An=function(e){return!Nn.includes(e)||"custom"===e},On=function(e){var t=e.value,n=e.onChange,r=(0,b.useState)(""),i=r[0],s=r[1],a=(0,z.useDebounce)(n,500);return(0,d.jsx)("div",{className:"parsely-tone-selector-custom",children:(0,d.jsx)(f.TextControl,{value:i||t,placeholder:(0,_.__)("Enter a custom tone","wp-parsely"),onChange:function(e){if(""===e)return n(""),void s("");e.length>32&&(e=e.slice(0,32)),a(e),s(e)}})})},Rn=function(e){var t=e.tone,n=e.value,r=void 0===n?(0,_.__)("Select a tone","wp-parsely"):n,i=e.label,s=void 0===i?(0,_.__)("Tone","wp-parsely"):i,a=e.onChange,o=e.onDropdownChange,l=e.disabled,c=void 0!==l&&l,u=e.allowCustom,p=void 0!==u&&u;return(0,d.jsxs)(f.Disabled,{isDisabled:c,children:[(0,d.jsx)("div",{className:"wp-parsely-dropdown-label",children:s}),(0,d.jsx)(f.DropdownMenu,{label:(0,_.__)("Tone","wp-parsely"),className:"parsely-tone-selector-dropdown"+(c?" is-disabled":""),popoverProps:{className:"wp-parsely-popover"},toggleProps:{children:(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)("div",{className:"parsely-tone-selector-label",children:An(t)?En.custom.label:r}),(0,d.jsx)(xn,{})]})},children:function(e){var n=e.onClose;return(0,d.jsx)(f.MenuGroup,{label:(0,_.__)("Select a tone","wp-parsely"),children:(0,d.jsx)(d.Fragment,{children:Nn.map((function(e){if(!p&&"custom"===e)return null;var r=En[e],i=e===t||An(t)&&"custom"===e;return(0,d.jsxs)(f.MenuItem,{isSelected:i,className:i?"is-selected":"",role:"menuitemradio",onClick:function(){null==o||o(e),a(e),n(),"custom"===e&&setTimeout((function(){var e=document.querySelector(".parsely-tone-selector-custom input");e&&e.focus()}),0)},children:[r.icon&&(0,d.jsx)(X,{icon:r.icon}),r.label]},e)}))})})}}),p&&An(t)&&(0,d.jsx)(On,{onChange:function(e){a(""!==e?e:"custom")},value:"custom"===t?"":t})]})},In=(0,d.jsx)(x.SVG,{width:"24",height:"24",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:(0,d.jsx)(x.Path,{d:"M10.97 10.159a3.382 3.382 0 0 0-2.857.955l1.724 1.723-2.836 2.913L7 17h1.25l2.913-2.837 1.723 1.723a3.38 3.38 0 0 0 .606-.825c.33-.63.446-1.343.35-2.032L17 10.695 13.305 7l-2.334 3.159Z"})}),Bn=(0,d.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,d.jsx)(x.Path,{d:"M18.3 11.7c-.6-.6-1.4-.9-2.3-.9H6.7l2.9-3.3-1.1-1-4.5 5L8.5 16l1-1-2.7-2.7H16c.5 0 .9.2 1.3.5 1 1 1 3.4 1 4.5v.3h1.5v-.2c0-1.5 0-4.3-1.5-5.7z"})}),Mn=(0,d.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,d.jsx)(x.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M12 5.5A2.25 2.25 0 0 0 9.878 7h4.244A2.251 2.251 0 0 0 12 5.5ZM12 4a3.751 3.751 0 0 0-3.675 3H5v1.5h1.27l.818 8.997a2.75 2.75 0 0 0 2.739 2.501h4.347a2.75 2.75 0 0 0 2.738-2.5L17.73 8.5H19V7h-3.325A3.751 3.751 0 0 0 12 4Zm4.224 4.5H7.776l.806 8.861a1.25 1.25 0 0 0 1.245 1.137h4.347a1.25 1.25 0 0 0 1.245-1.137l.805-8.861Z"})}),Dn=(0,d.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,d.jsx)(x.Path,{d:"m21.5 9.1-6.6-6.6-4.2 5.6c-1.2-.1-2.4.1-3.6.7-.1 0-.1.1-.2.1-.5.3-.9.6-1.2.9l3.7 3.7-5.7 5.7v1.1h1.1l5.7-5.7 3.7 3.7c.4-.4.7-.8.9-1.2.1-.1.1-.2.2-.3.6-1.1.8-2.4.6-3.6l5.6-4.1zm-7.3 3.5.1.9c.1.9 0 1.8-.4 2.6l-6-6c.8-.4 1.7-.5 2.6-.4l.9.1L15 4.9 19.1 9l-4.9 3.6z"})}),Fn=function(){return Fn=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0&&i[i.length-1])||6!==o[0]&&2!==o[0])){a=0;continue}if(3===o[0]&&(!i||o[1]>i[0]&&o[1]0?(0,d.jsx)("span",{className:"parsely-write-titles-text",children:(0,b.createInterpolateElement)( // translators: %1$s is the tone, %2$s is the persona. // translators: %1$s is the tone, %2$s is the persona. -(0,p.__)("We've generated a few titles based on the content of your post, written as a .","wp-parsely"),{tone:(0,i.jsx)("strong",{children:bn(d)}),persona:(0,i.jsx)("strong",{children:hn(g)})})}):(0,p.__)("Use Parse.ly AI to generate a title for your post.","wp-parsely"),(0,i.jsxs)(s.Button,{href:"https://docs.parse.ly/plugin-content-helper/#h-title-suggestions-beta",target:"_blank",variant:"link",children:[(0,p.__)("Learn more about Parse.ly AI","wp-parsely"),(0,i.jsx)(z,{icon:U,size:18,className:"parsely-external-link-icon"})]})]}),o&&(0,i.jsx)(s.Notice,{className:"wp-parsely-content-helper-error",onRemove:function(){return l(void 0)},status:"info",children:o.Message()}),void 0!==S&&(0,i.jsx)(Bn,{title:S,type:Jt.PostTitle,isOriginal:!0}),00&&(0,i.jsx)(Mn,{pinnedTitles:_,isOpen:!0}),b.length>0&&(0,i.jsx)(Fn,{suggestions:b,isOpen:!0,isLoading:w})]}),(0,i.jsx)(Dn,{isLoading:w,onPersonaChange:function(e){A("Persona",e),y(e)},onSettingChange:A,onToneChange:function(e){A("Tone",e),f(e)},persona:t.TitleSuggestions.Persona,tone:t.TitleSuggestions.Tone}),(0,i.jsx)("div",{className:"title-suggestions-generate",children:(0,i.jsxs)(s.Button,{variant:"primary",isBusy:w,disabled:w||"custom"===d||"custom"===g,onClick:function(){return zn(void 0,void 0,void 0,(function(){return Un(this,(function(e){switch(e.label){case 0:return l(void 0),!1!==w?[3,2]:(v.trackEvent("title_suggestions_generate_pressed",{request_more:b.length>0,total_titles:b.length,total_pinned:b.filter((function(e){return e.isPinned})).length,tone:d,persona:g}),[4,(t=Jt.PostTitle,n=O,r=d,i=g,zn(void 0,void 0,void 0,(function(){var e,s,a;return Un(this,(function(o){switch(o.label){case 0:return[4,L(!0)];case 1:o.sent(),e=Gn.getInstance(),o.label=2;case 2:return o.trys.push([2,5,,6]),[4,e.generateTitles(n,3,r,i)];case 3:return s=o.sent(),[4,T(t,s)];case 4:return o.sent(),[3,6];case 5:return a=o.sent(),l(a),T(t,[]),[3,6];case 6:return[4,L(!1)];case 7:return o.sent(),[2]}}))})))]);case 1:e.sent(),e.label=2;case 2:return[2]}var t,n,r,i}))}))},children:[w&&(0,p.__)("Generating Titles…","wp-parsely"),!w&&x.length>0&&(0,p.__)("Generate More","wp-parsely"),!w&&0===x.length&&(0,p.__)("Generate Titles","wp-parsely")]})})]})})},Zn=function(){return Zn=Object.assign||function(e){for(var t,n=1,r=arguments.length;n titles based on the content of your post, written as a .","wp-parsely"),{tone:(0,d.jsx)("strong",{children:Cn(o)}),persona:(0,d.jsx)("strong",{children:Pn(u)})})}):(0,_.__)("Use Parse.ly AI to generate a title for your post.","wp-parsely"),(0,d.jsxs)(f.Button,{href:"https://docs.parse.ly/plugin-content-helper/#h-title-suggestions-beta",target:"_blank",variant:"link",children:[(0,_.__)("Learn more about Parse.ly AI","wp-parsely"),(0,d.jsx)(X,{icon:ee,size:18,className:"parsely-external-link-icon"})]})]}),i&&(0,d.jsx)(f.Notice,{className:"wp-parsely-content-helper-error",onRemove:function(){return s(void 0)},status:"info",children:i.Message()}),void 0!==k&&(0,d.jsx)(Zn,{title:k,type:ln.PostTitle,isOriginal:!0}),00&&(0,d.jsx)(Wn,{pinnedTitles:m,isOpen:!0}),y.length>0&&(0,d.jsx)(Kn,{suggestions:y,isOpen:!0,isLoading:g})]}),(0,d.jsx)($n,{isLoading:g,onPersonaChange:function(e){C("Persona",e),p(e)},onSettingChange:C,onToneChange:function(e){C("Tone",e),l(e)},persona:t.TitleSuggestions.Persona,tone:t.TitleSuggestions.Tone}),(0,d.jsx)("div",{className:"title-suggestions-generate",children:(0,d.jsxs)(f.Button,{variant:"primary",isBusy:g,disabled:g||"custom"===o||"custom"===u,onClick:function(){return Xn(void 0,void 0,void 0,(function(){return er(this,(function(e){switch(e.label){case 0:return s(void 0),!1!==g?[3,2]:(P.trackEvent("title_suggestions_generate_pressed",{request_more:y.length>0,total_titles:y.length,total_pinned:y.filter((function(e){return e.isPinned})).length,tone:o,persona:u}),[4,(t=ln.PostTitle,n=A,r=o,i=u,Xn(void 0,void 0,void 0,(function(){var e,a,o;return er(this,(function(l){switch(l.label){case 0:return[4,T(!0)];case 1:l.sent(),e=Jn.getInstance(),l.label=2;case 2:return l.trys.push([2,5,,6]),[4,e.generateTitles(n,3,r,i)];case 3:return a=l.sent(),[4,j(t,a)];case 4:return l.sent(),[3,6];case 5:return o=l.sent(),s(o),j(t,[]),[3,6];case 6:return[4,T(!1)];case 7:return l.sent(),[2]}}))})))]);case 1:e.sent(),e.label=2;case 2:return[2]}var t,n,r,i}))}))},children:[g&&(0,_.__)("Generating Titles…","wp-parsely"),!g&&w.length>0&&(0,_.__)("Generate More","wp-parsely"),!g&&0===w.length&&(0,_.__)("Generate Titles","wp-parsely")]})})]})})},nr=function(){return nr=Object.assign||function(e){for(var t,n=1,r=arguments.length;n array('react', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-edit-post', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-plugins', 'wp-primitives', 'wp-url', 'wp-wordcount'), 'version' => 'bdba9e5ade5650d62b1a'); + array('react', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-plugins', 'wp-primitives', 'wp-url', 'wp-wordcount'), 'version' => '654bab3f782c2b075d8f'); diff --git a/build/content-helper/excerpt-generator.js b/build/content-helper/excerpt-generator.js index c48020d00..dfc1398c0 100644 --- a/build/content-helper/excerpt-generator.js +++ b/build/content-helper/excerpt-generator.js @@ -1,4 +1,4 @@ -!function(){"use strict";var e={20:function(e,t,r){var n=r(609),o=Symbol.for("react.element"),a=Symbol.for("react.fragment"),s=Object.prototype.hasOwnProperty,i=n.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function c(e,t,r){var n,a={},c=null,u=null;for(n in void 0!==r&&(c=""+r),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(u=t.ref),t)s.call(t,n)&&!l.hasOwnProperty(n)&&(a[n]=t[n]);if(e&&e.defaultProps)for(n in t=e.defaultProps)void 0===a[n]&&(a[n]=t[n]);return{$$typeof:o,type:e,key:c,ref:u,props:a,_owner:i.current}}t.Fragment=a,t.jsx=c,t.jsxs=c},848:function(e,t,r){e.exports=r(20)},609:function(e){e.exports=window.React}},t={};function r(n){var o=t[n];if(void 0!==o)return o.exports;var a=t[n]={exports:{}};return e[n](a,a.exports,r),a.exports}r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,{a:t}),t},r.d=function(e,t){for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},function(){var e,t,n=window.wp.data,o=window.wp.hooks,a=window.wp.plugins,s=((0,n.dispatch)("core/block-editor"),(0,n.dispatch)("core/editor"),(0,n.dispatch)("core/edit-post")),i=r(848),l=window.wp.components,c=window.wp.editPost,u=window.wp.editor,p=window.wp.element,d=window.wp.i18n,y=window.wp.wordcount,h=window.wp.primitives,f=(0,i.jsx)(h.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,i.jsx)(h.Path,{d:"M19.5 4.5h-7V6h4.44l-5.97 5.97 1.06 1.06L18 7.06v4.44h1.5v-7Zm-13 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-3H17v3a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h3V5.5h-3Z"})}),w=function(){function e(){this._tkq=[],this.isLoaded=!1,this.isEnabled=!1,"undefined"!=typeof wpParselyTracksTelemetry&&(this.isEnabled=!0,this.loadTrackingLibrary())}return e.getInstance=function(){return window.wpParselyTelemetryInstance||Object.defineProperty(window,"wpParselyTelemetryInstance",{value:new e,writable:!1,configurable:!1,enumerable:!1}),window.wpParselyTelemetryInstance},e.prototype.loadTrackingLibrary=function(){var e=this,t=document.createElement("script");t.async=!0,t.src="//stats.wp.com/w.js",t.onload=function(){e.isLoaded=!0,e._tkq=window._tkq||[]},document.head.appendChild(t)},e.trackEvent=function(t){return r=this,n=arguments,a=function(t,r){var n;return void 0===r&&(r={}),function(e,t){var r,n,o,a,s={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:i(0),throw:i(1),return:i(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function i(i){return function(l){return function(i){if(r)throw new TypeError("Generator is already executing.");for(;a&&(a=0,i[0]&&(s=0)),s;)try{if(r=1,n&&(o=2&i[0]?n.return:i[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,i[1])).done)return o;switch(n=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return s.label++,{value:i[1],done:!1};case 5:s.label++,n=i[1],i=[0];continue;case 7:i=s.ops.pop(),s.trys.pop();continue;default:if(!((o=(o=s.trys).length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){s=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]=1e4&&(clearInterval(a),r("Telemetry library not loaded"))}),100);else r("Telemetry not enabled")}))},e.prototype.trackEvent=function(t,r){var n;this.isLoaded?(0!==t.indexOf(e.TRACKS_PREFIX)&&(t=e.TRACKS_PREFIX+t),this.isEventNameValid(t)?(r=this.prepareProperties(r),null===(n=this._tkq)||void 0===n||n.push(["recordEvent",t,r])):console.error("Error tracking event: Invalid event name")):console.error("Error tracking event: Telemetry not loaded")},e.prototype.isTelemetryEnabled=function(){return this.isEnabled},e.prototype.isProprietyValid=function(t){return e.PROPERTY_REGEX.test(t)},e.prototype.isEventNameValid=function(t){return e.EVENT_NAME_REGEX.test(t)},e.prototype.prepareProperties=function(e){return(e=this.sanitizeProperties(e)).parsely_version=wpParselyTracksTelemetry.version,wpParselyTracksTelemetry.user&&(e._ut=wpParselyTracksTelemetry.user.type,e._ui=wpParselyTracksTelemetry.user.id),wpParselyTracksTelemetry.vipgo_env&&(e.vipgo_env=wpParselyTracksTelemetry.vipgo_env),this.sanitizeProperties(e)},e.prototype.sanitizeProperties=function(e){var t=this,r={};return Object.keys(e).forEach((function(n){t.isProprietyValid(n)&&(r[n]=e[n])})),r},e.TRACKS_PREFIX="wpparsely_",e.EVENT_NAME_REGEX=/^(([a-z0-9]+)_){2}([a-z0-9_]+)$/,e.PROPERTY_REGEX=/^[a-z_][a-z0-9_]*$/,e}(),v=(w.trackEvent,function(e){void 0===e&&(e=null);var t="";(null==e?void 0:e.children)&&(t=e.children);var r="content-helper-error-message";return(null==e?void 0:e.className)&&(r+=" "+e.className),(0,i.jsx)("div",{className:r,"data-testid":null==e?void 0:e.testId,dangerouslySetInnerHTML:{__html:t}})}),g=(e=function(t,r){return e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])},e(t,r)},function(t,r){if("function"!=typeof r&&null!==r)throw new TypeError("Class extends value "+String(r)+" is not a constructor or null");function __(){this.constructor=t}e(t,r),t.prototype=null===r?Object.create(r):(__.prototype=r.prototype,new __)});!function(e){e.AccessToFeatureDisabled="ch_access_to_feature_disabled",e.CannotFormulateApiQuery="ch_cannot_formulate_api_query",e.FetchError="fetch_error",e.HttpRequestFailed="http_request_failed",e.ParselyAborted="ch_parsely_aborted",e[e.ParselyApiForbidden=403]="ParselyApiForbidden",e.ParselyApiResponseContainsError="ch_response_contains_error",e.ParselyApiReturnedNoData="ch_parsely_api_returned_no_data",e.ParselyApiReturnedTooManyResults="ch_parsely_api_returned_too_many_results",e.PluginCredentialsNotSetMessageDetected="parsely_credentials_not_set_message_detected",e.PluginSettingsApiSecretNotSet="parsely_api_secret_not_set",e.PluginSettingsSiteIdNotSet="parsely_site_id_not_set",e.PostIsNotPublished="ch_post_not_published",e.UnknownError="ch_unknown_error",e.ParselySuggestionsApiAuthUnavailable="AUTH_UNAVAILABLE",e.ParselySuggestionsApiNoAuthentication="NO_AUTHENTICATION",e.ParselySuggestionsApiNoAuthorization="NO_AUTHORIZATION",e.ParselySuggestionsApiNoData="NO_DATA",e.ParselySuggestionsApiOpenAiError="OPENAI_ERROR",e.ParselySuggestionsApiOpenAiSchema="OPENAI_SCHEMA",e.ParselySuggestionsApiOpenAiUnavailable="OPENAI_UNAVAILABLE",e.ParselySuggestionsApiSchemaError="SCHEMA_ERROR"}(t||(t={}));var _=function(e){function r(n,o,a){void 0===a&&(a=(0,d.__)("Error: ","wp-parsely"));var s=this;n.startsWith(a)&&(a=""),(s=e.call(this,a+n)||this).hint=null,s.name=s.constructor.name,s.code=o;var i=[t.AccessToFeatureDisabled,t.ParselyApiForbidden,t.ParselyApiResponseContainsError,t.ParselyApiReturnedNoData,t.ParselyApiReturnedTooManyResults,t.PluginCredentialsNotSetMessageDetected,t.PluginSettingsApiSecretNotSet,t.PluginSettingsSiteIdNotSet,t.PostIsNotPublished,t.UnknownError,t.ParselySuggestionsApiAuthUnavailable,t.ParselySuggestionsApiNoAuthentication,t.ParselySuggestionsApiNoAuthorization,t.ParselySuggestionsApiNoData,t.ParselySuggestionsApiSchemaError];return s.retryFetch=!i.includes(s.code),Object.setPrototypeOf(s,r.prototype),s.code===t.AccessToFeatureDisabled?s.message=(0,d.__)("Access to this feature is disabled by the site's administration.","wp-parsely"):s.code===t.ParselySuggestionsApiNoAuthorization?s.message=(0,d.__)('This AI-powered feature is opt-in. To gain access, please submit a request here.',"wp-parsely"):s.code===t.ParselySuggestionsApiOpenAiError||s.code===t.ParselySuggestionsApiOpenAiUnavailable?s.message=(0,d.__)("The Parse.ly API returned an internal server error. Please retry with a different input, or try again later.","wp-parsely"):s.code===t.HttpRequestFailed&&s.message.includes("cURL error 28")?s.message=(0,d.__)("The Parse.ly API did not respond in a timely manner. Please try again later.","wp-parsely"):s.code===t.ParselySuggestionsApiSchemaError?s.message=(0,d.__)("The Parse.ly API returned a validation error. Please try again with different parameters.","wp-parsely"):s.code===t.ParselySuggestionsApiNoData?s.message=(0,d.__)("The Parse.ly API couldn't find any relevant data to fulfill the request. Please retry with a different input.","wp-parsely"):s.code===t.ParselySuggestionsApiOpenAiSchema?s.message=(0,d.__)("The Parse.ly API returned an incorrect response. Please try again later.","wp-parsely"):s.code===t.ParselySuggestionsApiAuthUnavailable&&(s.message=(0,d.__)("The Parse.ly API is currently unavailable. Please try again later.","wp-parsely")),s}return g(r,e),r.prototype.Message=function(e){return void 0===e&&(e=null),[t.PluginCredentialsNotSetMessageDetected,t.PluginSettingsSiteIdNotSet,t.PluginSettingsApiSecretNotSet].includes(this.code)?function(e){var t;return void 0===e&&(e=null),(0,i.jsx)(v,{className:null==e?void 0:e.className,testId:"empty-credentials-message",children:null!==(t=window.wpParselyEmptyCredentialsMessage)&&void 0!==t?t:(0,d.__)("Please ensure that the Site ID and API Secret given in the plugin's settings are correct.","wp-parsely")})}(e):(this.code===t.FetchError&&(this.hint=this.Hint((0,d.__)("This error can sometimes be caused by ad-blockers or browser tracking protections. Please add this site to any applicable allow lists and try again.","wp-parsely"))),this.code!==t.ParselyApiForbidden&&this.code!==t.ParselySuggestionsApiNoAuthentication||(this.hint=this.Hint((0,d.__)("Please ensure that the Site ID and API Secret given in the plugin's settings are correct.","wp-parsely"))),this.code===t.HttpRequestFailed&&(this.hint=this.Hint((0,d.__)("The Parse.ly API cannot be reached. Please verify that you are online.","wp-parsely"))),(0,i.jsx)(v,{className:null==e?void 0:e.className,testId:"error",children:"

".concat(this.message,"

").concat(this.hint?this.hint:"")}))},r.prototype.Hint=function(e){return'

'.concat((0,d.__)("Hint:","wp-parsely")," ").concat(e,"

")},r.prototype.createErrorSnackbar=function(){//.test(this.message)||(0,n.dispatch)("core/notices").createNotice("error",this.message,{type:"snackbar"})},r}(Error),b=function(e){var t=e.size,r=void 0===t?24:t,n=e.className,o=void 0===n?"wp-parsely-icon":n;return(0,i.jsxs)(l.SVG,{className:o,height:r,viewBox:"0 0 60 65",width:r,xmlns:"http://www.w3.org/2000/svg",children:[(0,i.jsx)(l.Path,{fill:"#5ba745",d:"M23.72,51.53c0-.18,0-.34-.06-.52a13.11,13.11,0,0,0-2.1-5.53A14.74,14.74,0,0,0,19.12,43c-.27-.21-.5-.11-.51.22l-.24,3.42c0,.33-.38.35-.49,0l-1.5-4.8a1.4,1.4,0,0,0-.77-.78,23.91,23.91,0,0,0-3.1-.84c-1.38-.24-3.39-.39-3.39-.39-.34,0-.45.21-.25.49l2.06,3.76c.2.27,0,.54-.29.33l-4.51-3.6a3.68,3.68,0,0,0-2.86-.48c-1,.16-2.44.46-2.44.46a.68.68,0,0,0-.39.25.73.73,0,0,0-.14.45S.41,43,.54,44a3.63,3.63,0,0,0,1.25,2.62L6.48,50c.28.2.09.49-.23.37l-4.18-.94c-.32-.12-.5,0-.4.37,0,0,.69,1.89,1.31,3.16a24,24,0,0,0,1.66,2.74,1.34,1.34,0,0,0,1,.52l5,.13c.33,0,.41.38.1.48L7.51,58c-.31.1-.34.35-.07.55a14.29,14.29,0,0,0,3.05,1.66,13.09,13.09,0,0,0,5.9.5,25.13,25.13,0,0,0,4.34-1,9.55,9.55,0,0,1-.08-1.2,9.32,9.32,0,0,1,3.07-6.91"}),(0,i.jsx)(l.Path,{fill:"#5ba745",d:"M59.7,41.53a.73.73,0,0,0-.14-.45.68.68,0,0,0-.39-.25s-1.43-.3-2.44-.46a3.64,3.64,0,0,0-2.86.48l-4.51,3.6c-.26.21-.49-.06-.29-.33l2.06-3.76c.2-.28.09-.49-.25-.49,0,0-2,.15-3.39.39a23.91,23.91,0,0,0-3.1.84,1.4,1.4,0,0,0-.77.78l-1.5,4.8c-.11.32-.48.3-.49,0l-.24-3.42c0-.33-.24-.43-.51-.22a14.74,14.74,0,0,0-2.44,2.47A13.11,13.11,0,0,0,36.34,51c0,.18,0,.34-.06.52a9.26,9.26,0,0,1,3,8.1,24.1,24.1,0,0,0,4.34,1,13.09,13.09,0,0,0,5.9-.5,14.29,14.29,0,0,0,3.05-1.66c.27-.2.24-.45-.07-.55l-3.22-1.17c-.31-.1-.23-.47.1-.48l5-.13a1.38,1.38,0,0,0,1-.52A24.6,24.6,0,0,0,57,52.92c.61-1.27,1.31-3.16,1.31-3.16.1-.33-.08-.49-.4-.37l-4.18.94c-.32.12-.51-.17-.23-.37l4.69-3.34A3.63,3.63,0,0,0,59.46,44c.13-1,.24-2.47.24-2.47"}),(0,i.jsx)(l.Path,{fill:"#5ba745",d:"M46.5,25.61c0-.53-.35-.72-.8-.43l-4.86,2.66c-.45.28-.56-.27-.23-.69l4.66-6.23a2,2,0,0,0,.28-1.68,36.51,36.51,0,0,0-2.19-4.89,34,34,0,0,0-2.81-3.94c-.33-.41-.74-.35-.91.16l-2.28,5.68c-.16.5-.6.48-.59-.05l.28-8.93a2.54,2.54,0,0,0-.66-1.64S35,4.27,33.88,3.27,30.78.69,30.78.69a1.29,1.29,0,0,0-1.54,0s-1.88,1.49-3.12,2.59-2.48,2.35-2.48,2.35A2.5,2.5,0,0,0,23,7.27l.27,8.93c0,.53-.41.55-.58.05l-2.29-5.69c-.17-.5-.57-.56-.91-.14a35.77,35.77,0,0,0-3,4.2,35.55,35.55,0,0,0-2,4.62,2,2,0,0,0,.27,1.67l4.67,6.24c.33.42.23,1-.22.69l-4.87-2.66c-.45-.29-.82-.1-.82.43a18.6,18.6,0,0,0,.83,5.07,20.16,20.16,0,0,0,5.37,7.77c3.19,3,5.93,7.8,7.45,11.08A9.6,9.6,0,0,1,30,49.09a9.31,9.31,0,0,1,2.86.45c1.52-3.28,4.26-8.11,7.44-11.09a20.46,20.46,0,0,0,5.09-7,19,19,0,0,0,1.11-5.82"}),(0,i.jsx)(l.Path,{fill:"#5ba745",d:"M36.12,58.44A6.12,6.12,0,1,1,30,52.32a6.11,6.11,0,0,1,6.12,6.12"})]})},m=window.wp.url,P=window.wp.apiFetch,x=r.n(P),E=function(){function e(){this.abortControllers=new Map}return e.prototype.cancelRequest=function(e){if(e)(t=this.abortControllers.get(e))&&(t.abort(),this.abortControllers.delete(e));else{var t,r=Array.from(this.abortControllers.keys()).pop();r&&(t=this.abortControllers.get(r))&&(t.abort(),this.abortControllers.delete(r))}},e.prototype.cancelAll=function(){this.abortControllers.forEach((function(e){return e.abort()})),this.abortControllers.clear()},e.prototype.getOrCreateController=function(e){if(e&&this.abortControllers.has(e))return{abortController:this.abortControllers.get(e),abortId:e};var t=null!=e?e:"auto-"+Date.now(),r=new AbortController;return this.abortControllers.set(t,r),{abortController:r,abortId:t}},e.prototype.fetch=function(e,r){return n=this,o=void 0,s=function(){var n,o,a,s,i,l;return function(e,t){var r,n,o,a,s={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:i(0),throw:i(1),return:i(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function i(i){return function(l){return function(i){if(r)throw new TypeError("Generator is already executing.");for(;a&&(a=0,i[0]&&(s=0)),s;)try{if(r=1,n&&(o=2&i[0]?n.return:i[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,i[1])).done)return o;switch(n=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return s.label++,{value:i[1],done:!1};case 5:s.label++,n=i[1],i=[0];continue;case 7:i=s.ops.pop(),s.trys.pop();continue;default:if(!((o=(o=s.trys).length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){s=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])||6!==i[0]&&2!==i[0])){s=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0&&o[o.length-1])||6!==i[0]&&2!==i[0])){s=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]0?(0,d.sprintf)( +!function(){"use strict";var e={20:function(e,t,r){var n=r(609),o=Symbol.for("react.element"),a=Symbol.for("react.fragment"),i=Object.prototype.hasOwnProperty,s=n.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function c(e,t,r){var n,a={},c=null,u=null;for(n in void 0!==r&&(c=""+r),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(u=t.ref),t)i.call(t,n)&&!l.hasOwnProperty(n)&&(a[n]=t[n]);if(e&&e.defaultProps)for(n in t=e.defaultProps)void 0===a[n]&&(a[n]=t[n]);return{$$typeof:o,type:e,key:c,ref:u,props:a,_owner:s.current}}t.Fragment=a,t.jsx=c,t.jsxs=c},848:function(e,t,r){e.exports=r(20)},609:function(e){e.exports=window.React}},t={};function r(n){var o=t[n];if(void 0!==o)return o.exports;var a=t[n]={exports:{}};return e[n](a,a.exports,r),a.exports}r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,{a:t}),t},r.d=function(e,t){for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},function(){var e,t,n,o,a,i,s,l,c,u,p,d=window.wp.data,y=window.wp.hooks,h=window.wp.plugins,f=((0,d.dispatch)("core/block-editor"),(0,d.dispatch)("core/editor"),(0,d.dispatch)("core/edit-post")),w=r(848),v=window.wp.components,g=window.wp.editor;void 0!==window.wp&&(p=null!==(t=null===(e=window.wp.editor)||void 0===e?void 0:e.PluginDocumentSettingPanel)&&void 0!==t?t:null!==(o=null===(n=window.wp.editPost)||void 0===n?void 0:n.PluginDocumentSettingPanel)&&void 0!==o?o:null===(a=window.wp.editSite)||void 0===a?void 0:a.PluginDocumentSettingPanel,null!==(s=null===(i=window.wp.editor)||void 0===i?void 0:i.PluginSidebar)&&void 0!==s||null!==(c=null===(l=window.wp.editPost)||void 0===l?void 0:l.PluginSidebar)&&void 0!==c||null===(u=window.wp.editSite)||void 0===u||u.PluginSidebar);var _,b,P=window.wp.element,m=window.wp.i18n,x=window.wp.wordcount,E=window.wp.primitives,A=(0,w.jsx)(E.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,w.jsx)(E.Path,{d:"M19.5 4.5h-7V6h4.44l-5.97 5.97 1.06 1.06L18 7.06v4.44h1.5v-7Zm-13 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-3H17v3a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h3V5.5h-3Z"})}),S=function(){function e(){this._tkq=[],this.isLoaded=!1,this.isEnabled=!1,"undefined"!=typeof wpParselyTracksTelemetry&&(this.isEnabled=!0,this.loadTrackingLibrary())}return e.getInstance=function(){return window.wpParselyTelemetryInstance||Object.defineProperty(window,"wpParselyTelemetryInstance",{value:new e,writable:!1,configurable:!1,enumerable:!1}),window.wpParselyTelemetryInstance},e.prototype.loadTrackingLibrary=function(){var e=this,t=document.createElement("script");t.async=!0,t.src="//stats.wp.com/w.js",t.onload=function(){e.isLoaded=!0,e._tkq=window._tkq||[]},document.head.appendChild(t)},e.trackEvent=function(t){return r=this,n=arguments,a=function(t,r){var n;return void 0===r&&(r={}),function(e,t){var r,n,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function s(s){return function(l){return function(s){if(r)throw new TypeError("Generator is already executing.");for(;a&&(a=0,s[0]&&(i=0)),i;)try{if(r=1,n&&(o=2&s[0]?n.return:s[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,s[1])).done)return o;switch(n=0,o&&(s=[2&s[0],o.value]),s[0]){case 0:case 1:o=s;break;case 4:return i.label++,{value:s[1],done:!1};case 5:i.label++,n=s[1],s=[0];continue;case 7:s=i.ops.pop(),i.trys.pop();continue;default:if(!((o=(o=i.trys).length>0&&o[o.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]=1e4&&(clearInterval(a),r("Telemetry library not loaded"))}),100);else r("Telemetry not enabled")}))},e.prototype.trackEvent=function(t,r){var n;this.isLoaded?(0!==t.indexOf(e.TRACKS_PREFIX)&&(t=e.TRACKS_PREFIX+t),this.isEventNameValid(t)?(r=this.prepareProperties(r),null===(n=this._tkq)||void 0===n||n.push(["recordEvent",t,r])):console.error("Error tracking event: Invalid event name")):console.error("Error tracking event: Telemetry not loaded")},e.prototype.isTelemetryEnabled=function(){return this.isEnabled},e.prototype.isProprietyValid=function(t){return e.PROPERTY_REGEX.test(t)},e.prototype.isEventNameValid=function(t){return e.EVENT_NAME_REGEX.test(t)},e.prototype.prepareProperties=function(e){return(e=this.sanitizeProperties(e)).parsely_version=wpParselyTracksTelemetry.version,wpParselyTracksTelemetry.user&&(e._ut=wpParselyTracksTelemetry.user.type,e._ui=wpParselyTracksTelemetry.user.id),wpParselyTracksTelemetry.vipgo_env&&(e.vipgo_env=wpParselyTracksTelemetry.vipgo_env),this.sanitizeProperties(e)},e.prototype.sanitizeProperties=function(e){var t=this,r={};return Object.keys(e).forEach((function(n){t.isProprietyValid(n)&&(r[n]=e[n])})),r},e.TRACKS_PREFIX="wpparsely_",e.EVENT_NAME_REGEX=/^(([a-z0-9]+)_){2}([a-z0-9_]+)$/,e.PROPERTY_REGEX=/^[a-z_][a-z0-9_]*$/,e}(),k=(S.trackEvent,function(e){void 0===e&&(e=null);var t="";(null==e?void 0:e.children)&&(t=e.children);var r="content-helper-error-message";return(null==e?void 0:e.className)&&(r+=" "+e.className),(0,w.jsx)("div",{className:r,"data-testid":null==e?void 0:e.testId,dangerouslySetInnerHTML:{__html:t}})}),T=(_=function(e,t){return _=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])},_(e,t)},function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function __(){this.constructor=e}_(e,t),e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)});!function(e){e.AccessToFeatureDisabled="ch_access_to_feature_disabled",e.CannotFormulateApiQuery="ch_cannot_formulate_api_query",e.FetchError="fetch_error",e.HttpRequestFailed="http_request_failed",e.ParselyAborted="ch_parsely_aborted",e[e.ParselyApiForbidden=403]="ParselyApiForbidden",e.ParselyApiResponseContainsError="ch_response_contains_error",e.ParselyApiReturnedNoData="ch_parsely_api_returned_no_data",e.ParselyApiReturnedTooManyResults="ch_parsely_api_returned_too_many_results",e.PluginCredentialsNotSetMessageDetected="parsely_credentials_not_set_message_detected",e.PluginSettingsApiSecretNotSet="parsely_api_secret_not_set",e.PluginSettingsSiteIdNotSet="parsely_site_id_not_set",e.PostIsNotPublished="ch_post_not_published",e.UnknownError="ch_unknown_error",e.ParselySuggestionsApiAuthUnavailable="AUTH_UNAVAILABLE",e.ParselySuggestionsApiNoAuthentication="NO_AUTHENTICATION",e.ParselySuggestionsApiNoAuthorization="NO_AUTHORIZATION",e.ParselySuggestionsApiNoData="NO_DATA",e.ParselySuggestionsApiOpenAiError="OPENAI_ERROR",e.ParselySuggestionsApiOpenAiSchema="OPENAI_SCHEMA",e.ParselySuggestionsApiOpenAiUnavailable="OPENAI_UNAVAILABLE",e.ParselySuggestionsApiSchemaError="SCHEMA_ERROR"}(b||(b={}));var N=function(e){function t(r,n,o){void 0===o&&(o=(0,m.__)("Error: ","wp-parsely"));var a=this;r.startsWith(o)&&(o=""),(a=e.call(this,o+r)||this).hint=null,a.name=a.constructor.name,a.code=n;var i=[b.AccessToFeatureDisabled,b.ParselyApiForbidden,b.ParselyApiResponseContainsError,b.ParselyApiReturnedNoData,b.ParselyApiReturnedTooManyResults,b.PluginCredentialsNotSetMessageDetected,b.PluginSettingsApiSecretNotSet,b.PluginSettingsSiteIdNotSet,b.PostIsNotPublished,b.UnknownError,b.ParselySuggestionsApiAuthUnavailable,b.ParselySuggestionsApiNoAuthentication,b.ParselySuggestionsApiNoAuthorization,b.ParselySuggestionsApiNoData,b.ParselySuggestionsApiSchemaError];return a.retryFetch=!i.includes(a.code),Object.setPrototypeOf(a,t.prototype),a.code===b.AccessToFeatureDisabled?a.message=(0,m.__)("Access to this feature is disabled by the site's administration.","wp-parsely"):a.code===b.ParselySuggestionsApiNoAuthorization?a.message=(0,m.__)('This AI-powered feature is opt-in. To gain access, please submit a request here.',"wp-parsely"):a.code===b.ParselySuggestionsApiOpenAiError||a.code===b.ParselySuggestionsApiOpenAiUnavailable?a.message=(0,m.__)("The Parse.ly API returned an internal server error. Please retry with a different input, or try again later.","wp-parsely"):a.code===b.HttpRequestFailed&&a.message.includes("cURL error 28")?a.message=(0,m.__)("The Parse.ly API did not respond in a timely manner. Please try again later.","wp-parsely"):a.code===b.ParselySuggestionsApiSchemaError?a.message=(0,m.__)("The Parse.ly API returned a validation error. Please try again with different parameters.","wp-parsely"):a.code===b.ParselySuggestionsApiNoData?a.message=(0,m.__)("The Parse.ly API couldn't find any relevant data to fulfill the request. Please retry with a different input.","wp-parsely"):a.code===b.ParselySuggestionsApiOpenAiSchema?a.message=(0,m.__)("The Parse.ly API returned an incorrect response. Please try again later.","wp-parsely"):a.code===b.ParselySuggestionsApiAuthUnavailable&&(a.message=(0,m.__)("The Parse.ly API is currently unavailable. Please try again later.","wp-parsely")),a}return T(t,e),t.prototype.Message=function(e){return void 0===e&&(e=null),[b.PluginCredentialsNotSetMessageDetected,b.PluginSettingsSiteIdNotSet,b.PluginSettingsApiSecretNotSet].includes(this.code)?function(e){var t;return void 0===e&&(e=null),(0,w.jsx)(k,{className:null==e?void 0:e.className,testId:"empty-credentials-message",children:null!==(t=window.wpParselyEmptyCredentialsMessage)&&void 0!==t?t:(0,m.__)("Please ensure that the Site ID and API Secret given in the plugin's settings are correct.","wp-parsely")})}(e):(this.code===b.FetchError&&(this.hint=this.Hint((0,m.__)("This error can sometimes be caused by ad-blockers or browser tracking protections. Please add this site to any applicable allow lists and try again.","wp-parsely"))),this.code!==b.ParselyApiForbidden&&this.code!==b.ParselySuggestionsApiNoAuthentication||(this.hint=this.Hint((0,m.__)("Please ensure that the Site ID and API Secret given in the plugin's settings are correct.","wp-parsely"))),this.code===b.HttpRequestFailed&&(this.hint=this.Hint((0,m.__)("The Parse.ly API cannot be reached. Please verify that you are online.","wp-parsely"))),(0,w.jsx)(k,{className:null==e?void 0:e.className,testId:"error",children:"

".concat(this.message,"

").concat(this.hint?this.hint:"")}))},t.prototype.Hint=function(e){return'

'.concat((0,m.__)("Hint:","wp-parsely")," ").concat(e,"

")},t.prototype.createErrorSnackbar=function(){//.test(this.message)||(0,d.dispatch)("core/notices").createNotice("error",this.message,{type:"snackbar"})},t}(Error),j=function(e){var t=e.size,r=void 0===t?24:t,n=e.className,o=void 0===n?"wp-parsely-icon":n;return(0,w.jsxs)(v.SVG,{className:o,height:r,viewBox:"0 0 60 65",width:r,xmlns:"http://www.w3.org/2000/svg",children:[(0,w.jsx)(v.Path,{fill:"#5ba745",d:"M23.72,51.53c0-.18,0-.34-.06-.52a13.11,13.11,0,0,0-2.1-5.53A14.74,14.74,0,0,0,19.12,43c-.27-.21-.5-.11-.51.22l-.24,3.42c0,.33-.38.35-.49,0l-1.5-4.8a1.4,1.4,0,0,0-.77-.78,23.91,23.91,0,0,0-3.1-.84c-1.38-.24-3.39-.39-3.39-.39-.34,0-.45.21-.25.49l2.06,3.76c.2.27,0,.54-.29.33l-4.51-3.6a3.68,3.68,0,0,0-2.86-.48c-1,.16-2.44.46-2.44.46a.68.68,0,0,0-.39.25.73.73,0,0,0-.14.45S.41,43,.54,44a3.63,3.63,0,0,0,1.25,2.62L6.48,50c.28.2.09.49-.23.37l-4.18-.94c-.32-.12-.5,0-.4.37,0,0,.69,1.89,1.31,3.16a24,24,0,0,0,1.66,2.74,1.34,1.34,0,0,0,1,.52l5,.13c.33,0,.41.38.1.48L7.51,58c-.31.1-.34.35-.07.55a14.29,14.29,0,0,0,3.05,1.66,13.09,13.09,0,0,0,5.9.5,25.13,25.13,0,0,0,4.34-1,9.55,9.55,0,0,1-.08-1.2,9.32,9.32,0,0,1,3.07-6.91"}),(0,w.jsx)(v.Path,{fill:"#5ba745",d:"M59.7,41.53a.73.73,0,0,0-.14-.45.68.68,0,0,0-.39-.25s-1.43-.3-2.44-.46a3.64,3.64,0,0,0-2.86.48l-4.51,3.6c-.26.21-.49-.06-.29-.33l2.06-3.76c.2-.28.09-.49-.25-.49,0,0-2,.15-3.39.39a23.91,23.91,0,0,0-3.1.84,1.4,1.4,0,0,0-.77.78l-1.5,4.8c-.11.32-.48.3-.49,0l-.24-3.42c0-.33-.24-.43-.51-.22a14.74,14.74,0,0,0-2.44,2.47A13.11,13.11,0,0,0,36.34,51c0,.18,0,.34-.06.52a9.26,9.26,0,0,1,3,8.1,24.1,24.1,0,0,0,4.34,1,13.09,13.09,0,0,0,5.9-.5,14.29,14.29,0,0,0,3.05-1.66c.27-.2.24-.45-.07-.55l-3.22-1.17c-.31-.1-.23-.47.1-.48l5-.13a1.38,1.38,0,0,0,1-.52A24.6,24.6,0,0,0,57,52.92c.61-1.27,1.31-3.16,1.31-3.16.1-.33-.08-.49-.4-.37l-4.18.94c-.32.12-.51-.17-.23-.37l4.69-3.34A3.63,3.63,0,0,0,59.46,44c.13-1,.24-2.47.24-2.47"}),(0,w.jsx)(v.Path,{fill:"#5ba745",d:"M46.5,25.61c0-.53-.35-.72-.8-.43l-4.86,2.66c-.45.28-.56-.27-.23-.69l4.66-6.23a2,2,0,0,0,.28-1.68,36.51,36.51,0,0,0-2.19-4.89,34,34,0,0,0-2.81-3.94c-.33-.41-.74-.35-.91.16l-2.28,5.68c-.16.5-.6.48-.59-.05l.28-8.93a2.54,2.54,0,0,0-.66-1.64S35,4.27,33.88,3.27,30.78.69,30.78.69a1.29,1.29,0,0,0-1.54,0s-1.88,1.49-3.12,2.59-2.48,2.35-2.48,2.35A2.5,2.5,0,0,0,23,7.27l.27,8.93c0,.53-.41.55-.58.05l-2.29-5.69c-.17-.5-.57-.56-.91-.14a35.77,35.77,0,0,0-3,4.2,35.55,35.55,0,0,0-2,4.62,2,2,0,0,0,.27,1.67l4.67,6.24c.33.42.23,1-.22.69l-4.87-2.66c-.45-.29-.82-.1-.82.43a18.6,18.6,0,0,0,.83,5.07,20.16,20.16,0,0,0,5.37,7.77c3.19,3,5.93,7.8,7.45,11.08A9.6,9.6,0,0,1,30,49.09a9.31,9.31,0,0,1,2.86.45c1.52-3.28,4.26-8.11,7.44-11.09a20.46,20.46,0,0,0,5.09-7,19,19,0,0,0,1.11-5.82"}),(0,w.jsx)(v.Path,{fill:"#5ba745",d:"M36.12,58.44A6.12,6.12,0,1,1,30,52.32a6.11,6.11,0,0,1,6.12,6.12"})]})},C=window.wp.url,I=window.wp.apiFetch,O=r.n(I),R=function(){function e(){this.abortControllers=new Map}return e.prototype.cancelRequest=function(e){if(e)(t=this.abortControllers.get(e))&&(t.abort(),this.abortControllers.delete(e));else{var t,r=Array.from(this.abortControllers.keys()).pop();r&&(t=this.abortControllers.get(r))&&(t.abort(),this.abortControllers.delete(r))}},e.prototype.cancelAll=function(){this.abortControllers.forEach((function(e){return e.abort()})),this.abortControllers.clear()},e.prototype.getOrCreateController=function(e){if(e&&this.abortControllers.has(e))return{abortController:this.abortControllers.get(e),abortId:e};var t=null!=e?e:"auto-"+Date.now(),r=new AbortController;return this.abortControllers.set(t,r),{abortController:r,abortId:t}},e.prototype.fetch=function(e,t){return r=this,n=void 0,a=function(){var r,n,o,a,i,s;return function(e,t){var r,n,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function s(s){return function(l){return function(s){if(r)throw new TypeError("Generator is already executing.");for(;a&&(a=0,s[0]&&(i=0)),i;)try{if(r=1,n&&(o=2&s[0]?n.return:s[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,s[1])).done)return o;switch(n=0,o&&(s=[2&s[0],o.value]),s[0]){case 0:case 1:o=s;break;case 4:return i.label++,{value:s[1],done:!1};case 5:i.label++,n=s[1],s=[0];continue;case 7:s=i.ops.pop(),i.trys.pop();continue;default:if(!((o=(o=i.trys).length>0&&o[o.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]0&&o[o.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]0&&o[o.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]0?(0,m.sprintf)( // Translators: %1$s the number of words in the excerpt. // Translators: %1$s the number of words in the excerpt. -(0,d._n)("%1$s word","%1$s words",e,"wp-parsely"),e):"")}),[A.currentExcerpt,R]),(0,p.useEffect)((function(){var e=document.querySelector(".editor-post-excerpt textarea");e&&(e.scrollTop=0)}),[A.newExcerptGeneratedCount]),(0,i.jsxs)("div",{className:"editor-post-excerpt",children:[(0,i.jsxs)("div",{style:{position:"relative"},children:[r&&(0,i.jsx)("div",{className:"editor-post-excerpt__loading_animation",children:(0,i.jsx)(C,{})}),(0,i.jsx)(l.TextareaControl,{__nextHasNoMarginBottom:!0,label:(0,d.__)("Write an excerpt (optional)","wp-parsely"),className:"editor-post-excerpt__textarea",onChange:function(e){A.isUnderReview||I({excerpt:e}),j(k(k({},A),{currentExcerpt:e})),g(!0)},onKeyUp:function(){var e;if(v)g(!1);else{var t=document.querySelector(".editor-post-excerpt textarea"),r=null!==(e=null==t?void 0:t.textContent)&&void 0!==e?e:"";j(k(k({},A),{currentExcerpt:r}))}},value:r?"":A.isUnderReview?A.currentExcerpt:R,help:P||null})]}),(0,i.jsxs)(l.Button,{href:(0,d.__)("https://wordpress.org/documentation/article/page-post-settings-sidebar/#excerpt","wp-parsely"),target:"_blank",variant:"link",children:[(0,d.__)("Learn more about manual excerpts","wp-parsely"),(0,i.jsx)(l.Icon,{icon:f,size:18,className:"parsely-external-link-icon"})]}),(0,i.jsxs)("div",{className:"wp-parsely-excerpt-generator",children:[(0,i.jsxs)("div",{className:"wp-parsely-excerpt-generator-header",children:[(0,i.jsx)(b,{size:16}),(0,i.jsxs)("div",{className:"wp-parsely-excerpt-generator-header-label",children:[(0,d.__)("Generate With Parse.ly","wp-parsely"),(0,i.jsx)("span",{className:"beta-label",children:(0,d.__)("Beta","wp-parsely")})]})]}),s&&(0,i.jsx)(l.Notice,{className:"wp-parsely-excerpt-generator-error",onRemove:function(){return c(void 0)},status:"info",children:s.Message()}),(0,i.jsx)("div",{className:"wp-parsely-excerpt-generator-controls",children:A.isUnderReview?(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(l.Button,{variant:"secondary",onClick:function(){return T(void 0,void 0,void 0,(function(){return N(this,(function(e){switch(e.label){case 0:return[4,I({excerpt:A.currentExcerpt})];case 1:return e.sent(),j(k(k({},A),{isUnderReview:!1})),w.trackEvent("excerpt_generator_accepted"),[2]}}))}))},children:(0,d.__)("Accept","wp-parsely")}),(0,i.jsx)(l.Button,{isDestructive:!0,variant:"secondary",onClick:function(){return T(void 0,void 0,void 0,(function(){return N(this,(function(e){return I({excerpt:A.oldExcerpt}),j(k(k({},A),{currentExcerpt:A.oldExcerpt,isUnderReview:!1})),w.trackEvent("excerpt_generator_discarded"),[2]}))}))},children:(0,d.__)("Discard","wp-parsely")})]}):(0,i.jsxs)(l.Button,{onClick:function(){return T(void 0,void 0,void 0,(function(){var e,r;return N(this,(function(n){switch(n.label){case 0:o(!0),c(void 0),n.label=1;case 1:return n.trys.push([1,3,4,5]),w.trackEvent("excerpt_generator_pressed"),[4,S.getInstance().generateExcerpt(F,U)];case 2:return e=n.sent(),j({currentExcerpt:e,isUnderReview:!0,newExcerptGeneratedCount:A.newExcerptGeneratedCount+1,oldExcerpt:R}),[3,5];case 3:return(r=n.sent())instanceof _?c(r):(c(new _((0,d.__)("An unknown error occurred.","wp-parsely"),t.UnknownError)),console.error(r)),[3,5];case 4:return o(!1),[7];case 5:return[2]}}))}))},variant:"primary",isBusy:r,disabled:r||!U,children:[r&&(0,d.__)("Generating Excerpt…","wp-parsely"),!r&&A.newExcerptGeneratedCount>0&&(0,d.__)("Regenerate Excerpt","wp-parsely"),!r&&0===A.newExcerptGeneratedCount&&(0,d.__)("Generate Excerpt","wp-parsely")]})}),(0,i.jsxs)(l.Button,{href:"https://docs.parse.ly/plugin-content-helper/#h-excerpt-generator-beta",target:"_blank",variant:"link",children:[(0,d.__)("Learn more about Parse.ly AI","wp-parsely"),(0,i.jsx)(l.Icon,{icon:f,size:18,className:"parsely-external-link-icon"})]})]})]})},C=function(){return(0,i.jsx)(l.Animate,{type:"loading",children:function(e){var t=e.className;return(0,i.jsx)("span",{className:t,children:(0,d.__)("Generating…","wp-parsely")})}})},I=function(){return(0,i.jsx)(u.PostTypeSupportCheck,{supportKeys:"excerpt",children:(0,i.jsx)(c.PluginDocumentSettingPanel,{name:"parsely-post-excerpt",title:(0,d.__)("Excerpt","wp-parsely"),children:(0,i.jsx)(j,{})})})};(0,o.addFilter)("plugins.registerPlugin","wp-parsely-excerpt-generator",(function(e,t){var r,i,l;return"wp-parsely-block-editor-sidebar"!==t||((null===(r=null===window||void 0===window?void 0:window.Jetpack_Editor_Initial_State)||void 0===r?void 0:r.available_blocks["ai-content-lens"])&&(console.log("Parse.ly: Jetpack AI is enabled and will be disabled."),(0,o.removeFilter)("blocks.registerBlockType","jetpack/ai-content-lens-features")),(0,a.registerPlugin)("wp-parsely-excerpt-generator",{render:I}),(null===(i=(0,n.dispatch)("core/editor"))||void 0===i?void 0:i.removeEditorPanel)?null===(l=(0,n.dispatch)("core/editor"))||void 0===l||l.removeEditorPanel("post-excerpt"):null==s||s.removeEditorPanel("post-excerpt")),e}),1e3)}()}(); \ No newline at end of file +(0,m._n)("%1$s word","%1$s words",e,"wp-parsely"),e):"")}),[h.currentExcerpt,k]),(0,P.useEffect)((function(){var e=document.querySelector(".editor-post-excerpt textarea");e&&(e.scrollTop=0)}),[h.newExcerptGeneratedCount]),(0,w.jsxs)("div",{className:"editor-post-excerpt",children:[(0,w.jsxs)("div",{style:{position:"relative"},children:[t&&(0,w.jsx)("div",{className:"editor-post-excerpt__loading_animation",children:(0,w.jsx)(H,{})}),(0,w.jsx)(v.TextareaControl,{__nextHasNoMarginBottom:!0,label:(0,m.__)("Write an excerpt (optional)","wp-parsely"),className:"editor-post-excerpt__textarea",onChange:function(e){h.isUnderReview||_({excerpt:e}),f(F(F({},h),{currentExcerpt:e})),l(!0)},onKeyUp:function(){var e;if(s)l(!1);else{var t=document.querySelector(".editor-post-excerpt textarea"),r=null!==(e=null==t?void 0:t.textContent)&&void 0!==e?e:"";f(F(F({},h),{currentExcerpt:r}))}},value:t?"":h.isUnderReview?h.currentExcerpt:k,help:u||null})]}),(0,w.jsxs)(v.Button,{href:(0,m.__)("https://wordpress.org/documentation/article/page-post-settings-sidebar/#excerpt","wp-parsely"),target:"_blank",variant:"link",children:[(0,m.__)("Learn more about manual excerpts","wp-parsely"),(0,w.jsx)(v.Icon,{icon:A,size:18,className:"parsely-external-link-icon"})]}),(0,w.jsxs)("div",{className:"wp-parsely-excerpt-generator",children:[(0,w.jsxs)("div",{className:"wp-parsely-excerpt-generator-header",children:[(0,w.jsx)(j,{size:16}),(0,w.jsxs)("div",{className:"wp-parsely-excerpt-generator-header-label",children:[(0,m.__)("Generate With Parse.ly","wp-parsely"),(0,w.jsx)("span",{className:"beta-label",children:(0,m.__)("Beta","wp-parsely")})]})]}),o&&(0,w.jsx)(v.Notice,{className:"wp-parsely-excerpt-generator-error",onRemove:function(){return a(void 0)},status:"info",children:o.Message()}),(0,w.jsx)("div",{className:"wp-parsely-excerpt-generator-controls",children:h.isUnderReview?(0,w.jsxs)(w.Fragment,{children:[(0,w.jsx)(v.Button,{variant:"secondary",onClick:function(){return L(void 0,void 0,void 0,(function(){return M(this,(function(e){switch(e.label){case 0:return[4,_({excerpt:h.currentExcerpt})];case 1:return e.sent(),f(F(F({},h),{isUnderReview:!1})),S.trackEvent("excerpt_generator_accepted"),[2]}}))}))},children:(0,m.__)("Accept","wp-parsely")}),(0,w.jsx)(v.Button,{isDestructive:!0,variant:"secondary",onClick:function(){return L(void 0,void 0,void 0,(function(){return M(this,(function(e){return _({excerpt:h.oldExcerpt}),f(F(F({},h),{currentExcerpt:h.oldExcerpt,isUnderReview:!1})),S.trackEvent("excerpt_generator_discarded"),[2]}))}))},children:(0,m.__)("Discard","wp-parsely")})]}):(0,w.jsxs)(v.Button,{onClick:function(){return L(void 0,void 0,void 0,(function(){var e,t;return M(this,(function(n){switch(n.label){case 0:r(!0),a(void 0),n.label=1;case 1:return n.trys.push([1,3,4,5]),S.trackEvent("excerpt_generator_pressed"),[4,D.getInstance().generateExcerpt(C,T)];case 2:return e=n.sent(),f({currentExcerpt:e,isUnderReview:!0,newExcerptGeneratedCount:h.newExcerptGeneratedCount+1,oldExcerpt:k}),[3,5];case 3:return(t=n.sent())instanceof N?a(t):(a(new N((0,m.__)("An unknown error occurred.","wp-parsely"),b.UnknownError)),console.error(t)),[3,5];case 4:return r(!1),[7];case 5:return[2]}}))}))},variant:"primary",isBusy:t,disabled:t||!T,children:[t&&(0,m.__)("Generating Excerpt…","wp-parsely"),!t&&h.newExcerptGeneratedCount>0&&(0,m.__)("Regenerate Excerpt","wp-parsely"),!t&&0===h.newExcerptGeneratedCount&&(0,m.__)("Generate Excerpt","wp-parsely")]})}),(0,w.jsxs)(v.Button,{href:"https://docs.parse.ly/plugin-content-helper/#h-excerpt-generator-beta",target:"_blank",variant:"link",children:[(0,m.__)("Learn more about Parse.ly AI","wp-parsely"),(0,w.jsx)(v.Icon,{icon:A,size:18,className:"parsely-external-link-icon"})]})]})]})},H=function(){return(0,w.jsx)(v.Animate,{type:"loading",children:function(e){var t=e.className;return(0,w.jsx)("span",{className:t,children:(0,m.__)("Generating…","wp-parsely")})}})},q=function(){return(0,w.jsx)(g.PostTypeSupportCheck,{supportKeys:"excerpt",children:(0,w.jsx)(p,{name:"parsely-post-excerpt",title:(0,m.__)("Excerpt","wp-parsely"),children:(0,w.jsx)(G,{})})})};(0,y.addFilter)("plugins.registerPlugin","wp-parsely-excerpt-generator",(function(e,t){var r,n,o;return"wp-parsely-block-editor-sidebar"!==t||((null===(r=null===window||void 0===window?void 0:window.Jetpack_Editor_Initial_State)||void 0===r?void 0:r.available_blocks["ai-content-lens"])&&(console.log("Parse.ly: Jetpack AI is enabled and will be disabled."),(0,y.removeFilter)("blocks.registerBlockType","jetpack/ai-content-lens-features")),(0,h.registerPlugin)("wp-parsely-excerpt-generator",{render:q}),(null===(n=(0,d.dispatch)("core/editor"))||void 0===n?void 0:n.removeEditorPanel)?null===(o=(0,d.dispatch)("core/editor"))||void 0===o||o.removeEditorPanel("post-excerpt"):null==f||f.removeEditorPanel("post-excerpt")),e}),1e3)}()}(); \ No newline at end of file diff --git a/src/@types/gutenberg/wrapper.ts b/src/@types/gutenberg/wrapper.ts new file mode 100644 index 000000000..6f320c5d1 --- /dev/null +++ b/src/@types/gutenberg/wrapper.ts @@ -0,0 +1,40 @@ +/** + * This file is used to wrap original Gutenberg components to avoid TypeScript errors. + * + * The original Gutenberg components are imported conditionally based on the environment. + * This is needed since these Gutenberg components have changed their location to a different package in WordPress 6.6. + * + * @since 3.17.0 + * + * @see https://make.wordpress.org/core/2024/06/18/editor-unified-extensibility-apis-in-6-6/ + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +import type { ComponentType } from 'react'; + +// Import the original Gutenberg components. +import { + PluginDocumentSettingPanel as OriginalPluginDocumentSettingPanel, + PluginSidebar as OriginalPluginSidebar, +} from '@wordpress/edit-post'; + +// Define the types for the props of the original Gutenberg components. +type PluginDocumentSettingPanelProps = React.ComponentProps; +type PluginSidebarProps = React.ComponentProps; + +// Define the types for the original Gutenberg components. +let PluginDocumentSettingPanel: ComponentType; +let PluginSidebar: ComponentType; + +// Use the correct Gutenberg components based on the environment. +if ( typeof window.wp !== 'undefined' ) { + PluginDocumentSettingPanel = window.wp.editor?.PluginDocumentSettingPanel ?? + ( window.wp.editPost?.PluginDocumentSettingPanel ?? window.wp.editSite?.PluginDocumentSettingPanel ); + PluginSidebar = window.wp.editor?.PluginSidebar ?? + ( window.wp.editPost?.PluginSidebar ?? window.wp.editSite?.PluginSidebar ); +} + +// Export the wrapped Gutenberg components. +export { + PluginDocumentSettingPanel, + PluginSidebar, +}; diff --git a/src/content-helper/editor-sidebar/editor-sidebar.tsx b/src/content-helper/editor-sidebar/editor-sidebar.tsx index 944c8b62c..f3e36d922 100644 --- a/src/content-helper/editor-sidebar/editor-sidebar.tsx +++ b/src/content-helper/editor-sidebar/editor-sidebar.tsx @@ -7,7 +7,7 @@ import { } from '@wordpress/components'; import { useSelect } from '@wordpress/data'; import domReady from '@wordpress/dom-ready'; -import { PluginSidebar } from '@wordpress/edit-post'; +import { PluginSidebar } from '../../@types/gutenberg/wrapper'; import { useEffect } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { chartBar as ChartIcon } from '@wordpress/icons'; @@ -186,6 +186,15 @@ const ContentHelperEditorSidebar = (): React.JSX.Element => { * @since 3.12.0 */ const activeComplementaryArea = useSelect( ( select ) => { + // By checking for the PluginSidebar, we can determine if the new unified editor is being used, and that the + // WordPress version is 6.6 or higher. + if ( window.wp.editor?.PluginSidebar ) { + // @ts-ignore getActiveComplementaryArea exists in the interface store. + return select( 'core/interface' ).getActiveComplementaryArea( 'core' ); + } + + // Fallback for WordPress <= 6.5. + // See https://make.wordpress.org/core/2024/03/05/unification-of-the-site-and-post-editors-in-6-5/ // @ts-ignore getActiveComplementaryArea exists in the interface store. return select( 'core/interface' ).getActiveComplementaryArea( 'core/edit-post' ); }, [ ] ); diff --git a/src/content-helper/excerpt-generator/components/excerpt-panel.tsx b/src/content-helper/excerpt-generator/components/excerpt-panel.tsx index 081d1c728..efa459b35 100644 --- a/src/content-helper/excerpt-generator/components/excerpt-panel.tsx +++ b/src/content-helper/excerpt-generator/components/excerpt-panel.tsx @@ -9,8 +9,8 @@ import { TextareaControl, } from '@wordpress/components'; import { useDispatch, useSelect } from '@wordpress/data'; -import { PluginDocumentSettingPanel } from '@wordpress/edit-post'; import { PostTypeSupportCheck, store as editorStore } from '@wordpress/editor'; +import { PluginDocumentSettingPanel } from '../../../@types/gutenberg/wrapper'; import { useEffect, useState } from '@wordpress/element'; import { __, _n, sprintf } from '@wordpress/i18n'; import { count } from '@wordpress/wordcount'; From 4b02bf897473a20792405dc1082301fe24f86835 Mon Sep 17 00:00:00 2001 From: Alex Cicovic <23142906+acicovic@users.noreply.github.com> Date: Fri, 26 Jul 2024 12:06:59 +0300 Subject: [PATCH 007/282] Add Excerpt Suggestions integration tests --- .../ContentHelperExcerptSuggestionsTest.php | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 tests/Integration/content-helper/ContentHelperExcerptSuggestionsTest.php diff --git a/tests/Integration/content-helper/ContentHelperExcerptSuggestionsTest.php b/tests/Integration/content-helper/ContentHelperExcerptSuggestionsTest.php new file mode 100644 index 000000000..719666ea7 --- /dev/null +++ b/tests/Integration/content-helper/ContentHelperExcerptSuggestionsTest.php @@ -0,0 +1,84 @@ + $additional_args Any required additional arguments. + */ + protected function assert_enqueued_status( + $global_filter_value, + $feature_filter_value, + bool $expected, + string $user_login, + string $user_role, + array $additional_args = array() + ): void { + parent::assert_enqueued_status_default( + new Excerpt_Generator( new Parsely() ), + $global_filter_value, + $feature_filter_value, + $expected, + $user_login, + $user_role + ); + } + + /** + * Verifies that by default, the run() method does not enqueue the assets + * when the current user isn't an administrator. + * + * @since 3.17.0 + * + * @covers \Parsely\Content_Helper\Content_Helper_Feature::can_enable_feature + * @covers \Parsely\Content_Helper\Excerpt_Generator::run + * @covers \Parsely\Permissions::current_user_can_use_pch_feature + * @covers \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\Content_Helper\Content_Helper_Feature::get_global_filter_name + * @uses \Parsely\Content_Helper\Excerpt_Generator::__construct + * @uses \Parsely\Content_Helper\Excerpt_Generator::can_enable_feature + * @uses \Parsely\Content_Helper\Excerpt_Generator::get_feature_filter_name + * @uses \Parsely\Content_Helper\Excerpt_Generator::get_script_id + * @uses \Parsely\Content_Helper\Excerpt_Generator::get_style_id + * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests + * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::set_default_track_as_values + * @uses \Parsely\Parsely::set_managed_options + */ + public function test_assets_do_not_get_enqueued_by_default_for_non_admin_users(): void { + $this->assert_enqueued_status( + null, + null, + false, + 'test_editor', + 'editor' + ); + } +} From d0a9d89fc3b91233f5b349484e607130230a8145 Mon Sep 17 00:00:00 2001 From: Alex Cicovic <23142906+acicovic@users.noreply.github.com> Date: Fri, 26 Jul 2024 14:58:38 +0300 Subject: [PATCH 008/282] Add Content Helper options integration tests --- tests/Integration/OptionsTest.php | 109 ++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/tests/Integration/OptionsTest.php b/tests/Integration/OptionsTest.php index a454b122b..9b6a02ffd 100644 --- a/tests/Integration/OptionsTest.php +++ b/tests/Integration/OptionsTest.php @@ -10,6 +10,7 @@ namespace Parsely\Tests\Integration; use Parsely\Parsely; +use Parsely\Permissions; /** * Integration Tests for plugin options. @@ -554,4 +555,112 @@ function () { self::assertSame( 'json_ld', $options['meta_type'] ); self::assertSame( false, $options['use_top_level_cats'] ); } + + /** + * Verifies that default Content Helper permission options are set as + * expected when we have a new plugin installation. + * + * In this case, the default Content Helper options should give AI feature + * access to administrators only. This is the default behavior for plugin + * versions 3.16.0 and newer. + * + * @since 3.17.0 + * + * @covers \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests + * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::set_default_track_as_values + * @uses \Parsely\Parsely::set_managed_options + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + */ + public function test_content_helper_options_in_a_new_plugin_install(): void { + delete_option( Parsely::OPTIONS_KEY ); + + $expected = Permissions::build_pch_permissions_settings_array( + true, + array( 'administrator' ) + ); + + self::assertSame( + $expected, + ( new Parsely() )->get_options()['content_helper'] + ); + } + + /** + * Verifies that default Content Helper permission options are set as + * expected when an existing plugin install does not have any Content Helper + * options (first run after upgrading to 3.16.0 or newer). + * + * In this case, the Content Helper permission options should be based on + * the edit_posts capability, to keep the behavior consistent with plugin + * versions prior to 3.16.0. + * + * @since 3.17.0 + * + * @covers \Parsely\Parsely::get_options + * @covers \Parsely\Parsely::set_default_content_helper_settings_values + * @covers \Parsely\Permissions::build_pch_permissions_settings_array + * @covers \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests + * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::set_default_track_as_values + * @uses \Parsely\Parsely::set_managed_options + */ + public function test_content_helper_options_in_existing_plugin_install_first_run(): void { + $options = ( new Parsely() )->get_options(); + unset( $options['content_helper'] ); + add_option( Parsely::OPTIONS_KEY, $options ); + + $expected = Permissions::build_pch_permissions_settings_array( + true, + array_keys( Permissions::get_user_roles_with_edit_posts_cap() ) + ); + + self::assertSame( + $expected, + ( new Parsely() )->get_options()['content_helper'] + ); + } + + /** + * Verifies that Content Helper options are as expected when we have an + * existing plugin installation with Content Helper options set. + * + * In this case, the options should be the ones fetched from the database, + * not being overwritten by any defaults. + * + * @since 3.17.0 + * + * @covers \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests + * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::set_default_track_as_values + * @uses \Parsely\Parsely::set_managed_options + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + */ + public function test_content_helper_options_in_existing_plugin_install_subsequent_runs(): void { + $options = ( new Parsely() )->get_options(); + $expected = Permissions::build_pch_permissions_settings_array( + true, + array( 'administrator', 'editor' ) + ); + + $options['content_helper'] = $expected; + add_option( Parsely::OPTIONS_KEY, $options ); + + self::assertSame( + $expected, + ( new Parsely() )->get_options()['content_helper'] + ); + } } From 8d5c411311924d80ecf4970e31b6674d56832910 Mon Sep 17 00:00:00 2001 From: Alex Cicovic <23142906+acicovic@users.noreply.github.com> Date: Tue, 30 Jul 2024 11:58:07 +0300 Subject: [PATCH 009/282] Fix PHPStan error --- src/Endpoints/class-base-api-proxy.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Endpoints/class-base-api-proxy.php b/src/Endpoints/class-base-api-proxy.php index 7faaac4f3..1c144010f 100644 --- a/src/Endpoints/class-base-api-proxy.php +++ b/src/Endpoints/class-base-api-proxy.php @@ -155,7 +155,7 @@ protected function get_data( WP_REST_Request $request, bool $require_api_secret } // A proxy with caching behavior is used here. - $response = $this->api->get_items( $params ); // @phpstan-ignore-line. + $response = $this->api->get_items( $params ); if ( is_wp_error( $response ) ) { return $response; From 92a0d957705236a227621af980c5ef3c64bdb435 Mon Sep 17 00:00:00 2001 From: Henrique Mouta Date: Thu, 8 Aug 2024 15:45:16 +0100 Subject: [PATCH 010/282] Use Composer autoloader (#2621) * Reorganize tests to be PSR4 compliant * Remove unnecessary imports * Enable composer autoload for the source files * Require utils file in the tests bootstrap file * Move the add_action/add_filter to be before the docblock * Make `ContentHelperExcerptSuggestionsTest` PSR-4 compliant * Refactor utils to be a class and autoloaded * `require_once` instead of `require` * Add `gen-autoload` composer command * class-tracks.php: Remove needless use declarations --------- Co-authored-by: Alex Cicovic <23142906+acicovic@users.noreply.github.com> --- .github/workflows/deploy.yml | 1 + .github/workflows/e2e-tests.yml | 3 + composer.json | 11 +- src/Endpoints/class-base-api-proxy.php | 14 +- src/Endpoints/class-base-endpoint.php | 9 +- .../class-referrers-post-detail-api-proxy.php | 7 +- src/Metadata/class-author-archive-builder.php | 5 +- src/Metadata/class-date-builder.php | 7 +- src/Metadata/class-metadata-builder.php | 7 +- src/Metadata/class-page-for-posts-builder.php | 4 +- src/RemoteAPI/class-base-endpoint-remote.php | 5 +- src/RemoteAPI/class-validate-api.php | 5 +- src/Telemetry/Tracks/class-tracks-event.php | 4 +- src/Telemetry/Tracks/class-tracks-pixel.php | 4 +- src/Telemetry/Tracks/class-tracks.php | 3 - src/Telemetry/class-telemetry-system.php | 4 +- src/UI/class-recommended-widget.php | 5 +- src/UI/class-settings-page.php | 5 +- src/Utils/class-utils.php | 410 ++++++++++++++++++ src/Utils/utils.php | 387 ----------------- src/class-metadata.php | 10 +- src/class-parsely.php | 3 +- src/class-scripts.php | 4 +- .../class-dashboard-widget.php | 4 +- .../editor-sidebar/class-editor-sidebar.php | 4 +- .../class-excerpt-generator.php | 4 +- .../post-list-stats/class-post-list-stats.php | 20 +- .../Blocks/RecommendationsBlockTest.php | 2 +- .../ContentHelperDashboardWidgetTest.php | 10 +- .../ContentHelperEditorSidebarTest.php | 2 +- .../ContentHelperExcerptSuggestionsTest.php | 2 +- .../ContentHelperFeatureTest.php | 60 +-- .../ContentHelperPostListStatsTest.php | 7 +- .../AnalyticsPostsProxyEndpointTest.php | 10 +- .../Proxy/BaseProxyEndpointTest.php} | 5 +- .../ReferrersPostDetailProxyEndpointTest.php | 5 +- .../{ => Proxy}/RelatedProxyEndpointTest.php | 5 +- .../StatsPostDetailProxyEndpointTest.php | 7 +- .../UserMeta}/BaseUserMetaEndpointTest.php | 5 +- .../DashboardWidgetSettingsEndpointTest.php | 16 +- .../EditorSidebarSettingsEndpointTest.php | 18 +- .../Metadata/AuthorArchiveTest.php | 2 +- .../Integration/Metadata/BlogArchiveTest.php | 13 +- .../Metadata/CustomPostTypeArchiveTest.php | 2 +- .../CustomTaxonomyTermArchiveTest.php | 2 +- .../Integration/Metadata/DateArchiveTest.php | 2 +- .../Metadata/GetCurrentUrlTest.php | 3 +- tests/Integration/Metadata/HomePageTest.php | 2 +- .../Integration/Metadata/NonPostTestCase.php | 2 +- tests/Integration/Metadata/SinglePageTest.php | 20 +- tests/Integration/Metadata/SinglePostTest.php | 7 +- .../Integration/Metadata/TermArchiveTest.php | 2 +- .../RemoteAPI/AnalyticsPostsRemoteAPITest.php | 10 +- .../BaseRemoteAPITest.php} | 7 +- .../BaseContentSuggestionsAPITest.php | 4 +- .../SuggestBriefAPITest.php | 0 .../SuggestHeadlineAPITest.php | 0 .../SuggestLinkedReferenceAPITest.php | 0 .../RemoteAPI/RelatedRemoteAPITest.php | 4 +- tests/Integration/ScriptsTest.php | 5 +- tests/Integration/TestCase.php | 15 +- tests/Integration/bootstrap.php | 5 - .../TestsReflection.php} | 4 +- tests/Unit/Utils/UtilsTest.php | 32 +- tests/Unit/bootstrap.php | 1 - wp-parsely.php | 95 +--- 66 files changed, 631 insertions(+), 711 deletions(-) create mode 100644 src/Utils/class-utils.php delete mode 100644 src/Utils/utils.php rename tests/Integration/{content-helper => ContentHelper}/ContentHelperDashboardWidgetTest.php (94%) rename tests/Integration/{content-helper => ContentHelper}/ContentHelperEditorSidebarTest.php (96%) rename tests/Integration/{content-helper => ContentHelper}/ContentHelperExcerptSuggestionsTest.php (98%) rename tests/Integration/{ => ContentHelper}/ContentHelperFeatureTest.php (96%) rename tests/Integration/{content-helper => ContentHelper}/ContentHelperPostListStatsTest.php (99%) rename tests/Integration/Endpoints/{ => Proxy}/AnalyticsPostsProxyEndpointTest.php (97%) rename tests/Integration/{ProxyEndpointTest.php => Endpoints/Proxy/BaseProxyEndpointTest.php} (97%) rename tests/Integration/Endpoints/{ => Proxy}/ReferrersPostDetailProxyEndpointTest.php (98%) rename tests/Integration/Endpoints/{ => Proxy}/RelatedProxyEndpointTest.php (96%) rename tests/Integration/Endpoints/{ => Proxy}/StatsPostDetailProxyEndpointTest.php (97%) rename tests/Integration/{ => Endpoints/UserMeta}/BaseUserMetaEndpointTest.php (95%) rename tests/Integration/Endpoints/{ => UserMeta}/DashboardWidgetSettingsEndpointTest.php (94%) rename tests/Integration/Endpoints/{ => UserMeta}/EditorSidebarSettingsEndpointTest.php (95%) rename tests/Integration/{RemoteAPITest.php => RemoteAPI/BaseRemoteAPITest.php} (97%) rename tests/Integration/RemoteAPI/{content-suggestions => ContentSuggestions}/BaseContentSuggestionsAPITest.php (96%) rename tests/Integration/RemoteAPI/{content-suggestions => ContentSuggestions}/SuggestBriefAPITest.php (100%) rename tests/Integration/RemoteAPI/{content-suggestions => ContentSuggestions}/SuggestHeadlineAPITest.php (100%) rename tests/Integration/RemoteAPI/{content-suggestions => ContentSuggestions}/SuggestLinkedReferenceAPITest.php (100%) rename tests/{trait-tests-reflection.php => Traits/TestsReflection.php} (96%) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index ca3d7f89a..d9b42ffb0 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -10,6 +10,7 @@ jobs: run: | npm ci npm run build + composer dump-autoload --classmap-authoritative - name: WordPress Plugin Deploy uses: 10up/action-wordpress-plugin-deploy@stable env: diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 067b83af5..099f295ff 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -23,6 +23,9 @@ jobs: - name: Checkout code uses: actions/checkout@v4 + - name: Refresh Composer autoload files + run: composer dump-autoload --classmap-authoritative + - name: Use desired version of NodeJS uses: actions/setup-node@v4.0.3 with: diff --git a/composer.json b/composer.json index 19166b64d..c701ba2f7 100644 --- a/composer.json +++ b/composer.json @@ -42,9 +42,6 @@ "autoload": { "classmap": [ "src/" - ], - "files": [ - "wp-parsely.php" ] }, "autoload-dev": { @@ -88,7 +85,7 @@ "@php ./vendor/bin/phpunit --no-coverage --order-by=random" ], "static-analysis": [ - "@php ./vendor/bin/phpstan analyze --memory-limit 1074000000" + "@php ./vendor/bin/phpstan analyze --memory-limit=2G" ], "test-ms": [ "@putenv WP_MULTISITE=1", @@ -103,6 +100,9 @@ "testwp-ms": [ "@putenv WP_MULTISITE=1", "@composer testwp" + ], + "gen-autoload": [ + "@composer dump-autoload --classmap-authoritative" ] }, "scripts-descriptions": { @@ -118,6 +118,7 @@ "test": "Run the unit tests for the Parse.ly plugin.", "test-ms": "Run the unit tests for the Parse.ly plugin on a multisite install.", "testwp": "Run the integration tests for the Parse.ly plugin.", - "testwp-ms": "Run the integration tests for the Parse.ly plugin on a multisite install." + "testwp-ms": "Run the integration tests for the Parse.ly plugin on a multisite install.", + "gen-autoload": "Generates the autoload class map with authoritative class maps." } } diff --git a/src/Endpoints/class-base-api-proxy.php b/src/Endpoints/class-base-api-proxy.php index 1c144010f..627543128 100644 --- a/src/Endpoints/class-base-api-proxy.php +++ b/src/Endpoints/class-base-api-proxy.php @@ -12,16 +12,12 @@ use Parsely\Parsely; use Parsely\RemoteAPI\Remote_API_Interface; +use Parsely\Utils\Utils; use stdClass; use WP_Error; use WP_REST_Request; use WP_REST_Server; -use function Parsely\Utils\convert_endpoint_to_filter_key; -use function Parsely\Utils\get_date_format; -use function Parsely\Utils\get_formatted_duration; -use function Parsely\Utils\parsely_is_https_supported; - /** * Configures a REST API endpoint for use. */ @@ -98,7 +94,7 @@ public function __construct( Parsely $parsely, Remote_API_Interface $api ) { * @param array $methods The HTTP methods to use for the endpoint. */ protected function register_endpoint( string $endpoint, array $methods = array( WP_REST_Server::READABLE ) ): void { - if ( ! apply_filters( 'wp_parsely_enable_' . convert_endpoint_to_filter_key( $endpoint ) . '_api_proxy', true ) ) { + if ( ! apply_filters( 'wp_parsely_enable_' . Utils::convert_endpoint_to_filter_key( $endpoint ) . '_api_proxy', true ) ) { return; } @@ -224,11 +220,11 @@ protected function extract_post_data( stdClass $item ): array { // endpoint and passed sort/url parameters. $avg_engaged = $item->metrics->avg_engaged ?? $item->avg_engaged ?? null; if ( null !== $avg_engaged ) { - $data['avgEngaged'] = get_formatted_duration( (float) $avg_engaged ); + $data['avgEngaged'] = Utils::get_formatted_duration( (float) $avg_engaged ); } if ( isset( $item->pub_date ) ) { - $data['date'] = wp_date( get_date_format(), strtotime( $item->pub_date ) ); + $data['date'] = wp_date( Utils::get_date_format(), strtotime( $item->pub_date ) ); } if ( isset( $item->title ) ) { @@ -241,7 +237,7 @@ protected function extract_post_data( stdClass $item ): array { $post_id = url_to_postid( $item->url ); // 0 if the post cannot be found. $post_url = Parsely::get_url_with_itm_source( $item->url, null ); - if ( parsely_is_https_supported() ) { + if ( Utils::parsely_is_https_supported() ) { $post_url = str_replace( 'http://', 'https://', $post_url ); } diff --git a/src/Endpoints/class-base-endpoint.php b/src/Endpoints/class-base-endpoint.php index a24c6f7de..d9e18812c 100644 --- a/src/Endpoints/class-base-endpoint.php +++ b/src/Endpoints/class-base-endpoint.php @@ -11,10 +11,9 @@ namespace Parsely\Endpoints; use Parsely\Parsely; +use Parsely\Utils\Utils; use WP_REST_Request; -use function Parsely\Utils\convert_endpoint_to_filter_key; - /** * Base class for API endpoints. * @@ -108,7 +107,7 @@ protected function apply_capability_filters( string $capability ): string { * @var string */ $endpoint_specific_user_capability = apply_filters( - 'wp_parsely_user_capability_for_' . convert_endpoint_to_filter_key( static::ENDPOINT ) . '_api', + 'wp_parsely_user_capability_for_' . Utils::convert_endpoint_to_filter_key( static::ENDPOINT ) . '_api', $default_user_capability ); @@ -129,7 +128,7 @@ public function register_endpoint( string $callback, array $methods = array( 'GET' ) ): void { - if ( ! apply_filters( 'wp_parsely_enable_' . convert_endpoint_to_filter_key( $endpoint ) . '_api_proxy', true ) ) { + if ( ! apply_filters( 'wp_parsely_enable_' . Utils::convert_endpoint_to_filter_key( $endpoint ) . '_api_proxy', true ) ) { return; } @@ -176,7 +175,7 @@ public function register_endpoint_with_args( array $methods = array( 'GET' ), array $args = array() ): void { - if ( ! apply_filters( 'wp_parsely_enable_' . convert_endpoint_to_filter_key( $endpoint ) . '_api_proxy', true ) ) { + if ( ! apply_filters( 'wp_parsely_enable_' . Utils::convert_endpoint_to_filter_key( $endpoint ) . '_api_proxy', true ) ) { return; } diff --git a/src/Endpoints/class-referrers-post-detail-api-proxy.php b/src/Endpoints/class-referrers-post-detail-api-proxy.php index d778db460..812a9ca81 100644 --- a/src/Endpoints/class-referrers-post-detail-api-proxy.php +++ b/src/Endpoints/class-referrers-post-detail-api-proxy.php @@ -10,12 +10,11 @@ namespace Parsely\Endpoints; +use Parsely\Utils\Utils; use stdClass; use WP_REST_Request; use WP_Error; -use function Parsely\Utils\convert_to_positive_integer; - /** * Configures the `/referrers/post/detail` REST API endpoint. * @@ -53,7 +52,7 @@ public function get_items( WP_REST_Request $request ) { $total_views = '0'; } - $this->total_views = convert_to_positive_integer( $total_views ); + $this->total_views = Utils::convert_to_positive_integer( $total_views ); $request->offsetUnset( 'total_views' ); // Remove param from request. return $this->get_data( $request ); } @@ -68,7 +67,7 @@ public function get_items( WP_REST_Request $request ) { */ protected function generate_data( $response ): array { $referrers_types = $this->generate_referrer_types_data( $response ); - $direct_views = convert_to_positive_integer( + $direct_views = Utils::convert_to_positive_integer( $referrers_types->direct->views ?? '0' ); $referrers_top = $this->generate_referrers_data( 5, $response, $direct_views ); diff --git a/src/Metadata/class-author-archive-builder.php b/src/Metadata/class-author-archive-builder.php index 0c2d4bc6c..9e66f1b47 100644 --- a/src/Metadata/class-author-archive-builder.php +++ b/src/Metadata/class-author-archive-builder.php @@ -10,11 +10,10 @@ namespace Parsely\Metadata; +use Parsely\Utils\Utils; use WP_User; use stdClass; -use function Parsely\Utils\get_string_query_var; - /** * Implements abstract Metadata Builder class to generate the metadata array * for an author archive page. @@ -46,7 +45,7 @@ public function get_metadata(): array { */ private function build_headline(): void { // Use the author's username as a display name fallback. - $author_username = get_string_query_var( 'author_name' ); + $author_username = Utils::get_string_query_var( 'author_name' ); $author_display_name = $author_username; // Attempt to get the author from the Co-Authors Plus plugin or from diff --git a/src/Metadata/class-date-builder.php b/src/Metadata/class-date-builder.php index 7eac9fa04..2b2c4bafd 100644 --- a/src/Metadata/class-date-builder.php +++ b/src/Metadata/class-date-builder.php @@ -10,8 +10,7 @@ namespace Parsely\Metadata; -use function Parsely\Utils\get_date_format; -use function Parsely\Utils\get_time_format; +use Parsely\Utils\Utils; /** * Implements abstract Metadata Builder class to generate the metadata array @@ -42,7 +41,7 @@ public function get_metadata(): array { * @since 3.4.0 */ private function build_headline(): void { - $site_date_format = get_date_format(); + $site_date_format = Utils::get_date_format(); if ( is_year() ) { /* translators: %s: Archive year */ @@ -54,7 +53,7 @@ private function build_headline(): void { /* translators: %s: Archive day, formatted as F jS, Y */ $this->metadata['headline'] = sprintf( __( 'Daily Archive - %s', 'wp-parsely' ), get_the_time( $site_date_format ) ); } elseif ( is_time() ) { - $site_time_format = get_time_format(); + $site_time_format = Utils::get_time_format(); /* translators: %s: Archive time, formatted as F jS g:i:s A */ $this->metadata['headline'] = sprintf( __( 'Hourly, Minutely, or Secondly Archive - %s', 'wp-parsely' ), get_the_time( "{$site_date_format} {$site_time_format}" ) ); } diff --git a/src/Metadata/class-metadata-builder.php b/src/Metadata/class-metadata-builder.php index 3b842b313..99959862f 100644 --- a/src/Metadata/class-metadata-builder.php +++ b/src/Metadata/class-metadata-builder.php @@ -11,11 +11,10 @@ namespace Parsely\Metadata; use Parsely\Parsely; +use Parsely\Utils\Utils; use WP_Post; use WP_User; -use function Parsely\Utils\get_default_category; - /** * Abstract class that implements modular builders for Metadata. * @@ -366,7 +365,7 @@ private function get_category_name( WP_Post $post_obj, $parsely_options ): strin // Get top-level taxonomy name for chosen taxonomy and assign to $parent_name; it will be used // as the category value if 'use_top_level_cats' option is checked. // Assign as the default category name if no value is checked for the chosen taxonomy. - $category_name = get_cat_name( get_default_category() ); + $category_name = get_cat_name( Utils::get_default_category() ); if ( false !== $taxonomy_dropdown_choice && ! is_wp_error( $taxonomy_dropdown_choice ) ) { if ( $parsely_options['use_top_level_cats'] ) { $first_term = array_shift( $taxonomy_dropdown_choice ); @@ -645,7 +644,7 @@ private function get_categories( int $post_id, string $delimiter = '/' ): array } // Remove default category name from tags if needed. - $default_category_name = get_cat_name( get_default_category() ); + $default_category_name = get_cat_name( Utils::get_default_category() ); return array_diff( $tags, array( $default_category_name ) ); } diff --git a/src/Metadata/class-page-for-posts-builder.php b/src/Metadata/class-page-for-posts-builder.php index 7a4363d40..2ec8460ab 100644 --- a/src/Metadata/class-page-for-posts-builder.php +++ b/src/Metadata/class-page-for-posts-builder.php @@ -10,7 +10,7 @@ namespace Parsely\Metadata; -use function Parsely\Utils\get_page_for_posts; +use Parsely\Utils\Utils; /** * Implements abstract Metadata Builder class to generate the metadata array @@ -41,6 +41,6 @@ public function get_metadata(): array { * @since 3.4.0 */ private function build_headline(): void { - $this->metadata['headline'] = get_the_title( get_page_for_posts( true ) ); + $this->metadata['headline'] = get_the_title( Utils::get_page_for_posts( true ) ); } } diff --git a/src/RemoteAPI/class-base-endpoint-remote.php b/src/RemoteAPI/class-base-endpoint-remote.php index ba922562f..334f38e0d 100644 --- a/src/RemoteAPI/class-base-endpoint-remote.php +++ b/src/RemoteAPI/class-base-endpoint-remote.php @@ -12,11 +12,10 @@ use Parsely\Endpoints\Base_Endpoint; use Parsely\Parsely; +use Parsely\Utils\Utils; use UnexpectedValueException; use WP_Error; -use function Parsely\Utils\convert_to_associative_array; - /** * Base class for remote API endpoints. * @@ -118,7 +117,7 @@ public function get_items( array $query, bool $associative = false ) { $data = $decoded->data; - return $associative ? convert_to_associative_array( $data ) : $data; + return $associative ? Utils::convert_to_associative_array( $data ) : $data; } /** diff --git a/src/RemoteAPI/class-validate-api.php b/src/RemoteAPI/class-validate-api.php index 9f5b6b3be..2fb0674e7 100644 --- a/src/RemoteAPI/class-validate-api.php +++ b/src/RemoteAPI/class-validate-api.php @@ -12,11 +12,10 @@ use Parsely\Endpoints\Base_Endpoint; use Parsely\Parsely; +use Parsely\Utils\Utils; use WP_Error; use WP_REST_Request; -use function Parsely\Utils\convert_to_associative_array; - /** * Class for credentials validation API (`/validate`). * @@ -120,6 +119,6 @@ private function api_validate_credentials( array $query ) { */ public function get_items( array $query, bool $associative = false ) { $api_request = $this->api_validate_credentials( $query ); - return $associative ? convert_to_associative_array( $api_request ) : $api_request; + return $associative ? Utils::convert_to_associative_array( $api_request ) : $api_request; } } diff --git a/src/Telemetry/Tracks/class-tracks-event.php b/src/Telemetry/Tracks/class-tracks-event.php index ffb1df71a..f093508fb 100644 --- a/src/Telemetry/Tracks/class-tracks-event.php +++ b/src/Telemetry/Tracks/class-tracks-event.php @@ -10,10 +10,10 @@ namespace Parsely\Telemetry; +use Parsely\Utils\Utils; use stdClass; use WP_Error; -use function Parsely\Utils\get_timestamp; use const Parsely\PARSELY_VERSION; /** @@ -122,7 +122,7 @@ protected static function process_properties( // Set event timestamp. if ( ! isset( $event->_ts ) ) { - $event->_ts = get_timestamp(); + $event->_ts = Utils::get_timestamp(); } // Remove non-routable IPs to prevent record from being discarded. diff --git a/src/Telemetry/Tracks/class-tracks-pixel.php b/src/Telemetry/Tracks/class-tracks-pixel.php index 771da8da7..619d420a8 100644 --- a/src/Telemetry/Tracks/class-tracks-pixel.php +++ b/src/Telemetry/Tracks/class-tracks-pixel.php @@ -10,9 +10,9 @@ namespace Parsely\Telemetry; +use Parsely\Utils\Utils; use WP_Error; -use function Parsely\Utils\get_timestamp; /** * Handles all operations related to the Tracks pixel. @@ -118,7 +118,7 @@ public function record_event_synchronously( Tracks_Event $event ) { // Add the Request Timestamp and URL terminator just before the HTTP // request. - $pixel_url .= '&_rt=' . get_timestamp() . '&_=_'; + $pixel_url .= '&_rt=' . Utils::get_timestamp() . '&_=_'; $request = wp_safe_remote_get( $pixel_url, diff --git a/src/Telemetry/Tracks/class-tracks.php b/src/Telemetry/Tracks/class-tracks.php index d4660d7b3..ec3865322 100644 --- a/src/Telemetry/Tracks/class-tracks.php +++ b/src/Telemetry/Tracks/class-tracks.php @@ -11,9 +11,6 @@ namespace Parsely\Telemetry; use WP_Error; -use function Parsely\Utils\get_asset_info; -use const Parsely\PARSELY_FILE; -use const Parsely\PARSELY_VERSION; /** * This class comprises the mechanics of sending events to the Automattic Tracks diff --git a/src/Telemetry/class-telemetry-system.php b/src/Telemetry/class-telemetry-system.php index b9eb7030e..2ae29d32c 100644 --- a/src/Telemetry/class-telemetry-system.php +++ b/src/Telemetry/class-telemetry-system.php @@ -10,8 +10,8 @@ namespace Parsely\Telemetry; +use Parsely\Utils\Utils; use WP_Error; -use function Parsely\Utils\get_asset_info; use const Parsely\PARSELY_FILE; use const Parsely\PARSELY_VERSION; @@ -103,7 +103,7 @@ public static function init_js_tracking(): void { add_action( 'admin_enqueue_scripts', function (): void { - $asset_php = get_asset_info( 'build/telemetry.asset.php' ); + $asset_php = Utils::get_asset_info( 'build/telemetry.asset.php' ); $built_assets_url = plugin_dir_url( PARSELY_FILE ) . 'build/'; // The Telemetry script is always enqueued in the admin. diff --git a/src/UI/class-recommended-widget.php b/src/UI/class-recommended-widget.php index dbfdb560c..b72bd2e5e 100644 --- a/src/UI/class-recommended-widget.php +++ b/src/UI/class-recommended-widget.php @@ -12,10 +12,9 @@ namespace Parsely\UI; use Parsely\Parsely; +use Parsely\Utils\Utils; use WP_Widget; -use function Parsely\Utils\get_asset_info; - use const Parsely\PARSELY_FILE; /** @@ -154,7 +153,7 @@ public function widget( $args, $widget_settings ): void /* @phpstan-ignore-line 'k', + '1000000' => 'M', + '1000000000' => 'B', + '1000000000000' => 'T', + '1000000000000000' => 'Q', + ); + $current_number = $number; + $current_number_as_string = (string) $number; + $unit = ''; + $previous_number = 0; + + foreach ( $unit_names as $thousands => $suffix ) { + $thousands_int = (int) preg_replace( '/\D/', '', (string) $thousands ); + + if ( $number >= $thousands_int ) { + $current_number = $number / $thousands_int; + $precision = $fraction_digits; + + // For over 10 units, we reduce the precision to 1 fraction digit. + $modulo = (int) fmod( $current_number, 1 ); + if ( 0 !== $previous_number && $modulo > 1 / $previous_number ) { + $precision = $current_number > 10 ? 1 : 2; + } + + // Precision override, where we want to show 2 fraction digits. + $zeroes = floatval( number_format( $current_number, 2 ) ) === floatval( number_format( $current_number, 0 ) ); + $precision = $zeroes ? 0 : $precision; + $current_number_as_string = number_format( $current_number, $precision, '.', '' ); + $unit = $suffix; + } + + $previous_number = $current_number; + } + + return $current_number_as_string . $glue . $unit; + } + + /** + * Gets time in formatted form. + * + * Example: + * - Input `1000` (seconds) and Output `16:40` which represents "16 minutes, 40 seconds” + * + * @since 3.7.0 + * + * @param float $seconds Time in seconds to be formatted. + * + * @return string + */ + public static function get_formatted_time( $seconds ): string { + $seconds = round( $seconds ); + $hours = floor( $seconds / 3600 ); + + if ( $hours >= 1 ) { + $seconds = $seconds - ( $hours * 3600 ); + $minutes = floor( $seconds / 60 ); + $seconds = round( $seconds % 60 ); + + return esc_html( + sprintf( + /* translators: 1: Number of hours 2: Number of minutes 3: Number of seconds */ + __( '%1$d:%2$02d:%3$02d', 'wp-parsely' ), + $hours, + $minutes, + $seconds + ) + ); + } + + $minutes = floor( $seconds / 60 ); + $seconds = round( $seconds % 60 ); + + if ( $minutes >= 1 ) { + return esc_html( + sprintf( + /* translators: 1: Number of minutes 2: Number of seconds */ + __( '%1$d:%2$02d', 'wp-parsely' ), + $minutes, + $seconds + ) + ); + } + + return esc_html( + sprintf( + /* translators: 1: Number of seconds */ + __( '%1$d sec.', 'wp-parsely' ), + round( $seconds ) + ) + ); + } + + /** + * Returns the passed float as a time duration in m:ss format. + * + * Examples: + * - $time of 1.005 yields '1:00'. + * - $time of 1.5 yields '1:30'. + * - $time of 1.999 yields '2:00'. + * + * @since 3.6.0 + * + * @param float $time The time as a float number. + * + * @return string The resulting formatted time duration. + */ + public static function get_formatted_duration( float $time ): string { + $minutes = absint( $time ); + $seconds = absint( round( fmod( $time, 1 ) * 60 ) ); + + if ( 60 === $seconds ) { + ++$minutes; + $seconds = 0; + } + + return sprintf( '%d:%02d', $minutes, $seconds ); + } + + /** + * Converts to associate array. + * + * @since 3.7.0 + * + * @param mixed $obj Input object. + * + * @return array|WP_Error + */ + public static function convert_to_associative_array( $obj ) { + $encoded = wp_json_encode( $obj ); + if ( false === $encoded ) { + return new WP_Error( 'parsely_encoding_failed', __( 'Unable to encode API response for associative array', 'wp-parsely' ) ); + } + + /** + * Variable. + * + * @var array + */ + return json_decode( $encoded, true ); + } + + /** + * Converts a string to a positive integer, removing any non-numeric + * characters. + * + * @param string $value The string to be converted to an integer. + * @return int The integer resulting from the conversion. + */ + public static function convert_to_positive_integer( string $value ): int { + return (int) preg_replace( '/\D/', '', $value ); + } + + /** + * Converts endpoint to filter key by replacing `/` with `_`. + * + * @param string $endpoint Route of the endpoint. + * + * @since 3.7.0 + * + * @return string + */ + public static function convert_endpoint_to_filter_key( string $endpoint ): string { + return trim( str_replace( array( '-', '/' ), '_', $endpoint ), '_' ); + } + + /** + * Gets content of asset file. + * + * @param string $path Path of the asset file. + * + * @since 3.8.0 + * + * @return Asset_Info + */ + public static function get_asset_info( string $path ) { + return require plugin_dir_path( PARSELY_FILE ) . $path; + } + + /** + * Checks if a string starts with a specific substring. + * + * This function uses the built-in PHP function `str_starts_with` if it's available (PHP 8.0 and later). + * If the function is not available (PHP versions prior to 8.0), it uses the `strpos` function as a fallback. + * + * @since 3.13.0 + * + * @param string $haystack The string to search in. + * @param string $needle The substring to search for at the start of $haystack. + * @return bool Returns true if $haystack starts with $needle, false otherwise. + */ + public static function str_starts_with( string $haystack, string $needle ): bool { + if ( function_exists( '\str_starts_with' ) ) { + return \str_starts_with( $haystack, $needle ); + } + return 0 === strpos( $haystack, $needle ); + } + + /** + * Checks if HTTPS is supported for the site. + * + * This function checks if the WordPress function 'wp_is_using_https' exists and uses it to determine if + * HTTPS is supported. + * If the function does not exist, it checks if the home URL scheme is HTTPS. + * If neither of the above conditions are met, it checks if the site URL option scheme is HTTPS. + * + * @since 3.14.1 + * + * @return bool Returns true if HTTPS is supported, false otherwise. + */ + public static function parsely_is_https_supported(): bool { + if ( function_exists( 'wp_is_using_https' ) ) { + return wp_is_using_https(); + } + + if ( 'https' === wp_parse_url( home_url(), PHP_URL_SCHEME ) ) { + return true; + } + + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound + $site_url = apply_filters( 'site_url', get_option( 'siteurl' ), '', null, null ); + return 'https' === wp_parse_url( $site_url, PHP_URL_SCHEME ); + } +} diff --git a/src/Utils/utils.php b/src/Utils/utils.php deleted file mode 100644 index ea99bc96d..000000000 --- a/src/Utils/utils.php +++ /dev/null @@ -1,387 +0,0 @@ - 'k', - '1000000' => 'M', - '1000000000' => 'B', - '1000000000000' => 'T', - '1000000000000000' => 'Q', - ); - $current_number = $number; - $current_number_as_string = (string) $number; - $unit = ''; - $previous_number = 0; - - foreach ( $unit_names as $thousands => $suffix ) { - $thousands_int = (int) preg_replace( '/\D/', '', (string) $thousands ); - - if ( $number >= $thousands_int ) { - $current_number = $number / $thousands_int; - $precision = $fraction_digits; - - // For over 10 units, we reduce the precision to 1 fraction digit. - $modulo = (int) fmod( $current_number, 1 ); - if ( 0 !== $previous_number && $modulo > 1 / $previous_number ) { - $precision = $current_number > 10 ? 1 : 2; - } - - // Precision override, where we want to show 2 fraction digits. - $zeroes = floatval( number_format( $current_number, 2 ) ) === - floatval( number_format( $current_number, 0 ) ); - $precision = $zeroes ? 0 : $precision; - $current_number_as_string = number_format( $current_number, $precision, '.', '' ); - $unit = $suffix; - } - - $previous_number = $current_number; - } - - return $current_number_as_string . $glue . $unit; -} - -/** - * Gets time in formatted form. - * - * Example: - * - Input `1000` (seconds) and Output `16:40` which represents "16 minutes, 40 seconds” - * - * @since 3.7.0 - * - * @param float $seconds Time in seconds to be formatted. - * - * @return string - */ -function get_formatted_time( $seconds ): string { - $seconds = round( $seconds ); - $hours = floor( $seconds / 3600 ); - - if ( $hours >= 1 ) { - $seconds = $seconds - ( $hours * 3600 ); - $minutes = floor( $seconds / 60 ); - $seconds = round( $seconds % 60 ); - - return esc_html( /* translators: 1: Number of hours 2: Number of minutes 3: Number of seconds */ - sprintf( __( '%1$d:%2$02d:%3$02d', 'wp-parsely' ), $hours, $minutes, $seconds ) - ); - } - - $minutes = floor( $seconds / 60 ); - $seconds = round( $seconds % 60 ); - - if ( $minutes >= 1 ) { - return esc_html( /* translators: 1: Number of minutes 2: Number of seconds */ - sprintf( __( '%1$d:%2$02d', 'wp-parsely' ), $minutes, $seconds ) - ); - } - - return esc_html( /* translators: 1: Number of seconds */ - sprintf( __( '%1$d sec.', 'wp-parsely' ), round( $seconds ) ) - ); -} - -/** - * Returns the passed float as a time duration in m:ss format. - * - * Examples: - * - $time of 1.005 yields '1:00'. - * - $time of 1.5 yields '1:30'. - * - $time of 1.999 yields '2:00'. - * - * @since 3.6.0 - * - * @param float $time The time as a float number. - * - * @return string The resulting formatted time duration. - */ -function get_formatted_duration( float $time ): string { - $minutes = absint( $time ); - $seconds = absint( round( fmod( $time, 1 ) * 60 ) ); - - if ( 60 === $seconds ) { - ++$minutes; - $seconds = 0; - } - - return sprintf( '%d:%02d', $minutes, $seconds ); -} - -/** - * Converts to associate array. - * - * @since 3.7.0 - * - * @param mixed $obj Input object. - * - * @return array|WP_Error - */ -function convert_to_associative_array( $obj ) { - $encoded = wp_json_encode( $obj ); - - if ( false === $encoded ) { - return new WP_Error( 'parsely_encoding_failed', __( 'Unable to encode API response for associative array', 'wp-parsely' ) ); - } - - /** - * Variable. - * - * @var array - */ - return json_decode( $encoded, true ); -} - -/** - * Converts a string to a positive integer, removing any non-numeric - * characters. - * - * @param string $value The string to be converted to an integer. - * @return int The integer resulting from the conversion. - */ -function convert_to_positive_integer( string $value ): int { - return (int) preg_replace( '/\D/', '', $value ); -} - -/** - * Converts endpoint to filter key by replacing `/` with `_`. - * - * @param string $endpoint Route of the endpoint. - * - * @since 3.7.0 - * - * @return string - */ -function convert_endpoint_to_filter_key( string $endpoint ): string { - return trim( str_replace( array( '-', '/' ), '_', $endpoint ), '_' ); -} - -/** - * Gets content of asset file. - * - * @param string $path Path of the asset file. - * - * @since 3.8.0 - * - * @return Asset_Info - */ -function get_asset_info( string $path ) { - return require plugin_dir_path( PARSELY_FILE ) . $path; -} - -/** - * Checks if a string starts with a specific substring. - * - * This function uses the built-in PHP function `str_starts_with` if it's available (PHP 8.0 and later). - * If the function is not available (PHP versions prior to 8.0), it uses the `strpos` function as a fallback. - * - * @since 3.13.0 - * - * @param string $haystack The string to search in. - * @param string $needle The substring to search for at the start of $haystack. - * @return bool Returns true if $haystack starts with $needle, false otherwise. - */ -function str_starts_with( string $haystack, string $needle ): bool { - if ( function_exists( '\str_starts_with' ) ) { - return \str_starts_with( $haystack, $needle ); - } - return 0 === strpos( $haystack, $needle ); -} - -/** - * Checks if HTTPS is supported for the site. - * - * This function checks if the WordPress function 'wp_is_using_https' exists and uses it to determine if - * HTTPS is supported. - * If the function does not exist, it checks if the home URL scheme is HTTPS. - * If neither of the above conditions are met, it checks if the site URL option scheme is HTTPS. - * - * @since 3.14.1 - * - * @return bool Returns true if HTTPS is supported, false otherwise. - */ -function parsely_is_https_supported(): bool { - if ( function_exists( 'wp_is_using_https' ) ) { - return wp_is_using_https(); - } - - if ( 'https' === wp_parse_url( home_url(), PHP_URL_SCHEME ) ) { - return true; - } - - // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound - $site_url = apply_filters( 'site_url', get_option( 'siteurl' ), '', null, null ); - return 'https' === wp_parse_url( $site_url, PHP_URL_SCHEME ); -} diff --git a/src/class-metadata.php b/src/class-metadata.php index aa01c22b6..6752ebc58 100644 --- a/src/class-metadata.php +++ b/src/class-metadata.php @@ -19,11 +19,9 @@ use Parsely\Metadata\Paginated_Front_Page_Builder; use Parsely\Metadata\Post_Builder; use Parsely\Metadata\Tag_Builder; +use Parsely\Utils\Utils; use WP_Post; -use function Parsely\Utils\get_page_for_posts; -use function Parsely\Utils\get_page_on_front; - /** * Generates and inserts metadata readable by the Parse.ly Crawler. * @@ -97,12 +95,12 @@ public function construct_metadata( WP_Post $post ): array { } else { $builder = new Paginated_Front_Page_Builder( $this->parsely ); } - } elseif ( 'page' === get_option( 'show_on_front' ) && ! get_page_on_front() ) { + } elseif ( 'page' === get_option( 'show_on_front' ) && ! Utils::get_page_on_front() ) { $builder = new Front_Page_Builder( $this->parsely ); } elseif ( is_home() && ( - ! ( 'page' === get_option( 'show_on_front' ) && ! get_page_on_front() ) || - get_page_for_posts() === $queried_object_id + ! ( 'page' === get_option( 'show_on_front' ) && ! Utils::get_page_on_front() ) || + Utils::get_page_for_posts() === $queried_object_id ) ) { $builder = new Page_For_Posts_Builder( $this->parsely ); diff --git a/src/class-parsely.php b/src/class-parsely.php index 4f60fb7ce..e7c673fed 100644 --- a/src/class-parsely.php +++ b/src/class-parsely.php @@ -12,6 +12,7 @@ use Parsely\UI\Metadata_Renderer; use Parsely\UI\Settings_Page; +use Parsely\Utils\Utils; use WP_Post; /** @@ -946,7 +947,7 @@ private function allow_parsely_remote_requests(): void { function ( $external, $host, $url ) use ( $allowed_urls ) { // Check if the URL matches any URLs on the allowed list. foreach ( $allowed_urls as $allowed_url ) { - if ( \Parsely\Utils\str_starts_with( $url, $allowed_url ) ) { + if ( Utils::str_starts_with( $url, $allowed_url ) ) { return true; } } diff --git a/src/class-scripts.php b/src/class-scripts.php index 385de1233..1b4b9abaf 100644 --- a/src/class-scripts.php +++ b/src/class-scripts.php @@ -10,7 +10,7 @@ namespace Parsely; -use function Parsely\Utils\get_asset_info; +use Parsely\Utils\Utils; /** * Inserts the scripts and tracking code into the site's front-end. @@ -63,7 +63,7 @@ public function register_scripts(): void { true ); - $loader_asset = get_asset_info( 'build/loader.asset.php' ); + $loader_asset = Utils::get_asset_info( 'build/loader.asset.php' ); wp_register_script( 'wp-parsely-loader', diff --git a/src/content-helper/dashboard-widget/class-dashboard-widget.php b/src/content-helper/dashboard-widget/class-dashboard-widget.php index 0e4b042a3..a166adff6 100644 --- a/src/content-helper/dashboard-widget/class-dashboard-widget.php +++ b/src/content-helper/dashboard-widget/class-dashboard-widget.php @@ -14,7 +14,7 @@ use Parsely\Parsely; use Parsely\RemoteAPI\Analytics_Posts_API; -use function Parsely\Utils\get_asset_info; +use Parsely\Utils\Utils; use const Parsely\PARSELY_FILE; @@ -125,7 +125,7 @@ public function enqueue_assets(): void { return; } - $asset_php = get_asset_info( 'build/content-helper/dashboard-widget.asset.php' ); + $asset_php = Utils::get_asset_info( 'build/content-helper/dashboard-widget.asset.php' ); $built_assets_url = plugin_dir_url( PARSELY_FILE ) . 'build/content-helper/'; wp_enqueue_script( diff --git a/src/content-helper/editor-sidebar/class-editor-sidebar.php b/src/content-helper/editor-sidebar/class-editor-sidebar.php index 0d13a5413..9d0accb25 100644 --- a/src/content-helper/editor-sidebar/class-editor-sidebar.php +++ b/src/content-helper/editor-sidebar/class-editor-sidebar.php @@ -16,8 +16,8 @@ use Parsely\Parsely; use Parsely\Content_Helper\Content_Helper_Feature; +use Parsely\Utils\Utils; use WP_Post; -use function Parsely\Utils\get_asset_info; use const Parsely\PARSELY_FILE; @@ -152,7 +152,7 @@ public function run(): void { return; } - $asset_php = get_asset_info( 'build/content-helper/editor-sidebar.asset.php' ); + $asset_php = Utils::get_asset_info( 'build/content-helper/editor-sidebar.asset.php' ); $built_assets_url = plugin_dir_url( PARSELY_FILE ) . 'build/content-helper/'; wp_enqueue_script( diff --git a/src/content-helper/excerpt-generator/class-excerpt-generator.php b/src/content-helper/excerpt-generator/class-excerpt-generator.php index 029fdb496..10cf360eb 100644 --- a/src/content-helper/excerpt-generator/class-excerpt-generator.php +++ b/src/content-helper/excerpt-generator/class-excerpt-generator.php @@ -13,7 +13,7 @@ use Parsely\Parsely; use Parsely\Permissions; -use function Parsely\Utils\get_asset_info; +use Parsely\Utils\Utils; use const Parsely\PARSELY_FILE; /** @@ -77,7 +77,7 @@ public function run(): void { return; } - $asset_php = get_asset_info( 'build/content-helper/excerpt-generator.asset.php' ); + $asset_php = Utils::get_asset_info( 'build/content-helper/excerpt-generator.asset.php' ); $built_assets_url = plugin_dir_url( PARSELY_FILE ) . 'build/content-helper/'; wp_enqueue_script( diff --git a/src/content-helper/post-list-stats/class-post-list-stats.php b/src/content-helper/post-list-stats/class-post-list-stats.php index 76e8c3c86..42b2452e8 100644 --- a/src/content-helper/post-list-stats/class-post-list-stats.php +++ b/src/content-helper/post-list-stats/class-post-list-stats.php @@ -15,14 +15,10 @@ use Parsely\Parsely; use Parsely\RemoteAPI\Base_Endpoint_Remote; use Parsely\RemoteAPI\Analytics_Posts_API; +use Parsely\Utils\Utils; use WP_Screen; -use function Parsely\Utils\get_asset_info; -use function Parsely\Utils\get_formatted_number; -use function Parsely\Utils\get_formatted_time; - use const Parsely\PARSELY_FILE; -use const Parsely\Utils\DATE_UTC_FORMAT; /** * Class for adding `Parse.ly Stats` on admin columns. @@ -156,7 +152,7 @@ public function enqueue_parsely_stats_styles(): void { return; } - $admin_settings_asset = get_asset_info( 'build/content-helper/post-list-stats.asset.php' ); + $admin_settings_asset = Utils::get_asset_info( 'build/content-helper/post-list-stats.asset.php' ); $built_assets_url = plugin_dir_url( PARSELY_FILE ) . 'build/content-helper/'; wp_enqueue_style( @@ -235,7 +231,7 @@ public function enqueue_parsely_stats_script_with_data(): void { return; } - $admin_settings_asset = get_asset_info( 'build/content-helper/post-list-stats.asset.php' ); + $admin_settings_asset = Utils::get_asset_info( 'build/content-helper/post-list-stats.asset.php' ); $built_assets_url = plugin_dir_url( PARSELY_FILE ) . 'build/content-helper/'; wp_enqueue_script( @@ -358,9 +354,9 @@ public function get_parsely_stats_response( $analytics_api ) { * @var Parsely_Post_Stats */ $stats = array( - 'page_views' => get_formatted_number( (string) $views ) . ' ' . _n( 'page view', 'page views', $views, 'wp-parsely' ), - 'visitors' => get_formatted_number( (string) $visitors ) . ' ' . _n( 'visitor', 'visitors', $visitors, 'wp-parsely' ), - 'avg_time' => get_formatted_time( $engaged_seconds ) . ' ' . __( 'avg time', 'wp-parsely' ), + 'page_views' => Utils::get_formatted_number( (string) $views ) . ' ' . _n( 'page view', 'page views', $views, 'wp-parsely' ), + 'visitors' => Utils::get_formatted_number( (string) $visitors ) . ' ' . _n( 'visitor', 'visitors', $visitors, 'wp-parsely' ), + 'avg_time' => Utils::get_formatted_time( $engaged_seconds ) . ' ' . __( 'avg time', 'wp-parsely' ), ); $parsely_stats_map[ $key ] = $stats; @@ -389,8 +385,8 @@ private function get_publish_date_params_for_analytics_api() { } return array( - 'pub_date_start' => ( new DateTime( min( $published_times ) ) )->format( DATE_UTC_FORMAT ), - 'pub_date_end' => ( new DateTime( max( $published_times ) ) )->format( DATE_UTC_FORMAT ), + 'pub_date_start' => ( new DateTime( min( $published_times ) ) )->format( Utils::DATE_UTC_FORMAT ), + 'pub_date_end' => ( new DateTime( max( $published_times ) ) )->format( Utils::DATE_UTC_FORMAT ), ); } diff --git a/tests/Integration/Blocks/RecommendationsBlockTest.php b/tests/Integration/Blocks/RecommendationsBlockTest.php index 32039da0b..3fc86a4d1 100644 --- a/tests/Integration/Blocks/RecommendationsBlockTest.php +++ b/tests/Integration/Blocks/RecommendationsBlockTest.php @@ -7,7 +7,7 @@ declare(strict_types=1); -namespace Parsely\Tests\Blocks; +namespace Parsely\Tests\Integration\Blocks; use Parsely\Recommendations_Block; use Parsely\Tests\Integration\TestCase; diff --git a/tests/Integration/content-helper/ContentHelperDashboardWidgetTest.php b/tests/Integration/ContentHelper/ContentHelperDashboardWidgetTest.php similarity index 94% rename from tests/Integration/content-helper/ContentHelperDashboardWidgetTest.php rename to tests/Integration/ContentHelper/ContentHelperDashboardWidgetTest.php index 39801809c..cfb9f5d8e 100644 --- a/tests/Integration/content-helper/ContentHelperDashboardWidgetTest.php +++ b/tests/Integration/ContentHelper/ContentHelperDashboardWidgetTest.php @@ -7,7 +7,7 @@ declare(strict_types=1); -namespace Parsely\Tests\ContentHelper; +namespace Parsely\Tests\Integration\ContentHelper; use Parsely\Content_Helper\Dashboard_Widget; use Parsely\Parsely; @@ -88,8 +88,8 @@ protected function assert_enqueued_status( * @covers \Parsely\RemoteAPI\Analytics_Posts_API::is_available_to_current_user * @uses \Parsely\Parsely::__construct * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\Utils\convert_endpoint_to_filter_key - * @uses \Parsely\Utils\get_asset_info + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Utils::get_asset_info * * @group content-helper */ @@ -115,8 +115,8 @@ public function test_assets_do_not_get_enqueued_when_user_has_not_enough_capabil * @covers \Parsely\RemoteAPI\Analytics_Posts_API::is_available_to_current_user * @uses \Parsely\Parsely::__construct * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\Utils\convert_endpoint_to_filter_key - * @uses \Parsely\Utils\get_asset_info + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Utils::get_asset_info * * @group content-helper */ diff --git a/tests/Integration/content-helper/ContentHelperEditorSidebarTest.php b/tests/Integration/ContentHelper/ContentHelperEditorSidebarTest.php similarity index 96% rename from tests/Integration/content-helper/ContentHelperEditorSidebarTest.php rename to tests/Integration/ContentHelper/ContentHelperEditorSidebarTest.php index 6934d6225..a22203da3 100644 --- a/tests/Integration/content-helper/ContentHelperEditorSidebarTest.php +++ b/tests/Integration/ContentHelper/ContentHelperEditorSidebarTest.php @@ -7,7 +7,7 @@ declare(strict_types=1); -namespace Parsely\Tests\ContentHelper; +namespace Parsely\Tests\Integration\ContentHelper; use Parsely\Content_Helper\Editor_Sidebar; use Parsely\Parsely; diff --git a/tests/Integration/content-helper/ContentHelperExcerptSuggestionsTest.php b/tests/Integration/ContentHelper/ContentHelperExcerptSuggestionsTest.php similarity index 98% rename from tests/Integration/content-helper/ContentHelperExcerptSuggestionsTest.php rename to tests/Integration/ContentHelper/ContentHelperExcerptSuggestionsTest.php index 719666ea7..e410ee818 100644 --- a/tests/Integration/content-helper/ContentHelperExcerptSuggestionsTest.php +++ b/tests/Integration/ContentHelper/ContentHelperExcerptSuggestionsTest.php @@ -7,7 +7,7 @@ declare(strict_types=1); -namespace Parsely\Tests\ContentHelper; +namespace Parsely\Tests\Integration\ContentHelper; use Parsely\Content_Helper\Excerpt_Generator; use Parsely\Parsely; diff --git a/tests/Integration/ContentHelperFeatureTest.php b/tests/Integration/ContentHelper/ContentHelperFeatureTest.php similarity index 96% rename from tests/Integration/ContentHelperFeatureTest.php rename to tests/Integration/ContentHelper/ContentHelperFeatureTest.php index 02f0905a5..977a968ba 100644 --- a/tests/Integration/ContentHelperFeatureTest.php +++ b/tests/Integration/ContentHelper/ContentHelperFeatureTest.php @@ -8,10 +8,10 @@ declare(strict_types=1); -namespace Parsely\Tests\ContentHelper; +namespace Parsely\Tests\Integration\ContentHelper; -use Parsely\Tests\Integration\TestCase; use Parsely\Content_Helper\Content_Helper_Feature; +use Parsely\Tests\Integration\TestCase; /** * Base class for all Content Helper feature integration tests. @@ -183,8 +183,8 @@ protected static function deregister_feature_assets_and_run( * @uses \Parsely\Parsely::set_default_track_as_values * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Utils\convert_endpoint_to_filter_key - * @uses \Parsely\Utils\get_asset_info + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Utils::get_asset_info * * @group content-helper */ @@ -240,8 +240,8 @@ public function test_assets_get_enqueued_by_default(): void { * @uses \Parsely\Parsely::set_default_track_as_values * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Utils\convert_endpoint_to_filter_key - * @uses \Parsely\Utils\get_asset_info + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Utils::get_asset_info * * @group content-helper */ @@ -285,8 +285,8 @@ public function test_assets_get_enqueued_when_global_filter_is_true(): void { * @uses \Parsely\Parsely::get_options * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Utils\convert_endpoint_to_filter_key - * @uses \Parsely\Utils\get_asset_info + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Utils::get_asset_info * * @group content-helper */ @@ -330,8 +330,8 @@ public function test_assets_do_not_get_enqueued_when_global_filter_is_false(): v * @uses \Parsely\Parsely::get_options * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Utils\convert_endpoint_to_filter_key - * @uses \Parsely\Utils\get_asset_info + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Utils::get_asset_info * * @group content-helper */ @@ -388,8 +388,8 @@ public function test_assets_do_not_get_enqueued_when_global_filter_is_invalid(): * @uses \Parsely\Parsely::set_default_track_as_values * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Utils\convert_endpoint_to_filter_key - * @uses \Parsely\Utils\get_asset_info + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Utils::get_asset_info * * @group content-helper */ @@ -433,8 +433,8 @@ public function test_assets_get_enqueued_when_feature_filter_is_true(): void { * @uses \Parsely\Parsely::get_options * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Utils\convert_endpoint_to_filter_key - * @uses \Parsely\Utils\get_asset_info + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Utils::get_asset_info * * @group content-helper */ @@ -478,8 +478,8 @@ public function test_assets_do_not_get_enqueued_when_feature_filter_is_false(): * @uses \Parsely\Parsely::get_options * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Utils\convert_endpoint_to_filter_key - * @uses \Parsely\Utils\get_asset_info + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Utils::get_asset_info * * @group content-helper */ @@ -535,8 +535,8 @@ public function test_assets_do_not_get_enqueued_when_feature_filter_is_invalid() * @uses \Parsely\Parsely::set_default_track_as_values * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Utils\convert_endpoint_to_filter_key - * @uses \Parsely\Utils\get_asset_info + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Utils::get_asset_info * * @group content-helper */ @@ -587,8 +587,8 @@ public function test_assets_get_enqueued_when_both_filters_are_true(): void { * @uses \Parsely\Parsely::get_options * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Utils\convert_endpoint_to_filter_key - * @uses \Parsely\Utils\get_asset_info + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Utils::get_asset_info * * @group content-helper */ @@ -632,8 +632,8 @@ public function test_assets_do_not_get_enqueued_when_both_filters_are_false(): v * @uses \Parsely\Parsely::get_options * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Utils\convert_endpoint_to_filter_key - * @uses \Parsely\Utils\get_asset_info + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Utils::get_asset_info * * @group content-helper */ @@ -677,8 +677,8 @@ public function test_assets_do_not_get_enqueued_when_both_filters_are_invalid(): * @uses \Parsely\Parsely::get_options * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Utils\convert_endpoint_to_filter_key - * @uses \Parsely\Utils\get_asset_info + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Utils::get_asset_info * * @group content-helper */ @@ -734,8 +734,8 @@ public function test_assets_do_not_get_enqueued_when_global_filter_is_true_and_f * @uses \Parsely\Parsely::set_default_track_as_values * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Utils\convert_endpoint_to_filter_key - * @uses \Parsely\Utils\get_asset_info + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Utils::get_asset_info * * @group content-helper */ @@ -780,8 +780,8 @@ public function test_assets_get_enqueued_when_global_filter_is_false_and_feature * @uses \Parsely\Parsely::get_options * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Utils\convert_endpoint_to_filter_key - * @uses \Parsely\Utils\get_asset_info + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Utils::get_asset_info * * @group content-helper */ @@ -837,8 +837,8 @@ public function test_assets_do_not_get_enqueued_when_global_filter_is_true_and_f * @uses \Parsely\Parsely::set_default_track_as_values * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Utils\convert_endpoint_to_filter_key - * @uses \Parsely\Utils\get_asset_info + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Utils::get_asset_info * * @group content-helper */ diff --git a/tests/Integration/content-helper/ContentHelperPostListStatsTest.php b/tests/Integration/ContentHelper/ContentHelperPostListStatsTest.php similarity index 99% rename from tests/Integration/content-helper/ContentHelperPostListStatsTest.php rename to tests/Integration/ContentHelper/ContentHelperPostListStatsTest.php index 3bd358037..7ea57fc8c 100644 --- a/tests/Integration/content-helper/ContentHelperPostListStatsTest.php +++ b/tests/Integration/ContentHelper/ContentHelperPostListStatsTest.php @@ -7,13 +7,12 @@ declare(strict_types=1); -namespace Parsely\Tests\ContentHelper; +namespace Parsely\Tests\Integration\ContentHelper; use Mockery; use Parsely\Content_Helper\Post_List_Stats; use Parsely\Parsely; use Parsely\RemoteAPI\Analytics_Posts_API; -use Parsely\Tests\ContentHelper\ContentHelperFeatureTest; use Parsely\Tests\Integration\TestCase; use WP_Error; use WP_Post; @@ -123,7 +122,7 @@ protected function assert_enqueued_status( * @covers \Parsely\Content_Helper\Post_List_Stats::get_feature_filter_name * @covers \Parsely\Content_Helper\Post_List_Stats::run * @covers \Parsely\RemoteAPI\Analytics_Posts_API::is_available_to_current_user - * @covers \Parsely\Utils\convert_endpoint_to_filter_key + * @covers \Parsely\Utils\Utils::convert_endpoint_to_filter_key * @uses \Parsely\Parsely::__construct * @uses \Parsely\Parsely::api_secret_is_set * @uses \Parsely\Parsely::get_options @@ -152,7 +151,7 @@ public function test_assets_do_not_get_enqueued_when_user_has_not_enough_capabil * @covers \Parsely\Content_Helper\Post_List_Stats::run * @covers \Parsely\Content_Helper\Post_List_Stats::set_current_screen * @covers \Parsely\RemoteAPI\Analytics_Posts_API::is_available_to_current_user - * @covers \Parsely\Utils\convert_endpoint_to_filter_key + * @covers \Parsely\Utils\Utils::convert_endpoint_to_filter_key * @uses \Parsely\Parsely::__construct * @uses \Parsely\Parsely::api_secret_is_set * @uses \Parsely\Parsely::get_options diff --git a/tests/Integration/Endpoints/AnalyticsPostsProxyEndpointTest.php b/tests/Integration/Endpoints/Proxy/AnalyticsPostsProxyEndpointTest.php similarity index 97% rename from tests/Integration/Endpoints/AnalyticsPostsProxyEndpointTest.php rename to tests/Integration/Endpoints/Proxy/AnalyticsPostsProxyEndpointTest.php index 4c490be8c..b0a7c366b 100644 --- a/tests/Integration/Endpoints/AnalyticsPostsProxyEndpointTest.php +++ b/tests/Integration/Endpoints/Proxy/AnalyticsPostsProxyEndpointTest.php @@ -8,21 +8,21 @@ declare(strict_types=1); -namespace Parsely\Tests\Integration; +namespace Parsely\Tests\Integration\Endpoints\Proxy; use Parsely\Endpoints\Analytics_Posts_API_Proxy; use Parsely\Endpoints\Base_API_Proxy; use Parsely\Parsely; use Parsely\RemoteAPI\Analytics_Posts_API; +use Parsely\Tests\Integration\TestCase; +use Parsely\Utils\Utils; use WP_Error; use WP_REST_Request; -use function Parsely\Utils\get_date_format; - /** * Integration Tests for the Analytics Posts API Proxy Endpoint. */ -final class AnalyticsPostsProxyEndpointTest extends ProxyEndpointTest { +final class AnalyticsPostsProxyEndpointTest extends BaseProxyEndpointTest { /** * Initializes all required values for the test. @@ -193,7 +193,7 @@ public function test_get_items(): void { ); $dispatched = 0; - $date_format = get_date_format(); + $date_format = Utils::get_date_format(); add_filter( 'pre_http_request', diff --git a/tests/Integration/ProxyEndpointTest.php b/tests/Integration/Endpoints/Proxy/BaseProxyEndpointTest.php similarity index 97% rename from tests/Integration/ProxyEndpointTest.php rename to tests/Integration/Endpoints/Proxy/BaseProxyEndpointTest.php index 708b0db80..208e0abaa 100644 --- a/tests/Integration/ProxyEndpointTest.php +++ b/tests/Integration/Endpoints/Proxy/BaseProxyEndpointTest.php @@ -8,11 +8,12 @@ declare(strict_types=1); -namespace Parsely\Tests\Integration; +namespace Parsely\Tests\Integration\Endpoints\Proxy; use Parsely\Endpoints\Base_API_Proxy; use Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta; use Parsely\Parsely; +use Parsely\Tests\Integration\TestCase; use WP_Error; use WP_REST_Request; use WP_REST_Server; @@ -22,7 +23,7 @@ * * @phpstan-import-type Parsely_Options from Parsely */ -abstract class ProxyEndpointTest extends TestCase { +abstract class BaseProxyEndpointTest extends TestCase { /** * Holds a reference to the global $wp_rest_server object to restore in diff --git a/tests/Integration/Endpoints/ReferrersPostDetailProxyEndpointTest.php b/tests/Integration/Endpoints/Proxy/ReferrersPostDetailProxyEndpointTest.php similarity index 98% rename from tests/Integration/Endpoints/ReferrersPostDetailProxyEndpointTest.php rename to tests/Integration/Endpoints/Proxy/ReferrersPostDetailProxyEndpointTest.php index b0eafdb76..38ec499a4 100644 --- a/tests/Integration/Endpoints/ReferrersPostDetailProxyEndpointTest.php +++ b/tests/Integration/Endpoints/Proxy/ReferrersPostDetailProxyEndpointTest.php @@ -8,18 +8,19 @@ declare(strict_types=1); -namespace Parsely\Tests\Integration; +namespace Parsely\Tests\Integration\Endpoints\Proxy; use Parsely\Endpoints\Base_API_Proxy; use Parsely\Endpoints\Referrers_Post_Detail_API_Proxy; use Parsely\Parsely; use Parsely\RemoteAPI\Referrers_Post_Detail_API; +use Parsely\Tests\Integration\TestCase; use WP_REST_Request; /** * Integration Tests for the Referrers Post Detail API Proxy Endpoint. */ -final class ReferrersPostDetailProxyEndpointTest extends ProxyEndpointTest { +final class ReferrersPostDetailProxyEndpointTest extends BaseProxyEndpointTest { /** * Initializes all required values for the test. diff --git a/tests/Integration/Endpoints/RelatedProxyEndpointTest.php b/tests/Integration/Endpoints/Proxy/RelatedProxyEndpointTest.php similarity index 96% rename from tests/Integration/Endpoints/RelatedProxyEndpointTest.php rename to tests/Integration/Endpoints/Proxy/RelatedProxyEndpointTest.php index d576f3bc7..7584fa597 100644 --- a/tests/Integration/Endpoints/RelatedProxyEndpointTest.php +++ b/tests/Integration/Endpoints/Proxy/RelatedProxyEndpointTest.php @@ -7,18 +7,19 @@ declare(strict_types=1); -namespace Parsely\Tests\Integration; +namespace Parsely\Tests\Integration\Endpoints\Proxy; use Parsely\Endpoints\Base_API_Proxy; use Parsely\Endpoints\Related_API_Proxy; use Parsely\Parsely; use Parsely\RemoteAPI\Related_API; +use Parsely\Tests\Integration\TestCase; use WP_REST_Request; /** * Integration Tests for the Related API Proxy Endpoint. */ -final class RelatedProxyEndpointTest extends ProxyEndpointTest { +final class RelatedProxyEndpointTest extends BaseProxyEndpointTest { /** * Initializes all required values for the test. diff --git a/tests/Integration/Endpoints/StatsPostDetailProxyEndpointTest.php b/tests/Integration/Endpoints/Proxy/StatsPostDetailProxyEndpointTest.php similarity index 97% rename from tests/Integration/Endpoints/StatsPostDetailProxyEndpointTest.php rename to tests/Integration/Endpoints/Proxy/StatsPostDetailProxyEndpointTest.php index 321949374..c442d098a 100644 --- a/tests/Integration/Endpoints/StatsPostDetailProxyEndpointTest.php +++ b/tests/Integration/Endpoints/Proxy/StatsPostDetailProxyEndpointTest.php @@ -8,18 +8,19 @@ declare(strict_types=1); -namespace Parsely\Tests\Integration; +namespace Parsely\Tests\Integration\Endpoints\Proxy; -use Parsely\Endpoints\Base_API_Proxy; use Parsely\Endpoints\Analytics_Post_Detail_API_Proxy; +use Parsely\Endpoints\Base_API_Proxy; use Parsely\Parsely; use Parsely\RemoteAPI\Analytics_Post_Detail_API; +use Parsely\Tests\Integration\TestCase; use WP_REST_Request; /** * Integration Tests for the Stats Post Detail API Proxy Endpoint. */ -final class StatsPostDetailProxyEndpointTest extends ProxyEndpointTest { +final class StatsPostDetailProxyEndpointTest extends BaseProxyEndpointTest { /** * Initializes all required values for the test. diff --git a/tests/Integration/BaseUserMetaEndpointTest.php b/tests/Integration/Endpoints/UserMeta/BaseUserMetaEndpointTest.php similarity index 95% rename from tests/Integration/BaseUserMetaEndpointTest.php rename to tests/Integration/Endpoints/UserMeta/BaseUserMetaEndpointTest.php index d2c082b2f..c2ad8ec40 100644 --- a/tests/Integration/BaseUserMetaEndpointTest.php +++ b/tests/Integration/Endpoints/UserMeta/BaseUserMetaEndpointTest.php @@ -8,8 +8,9 @@ declare(strict_types=1); -namespace Parsely\Tests\Integration; +namespace Parsely\Tests\Integration\Endpoints\UserMeta; +use Parsely\Tests\Integration\Endpoints\Proxy\BaseProxyEndpointTest; use WP_REST_Request; /** @@ -17,7 +18,7 @@ * * @since 3.13.0 */ -abstract class BaseUserMetaEndpointTest extends ProxyEndpointTest { +abstract class BaseUserMetaEndpointTest extends BaseProxyEndpointTest { /** * The endpoint's default value. * diff --git a/tests/Integration/Endpoints/DashboardWidgetSettingsEndpointTest.php b/tests/Integration/Endpoints/UserMeta/DashboardWidgetSettingsEndpointTest.php similarity index 94% rename from tests/Integration/Endpoints/DashboardWidgetSettingsEndpointTest.php rename to tests/Integration/Endpoints/UserMeta/DashboardWidgetSettingsEndpointTest.php index 401781bf1..7af087282 100644 --- a/tests/Integration/Endpoints/DashboardWidgetSettingsEndpointTest.php +++ b/tests/Integration/Endpoints/UserMeta/DashboardWidgetSettingsEndpointTest.php @@ -8,14 +8,12 @@ declare(strict_types=1); -namespace Parsely\Tests\ContentHelper; +namespace Parsely\Tests\Integration\Endpoints\UserMeta; use Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta; use Parsely\Endpoints\User_Meta\Dashboard_Widget_Settings_Endpoint; use Parsely\Parsely; -use Parsely\Tests\Integration\BaseUserMetaEndpointTest; - -use function Parsely\Utils\convert_endpoint_to_filter_key; +use Parsely\Utils\Utils; /** * Integration Tests for the PCH Dashboard Widget Settings Endpoint. @@ -44,7 +42,7 @@ public static function initialize(): void { $route = Dashboard_Widget_Settings_Endpoint::get_route(); self::$route = '/wp-parsely/v1' . $route; - self::$filter_key = convert_endpoint_to_filter_key( $route ); + self::$filter_key = Utils::convert_endpoint_to_filter_key( $route ); } /** @@ -75,7 +73,7 @@ public function get_endpoint(): Base_Endpoint_User_Meta { * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::are_credentials_managed * @uses \Parsely\Parsely::set_managed_options - * @uses \Parsely\Utils\convert_endpoint_to_filter_key + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_register_routes_by_default(): void { parent::run_test_register_routes_by_default( @@ -103,7 +101,7 @@ public function test_register_routes_by_default(): void { * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::are_credentials_managed * @uses \Parsely\Parsely::set_managed_options - * @uses \Parsely\Utils\convert_endpoint_to_filter_key + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_verify_that_route_is_not_registered_when_endpoint_is_disabled(): void { parent::run_test_do_not_register_route_when_proxy_is_disabled(); @@ -129,7 +127,7 @@ public function test_verify_that_route_is_not_registered_when_endpoint_is_disabl * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::are_credentials_managed * @uses \Parsely\Parsely::set_managed_options - * @uses \Parsely\Utils\convert_endpoint_to_filter_key + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_endpoint_returns_value_on_get_request(): void { parent::run_test_endpoint_returns_value_on_get_request(); @@ -161,7 +159,7 @@ public function test_endpoint_returns_value_on_get_request(): void { * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::are_credentials_managed * @uses \Parsely\Parsely::set_managed_options - * @uses \Parsely\Utils\convert_endpoint_to_filter_key + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key * * @dataProvider provide_put_requests_data */ diff --git a/tests/Integration/Endpoints/EditorSidebarSettingsEndpointTest.php b/tests/Integration/Endpoints/UserMeta/EditorSidebarSettingsEndpointTest.php similarity index 95% rename from tests/Integration/Endpoints/EditorSidebarSettingsEndpointTest.php rename to tests/Integration/Endpoints/UserMeta/EditorSidebarSettingsEndpointTest.php index 99f74b3fe..00071489b 100644 --- a/tests/Integration/Endpoints/EditorSidebarSettingsEndpointTest.php +++ b/tests/Integration/Endpoints/UserMeta/EditorSidebarSettingsEndpointTest.php @@ -8,14 +8,12 @@ declare(strict_types=1); -namespace Parsely\Tests\ContentHelper; +namespace Parsely\Tests\Integration\Endpoints\UserMeta; use Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta; use Parsely\Endpoints\User_Meta\Editor_Sidebar_Settings_Endpoint; use Parsely\Parsely; -use Parsely\Tests\Integration\BaseUserMetaEndpointTest; - -use function Parsely\Utils\convert_endpoint_to_filter_key; +use Parsely\Utils\Utils; /** * Integration Tests for the PCH Editor Sidebar Settings Endpoint. @@ -65,7 +63,7 @@ public static function initialize(): void { $route = Editor_Sidebar_Settings_Endpoint::get_route(); self::$route = '/wp-parsely/v1' . $route; - self::$filter_key = convert_endpoint_to_filter_key( $route ); + self::$filter_key = Utils::convert_endpoint_to_filter_key( $route ); } /** @@ -96,7 +94,7 @@ public function get_endpoint(): Base_Endpoint_User_Meta { * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::are_credentials_managed * @uses \Parsely\Parsely::set_managed_options - * @uses \Parsely\Utils\convert_endpoint_to_filter_key + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_register_routes_by_default(): void { parent::run_test_register_routes_by_default( @@ -124,7 +122,7 @@ public function test_register_routes_by_default(): void { * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::are_credentials_managed * @uses \Parsely\Parsely::set_managed_options - * @uses \Parsely\Utils\convert_endpoint_to_filter_key + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_verify_that_route_is_not_registered_when_endpoint_is_disabled(): void { parent::run_test_do_not_register_route_when_proxy_is_disabled(); @@ -150,7 +148,7 @@ public function test_verify_that_route_is_not_registered_when_endpoint_is_disabl * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::are_credentials_managed * @uses \Parsely\Parsely::set_managed_options - * @uses \Parsely\Utils\convert_endpoint_to_filter_key + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_endpoint_returns_value_on_get_request(): void { parent::run_test_endpoint_returns_value_on_get_request(); @@ -186,7 +184,7 @@ public function test_endpoint_returns_value_on_get_request(): void { * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::are_credentials_managed * @uses \Parsely\Parsely::set_managed_options - * @uses \Parsely\Utils\convert_endpoint_to_filter_key + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key * @dataProvider provide_put_requests_data */ public function test_endpoint_correctly_handles_put_requests( @@ -222,7 +220,7 @@ public function test_endpoint_correctly_handles_put_requests( * @uses \Parsely\Parsely::allow_parsely_remote_requests() * @uses \Parsely\Parsely::are_credentials_managed() * @uses \Parsely\Parsely::set_managed_options() - * @uses \Parsely\Utils\convert_endpoint_to_filter_key() + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key() */ public function test_valid_nested_performance_stats_settings_period(): void { $this->set_current_user_to_admin(); diff --git a/tests/Integration/Metadata/AuthorArchiveTest.php b/tests/Integration/Metadata/AuthorArchiveTest.php index 082ab15a2..089abc3cd 100644 --- a/tests/Integration/Metadata/AuthorArchiveTest.php +++ b/tests/Integration/Metadata/AuthorArchiveTest.php @@ -7,7 +7,7 @@ declare(strict_types=1); -namespace Parsely\Tests\Integration\StructuredData; +namespace Parsely\Tests\Integration\Metadata; use Parsely\Metadata; use Parsely\Parsely; diff --git a/tests/Integration/Metadata/BlogArchiveTest.php b/tests/Integration/Metadata/BlogArchiveTest.php index 73fc4c6d7..819b0638a 100644 --- a/tests/Integration/Metadata/BlogArchiveTest.php +++ b/tests/Integration/Metadata/BlogArchiveTest.php @@ -7,7 +7,7 @@ declare(strict_types=1); -namespace Parsely\Tests\Integration\StructuredData; +namespace Parsely\Tests\Integration\Metadata; use Parsely\Metadata; use Parsely\Parsely; @@ -35,6 +35,17 @@ final class BlogArchiveTest extends NonPostTestCase { * @uses \Parsely\Parsely::get_options * @uses \Parsely\Parsely::post_has_trackable_status * @uses \Parsely\Parsely::update_metadata_endpoint + * @uses \Parsely\Utils\Utils::get_page_on_front + * @uses \Parsely\Utils\Utils::get_page_for_posts + * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests + * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::set_managed_options + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap * @group metadata */ public function test_blog_page_for_posts_paged(): void { diff --git a/tests/Integration/Metadata/CustomPostTypeArchiveTest.php b/tests/Integration/Metadata/CustomPostTypeArchiveTest.php index 6c30b2ef1..a9d3327d0 100644 --- a/tests/Integration/Metadata/CustomPostTypeArchiveTest.php +++ b/tests/Integration/Metadata/CustomPostTypeArchiveTest.php @@ -7,7 +7,7 @@ declare(strict_types=1); -namespace Parsely\Tests\Integration\StructuredData; +namespace Parsely\Tests\Integration\Metadata; use Parsely\Metadata; use Parsely\Parsely; diff --git a/tests/Integration/Metadata/CustomTaxonomyTermArchiveTest.php b/tests/Integration/Metadata/CustomTaxonomyTermArchiveTest.php index d8b969649..869ac5a31 100644 --- a/tests/Integration/Metadata/CustomTaxonomyTermArchiveTest.php +++ b/tests/Integration/Metadata/CustomTaxonomyTermArchiveTest.php @@ -7,7 +7,7 @@ declare(strict_types=1); -namespace Parsely\Tests\Integration\StructuredData; +namespace Parsely\Tests\Integration\Metadata; use Parsely\Metadata; use Parsely\Parsely; diff --git a/tests/Integration/Metadata/DateArchiveTest.php b/tests/Integration/Metadata/DateArchiveTest.php index 1c00da502..49fd73a80 100644 --- a/tests/Integration/Metadata/DateArchiveTest.php +++ b/tests/Integration/Metadata/DateArchiveTest.php @@ -7,7 +7,7 @@ declare(strict_types=1); -namespace Parsely\Tests\Integration\StructuredData; +namespace Parsely\Tests\Integration\Metadata; use Parsely\Tests\Integration\TestCase; use Parsely\Metadata\Date_Builder; diff --git a/tests/Integration/Metadata/GetCurrentUrlTest.php b/tests/Integration/Metadata/GetCurrentUrlTest.php index fef56e32a..d9f239034 100644 --- a/tests/Integration/Metadata/GetCurrentUrlTest.php +++ b/tests/Integration/Metadata/GetCurrentUrlTest.php @@ -7,10 +7,11 @@ declare(strict_types=1); -namespace Parsely\Tests\Integration; +namespace Parsely\Tests\Integration\Metadata; use Parsely\Metadata\Front_Page_Builder; use Parsely\Parsely; +use Parsely\Tests\Integration\TestCase; /** * Integration Tests for \Parsely\MetadataMetadata_Builder->get_current_url(). diff --git a/tests/Integration/Metadata/HomePageTest.php b/tests/Integration/Metadata/HomePageTest.php index 0c2a4a367..8373503b2 100644 --- a/tests/Integration/Metadata/HomePageTest.php +++ b/tests/Integration/Metadata/HomePageTest.php @@ -7,7 +7,7 @@ declare(strict_types=1); -namespace Parsely\Tests\Integration\StructuredData; +namespace Parsely\Tests\Integration\Metadata; use Parsely\Metadata; use Parsely\Parsely; diff --git a/tests/Integration/Metadata/NonPostTestCase.php b/tests/Integration/Metadata/NonPostTestCase.php index 44d087016..71e873e2b 100644 --- a/tests/Integration/Metadata/NonPostTestCase.php +++ b/tests/Integration/Metadata/NonPostTestCase.php @@ -7,7 +7,7 @@ declare(strict_types=1); -namespace Parsely\Tests\Integration\StructuredData; +namespace Parsely\Tests\Integration\Metadata; use Parsely\Tests\Integration\TestCase; diff --git a/tests/Integration/Metadata/SinglePageTest.php b/tests/Integration/Metadata/SinglePageTest.php index 7afc84600..f2ce9ca00 100644 --- a/tests/Integration/Metadata/SinglePageTest.php +++ b/tests/Integration/Metadata/SinglePageTest.php @@ -7,7 +7,7 @@ declare(strict_types=1); -namespace Parsely\Tests\Integration\StructuredData; +namespace Parsely\Tests\Integration\Metadata; use Parsely\Metadata; use Parsely\Parsely; @@ -53,7 +53,7 @@ final class SinglePageTest extends NonPostTestCase { * @uses \Parsely\Parsely::post_has_trackable_status * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::update_metadata_endpoint - * @uses \Parsely\Utils\get_default_category + * @uses \Parsely\Utils\Utils::get_default_category * @group metadata */ public function test_single_page(): void { @@ -93,7 +93,7 @@ public function test_single_page(): void { * @uses \Parsely\Parsely::post_has_trackable_status * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::update_metadata_endpoint - * @uses \Parsely\Utils\get_default_category + * @uses \Parsely\Utils\Utils::get_default_category * @group metadata */ public function test_single_page_with_author(): void { @@ -133,7 +133,7 @@ public function test_single_page_with_author(): void { * @uses \Parsely\Parsely::post_has_trackable_status * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::update_metadata_endpoint - * @uses \Parsely\Utils\get_default_category + * @uses \Parsely\Utils\Utils::get_default_category * @group metadata */ public function test_single_page_with_category(): void { @@ -173,7 +173,7 @@ public function test_single_page_with_category(): void { * @uses \Parsely\Parsely::post_has_trackable_status * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::update_metadata_endpoint - * @uses \Parsely\Utils\get_default_category + * @uses \Parsely\Utils\Utils::get_default_category * @group metadata */ public function test_single_page_with_tag(): void { @@ -213,7 +213,7 @@ public function test_single_page_with_tag(): void { * @uses \Parsely\Parsely::post_has_trackable_status * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::update_metadata_endpoint - * @uses \Parsely\Utils\get_default_category + * @uses \Parsely\Utils\Utils::get_default_category * @group metadata */ public function test_single_page_with_tag_lowercase_off(): void { @@ -253,7 +253,7 @@ public function test_single_page_with_tag_lowercase_off(): void { * @uses \Parsely\Parsely::post_has_trackable_status * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::update_metadata_endpoint - * @uses \Parsely\Utils\get_default_category + * @uses \Parsely\Utils\Utils::get_default_category * @group metadata */ public function test_single_page_with_author_and_category(): void { @@ -293,7 +293,7 @@ public function test_single_page_with_author_and_category(): void { * @uses \Parsely\Parsely::post_has_trackable_status * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::update_metadata_endpoint - * @uses \Parsely\Utils\get_default_category + * @uses \Parsely\Utils\Utils::get_default_category * @group metadata */ public function test_single_page_with_author_and_tag(): void { @@ -333,7 +333,7 @@ public function test_single_page_with_author_and_tag(): void { * @uses \Parsely\Parsely::post_has_trackable_status * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::update_metadata_endpoint - * @uses \Parsely\Utils\get_default_category + * @uses \Parsely\Utils\Utils::get_default_category * @group metadata */ public function test_single_page_with_category_and_tag(): void { @@ -373,7 +373,7 @@ public function test_single_page_with_category_and_tag(): void { * @uses \Parsely\Parsely::post_has_trackable_status * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::update_metadata_endpoint - * @uses \Parsely\Utils\get_default_category + * @uses \Parsely\Utils\Utils::get_default_category * @group metadata */ public function test_single_page_with_author_and_category_and_tag(): void { diff --git a/tests/Integration/Metadata/SinglePostTest.php b/tests/Integration/Metadata/SinglePostTest.php index 005538d2a..ffbe1503d 100644 --- a/tests/Integration/Metadata/SinglePostTest.php +++ b/tests/Integration/Metadata/SinglePostTest.php @@ -7,15 +7,14 @@ declare(strict_types=1); -namespace Parsely\Tests\Integration\StructuredData; +namespace Parsely\Tests\Integration\Metadata; use Parsely\Metadata; use Parsely\Parsely; use Parsely\Tests\Integration\TestCase; +use Parsely\Utils\Utils; use WP_Post; -use function Parsely\Utils\get_default_category; - const TEST_CATEGORY_1 = 'Test Category 1'; const POST_DATETIME = '2021-12-30 20:11:42'; const EXPECTED_POST_DATETIME = '2021-12-30T20:11:42Z'; @@ -973,7 +972,7 @@ public function test_post_with_categories_as_tags_without_categories(): void { $parsely_options['cats_as_tags'] = true; update_option( 'parsely', $parsely_options ); - $default_category_slug = $this->get_term( get_default_category() )->slug; + $default_category_slug = $this->get_term( Utils::get_default_category() )->slug; wp_remove_object_terms( $post_id, $default_category_slug, 'category' ); // Go to current post to update WP_Query with correct data. diff --git a/tests/Integration/Metadata/TermArchiveTest.php b/tests/Integration/Metadata/TermArchiveTest.php index 497723faa..8541f7cfb 100644 --- a/tests/Integration/Metadata/TermArchiveTest.php +++ b/tests/Integration/Metadata/TermArchiveTest.php @@ -7,7 +7,7 @@ declare(strict_types=1); -namespace Parsely\Tests\Integration\StructuredData; +namespace Parsely\Tests\Integration\Metadata; use Parsely\Metadata; use Parsely\Parsely; diff --git a/tests/Integration/RemoteAPI/AnalyticsPostsRemoteAPITest.php b/tests/Integration/RemoteAPI/AnalyticsPostsRemoteAPITest.php index c0e8dc7ea..8eb7dc105 100644 --- a/tests/Integration/RemoteAPI/AnalyticsPostsRemoteAPITest.php +++ b/tests/Integration/RemoteAPI/AnalyticsPostsRemoteAPITest.php @@ -8,7 +8,7 @@ declare(strict_types=1); -namespace Parsely\Tests\Integration; +namespace Parsely\Tests\Integration\RemoteAPI; use Parsely\Parsely; use Parsely\RemoteAPI\Analytics_Posts_API; @@ -16,7 +16,7 @@ /** * Integration Tests for the Parsely `/analytics/posts` Remote API. */ -final class AnalyticsPostsRemoteAPITest extends RemoteAPITest { +final class AnalyticsPostsRemoteAPITest extends BaseRemoteAPITest { /** * Initializes all required values for the test. @@ -50,7 +50,7 @@ public function data_api_url(): iterable { * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::are_credentials_managed * @uses \Parsely\Parsely::set_managed_options - * @uses \Parsely\Utils\convert_endpoint_to_filter_key + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_user_is_allowed_to_make_api_call_if_default_user_capability_is_changed(): void { $this->set_current_user_to_contributor(); @@ -76,7 +76,7 @@ function () { * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::are_credentials_managed * @uses \Parsely\Parsely::set_managed_options - * @uses \Parsely\Utils\convert_endpoint_to_filter_key + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_user_is_allowed_to_make_api_call_if_endpoint_specific_user_capability_is_changed(): void { $this->set_current_user_to_contributor(); @@ -102,7 +102,7 @@ function () { * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::are_credentials_managed * @uses \Parsely\Parsely::set_managed_options - * @uses \Parsely\Utils\convert_endpoint_to_filter_key + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_endpoint_specific_user_capability_filter_have_more_priority_than_default(): void { $this->set_current_user_to_contributor(); diff --git a/tests/Integration/RemoteAPITest.php b/tests/Integration/RemoteAPI/BaseRemoteAPITest.php similarity index 97% rename from tests/Integration/RemoteAPITest.php rename to tests/Integration/RemoteAPI/BaseRemoteAPITest.php index 9b8f5b84a..6f978d11c 100644 --- a/tests/Integration/RemoteAPITest.php +++ b/tests/Integration/RemoteAPI/BaseRemoteAPITest.php @@ -8,16 +8,17 @@ declare(strict_types=1); -namespace Parsely\Tests\Integration; +namespace Parsely\Tests\Integration\RemoteAPI; -use Parsely\RemoteAPI\Cache; use Parsely\RemoteAPI\Base_Endpoint_Remote; +use Parsely\RemoteAPI\Cache; use Parsely\RemoteAPI\Remote_API_Cache; +use Parsely\Tests\Integration\TestCase; /** * Integration Tests for the Parse.ly Remote API. */ -abstract class RemoteAPITest extends TestCase { +abstract class BaseRemoteAPITest extends TestCase { /** * Internal variable. * diff --git a/tests/Integration/RemoteAPI/content-suggestions/BaseContentSuggestionsAPITest.php b/tests/Integration/RemoteAPI/ContentSuggestions/BaseContentSuggestionsAPITest.php similarity index 96% rename from tests/Integration/RemoteAPI/content-suggestions/BaseContentSuggestionsAPITest.php rename to tests/Integration/RemoteAPI/ContentSuggestions/BaseContentSuggestionsAPITest.php index b472a0dc7..708b08a6c 100644 --- a/tests/Integration/RemoteAPI/content-suggestions/BaseContentSuggestionsAPITest.php +++ b/tests/Integration/RemoteAPI/ContentSuggestions/BaseContentSuggestionsAPITest.php @@ -9,14 +9,14 @@ namespace Parsely\Tests\Integration\RemoteAPI\ContentSuggestions; use Parsely\RemoteAPI\ContentSuggestions\Content_Suggestions_Base_API; -use Parsely\Tests\Integration\RemoteAPITest; +use Parsely\Tests\Integration\RemoteAPI\BaseRemoteAPITest; /** * Integration Tests for the Parse.ly Content Suggestions API endpoints. * * @since 3.14.0 */ -abstract class BaseContentSuggestionsAPITest extends RemoteAPITest { +abstract class BaseContentSuggestionsAPITest extends BaseRemoteAPITest { /** * Verifies the basic generation of the API headers. * diff --git a/tests/Integration/RemoteAPI/content-suggestions/SuggestBriefAPITest.php b/tests/Integration/RemoteAPI/ContentSuggestions/SuggestBriefAPITest.php similarity index 100% rename from tests/Integration/RemoteAPI/content-suggestions/SuggestBriefAPITest.php rename to tests/Integration/RemoteAPI/ContentSuggestions/SuggestBriefAPITest.php diff --git a/tests/Integration/RemoteAPI/content-suggestions/SuggestHeadlineAPITest.php b/tests/Integration/RemoteAPI/ContentSuggestions/SuggestHeadlineAPITest.php similarity index 100% rename from tests/Integration/RemoteAPI/content-suggestions/SuggestHeadlineAPITest.php rename to tests/Integration/RemoteAPI/ContentSuggestions/SuggestHeadlineAPITest.php diff --git a/tests/Integration/RemoteAPI/content-suggestions/SuggestLinkedReferenceAPITest.php b/tests/Integration/RemoteAPI/ContentSuggestions/SuggestLinkedReferenceAPITest.php similarity index 100% rename from tests/Integration/RemoteAPI/content-suggestions/SuggestLinkedReferenceAPITest.php rename to tests/Integration/RemoteAPI/ContentSuggestions/SuggestLinkedReferenceAPITest.php diff --git a/tests/Integration/RemoteAPI/RelatedRemoteAPITest.php b/tests/Integration/RemoteAPI/RelatedRemoteAPITest.php index 885e71f0f..52c4ab80d 100644 --- a/tests/Integration/RemoteAPI/RelatedRemoteAPITest.php +++ b/tests/Integration/RemoteAPI/RelatedRemoteAPITest.php @@ -7,7 +7,7 @@ declare(strict_types=1); -namespace Parsely\Tests\Integration; +namespace Parsely\Tests\Integration\RemoteAPI; use Parsely\Parsely; use Parsely\RemoteAPI\Related_API; @@ -15,7 +15,7 @@ /** * Integration Tests for the Parsely `/related` Remote API. */ -final class RelatedRemoteAPITest extends RemoteAPITest { +final class RelatedRemoteAPITest extends BaseRemoteAPITest { /** * Initializes all required values for the test. diff --git a/tests/Integration/ScriptsTest.php b/tests/Integration/ScriptsTest.php index 8798f5507..7f598df63 100644 --- a/tests/Integration/ScriptsTest.php +++ b/tests/Integration/ScriptsTest.php @@ -11,10 +11,9 @@ use Parsely\Parsely; use Parsely\Scripts; +use Parsely\Utils\Utils; use WP_Scripts; -use function Parsely\Utils\get_asset_info; - use const Parsely\PARSELY_FILE; /** @@ -520,7 +519,7 @@ public function test_tracker_markup_has_attribute_when_cfasync_filter_is_used(): * @var string */ $output = ob_get_clean(); - $loader_asset = get_asset_info( 'build/loader.asset.php' ); + $loader_asset = Utils::get_asset_info( 'build/loader.asset.php' ); self::assertStringContainsString( 'data-cfasync="false"', $output ); self::assertStringContainsString( 'http://example.org/wp-content/plugins/wp-parsely/tests/Integration/../../build/loader.js?ver=' . $loader_asset['version'], $output ); diff --git a/tests/Integration/TestCase.php b/tests/Integration/TestCase.php index 23882e042..c2bc79058 100644 --- a/tests/Integration/TestCase.php +++ b/tests/Integration/TestCase.php @@ -12,11 +12,12 @@ use DateInterval; use DateTime; use DateTimeZone; -use ReflectionClass; -use ReflectionProperty; -use ReflectionMethod; use Parsely\Parsely; +use Parsely\Utils\Utils; use PHPUnit\Framework\RiskyTestError; +use ReflectionClass; +use ReflectionMethod; +use ReflectionProperty; use UnexpectedValueException; use WP_Error; use WP_Post; @@ -24,8 +25,6 @@ use WP_Term; use Yoast\WPTestUtils\WPIntegration\TestCase as WPIntegrationTestCase; -use const Parsely\Utils\WP_DATE_TIME_FORMAT; - /** * Abstract base class for all test case implementations. * @@ -33,7 +32,7 @@ */ abstract class TestCase extends WPIntegrationTestCase { - use \Parsely\Tests\Tests_Reflection; + use \Parsely\Tests\Traits\TestsReflection; public const VALID_SITE_ID = 'demoaccount.parsely.com'; @@ -226,8 +225,8 @@ private function create_posts_and_get_ids( int $num_of_posts = 1, string $post_t 'post_title' => "Title $i-($post_status)", 'post_author' => $i, 'post_content' => "Content $i", - 'post_date' => $post_date->format( WP_DATE_TIME_FORMAT ), - 'post_date_gmt' => gmdate( WP_DATE_TIME_FORMAT, $post_date->getTimestamp() ), + 'post_date' => $post_date->format( Utils::WP_DATE_TIME_FORMAT ), + 'post_date_gmt' => gmdate( Utils::WP_DATE_TIME_FORMAT, $post_date->getTimestamp() ), ) ); diff --git a/tests/Integration/bootstrap.php b/tests/Integration/bootstrap.php index 72a2cabad..5c373d015 100644 --- a/tests/Integration/bootstrap.php +++ b/tests/Integration/bootstrap.php @@ -45,11 +45,6 @@ echo PHP_EOL, 'ERROR: Please check whether the WP_PLUGIN_DIR environment variable is set and set to the correct value. The unit test suite won\'t be able to run without it.', PHP_EOL; exit( 1 ); } - - // Additional necessary requires. - require_once dirname( __DIR__ ) . '/trait-tests-reflection.php'; - require_once __DIR__ . '/TestCase.php'; - require_once __DIR__ . '/Metadata/NonPostTestCase.php'; } // Plugin root file is not included during tests, so define the namespaced diff --git a/tests/trait-tests-reflection.php b/tests/Traits/TestsReflection.php similarity index 96% rename from tests/trait-tests-reflection.php rename to tests/Traits/TestsReflection.php index bca4a6e62..5223b4b0e 100644 --- a/tests/trait-tests-reflection.php +++ b/tests/Traits/TestsReflection.php @@ -7,13 +7,13 @@ declare(strict_types=1); -namespace Parsely\Tests; +namespace Parsely\Tests\Traits; use Parsely\Parsely; use ReflectionException; use ReflectionMethod; -trait Tests_Reflection { +trait TestsReflection { /** * Gets a method from a class. This should be used when trying to access a * private method for testing. diff --git a/tests/Unit/Utils/UtilsTest.php b/tests/Unit/Utils/UtilsTest.php index 209d4780e..732c6af84 100644 --- a/tests/Unit/Utils/UtilsTest.php +++ b/tests/Unit/Utils/UtilsTest.php @@ -7,17 +7,11 @@ declare(strict_types=1); -namespace Parsely\Tests\Unit; +namespace Parsely\Tests\Unit\Utils; +use Parsely\Utils\Utils; use Yoast\WPTestUtils\BrainMonkey\TestCase; -use function Parsely\Utils\convert_to_associative_array; -use function Parsely\Utils\get_formatted_number; -use function Parsely\Utils\get_formatted_time; -use function Parsely\Utils\get_utc_date_format; - -use const Parsely\Utils\DATE_UTC_FORMAT; - /** * Unit Tests: Util Functions * @@ -57,12 +51,12 @@ final class UtilsTest extends TestCase { /** * Tests get_utc_date_format function. * - * @covers function \Parsely\Utils\get_utc_date_format + * @covers function \Parsely\Utils\Utils::get_utc_date_format */ public function test_get_utc_date_format(): void { - $current_date = gmdate( DATE_UTC_FORMAT ); - $past_date = gmdate( DATE_UTC_FORMAT, strtotime( '-1 days' ) ); - $future_date = gmdate( DATE_UTC_FORMAT, strtotime( '1 days' ) ); + $current_date = gmdate( Utils::DATE_UTC_FORMAT ); + $past_date = gmdate( Utils::DATE_UTC_FORMAT, strtotime( '-1 days' ) ); + $future_date = gmdate( Utils::DATE_UTC_FORMAT, strtotime( '1 days' ) ); /** * Variable. @@ -89,7 +83,7 @@ public function test_get_utc_date_format(): void { foreach ( $tests_data as $t ) { $args = $t['args']; - $output = get_utc_date_format( $args['days'] ); + $output = Utils::get_utc_date_format( $args['days'] ); self::assertSame( $t['expected_output'], $output, $t['msg'] ); } @@ -98,7 +92,7 @@ public function test_get_utc_date_format(): void { /** * Tests get_formatted_number function. * - * @covers function \Parsely\Utils\get_formatted_number + * @covers function \Parsely\Utils\Utils::get_formatted_number */ public function test_get_formatted_number(): void { $this->mock_wordpress_functions(); @@ -143,7 +137,7 @@ public function test_get_formatted_number(): void { foreach ( $tests_data as $t ) { $args = $t['args']; - $output = get_formatted_number( (string) $args['number'] ); + $output = Utils::get_formatted_number( (string) $args['number'] ); self::assertSame( $t['expected_output'], $output, $t['msg'] ); } @@ -152,7 +146,7 @@ public function test_get_formatted_number(): void { /** * Tests get_formatted_time function. * - * @covers function \Parsely\Utils\get_formatted_time + * @covers function \Parsely\Utils\Utils::get_formatted_time */ public function test_get_formatted_time(): void { $this->mock_wordpress_functions(); @@ -202,7 +196,7 @@ public function test_get_formatted_time(): void { foreach ( $tests_data as $t ) { $args = $t['args']; - $output = get_formatted_time( $args['seconds'] ); + $output = Utils::get_formatted_time( $args['seconds'] ); self::assertSame( $t['expected_output'], $output, $t['msg'] ); } @@ -211,7 +205,7 @@ public function test_get_formatted_time(): void { /** * Tests convert_to_associative_array function. * - * @covers function \Parsely\Utils\convert_to_associative_array + * @covers function \Parsely\Utils\Utils::convert_to_associative_array */ public function test_convert_to_associative_array(): void { /** @@ -256,7 +250,7 @@ public function test_convert_to_associative_array(): void { foreach ( $tests_data as $t ) { $args = $t['args']; - $output = convert_to_associative_array( $args['obj'] ); + $output = Utils::convert_to_associative_array( $args['obj'] ); self::assertSame( $t['expected_output'], $output, $t['msg'] ); } diff --git a/tests/Unit/bootstrap.php b/tests/Unit/bootstrap.php index 9c9db8b93..df68dc67f 100644 --- a/tests/Unit/bootstrap.php +++ b/tests/Unit/bootstrap.php @@ -10,7 +10,6 @@ // phpcs:ignore Universal.Namespaces.DisallowCurlyBraceSyntax.Forbidden namespace Parsely\Tests\Unit { // Require any necessary files and autoload the plugin code. - require_once dirname( __DIR__ ) . '/trait-tests-reflection.php'; require_once dirname( __DIR__ ) . '/../vendor/yoast/wp-test-utils/src/BrainMonkey/bootstrap.php'; require_once dirname( __DIR__ ) . '/../vendor/autoload.php'; } diff --git a/wp-parsely.php b/wp-parsely.php index f89339570..ab26ee73c 100644 --- a/wp-parsely.php +++ b/wp-parsely.php @@ -64,8 +64,6 @@ use Parsely\UI\Settings_Page; use Parsely\UI\Site_Health; -require_once __DIR__ . '/src/Utils/utils.php'; - if ( class_exists( Parsely::class ) ) { return; } @@ -73,32 +71,9 @@ const PARSELY_VERSION = '3.16.3'; const PARSELY_FILE = __FILE__; -require_once __DIR__ . '/src/Models/class-base-model.php'; -require_once __DIR__ . '/src/Models/class-smart-link.php'; -require_once __DIR__ . '/src/Models/class-inbound-smart-link.php'; - -require_once __DIR__ . '/src/class-parsely.php'; -require_once __DIR__ . '/src/class-permissions.php'; -require_once __DIR__ . '/src/class-scripts.php'; -require_once __DIR__ . '/src/class-dashboard-link.php'; -require_once __DIR__ . '/src/class-validator.php'; -require_once __DIR__ . '/src/UI/class-admin-bar.php'; -require_once __DIR__ . '/src/UI/class-metadata-renderer.php'; -require_once __DIR__ . '/src/Endpoints/class-metadata-endpoint.php'; -require_once __DIR__ . '/src/Endpoints/class-graphql-metadata.php'; -require_once __DIR__ . '/src/Telemetry/telemetry-init.php'; - -require_once __DIR__ . '/src/class-metadata.php'; -require_once __DIR__ . '/src/Metadata/class-metadata-builder.php'; -require_once __DIR__ . '/src/Metadata/class-author-archive-builder.php'; -require_once __DIR__ . '/src/Metadata/class-category-builder.php'; -require_once __DIR__ . '/src/Metadata/class-date-builder.php'; -require_once __DIR__ . '/src/Metadata/class-front-page-builder.php'; -require_once __DIR__ . '/src/Metadata/class-page-builder.php'; -require_once __DIR__ . '/src/Metadata/class-page-for-posts-builder.php'; -require_once __DIR__ . '/src/Metadata/class-paginated-front-page-builder.php'; -require_once __DIR__ . '/src/Metadata/class-post-builder.php'; -require_once __DIR__ . '/src/Metadata/class-tag-builder.php'; +if ( file_exists( __DIR__ . '/vendor/autoload.php' ) ) { + require_once __DIR__ . '/vendor/autoload.php'; +} add_action( 'plugins_loaded', __NAMESPACE__ . '\\parsely_initialize_plugin' ); /** @@ -123,14 +98,6 @@ function parsely_initialize_plugin(): void { $metadata_renderer->run(); } -require_once __DIR__ . '/src/content-helper/common/class-content-helper-feature.php'; -require_once __DIR__ . '/src/content-helper/post-list-stats/class-post-list-stats.php'; -require_once __DIR__ . '/src/UI/class-admin-warning.php'; -require_once __DIR__ . '/src/UI/class-plugins-actions.php'; -require_once __DIR__ . '/src/UI/class-row-actions.php'; -require_once __DIR__ . '/src/UI/class-site-health.php'; -require_once __DIR__ . '/src/content-helper/dashboard-widget/class-dashboard-widget.php'; - add_action( 'admin_init', __NAMESPACE__ . '\\parsely_admin_init_register' ); /** * Registers the Parse.ly wp-admin warnings, plugin actions and row actions. @@ -146,9 +113,6 @@ function parsely_admin_init_register(): void { ( new Dashboard_Widget( $parsely ) )->run(); } -require_once __DIR__ . '/src/UI/class-settings-page.php'; -require_once __DIR__ . '/src/UI/class-network-admin-sites-list.php'; - add_action( 'init', __NAMESPACE__ . '\\parsely_wp_admin_early_register' ); /** * Registers the additions the Parse.ly wp-admin settings page and Multisite @@ -162,42 +126,6 @@ function parsely_wp_admin_early_register(): void { $network_admin_sites_list->run(); } -// Endpoint base classes. -require_once __DIR__ . '/src/Endpoints/class-base-endpoint.php'; -require_once __DIR__ . '/src/Endpoints/class-base-api-proxy.php'; -require_once __DIR__ . '/src/Endpoints/user-meta/class-base-endpoint-user-meta.php'; - -// Endpoint classes. -require_once __DIR__ . '/src/Endpoints/class-analytics-post-detail-api-proxy.php'; -require_once __DIR__ . '/src/Endpoints/class-analytics-posts-api-proxy.php'; -require_once __DIR__ . '/src/Endpoints/class-referrers-post-detail-api-proxy.php'; -require_once __DIR__ . '/src/Endpoints/class-related-api-proxy.php'; -require_once __DIR__ . '/src/Endpoints/class-rest-metadata.php'; -require_once __DIR__ . '/src/Endpoints/content-suggestions/class-suggest-brief-api-proxy.php'; -require_once __DIR__ . '/src/Endpoints/content-suggestions/class-suggest-headline-api-proxy.php'; -require_once __DIR__ . '/src/Endpoints/content-suggestions/class-suggest-linked-reference-api-proxy.php'; -require_once __DIR__ . '/src/Endpoints/user-meta/class-dashboard-widget-settings-endpoint.php'; -require_once __DIR__ . '/src/Endpoints/user-meta/class-editor-sidebar-settings-endpoint.php'; -require_once __DIR__ . '/src/Endpoints/content-helper/class-smart-linking-endpoint.php'; - -// RemoteAPI base classes. -require_once __DIR__ . '/src/RemoteAPI/interface-cache.php'; -require_once __DIR__ . '/src/RemoteAPI/interface-remote-api.php'; -require_once __DIR__ . '/src/RemoteAPI/class-remote-api-cache.php'; -require_once __DIR__ . '/src/RemoteAPI/class-wordpress-cache.php'; -require_once __DIR__ . '/src/RemoteAPI/class-base-endpoint-remote.php'; -require_once __DIR__ . '/src/RemoteAPI/content-suggestions/class-content-suggestions-base-api.php'; - -// RemoteAPI classes. -require_once __DIR__ . '/src/RemoteAPI/class-analytics-post-detail-api.php'; -require_once __DIR__ . '/src/RemoteAPI/class-analytics-posts-api.php'; -require_once __DIR__ . '/src/RemoteAPI/class-referrers-post-detail-api.php'; -require_once __DIR__ . '/src/RemoteAPI/class-related-api.php'; -require_once __DIR__ . '/src/RemoteAPI/class-validate-api.php'; -require_once __DIR__ . '/src/RemoteAPI/content-suggestions/class-suggest-brief-api.php'; -require_once __DIR__ . '/src/RemoteAPI/content-suggestions/class-suggest-headline-api.php'; -require_once __DIR__ . '/src/RemoteAPI/content-suggestions/class-suggest-linked-reference-api.php'; - add_action( 'rest_api_init', __NAMESPACE__ . '\\parsely_rest_api_init' ); /** * Registers REST Endpoints that act as a proxy to the Parse.ly API. @@ -260,8 +188,6 @@ function parsely_rest_api_init(): void { ); } -require_once __DIR__ . '/src/blocks/recommendations/class-recommendations-block.php'; - add_action( 'init', __NAMESPACE__ . '\\init_recommendations_block' ); /** * Registers the Recommendations Block. @@ -271,8 +197,6 @@ function init_recommendations_block(): void { $recommendations_block->run(); } -require_once __DIR__ . '/src/content-helper/editor-sidebar/class-editor-sidebar.php'; - add_action( 'enqueue_block_editor_assets', __NAMESPACE__ . '\\init_content_helper_editor_sidebar' ); /** * Inserts the PCH Editor Sidebar. @@ -284,11 +208,8 @@ function init_content_helper_editor_sidebar(): void { $GLOBALS['parsely_editor_sidebar']->run(); } -require_once __DIR__ . '/src/content-helper/excerpt-generator/class-excerpt-generator.php'; - add_action( 'admin_init', __NAMESPACE__ . '\\parsely_content_helper_editor_sidebar_features' ); add_action( 'rest_api_init', __NAMESPACE__ . '\\parsely_content_helper_editor_sidebar_features' ); - /** * Initializes the PCH Editor Sidebar features. * @@ -318,7 +239,6 @@ function init_content_helper_excerpt_generator(): void { ( new Excerpt_Generator( $GLOBALS['parsely'] ) )->run(); } -require_once __DIR__ . '/src/UI/class-recommended-widget.php'; add_action( 'widgets_init', __NAMESPACE__ . '\\parsely_recommended_widget_register' ); /** @@ -328,11 +248,6 @@ function parsely_recommended_widget_register(): void { register_widget( new Recommended_Widget( $GLOBALS['parsely'] ) ); } -require_once __DIR__ . '/src/Integrations/class-integration.php'; -require_once __DIR__ . '/src/Integrations/class-integrations.php'; -require_once __DIR__ . '/src/Integrations/class-amp.php'; -require_once __DIR__ . '/src/Integrations/class-google-web-stories.php'; - add_action( 'init', __NAMESPACE__ . '\\parsely_integrations' ); // @phpstan-ignore-line /** * Instantiates Integrations collection and registers built-in integrations. @@ -376,7 +291,7 @@ function parsely_run_rest_api_endpoint( /** * Internal Variable. * - * @var RemoteAPI\Base_Endpoint_Remote + * @var RemoteAPI\Base_Endpoint_Remote $remote_api */ $remote_api = new $api_class_name( $GLOBALS['parsely'] ); $remote_api_cache = new Remote_API_Cache( $remote_api, $wp_cache ); @@ -384,7 +299,7 @@ function parsely_run_rest_api_endpoint( /** * Internal Variable. * - * @var Endpoints\Base_API_Proxy + * @var Endpoints\Base_API_Proxy $remote_api_proxy */ $remote_api_proxy = new $proxy_api_class_name( $GLOBALS['parsely'], $remote_api_cache ); $remote_api_proxy->run(); From 13299dbb415b0031114c362fe5399754cc89179f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 07:39:06 +0000 Subject: [PATCH 011/282] build(deps-dev): bump @wordpress/element from 6.3.0 to 6.5.0 Bumps [@wordpress/element](https://github.com/WordPress/gutenberg/tree/HEAD/packages/element) from 6.3.0 to 6.5.0. - [Release notes](https://github.com/WordPress/gutenberg/releases) - [Changelog](https://github.com/WordPress/gutenberg/blob/trunk/packages/element/CHANGELOG.md) - [Commits](https://github.com/WordPress/gutenberg/commits/@wordpress/element@6.5.0/packages/element) --- updated-dependencies: - dependency-name: "@wordpress/element" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 16 ++++++++-------- package.json | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 40ab6e410..0f66561d8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,7 +37,7 @@ "@wordpress/e2e-test-utils": "^11.3.0", "@wordpress/edit-post": "^8.3.0", "@wordpress/editor": "^14.3.0", - "@wordpress/element": "^6.2.0", + "@wordpress/element": "^6.5.0", "@wordpress/env": "^10.3.0", "@wordpress/eslint-plugin": "^20.0.0", "@wordpress/hooks": "^4.0.0", @@ -10323,15 +10323,15 @@ } }, "node_modules/@wordpress/element": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-6.3.0.tgz", - "integrity": "sha512-DsiqzjuXqxJkLUoLomsGTFFxbSZgk+Lz+2/1yFH+BU3jQ6zeD64+JWv8Lt4+fKU154rV0KpfMwfD/oAC/Lp1zQ==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-6.5.0.tgz", + "integrity": "sha512-N9w3jfceltdDEN71jpaMCXU+jbvec9kredvQIn/6YNiUMarPXWth7DJYU3+mDtbYawnTIvytzGjbj/J+bqqdHg==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", "@types/react": "^18.2.79", "@types/react-dom": "^18.2.25", - "@wordpress/escape-html": "^3.3.0", + "@wordpress/escape-html": "^3.5.0", "change-case": "^4.1.2", "is-plain-object": "^5.0.0", "react": "^18.3.0", @@ -10446,9 +10446,9 @@ } }, "node_modules/@wordpress/escape-html": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-3.3.0.tgz", - "integrity": "sha512-Wu/Fq96E28UGnIO5VQW/aEgCiHWvzrD8izDnP8U0WZSuwIPYcS5iYmRe2UWc7rwyoeY2YXNd6xFjgd7oTOKNCA==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-3.5.0.tgz", + "integrity": "sha512-8dUWTmsDZuqAmBtRgk0JpiIafRKPM4n8tqCr147AugTbP/vyQ7rIzG3M/YCtVSmDr6f/qZ32YU8J7c34RhZ/9g==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" diff --git a/package.json b/package.json index dd4fd7a5a..6186af0c0 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "@wordpress/e2e-test-utils": "^11.3.0", "@wordpress/edit-post": "^8.3.0", "@wordpress/editor": "^14.3.0", - "@wordpress/element": "^6.2.0", + "@wordpress/element": "^6.5.0", "@wordpress/env": "^10.3.0", "@wordpress/eslint-plugin": "^20.0.0", "@wordpress/hooks": "^4.0.0", From 84f7ad5b546d555c579c972f7eb73965f8fda646 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 07:39:44 +0000 Subject: [PATCH 012/282] build(deps-dev): bump @wordpress/components from 28.3.0 to 28.5.0 Bumps [@wordpress/components](https://github.com/WordPress/gutenberg/tree/HEAD/packages/components) from 28.3.0 to 28.5.0. - [Release notes](https://github.com/WordPress/gutenberg/releases) - [Changelog](https://github.com/WordPress/gutenberg/blob/trunk/packages/components/CHANGELOG.md) - [Commits](https://github.com/WordPress/gutenberg/commits/@wordpress/components@28.5.0/packages/components) --- updated-dependencies: - dependency-name: "@wordpress/components" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 302 ++++++++++++++++++++++++++-------------------- package.json | 2 +- 2 files changed, 172 insertions(+), 132 deletions(-) diff --git a/package-lock.json b/package-lock.json index 40ab6e410..eb3eebca6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,7 +30,7 @@ "@wordpress/babel-preset-default": "^7.42.0", "@wordpress/block-editor": "^13.0.0", "@wordpress/blocks": "^13.3.0", - "@wordpress/components": "^28.3.0", + "@wordpress/components": "^28.5.0", "@wordpress/compose": "^7.0.0", "@wordpress/core-data": "^7.3.0", "@wordpress/data": "^10.3.0", @@ -9369,14 +9369,14 @@ } }, "node_modules/@wordpress/a11y": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/a11y/-/a11y-4.3.0.tgz", - "integrity": "sha512-kmAE8hshmldudMhtj/RKY7lEwyux5w6zvCTbIj3a6iq0ZMhU3vsxTlCp/vEGLoYdfetwRN4zeJA9jvPki+IOUA==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/a11y/-/a11y-4.5.0.tgz", + "integrity": "sha512-sQmA4kTqu252to6ppVhti2RxSCFcAgWMc3l6rY2kBpj90uK5gtvLKQMr/GvydhildG/OzFSswbk1YBgSPGaudw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/dom-ready": "^4.3.0", - "@wordpress/i18n": "^5.3.0" + "@wordpress/dom-ready": "^4.5.0", + "@wordpress/i18n": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -9718,12 +9718,12 @@ } }, "node_modules/@wordpress/components": { - "version": "28.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-28.3.0.tgz", - "integrity": "sha512-zLHtxmhbuD7j5f7wOqRu6+KYVWPRpgHsYzxOavWkkiKv0XUvWeYWBIZFM4oy6A1WJqW2nEELcAjIeBX/0UWMig==", + "version": "28.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-28.5.0.tgz", + "integrity": "sha512-kZPb8MdpGW/Yv/ycJhbf+myb4czkyQ28gb5PY1kT2ABRB07J3oS1/badSLex3x06zD6NPtJt3kInbPUsSF2prQ==", "dev": true, "dependencies": { - "@ariakit/react": "^0.3.12", + "@ariakit/react": "^0.4.7", "@babel/runtime": "^7.16.0", "@emotion/cache": "^11.7.1", "@emotion/css": "^11.7.1", @@ -9735,29 +9735,28 @@ "@types/gradient-parser": "0.1.3", "@types/highlight-words-core": "1.2.1", "@use-gesture/react": "^10.3.1", - "@wordpress/a11y": "^4.3.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/date": "^5.3.0", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/dom": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/escape-html": "^3.3.0", - "@wordpress/hooks": "^4.3.0", - "@wordpress/html-entities": "^4.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/icons": "^10.3.0", - "@wordpress/is-shallow-equal": "^5.3.0", - "@wordpress/keycodes": "^4.3.0", - "@wordpress/primitives": "^4.3.0", - "@wordpress/private-apis": "^1.3.0", - "@wordpress/rich-text": "^7.3.0", - "@wordpress/warning": "^3.3.0", + "@wordpress/a11y": "^4.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/date": "^5.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/dom": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/escape-html": "^3.5.0", + "@wordpress/hooks": "^4.5.0", + "@wordpress/html-entities": "^4.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/icons": "^10.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/keycodes": "^4.5.0", + "@wordpress/primitives": "^4.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/rich-text": "^7.5.0", + "@wordpress/warning": "^3.5.0", "change-case": "^4.1.2", "clsx": "^2.1.1", "colord": "^2.7.0", "date-fns": "^3.6.0", "deepmerge": "^4.3.0", - "downshift": "^6.0.15", "fast-deep-equal": "^3.1.3", "framer-motion": "^11.1.9", "gradient-parser": "^0.1.5", @@ -9780,14 +9779,52 @@ "react-dom": "^18.0.0" } }, + "node_modules/@wordpress/components/node_modules/@ariakit/core": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/@ariakit/core/-/core-0.4.8.tgz", + "integrity": "sha512-HQS+9CI7pMqqVlAt5bPGenT0/e65UxXY+PKtgU7Y+0UToBDBRolO5S9+UUSDm8OmJHSnq24owEGm1Mv28l5XCQ==", + "dev": true + }, + "node_modules/@wordpress/components/node_modules/@ariakit/react": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/@ariakit/react/-/react-0.4.8.tgz", + "integrity": "sha512-Bb1vOrp0X52hxi1wE9TEHjjZ/Y08tVq2ZH+RFDwRQB3g04uVwrrhnTccHepC6rsObrDpAOV3/YlJCi4k/lSUaQ==", + "dev": true, + "dependencies": { + "@ariakit/react-core": "0.4.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ariakit" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@wordpress/components/node_modules/@ariakit/react-core": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/@ariakit/react-core/-/react-core-0.4.8.tgz", + "integrity": "sha512-TzsddUWQwWYhrEVWHA/Gf7KCGx8rwFohAHfuljjqidKeZi2kUmuRAImCTG9oga34FWHFf4AdXQbBKclMNt0nrQ==", + "dev": true, + "dependencies": { + "@ariakit/core": "0.4.8", + "@floating-ui/dom": "^1.0.0", + "use-sync-external-store": "^1.2.0" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/@wordpress/components/node_modules/@wordpress/keycodes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.3.0.tgz", - "integrity": "sha512-o+L110/Y9ufS2eWVG1gXFs6+jPsMNVZoGJCt4PLjMmVabke0iaYstFppUdtQiOEDbnnhX9MH3RRtqp2AoSnaRQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0" + "@wordpress/i18n": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -9795,9 +9832,9 @@ } }, "node_modules/@wordpress/components/node_modules/@wordpress/warning": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.3.0.tgz", - "integrity": "sha512-n82aKCxuGRNwAtSLaycErJuhKgfOc+KtiljyQITPperMh9i8bH6I+JxtYiu+aLMaY5vrVLVb+/kCzKuWVQIKPA==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.5.0.tgz", + "integrity": "sha512-cYM2Vqf2EokJJoWHD5Ry15OUmdsKtDgR8/qxE0sWHUAdSQeoTuJZnqhgYI898cZGxHaZWX2xJCxQa7Qtwl8lqw==", "dev": true, "engines": { "node": ">=18.12.0", @@ -9805,20 +9842,20 @@ } }, "node_modules/@wordpress/compose": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-7.3.0.tgz", - "integrity": "sha512-TtAYdKnqQ/L/nF0+fmlQ1wAvm90X9HRBrAuEMNmkzKhews/5GR0rR3dNSMjlf7C6mNdTO3mkYt6AQf9fvZFoiQ==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-7.5.0.tgz", + "integrity": "sha512-jWRmleIGxmvTIC/1VYtAvq0iRfCkW/AtlNmqoKiyd0Ah5lccWRtxSH5V3Vh1BEkBQRANMWxJpOpRTKDFTcfTvg==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", "@types/mousetrap": "^1.6.8", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/dom": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/is-shallow-equal": "^5.3.0", - "@wordpress/keycodes": "^4.3.0", - "@wordpress/priority-queue": "^3.3.0", - "@wordpress/undo-manager": "^1.3.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/dom": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/keycodes": "^4.5.0", + "@wordpress/priority-queue": "^3.5.0", + "@wordpress/undo-manager": "^1.5.0", "change-case": "^4.1.2", "clipboard": "^2.0.11", "mousetrap": "^1.6.5", @@ -9833,13 +9870,13 @@ } }, "node_modules/@wordpress/compose/node_modules/@wordpress/keycodes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.3.0.tgz", - "integrity": "sha512-o+L110/Y9ufS2eWVG1gXFs6+jPsMNVZoGJCt4PLjMmVabke0iaYstFppUdtQiOEDbnnhX9MH3RRtqp2AoSnaRQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0" + "@wordpress/i18n": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -9913,19 +9950,19 @@ } }, "node_modules/@wordpress/data": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-10.3.0.tgz", - "integrity": "sha512-cImJw4k30coosH6QtiJllxEYr93w8981PPvhGhemMbRQ28MnSA7rbJPv3h2LO9oss5SQH1gU9kwNGAZcF6PMPg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-10.5.0.tgz", + "integrity": "sha512-Y2P5SC0fuTivcfdYmubL3c15WRbE0FJAyYcEfZeJ2C37a2DmBnCBz3uEzGy2kCilz56qMfK0qutAHkfytOpRQw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/is-shallow-equal": "^5.3.0", - "@wordpress/priority-queue": "^3.3.0", - "@wordpress/private-apis": "^1.3.0", - "@wordpress/redux-routine": "^5.3.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/priority-queue": "^3.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/redux-routine": "^5.5.0", "deepmerge": "^4.3.0", "equivalent-key-map": "^0.2.2", "is-plain-object": "^5.0.0", @@ -9970,13 +10007,13 @@ } }, "node_modules/@wordpress/date": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/date/-/date-5.3.0.tgz", - "integrity": "sha512-vD0rLQxNlOoFd4n32HohhTif4P1JPW/Igjp0c/O2WZji+eXQM6P54fBu5veKvgwMmXpUn8y0xzgssj3pKAUgCg==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/date/-/date-5.5.0.tgz", + "integrity": "sha512-dIo02TAIuXG/wkcVf+jsyXn64PUVsxs6HwuHanNiDNVZt95QVJ8b7wdJZNIrhTkmVXhIUzYAz5BpuXUC6IZAqg==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/deprecated": "^4.3.0", + "@wordpress/deprecated": "^4.5.0", "moment": "^2.29.4", "moment-timezone": "^0.5.40" }, @@ -10002,13 +10039,13 @@ } }, "node_modules/@wordpress/deprecated": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-4.3.0.tgz", - "integrity": "sha512-K2GHXlwjx6GMhZjs52X1MXySCrqzh4IjoqF5IOcydMgWqOIE2++hMuB9Y55qN/Mhsrv/HO8Q1LaTxbEd6BuNJQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-4.5.0.tgz", + "integrity": "sha512-r3xGAM45XTd+z+hnUvLGtSz+Y0ebybuw/cyE0CatksJBGvXez3kiTDaknALkgzjHRZzIGpNu6XTVUoIJs0H39A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/hooks": "^4.3.0" + "@wordpress/hooks": "^4.5.0" }, "engines": { "node": ">=18.12.0", @@ -10016,13 +10053,13 @@ } }, "node_modules/@wordpress/dom": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-4.3.0.tgz", - "integrity": "sha512-sf4h6jVqboRdhe3soyr5bt+Vpz24WG/AIMHm7pGaxfbV5jxx06ZZ8K1RKzhr7jF3wn7IgIc1wmMA+OFzEYqGyw==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-4.5.0.tgz", + "integrity": "sha512-XjnpRbbhZ1hdgv758vSXQacjfy/N0H2oI0oWukrLmlkKDP5ZrGfdziHQ2+KcoW+QDx8pu4JYcUpjmuJLugDStw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/deprecated": "^4.3.0" + "@wordpress/deprecated": "^4.5.0" }, "engines": { "node": ">=18.12.0", @@ -10030,9 +10067,9 @@ } }, "node_modules/@wordpress/dom-ready": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/dom-ready/-/dom-ready-4.3.0.tgz", - "integrity": "sha512-zuLLMIeJt1hZ95R4kdJFcsIaL2eud1kF40VCmwK3mK0qpgXv/1avtGX8lx6DMLL/GGL1yYcJhR13RSKSjxuGEQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom-ready/-/dom-ready-4.5.0.tgz", + "integrity": "sha512-5dALG1lQtoH/Rk7DWFe9DaIF2bQQM5U0x+c1lQnk1cnBJ69AijIcbZMYaMzlgngo4dVF2PnFZ/VKVSUOKghhQQ==", "dependencies": { "@babel/runtime": "^7.16.0" }, @@ -10323,15 +10360,15 @@ } }, "node_modules/@wordpress/element": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-6.3.0.tgz", - "integrity": "sha512-DsiqzjuXqxJkLUoLomsGTFFxbSZgk+Lz+2/1yFH+BU3jQ6zeD64+JWv8Lt4+fKU154rV0KpfMwfD/oAC/Lp1zQ==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-6.5.0.tgz", + "integrity": "sha512-N9w3jfceltdDEN71jpaMCXU+jbvec9kredvQIn/6YNiUMarPXWth7DJYU3+mDtbYawnTIvytzGjbj/J+bqqdHg==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", "@types/react": "^18.2.79", "@types/react-dom": "^18.2.25", - "@wordpress/escape-html": "^3.3.0", + "@wordpress/escape-html": "^3.5.0", "change-case": "^4.1.2", "is-plain-object": "^5.0.0", "react": "^18.3.0", @@ -10446,9 +10483,9 @@ } }, "node_modules/@wordpress/escape-html": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-3.3.0.tgz", - "integrity": "sha512-Wu/Fq96E28UGnIO5VQW/aEgCiHWvzrD8izDnP8U0WZSuwIPYcS5iYmRe2UWc7rwyoeY2YXNd6xFjgd7oTOKNCA==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-3.5.0.tgz", + "integrity": "sha512-8dUWTmsDZuqAmBtRgk0JpiIafRKPM4n8tqCr147AugTbP/vyQ7rIzG3M/YCtVSmDr6f/qZ32YU8J7c34RhZ/9g==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -10718,9 +10755,9 @@ } }, "node_modules/@wordpress/hooks": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-4.3.0.tgz", - "integrity": "sha512-bpqwSXGyxPfhuxESKoAtL4ofB3CazzvcwcucTZ0g9Pat3KNuBaloSrPBliqqNOiSLWNH3nmpkaRmv4u89EdKAw==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-4.5.0.tgz", + "integrity": "sha512-wr1l1WM1yobyNGFLRgbLNBGtYIkzAGfmbT2e9zIOvqllRJT4wprYTqqhgovOKHlET5ij/TKdv4tApkGLUIXTsA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -10731,9 +10768,9 @@ } }, "node_modules/@wordpress/html-entities": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/html-entities/-/html-entities-4.3.0.tgz", - "integrity": "sha512-rJDf9KjCuUnFwIwmOdN4FcL7RJnDzPxIdvvMoWXkYd9GseEeRTsY6xIG+fGgVGgYe3HwXDYSFCWTF/x2M9Eerg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/html-entities/-/html-entities-4.5.0.tgz", + "integrity": "sha512-iQo2P1Sc499MxguelJ4aMcF08jnYkOdvb+FAOyOfGCyDjEtNbldRFc2BJ9NmJ/9nmtlwc/IzUzXop0M1gjy9tw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -10744,13 +10781,13 @@ } }, "node_modules/@wordpress/i18n": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-5.3.0.tgz", - "integrity": "sha512-edHKkdZb6jNpbn+LUPu2wo1mKyhT819WJ7kI8hmMcHq82rNwwbMfcGoB3oSaphTphWfhlgxIxLczKOAbWDKudw==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-5.5.0.tgz", + "integrity": "sha512-MtCJIjNHCWs7R77f5Xml1CCnVXqrle4cDpqMU9myx4Cq8ZijqSayX1CTtwtk+Z3/3xa+dBZu5Koe4wiW1yIUSA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/hooks": "^4.3.0", + "@wordpress/hooks": "^4.5.0", "gettext-parser": "^1.3.1", "memize": "^2.1.0", "sprintf-js": "^1.1.1", @@ -10765,14 +10802,14 @@ } }, "node_modules/@wordpress/icons": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/icons/-/icons-10.3.0.tgz", - "integrity": "sha512-d2jOFfLIAxPr+/Bzg7wnRDEDPogMpVefe4cHgIx9kXp/+7DG4KWNJm842qVithjs1wVgSzavzWbFrTtPEZ+Uhw==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/icons/-/icons-10.5.0.tgz", + "integrity": "sha512-BZwKBRKoTef9uW73T+FwK6d4JlcvgdVAaz3LB5dCluXg5PLV5ufMdumAaMxKWq/Ffl92/ddt8CKIdHjxfAZF4A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/element": "^6.3.0", - "@wordpress/primitives": "^4.3.0" + "@wordpress/element": "^6.5.0", + "@wordpress/primitives": "^4.5.0" }, "engines": { "node": ">=18.12.0", @@ -10838,9 +10875,9 @@ } }, "node_modules/@wordpress/is-shallow-equal": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-5.3.0.tgz", - "integrity": "sha512-sZ+fypqjYX0/DTAKsm1G9ND9Wn4d3Ju4lI7SLSmCKdUL5EPY3g/2LpKQKDqljh9m6Ex5NWp2XfU8UVXpkEfbMQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-5.5.0.tgz", + "integrity": "sha512-nkCz45HgMBkjhyxffDgpAgJbfnKyZML94/gHhBtxizHfaNuZ5as7DfEyN1xgebvDiLbOaRU7em1pPAuEhIoTfQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -11127,24 +11164,27 @@ } }, "node_modules/@wordpress/primitives": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/primitives/-/primitives-4.3.0.tgz", - "integrity": "sha512-h7wb2Np3n5etOg3j38GN80NEA8NgNdsSF/JJcRhpRf8FQOJd1mnKzj6szVHeKv0G7bvBif0NTgdSUm5M6Nikfg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/primitives/-/primitives-4.5.0.tgz", + "integrity": "sha512-1TYCpCAr2BmYJESlD8v325GgYXSgUbrFtebwgvpMN/28CEwmPN+ORRECV41nPX4yVJ2k0kYzYxzQUGp/78xWsw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/element": "^6.3.0", + "@wordpress/element": "^6.5.0", "clsx": "^2.1.1" }, "engines": { "node": ">=18.12.0", "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0" } }, "node_modules/@wordpress/priority-queue": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-3.3.0.tgz", - "integrity": "sha512-H7dGei1mFqKlz7NLFOGGtVgaBsORRaXeXNwWLI5rE0pI3XfGYd+zxNrG5aBzHw4fPqsITsxecNSaacc9fjqgjQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-3.5.0.tgz", + "integrity": "sha512-ilbG70ZuUJd0UTC7uyLP8zI/ZSN0d4ceG3qwlDx13yQAcjAcuw1Ei1CwzFBsbmI3OS1KkfkDpwZzKOrA+j/00Q==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", @@ -11156,9 +11196,9 @@ } }, "node_modules/@wordpress/private-apis": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/private-apis/-/private-apis-1.3.0.tgz", - "integrity": "sha512-IbtH8ZENAKixSoTBKbmJ2ZCIkxsxqAoWPBtvbNJG9rYdzSk+BExdy/5VGO6Pv5GcUElHT+8uV26W4XxBVNl4UQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/private-apis/-/private-apis-1.5.0.tgz", + "integrity": "sha512-taGW34kyyHMnbmTbWIyOJt7C4KFVCg7F5PNFwJQmS43FESC9BAjPw7VeEDTJ0XNqocH4NNeBJclhFyj82QySTQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -11169,9 +11209,9 @@ } }, "node_modules/@wordpress/redux-routine": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/redux-routine/-/redux-routine-5.3.0.tgz", - "integrity": "sha512-5HGdW8PqIK5fTyg1yo6NL2x1LTxU9vBvgUan/bLxYLX0YNw4+gQUex3djE0dwXNgrdE4mvWvYTcccc+2L59hig==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/redux-routine/-/redux-routine-5.5.0.tgz", + "integrity": "sha512-PvIgq0lI2PLjechCq+pRFIE/xbFwznytupGscD95qks3fFM9jtqVhlgO2oW0pA7C6CIz8zQ0zONFjsQlOaeDKA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", @@ -11216,20 +11256,20 @@ } }, "node_modules/@wordpress/rich-text": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/rich-text/-/rich-text-7.3.0.tgz", - "integrity": "sha512-iL7qEybPOwtMp8WXMQndzfvT2k647ZqIMTj0rji4h2QAp/KaEHyYaIF6YhuQ7v5bSQ/9IAAOy3KGhguIuxIt8A==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/rich-text/-/rich-text-7.5.0.tgz", + "integrity": "sha512-qHeTZNaLbsO6coBph1CD4qn/nfzvJV/DamiCpSgBJ1eQO7u8DdVB8abDxODOOD5hVOLHTOM/OBjFPTVFevNrmw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/a11y": "^4.3.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/data": "^10.3.0", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/escape-html": "^3.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/keycodes": "^4.3.0", + "@wordpress/a11y": "^4.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/escape-html": "^3.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/keycodes": "^4.5.0", "memize": "^2.1.0" }, "engines": { @@ -11241,13 +11281,13 @@ } }, "node_modules/@wordpress/rich-text/node_modules/@wordpress/keycodes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.3.0.tgz", - "integrity": "sha512-o+L110/Y9ufS2eWVG1gXFs6+jPsMNVZoGJCt4PLjMmVabke0iaYstFppUdtQiOEDbnnhX9MH3RRtqp2AoSnaRQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0" + "@wordpress/i18n": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -11967,13 +12007,13 @@ } }, "node_modules/@wordpress/undo-manager": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/undo-manager/-/undo-manager-1.3.0.tgz", - "integrity": "sha512-1XvU3GKpWeKFLCRx/3yEttRbIszD38vfH53XmCq2Y6IbWiyJLUGCnq4kiZjOaxA0o/DcAa4edscPyqmJj+wE+g==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/undo-manager/-/undo-manager-1.5.0.tgz", + "integrity": "sha512-ijvKwnXzKMV9xEcVB4mOIPih6BP5ZnZ1QYsv/EaPV7qlt2zgEevAHGa/FLQMW/lWlGCa5OhUK4tqDV+ZvrjTGw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/is-shallow-equal": "^5.3.0" + "@wordpress/is-shallow-equal": "^5.5.0" }, "engines": { "node": ">=18.12.0", diff --git a/package.json b/package.json index dd4fd7a5a..a8ca7b120 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "@wordpress/babel-preset-default": "^7.42.0", "@wordpress/block-editor": "^13.0.0", "@wordpress/blocks": "^13.3.0", - "@wordpress/components": "^28.3.0", + "@wordpress/components": "^28.5.0", "@wordpress/compose": "^7.0.0", "@wordpress/core-data": "^7.3.0", "@wordpress/data": "^10.3.0", From c45e690c4313e054a397a239f9e30247d64e2c57 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 07:40:19 +0000 Subject: [PATCH 013/282] build(deps-dev): bump @wordpress/icons from 10.3.0 to 10.5.0 Bumps [@wordpress/icons](https://github.com/WordPress/gutenberg/tree/HEAD/packages/icons) from 10.3.0 to 10.5.0. - [Release notes](https://github.com/WordPress/gutenberg/releases) - [Changelog](https://github.com/WordPress/gutenberg/blob/trunk/packages/icons/CHANGELOG.md) - [Commits](https://github.com/WordPress/gutenberg/commits/@wordpress/icons@10.5.0/packages/icons) --- updated-dependencies: - dependency-name: "@wordpress/icons" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 37 ++++++++++++++++++++----------------- package.json | 2 +- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index 40ab6e410..8ea18a59d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,7 +42,7 @@ "@wordpress/eslint-plugin": "^20.0.0", "@wordpress/hooks": "^4.0.0", "@wordpress/i18n": "^5.0.0", - "@wordpress/icons": "^10.0.0", + "@wordpress/icons": "^10.5.0", "@wordpress/plugins": "^7.3.0", "@wordpress/scripts": "^27.9.0", "@wordpress/url": "^4.2.0", @@ -10323,15 +10323,15 @@ } }, "node_modules/@wordpress/element": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-6.3.0.tgz", - "integrity": "sha512-DsiqzjuXqxJkLUoLomsGTFFxbSZgk+Lz+2/1yFH+BU3jQ6zeD64+JWv8Lt4+fKU154rV0KpfMwfD/oAC/Lp1zQ==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-6.5.0.tgz", + "integrity": "sha512-N9w3jfceltdDEN71jpaMCXU+jbvec9kredvQIn/6YNiUMarPXWth7DJYU3+mDtbYawnTIvytzGjbj/J+bqqdHg==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", "@types/react": "^18.2.79", "@types/react-dom": "^18.2.25", - "@wordpress/escape-html": "^3.3.0", + "@wordpress/escape-html": "^3.5.0", "change-case": "^4.1.2", "is-plain-object": "^5.0.0", "react": "^18.3.0", @@ -10446,9 +10446,9 @@ } }, "node_modules/@wordpress/escape-html": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-3.3.0.tgz", - "integrity": "sha512-Wu/Fq96E28UGnIO5VQW/aEgCiHWvzrD8izDnP8U0WZSuwIPYcS5iYmRe2UWc7rwyoeY2YXNd6xFjgd7oTOKNCA==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-3.5.0.tgz", + "integrity": "sha512-8dUWTmsDZuqAmBtRgk0JpiIafRKPM4n8tqCr147AugTbP/vyQ7rIzG3M/YCtVSmDr6f/qZ32YU8J7c34RhZ/9g==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -10765,14 +10765,14 @@ } }, "node_modules/@wordpress/icons": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/icons/-/icons-10.3.0.tgz", - "integrity": "sha512-d2jOFfLIAxPr+/Bzg7wnRDEDPogMpVefe4cHgIx9kXp/+7DG4KWNJm842qVithjs1wVgSzavzWbFrTtPEZ+Uhw==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/icons/-/icons-10.5.0.tgz", + "integrity": "sha512-BZwKBRKoTef9uW73T+FwK6d4JlcvgdVAaz3LB5dCluXg5PLV5ufMdumAaMxKWq/Ffl92/ddt8CKIdHjxfAZF4A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/element": "^6.3.0", - "@wordpress/primitives": "^4.3.0" + "@wordpress/element": "^6.5.0", + "@wordpress/primitives": "^4.5.0" }, "engines": { "node": ">=18.12.0", @@ -11127,18 +11127,21 @@ } }, "node_modules/@wordpress/primitives": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/primitives/-/primitives-4.3.0.tgz", - "integrity": "sha512-h7wb2Np3n5etOg3j38GN80NEA8NgNdsSF/JJcRhpRf8FQOJd1mnKzj6szVHeKv0G7bvBif0NTgdSUm5M6Nikfg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/primitives/-/primitives-4.5.0.tgz", + "integrity": "sha512-1TYCpCAr2BmYJESlD8v325GgYXSgUbrFtebwgvpMN/28CEwmPN+ORRECV41nPX4yVJ2k0kYzYxzQUGp/78xWsw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/element": "^6.3.0", + "@wordpress/element": "^6.5.0", "clsx": "^2.1.1" }, "engines": { "node": ">=18.12.0", "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0" } }, "node_modules/@wordpress/priority-queue": { diff --git a/package.json b/package.json index dd4fd7a5a..636a19831 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "@wordpress/eslint-plugin": "^20.0.0", "@wordpress/hooks": "^4.0.0", "@wordpress/i18n": "^5.0.0", - "@wordpress/icons": "^10.0.0", + "@wordpress/icons": "^10.5.0", "@wordpress/plugins": "^7.3.0", "@wordpress/scripts": "^27.9.0", "@wordpress/url": "^4.2.0", From 6441447d4f4c091e2f77a02bfc81906baf773e8b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 07:40:58 +0000 Subject: [PATCH 014/282] build(deps-dev): bump @wordpress/block-editor from 13.3.0 to 14.0.0 Bumps [@wordpress/block-editor](https://github.com/WordPress/gutenberg/tree/HEAD/packages/block-editor) from 13.3.0 to 14.0.0. - [Release notes](https://github.com/WordPress/gutenberg/releases) - [Changelog](https://github.com/WordPress/gutenberg/blob/trunk/packages/block-editor/CHANGELOG.md) - [Commits](https://github.com/WordPress/gutenberg/commits/@wordpress/block-editor@14.0.0/packages/block-editor) --- updated-dependencies: - dependency-name: "@wordpress/block-editor" dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 1629 +++++++++++++++++++++++++++++++++++++-------- package.json | 2 +- 2 files changed, 1343 insertions(+), 288 deletions(-) diff --git a/package-lock.json b/package-lock.json index 40ab6e410..979321633 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,7 +28,7 @@ "@typescript-eslint/eslint-plugin": "^6.21.0", "@wordpress/api-fetch": "^7.0.0", "@wordpress/babel-preset-default": "^7.42.0", - "@wordpress/block-editor": "^13.0.0", + "@wordpress/block-editor": "^14.0.0", "@wordpress/blocks": "^13.3.0", "@wordpress/components": "^28.3.0", "@wordpress/compose": "^7.0.0", @@ -9369,14 +9369,14 @@ } }, "node_modules/@wordpress/a11y": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/a11y/-/a11y-4.3.0.tgz", - "integrity": "sha512-kmAE8hshmldudMhtj/RKY7lEwyux5w6zvCTbIj3a6iq0ZMhU3vsxTlCp/vEGLoYdfetwRN4zeJA9jvPki+IOUA==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/a11y/-/a11y-4.5.0.tgz", + "integrity": "sha512-sQmA4kTqu252to6ppVhti2RxSCFcAgWMc3l6rY2kBpj90uK5gtvLKQMr/GvydhildG/OzFSswbk1YBgSPGaudw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/dom-ready": "^4.3.0", - "@wordpress/i18n": "^5.3.0" + "@wordpress/dom-ready": "^4.5.0", + "@wordpress/i18n": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -9384,14 +9384,14 @@ } }, "node_modules/@wordpress/api-fetch": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-7.3.0.tgz", - "integrity": "sha512-VpHG+9cLRZG13V2t1+xXpwuHJCeqiOl0ent9qXzbe6am9DtKSJ3oxiNdZaHjs6tdgGNuN/mTowRi5ceYJZb83Q==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-7.5.0.tgz", + "integrity": "sha512-ShUbXTYaQD9G7rROidMtlByu4i1N8Pj4gB5tIUUg2d0IUwDdXJnABQWI2+ebSXLKIRNaAOrw/Gb5xef08TR0ag==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/url": "^4.3.0" + "@wordpress/i18n": "^5.5.0", + "@wordpress/url": "^4.5.0" }, "engines": { "node": ">=18.12.0", @@ -9399,9 +9399,9 @@ } }, "node_modules/@wordpress/autop": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/autop/-/autop-4.3.0.tgz", - "integrity": "sha512-ml34lWwTPZwD2QYTRcecC94KC/V4SBHaCetlEUz0GPzhyfi48Zku6RCoebMDmayqYlme1iF/4quC4zOA0QLoAg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/autop/-/autop-4.5.0.tgz", + "integrity": "sha512-r68rGyfig+qxonsGQTOOWVpxnmGRYlWgzvDlGRPQbM3KKHA46C7ZS0kYhiZ1RC1RTinLRsu+KX2Y3FbEWcNaWg==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -9456,9 +9456,9 @@ "license": "GPL-2.0-or-later" }, "node_modules/@wordpress/blob": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/blob/-/blob-4.3.0.tgz", - "integrity": "sha512-4BQMpcamwx/2rYGZpvcrmddTuo+hXnDtiylvzP0vAnukJ9p1ae2MGJrWCRNp1qNo/hRbyq8lzA43wgOFxKkp0g==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/blob/-/blob-4.5.0.tgz", + "integrity": "sha512-EVTa4duxIesuRc9p8GWEGb3067v30tEngR+ZF1CoVrboRusJ8WSYtQdmEIvJRgQt3t7WTUtc6P4uAFjONOqU0g==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -9469,44 +9469,44 @@ } }, "node_modules/@wordpress/block-editor": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-13.3.0.tgz", - "integrity": "sha512-z83dKTRSeTe0SbyECQ3LQ3f+6Wqv01Y861f9g9vXQdSobrOH3Q0sBUO90ulcfEC4fna57nIi70SgaCG+aXJGUA==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-14.0.0.tgz", + "integrity": "sha512-IODsUPm37DpZxLMcJXidlHeUAvALX+E9edY+z9UGJWP/PvhLCXllCRVQABcuYkPTsraFSF0Yrk9i/7WJF2NkaA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", "@emotion/react": "^11.7.1", "@emotion/styled": "^11.6.0", "@react-spring/web": "^9.4.5", - "@wordpress/a11y": "^4.3.0", - "@wordpress/api-fetch": "^7.3.0", - "@wordpress/blob": "^4.3.0", - "@wordpress/blocks": "^13.3.0", - "@wordpress/commands": "^1.3.0", - "@wordpress/components": "^28.3.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/data": "^10.3.0", - "@wordpress/date": "^5.3.0", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/dom": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/escape-html": "^3.3.0", - "@wordpress/hooks": "^4.3.0", - "@wordpress/html-entities": "^4.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/icons": "^10.3.0", - "@wordpress/is-shallow-equal": "^5.3.0", - "@wordpress/keyboard-shortcuts": "^5.3.0", - "@wordpress/keycodes": "^4.3.0", - "@wordpress/notices": "^5.3.0", - "@wordpress/preferences": "^4.3.0", - "@wordpress/private-apis": "^1.3.0", - "@wordpress/rich-text": "^7.3.0", - "@wordpress/style-engine": "^2.3.0", - "@wordpress/token-list": "^3.3.0", - "@wordpress/url": "^4.3.0", - "@wordpress/warning": "^3.3.0", - "@wordpress/wordcount": "^4.3.0", + "@wordpress/a11y": "^4.5.0", + "@wordpress/api-fetch": "^7.5.0", + "@wordpress/blob": "^4.5.0", + "@wordpress/blocks": "^13.5.0", + "@wordpress/commands": "^1.5.0", + "@wordpress/components": "^28.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/date": "^5.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/dom": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/escape-html": "^3.5.0", + "@wordpress/hooks": "^4.5.0", + "@wordpress/html-entities": "^4.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/icons": "^10.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/keyboard-shortcuts": "^5.5.0", + "@wordpress/keycodes": "^4.5.0", + "@wordpress/notices": "^5.5.0", + "@wordpress/preferences": "^4.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/rich-text": "^7.5.0", + "@wordpress/style-engine": "^2.5.0", + "@wordpress/token-list": "^3.5.0", + "@wordpress/url": "^4.5.0", + "@wordpress/warning": "^3.5.0", + "@wordpress/wordcount": "^4.5.0", "change-case": "^4.1.2", "clsx": "^2.1.1", "colord": "^2.7.0", @@ -9531,13 +9531,13 @@ } }, "node_modules/@wordpress/block-editor/node_modules/@wordpress/keycodes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.3.0.tgz", - "integrity": "sha512-o+L110/Y9ufS2eWVG1gXFs6+jPsMNVZoGJCt4PLjMmVabke0iaYstFppUdtQiOEDbnnhX9MH3RRtqp2AoSnaRQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0" + "@wordpress/i18n": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -9545,9 +9545,9 @@ } }, "node_modules/@wordpress/block-editor/node_modules/@wordpress/warning": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.3.0.tgz", - "integrity": "sha512-n82aKCxuGRNwAtSLaycErJuhKgfOc+KtiljyQITPperMh9i8bH6I+JxtYiu+aLMaY5vrVLVb+/kCzKuWVQIKPA==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.5.0.tgz", + "integrity": "sha512-cYM2Vqf2EokJJoWHD5Ry15OUmdsKtDgR8/qxE0sWHUAdSQeoTuJZnqhgYI898cZGxHaZWX2xJCxQa7Qtwl8lqw==", "dev": true, "engines": { "node": ">=18.12.0", @@ -9613,24 +9613,96 @@ "react-dom": "^18.0.0" } }, + "node_modules/@wordpress/block-library/node_modules/@wordpress/block-editor": { + "version": "13.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-13.4.0.tgz", + "integrity": "sha512-J2XwsngpxLaue8EROloT6KyRFjCk8JCl/K9UalEkrpYFFj084z7/px6LT6300Maue0ejkN8I3X4/XOe0tgOdbQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@emotion/react": "^11.7.1", + "@emotion/styled": "^11.6.0", + "@react-spring/web": "^9.4.5", + "@wordpress/a11y": "^4.4.0", + "@wordpress/api-fetch": "^7.4.0", + "@wordpress/blob": "^4.4.0", + "@wordpress/blocks": "^13.4.0", + "@wordpress/commands": "^1.4.0", + "@wordpress/components": "^28.4.0", + "@wordpress/compose": "^7.4.0", + "@wordpress/data": "^10.4.0", + "@wordpress/date": "^5.4.0", + "@wordpress/deprecated": "^4.4.0", + "@wordpress/dom": "^4.4.0", + "@wordpress/element": "^6.4.0", + "@wordpress/escape-html": "^3.4.0", + "@wordpress/hooks": "^4.4.0", + "@wordpress/html-entities": "^4.4.0", + "@wordpress/i18n": "^5.4.0", + "@wordpress/icons": "^10.4.0", + "@wordpress/is-shallow-equal": "^5.4.0", + "@wordpress/keyboard-shortcuts": "^5.4.0", + "@wordpress/keycodes": "^4.4.0", + "@wordpress/notices": "^5.4.0", + "@wordpress/preferences": "^4.4.0", + "@wordpress/private-apis": "^1.4.0", + "@wordpress/rich-text": "^7.4.0", + "@wordpress/style-engine": "^2.4.0", + "@wordpress/token-list": "^3.4.0", + "@wordpress/url": "^4.4.0", + "@wordpress/warning": "^3.4.0", + "@wordpress/wordcount": "^4.4.0", + "change-case": "^4.1.2", + "clsx": "^2.1.1", + "colord": "^2.7.0", + "deepmerge": "^4.3.0", + "diff": "^4.0.2", + "fast-deep-equal": "^3.1.3", + "memize": "^2.1.0", + "postcss": "^8.4.21", + "postcss-prefixwrap": "^1.41.0", + "postcss-urlrebase": "^1.4.0", + "react-autosize-textarea": "^7.1.0", + "react-easy-crop": "^5.0.6", + "remove-accents": "^0.5.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, "node_modules/@wordpress/block-library/node_modules/@wordpress/keycodes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.3.0.tgz", - "integrity": "sha512-o+L110/Y9ufS2eWVG1gXFs6+jPsMNVZoGJCt4PLjMmVabke0iaYstFppUdtQiOEDbnnhX9MH3RRtqp2AoSnaRQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0" + "@wordpress/i18n": "^5.5.0" }, "engines": { "node": ">=18.12.0", "npm": ">=8.19.2" } }, + "node_modules/@wordpress/block-library/node_modules/@wordpress/warning": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.5.0.tgz", + "integrity": "sha512-cYM2Vqf2EokJJoWHD5Ry15OUmdsKtDgR8/qxE0sWHUAdSQeoTuJZnqhgYI898cZGxHaZWX2xJCxQa7Qtwl8lqw==", + "dev": true, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, "node_modules/@wordpress/block-serialization-default-parser": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/block-serialization-default-parser/-/block-serialization-default-parser-5.3.0.tgz", - "integrity": "sha512-H9xXMIqShBdMbt2cRmct+nDy/dzX9last1j3kwJ5Gr0WfvgSLXQOk3p7jnCYYbixgK08VzLvkfqEofg314QSbg==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-serialization-default-parser/-/block-serialization-default-parser-5.5.0.tgz", + "integrity": "sha512-tUQ9LDFXbMvJY+BYI6lPqucwwSWISe9voBdwwYAbHfHcAcS5veYMdZGREOYpXNgmgd+RCI4+j49oy3EwqUUr4w==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -9641,26 +9713,27 @@ } }, "node_modules/@wordpress/blocks": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/blocks/-/blocks-13.3.0.tgz", - "integrity": "sha512-Df0aW+IardBoiWwLopqex450s7HQjP+QRfD4Pi8Skr5ELuVxwPRAJK9Dv4X2eLQyEPIucErIBjgW6tcSXNIhQQ==", + "version": "13.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/blocks/-/blocks-13.5.0.tgz", + "integrity": "sha512-k8XSlVJQZ/HaZKib7HKILwi4MKMH8UxfdsB2j55Ed41v0exkV42wSK12H8IhFx6GXN/iy13m/f0tsIVGM4ZtIQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/autop": "^4.3.0", - "@wordpress/blob": "^4.3.0", - "@wordpress/block-serialization-default-parser": "^5.3.0", - "@wordpress/data": "^10.3.0", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/dom": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/hooks": "^4.3.0", - "@wordpress/html-entities": "^4.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/is-shallow-equal": "^5.3.0", - "@wordpress/private-apis": "^1.3.0", - "@wordpress/rich-text": "^7.3.0", - "@wordpress/shortcode": "^4.3.0", + "@wordpress/autop": "^4.5.0", + "@wordpress/blob": "^4.5.0", + "@wordpress/block-serialization-default-parser": "^5.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/dom": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/hooks": "^4.5.0", + "@wordpress/html-entities": "^4.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/rich-text": "^7.5.0", + "@wordpress/shortcode": "^4.5.0", + "@wordpress/warning": "^3.5.0", "change-case": "^4.1.2", "colord": "^2.7.0", "fast-deep-equal": "^3.1.3", @@ -9678,52 +9751,440 @@ "npm": ">=8.19.2" }, "peerDependencies": { - "react": "^18.0.0" + "react": "^18.0.0" + } + }, + "node_modules/@wordpress/blocks/node_modules/@wordpress/warning": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.5.0.tgz", + "integrity": "sha512-cYM2Vqf2EokJJoWHD5Ry15OUmdsKtDgR8/qxE0sWHUAdSQeoTuJZnqhgYI898cZGxHaZWX2xJCxQa7Qtwl8lqw==", + "dev": true, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, + "node_modules/@wordpress/browserslist-config": { + "version": "5.41.0", + "resolved": "https://registry.npmjs.org/@wordpress/browserslist-config/-/browserslist-config-5.41.0.tgz", + "integrity": "sha512-J7ejzzDpPZddVIiq2YiK8J/pNTJDy3X1s+5ZtwkwklCxBMZJurxf9pEhtbaf7us0Q6c1j8Ubv7Fpx3lqk2ypxA==", + "dev": true, + "license": "GPL-2.0-or-later", + "engines": { + "node": ">=14" + } + }, + "node_modules/@wordpress/commands": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/commands/-/commands-1.5.0.tgz", + "integrity": "sha512-44BoBnVkdOllkrqXY1lcjdEXzyQrk3WF7hC6IjBgGHhXtdHm4ejn1VthLiAlK2KeA+M/XT5H/x1AiAhpnsrToA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@wordpress/components": "^28.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/icons": "^10.5.0", + "@wordpress/keyboard-shortcuts": "^5.5.0", + "@wordpress/private-apis": "^1.5.0", + "clsx": "^2.1.1", + "cmdk": "^1.0.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.1.tgz", + "integrity": "sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-compose-refs": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz", + "integrity": "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-context": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.1.tgz", + "integrity": "sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-dialog": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.0.5.tgz", + "integrity": "sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.5", + "@radix-ui/react-focus-guards": "1.0.1", + "@radix-ui/react-focus-scope": "1.0.4", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-portal": "1.0.4", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-slot": "1.0.2", + "@radix-ui/react-use-controllable-state": "1.0.1", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.5" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.5.tgz", + "integrity": "sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1", + "@radix-ui/react-use-escape-keydown": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-focus-guards": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz", + "integrity": "sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-focus-scope": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.4.tgz", + "integrity": "sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-id": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.1.tgz", + "integrity": "sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-layout-effect": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-portal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.4.tgz", + "integrity": "sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-presence": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.1.tgz", + "integrity": "sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-primitive": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz", + "integrity": "sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-slot": "1.0.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-slot": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz", + "integrity": "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz", + "integrity": "sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.1.tgz", + "integrity": "sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz", + "integrity": "sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.1.tgz", + "integrity": "sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@wordpress/browserslist-config": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/@wordpress/browserslist-config/-/browserslist-config-5.41.0.tgz", - "integrity": "sha512-J7ejzzDpPZddVIiq2YiK8J/pNTJDy3X1s+5ZtwkwklCxBMZJurxf9pEhtbaf7us0Q6c1j8Ubv7Fpx3lqk2ypxA==", + "node_modules/@wordpress/commands/node_modules/cmdk": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cmdk/-/cmdk-1.0.0.tgz", + "integrity": "sha512-gDzVf0a09TvoJ5jnuPvygTB77+XdOSwEmJ88L6XPFPlv7T3RxbP9jgenfylrAMD0+Le1aO0nVjQUzl2g+vjz5Q==", "dev": true, - "license": "GPL-2.0-or-later", - "engines": { - "node": ">=14" + "dependencies": { + "@radix-ui/react-dialog": "1.0.5", + "@radix-ui/react-primitive": "1.0.3" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, - "node_modules/@wordpress/commands": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/commands/-/commands-1.3.0.tgz", - "integrity": "sha512-6toFSZTYfNPqHBG2IxuClZ7uZpuXsV7kJRjC+liy3ew1U6vG/Xx9Ps4gvUT1lun6uRsYmftTEqV9GUz2V6IadA==", + "node_modules/@wordpress/commands/node_modules/react-remove-scroll": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz", + "integrity": "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==", "dev": true, "dependencies": { - "@babel/runtime": "^7.16.0", - "@wordpress/components": "^28.3.0", - "@wordpress/data": "^10.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/icons": "^10.3.0", - "@wordpress/keyboard-shortcuts": "^5.3.0", - "@wordpress/private-apis": "^1.3.0", - "clsx": "^2.1.1", - "cmdk": "^0.2.0" + "react-remove-scroll-bar": "^2.3.3", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" }, "engines": { - "node": ">=18.12.0", - "npm": ">=8.19.2" + "node": ">=10" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, "node_modules/@wordpress/components": { - "version": "28.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-28.3.0.tgz", - "integrity": "sha512-zLHtxmhbuD7j5f7wOqRu6+KYVWPRpgHsYzxOavWkkiKv0XUvWeYWBIZFM4oy6A1WJqW2nEELcAjIeBX/0UWMig==", + "version": "28.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-28.5.0.tgz", + "integrity": "sha512-kZPb8MdpGW/Yv/ycJhbf+myb4czkyQ28gb5PY1kT2ABRB07J3oS1/badSLex3x06zD6NPtJt3kInbPUsSF2prQ==", "dev": true, "dependencies": { - "@ariakit/react": "^0.3.12", + "@ariakit/react": "^0.4.7", "@babel/runtime": "^7.16.0", "@emotion/cache": "^11.7.1", "@emotion/css": "^11.7.1", @@ -9735,29 +10196,28 @@ "@types/gradient-parser": "0.1.3", "@types/highlight-words-core": "1.2.1", "@use-gesture/react": "^10.3.1", - "@wordpress/a11y": "^4.3.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/date": "^5.3.0", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/dom": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/escape-html": "^3.3.0", - "@wordpress/hooks": "^4.3.0", - "@wordpress/html-entities": "^4.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/icons": "^10.3.0", - "@wordpress/is-shallow-equal": "^5.3.0", - "@wordpress/keycodes": "^4.3.0", - "@wordpress/primitives": "^4.3.0", - "@wordpress/private-apis": "^1.3.0", - "@wordpress/rich-text": "^7.3.0", - "@wordpress/warning": "^3.3.0", + "@wordpress/a11y": "^4.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/date": "^5.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/dom": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/escape-html": "^3.5.0", + "@wordpress/hooks": "^4.5.0", + "@wordpress/html-entities": "^4.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/icons": "^10.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/keycodes": "^4.5.0", + "@wordpress/primitives": "^4.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/rich-text": "^7.5.0", + "@wordpress/warning": "^3.5.0", "change-case": "^4.1.2", "clsx": "^2.1.1", "colord": "^2.7.0", "date-fns": "^3.6.0", "deepmerge": "^4.3.0", - "downshift": "^6.0.15", "fast-deep-equal": "^3.1.3", "framer-motion": "^11.1.9", "gradient-parser": "^0.1.5", @@ -9780,14 +10240,52 @@ "react-dom": "^18.0.0" } }, + "node_modules/@wordpress/components/node_modules/@ariakit/core": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/@ariakit/core/-/core-0.4.8.tgz", + "integrity": "sha512-HQS+9CI7pMqqVlAt5bPGenT0/e65UxXY+PKtgU7Y+0UToBDBRolO5S9+UUSDm8OmJHSnq24owEGm1Mv28l5XCQ==", + "dev": true + }, + "node_modules/@wordpress/components/node_modules/@ariakit/react": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/@ariakit/react/-/react-0.4.8.tgz", + "integrity": "sha512-Bb1vOrp0X52hxi1wE9TEHjjZ/Y08tVq2ZH+RFDwRQB3g04uVwrrhnTccHepC6rsObrDpAOV3/YlJCi4k/lSUaQ==", + "dev": true, + "dependencies": { + "@ariakit/react-core": "0.4.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ariakit" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@wordpress/components/node_modules/@ariakit/react-core": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/@ariakit/react-core/-/react-core-0.4.8.tgz", + "integrity": "sha512-TzsddUWQwWYhrEVWHA/Gf7KCGx8rwFohAHfuljjqidKeZi2kUmuRAImCTG9oga34FWHFf4AdXQbBKclMNt0nrQ==", + "dev": true, + "dependencies": { + "@ariakit/core": "0.4.8", + "@floating-ui/dom": "^1.0.0", + "use-sync-external-store": "^1.2.0" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/@wordpress/components/node_modules/@wordpress/keycodes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.3.0.tgz", - "integrity": "sha512-o+L110/Y9ufS2eWVG1gXFs6+jPsMNVZoGJCt4PLjMmVabke0iaYstFppUdtQiOEDbnnhX9MH3RRtqp2AoSnaRQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0" + "@wordpress/i18n": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -9795,9 +10293,9 @@ } }, "node_modules/@wordpress/components/node_modules/@wordpress/warning": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.3.0.tgz", - "integrity": "sha512-n82aKCxuGRNwAtSLaycErJuhKgfOc+KtiljyQITPperMh9i8bH6I+JxtYiu+aLMaY5vrVLVb+/kCzKuWVQIKPA==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.5.0.tgz", + "integrity": "sha512-cYM2Vqf2EokJJoWHD5Ry15OUmdsKtDgR8/qxE0sWHUAdSQeoTuJZnqhgYI898cZGxHaZWX2xJCxQa7Qtwl8lqw==", "dev": true, "engines": { "node": ">=18.12.0", @@ -9805,20 +10303,20 @@ } }, "node_modules/@wordpress/compose": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-7.3.0.tgz", - "integrity": "sha512-TtAYdKnqQ/L/nF0+fmlQ1wAvm90X9HRBrAuEMNmkzKhews/5GR0rR3dNSMjlf7C6mNdTO3mkYt6AQf9fvZFoiQ==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-7.5.0.tgz", + "integrity": "sha512-jWRmleIGxmvTIC/1VYtAvq0iRfCkW/AtlNmqoKiyd0Ah5lccWRtxSH5V3Vh1BEkBQRANMWxJpOpRTKDFTcfTvg==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", "@types/mousetrap": "^1.6.8", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/dom": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/is-shallow-equal": "^5.3.0", - "@wordpress/keycodes": "^4.3.0", - "@wordpress/priority-queue": "^3.3.0", - "@wordpress/undo-manager": "^1.3.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/dom": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/keycodes": "^4.5.0", + "@wordpress/priority-queue": "^3.5.0", + "@wordpress/undo-manager": "^1.5.0", "change-case": "^4.1.2", "clipboard": "^2.0.11", "mousetrap": "^1.6.5", @@ -9833,13 +10331,13 @@ } }, "node_modules/@wordpress/compose/node_modules/@wordpress/keycodes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.3.0.tgz", - "integrity": "sha512-o+L110/Y9ufS2eWVG1gXFs6+jPsMNVZoGJCt4PLjMmVabke0iaYstFppUdtQiOEDbnnhX9MH3RRtqp2AoSnaRQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0" + "@wordpress/i18n": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -9875,6 +10373,92 @@ "react-dom": "^18.0.0" } }, + "node_modules/@wordpress/core-commands/node_modules/@wordpress/block-editor": { + "version": "13.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-13.4.0.tgz", + "integrity": "sha512-J2XwsngpxLaue8EROloT6KyRFjCk8JCl/K9UalEkrpYFFj084z7/px6LT6300Maue0ejkN8I3X4/XOe0tgOdbQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@emotion/react": "^11.7.1", + "@emotion/styled": "^11.6.0", + "@react-spring/web": "^9.4.5", + "@wordpress/a11y": "^4.4.0", + "@wordpress/api-fetch": "^7.4.0", + "@wordpress/blob": "^4.4.0", + "@wordpress/blocks": "^13.4.0", + "@wordpress/commands": "^1.4.0", + "@wordpress/components": "^28.4.0", + "@wordpress/compose": "^7.4.0", + "@wordpress/data": "^10.4.0", + "@wordpress/date": "^5.4.0", + "@wordpress/deprecated": "^4.4.0", + "@wordpress/dom": "^4.4.0", + "@wordpress/element": "^6.4.0", + "@wordpress/escape-html": "^3.4.0", + "@wordpress/hooks": "^4.4.0", + "@wordpress/html-entities": "^4.4.0", + "@wordpress/i18n": "^5.4.0", + "@wordpress/icons": "^10.4.0", + "@wordpress/is-shallow-equal": "^5.4.0", + "@wordpress/keyboard-shortcuts": "^5.4.0", + "@wordpress/keycodes": "^4.4.0", + "@wordpress/notices": "^5.4.0", + "@wordpress/preferences": "^4.4.0", + "@wordpress/private-apis": "^1.4.0", + "@wordpress/rich-text": "^7.4.0", + "@wordpress/style-engine": "^2.4.0", + "@wordpress/token-list": "^3.4.0", + "@wordpress/url": "^4.4.0", + "@wordpress/warning": "^3.4.0", + "@wordpress/wordcount": "^4.4.0", + "change-case": "^4.1.2", + "clsx": "^2.1.1", + "colord": "^2.7.0", + "deepmerge": "^4.3.0", + "diff": "^4.0.2", + "fast-deep-equal": "^3.1.3", + "memize": "^2.1.0", + "postcss": "^8.4.21", + "postcss-prefixwrap": "^1.41.0", + "postcss-urlrebase": "^1.4.0", + "react-autosize-textarea": "^7.1.0", + "react-easy-crop": "^5.0.6", + "remove-accents": "^0.5.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@wordpress/core-commands/node_modules/@wordpress/keycodes": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@wordpress/i18n": "^5.5.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, + "node_modules/@wordpress/core-commands/node_modules/@wordpress/warning": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.5.0.tgz", + "integrity": "sha512-cYM2Vqf2EokJJoWHD5Ry15OUmdsKtDgR8/qxE0sWHUAdSQeoTuJZnqhgYI898cZGxHaZWX2xJCxQa7Qtwl8lqw==", + "dev": true, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, "node_modules/@wordpress/core-data": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/@wordpress/core-data/-/core-data-7.3.0.tgz", @@ -9912,20 +10496,106 @@ "react-dom": "^18.0.0" } }, + "node_modules/@wordpress/core-data/node_modules/@wordpress/block-editor": { + "version": "13.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-13.4.0.tgz", + "integrity": "sha512-J2XwsngpxLaue8EROloT6KyRFjCk8JCl/K9UalEkrpYFFj084z7/px6LT6300Maue0ejkN8I3X4/XOe0tgOdbQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@emotion/react": "^11.7.1", + "@emotion/styled": "^11.6.0", + "@react-spring/web": "^9.4.5", + "@wordpress/a11y": "^4.4.0", + "@wordpress/api-fetch": "^7.4.0", + "@wordpress/blob": "^4.4.0", + "@wordpress/blocks": "^13.4.0", + "@wordpress/commands": "^1.4.0", + "@wordpress/components": "^28.4.0", + "@wordpress/compose": "^7.4.0", + "@wordpress/data": "^10.4.0", + "@wordpress/date": "^5.4.0", + "@wordpress/deprecated": "^4.4.0", + "@wordpress/dom": "^4.4.0", + "@wordpress/element": "^6.4.0", + "@wordpress/escape-html": "^3.4.0", + "@wordpress/hooks": "^4.4.0", + "@wordpress/html-entities": "^4.4.0", + "@wordpress/i18n": "^5.4.0", + "@wordpress/icons": "^10.4.0", + "@wordpress/is-shallow-equal": "^5.4.0", + "@wordpress/keyboard-shortcuts": "^5.4.0", + "@wordpress/keycodes": "^4.4.0", + "@wordpress/notices": "^5.4.0", + "@wordpress/preferences": "^4.4.0", + "@wordpress/private-apis": "^1.4.0", + "@wordpress/rich-text": "^7.4.0", + "@wordpress/style-engine": "^2.4.0", + "@wordpress/token-list": "^3.4.0", + "@wordpress/url": "^4.4.0", + "@wordpress/warning": "^3.4.0", + "@wordpress/wordcount": "^4.4.0", + "change-case": "^4.1.2", + "clsx": "^2.1.1", + "colord": "^2.7.0", + "deepmerge": "^4.3.0", + "diff": "^4.0.2", + "fast-deep-equal": "^3.1.3", + "memize": "^2.1.0", + "postcss": "^8.4.21", + "postcss-prefixwrap": "^1.41.0", + "postcss-urlrebase": "^1.4.0", + "react-autosize-textarea": "^7.1.0", + "react-easy-crop": "^5.0.6", + "remove-accents": "^0.5.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@wordpress/core-data/node_modules/@wordpress/keycodes": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@wordpress/i18n": "^5.5.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, + "node_modules/@wordpress/core-data/node_modules/@wordpress/warning": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.5.0.tgz", + "integrity": "sha512-cYM2Vqf2EokJJoWHD5Ry15OUmdsKtDgR8/qxE0sWHUAdSQeoTuJZnqhgYI898cZGxHaZWX2xJCxQa7Qtwl8lqw==", + "dev": true, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, "node_modules/@wordpress/data": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-10.3.0.tgz", - "integrity": "sha512-cImJw4k30coosH6QtiJllxEYr93w8981PPvhGhemMbRQ28MnSA7rbJPv3h2LO9oss5SQH1gU9kwNGAZcF6PMPg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-10.5.0.tgz", + "integrity": "sha512-Y2P5SC0fuTivcfdYmubL3c15WRbE0FJAyYcEfZeJ2C37a2DmBnCBz3uEzGy2kCilz56qMfK0qutAHkfytOpRQw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/is-shallow-equal": "^5.3.0", - "@wordpress/priority-queue": "^3.3.0", - "@wordpress/private-apis": "^1.3.0", - "@wordpress/redux-routine": "^5.3.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/priority-queue": "^3.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/redux-routine": "^5.5.0", "deepmerge": "^4.3.0", "equivalent-key-map": "^0.2.2", "is-plain-object": "^5.0.0", @@ -9970,13 +10640,13 @@ } }, "node_modules/@wordpress/date": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/date/-/date-5.3.0.tgz", - "integrity": "sha512-vD0rLQxNlOoFd4n32HohhTif4P1JPW/Igjp0c/O2WZji+eXQM6P54fBu5veKvgwMmXpUn8y0xzgssj3pKAUgCg==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/date/-/date-5.5.0.tgz", + "integrity": "sha512-dIo02TAIuXG/wkcVf+jsyXn64PUVsxs6HwuHanNiDNVZt95QVJ8b7wdJZNIrhTkmVXhIUzYAz5BpuXUC6IZAqg==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/deprecated": "^4.3.0", + "@wordpress/deprecated": "^4.5.0", "moment": "^2.29.4", "moment-timezone": "^0.5.40" }, @@ -10002,13 +10672,13 @@ } }, "node_modules/@wordpress/deprecated": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-4.3.0.tgz", - "integrity": "sha512-K2GHXlwjx6GMhZjs52X1MXySCrqzh4IjoqF5IOcydMgWqOIE2++hMuB9Y55qN/Mhsrv/HO8Q1LaTxbEd6BuNJQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-4.5.0.tgz", + "integrity": "sha512-r3xGAM45XTd+z+hnUvLGtSz+Y0ebybuw/cyE0CatksJBGvXez3kiTDaknALkgzjHRZzIGpNu6XTVUoIJs0H39A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/hooks": "^4.3.0" + "@wordpress/hooks": "^4.5.0" }, "engines": { "node": ">=18.12.0", @@ -10016,13 +10686,13 @@ } }, "node_modules/@wordpress/dom": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-4.3.0.tgz", - "integrity": "sha512-sf4h6jVqboRdhe3soyr5bt+Vpz24WG/AIMHm7pGaxfbV5jxx06ZZ8K1RKzhr7jF3wn7IgIc1wmMA+OFzEYqGyw==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-4.5.0.tgz", + "integrity": "sha512-XjnpRbbhZ1hdgv758vSXQacjfy/N0H2oI0oWukrLmlkKDP5ZrGfdziHQ2+KcoW+QDx8pu4JYcUpjmuJLugDStw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/deprecated": "^4.3.0" + "@wordpress/deprecated": "^4.5.0" }, "engines": { "node": ">=18.12.0", @@ -10030,9 +10700,9 @@ } }, "node_modules/@wordpress/dom-ready": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/dom-ready/-/dom-ready-4.3.0.tgz", - "integrity": "sha512-zuLLMIeJt1hZ95R4kdJFcsIaL2eud1kF40VCmwK3mK0qpgXv/1avtGX8lx6DMLL/GGL1yYcJhR13RSKSjxuGEQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom-ready/-/dom-ready-4.5.0.tgz", + "integrity": "sha512-5dALG1lQtoH/Rk7DWFe9DaIF2bQQM5U0x+c1lQnk1cnBJ69AijIcbZMYaMzlgngo4dVF2PnFZ/VKVSUOKghhQQ==", "dependencies": { "@babel/runtime": "^7.16.0" }, @@ -10213,14 +10883,76 @@ "react-dom": "^18.0.0" } }, + "node_modules/@wordpress/edit-post/node_modules/@wordpress/block-editor": { + "version": "13.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-13.4.0.tgz", + "integrity": "sha512-J2XwsngpxLaue8EROloT6KyRFjCk8JCl/K9UalEkrpYFFj084z7/px6LT6300Maue0ejkN8I3X4/XOe0tgOdbQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@emotion/react": "^11.7.1", + "@emotion/styled": "^11.6.0", + "@react-spring/web": "^9.4.5", + "@wordpress/a11y": "^4.4.0", + "@wordpress/api-fetch": "^7.4.0", + "@wordpress/blob": "^4.4.0", + "@wordpress/blocks": "^13.4.0", + "@wordpress/commands": "^1.4.0", + "@wordpress/components": "^28.4.0", + "@wordpress/compose": "^7.4.0", + "@wordpress/data": "^10.4.0", + "@wordpress/date": "^5.4.0", + "@wordpress/deprecated": "^4.4.0", + "@wordpress/dom": "^4.4.0", + "@wordpress/element": "^6.4.0", + "@wordpress/escape-html": "^3.4.0", + "@wordpress/hooks": "^4.4.0", + "@wordpress/html-entities": "^4.4.0", + "@wordpress/i18n": "^5.4.0", + "@wordpress/icons": "^10.4.0", + "@wordpress/is-shallow-equal": "^5.4.0", + "@wordpress/keyboard-shortcuts": "^5.4.0", + "@wordpress/keycodes": "^4.4.0", + "@wordpress/notices": "^5.4.0", + "@wordpress/preferences": "^4.4.0", + "@wordpress/private-apis": "^1.4.0", + "@wordpress/rich-text": "^7.4.0", + "@wordpress/style-engine": "^2.4.0", + "@wordpress/token-list": "^3.4.0", + "@wordpress/url": "^4.4.0", + "@wordpress/warning": "^3.4.0", + "@wordpress/wordcount": "^4.4.0", + "change-case": "^4.1.2", + "clsx": "^2.1.1", + "colord": "^2.7.0", + "deepmerge": "^4.3.0", + "diff": "^4.0.2", + "fast-deep-equal": "^3.1.3", + "memize": "^2.1.0", + "postcss": "^8.4.21", + "postcss-prefixwrap": "^1.41.0", + "postcss-urlrebase": "^1.4.0", + "react-autosize-textarea": "^7.1.0", + "react-easy-crop": "^5.0.6", + "remove-accents": "^0.5.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, "node_modules/@wordpress/edit-post/node_modules/@wordpress/keycodes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.3.0.tgz", - "integrity": "sha512-o+L110/Y9ufS2eWVG1gXFs6+jPsMNVZoGJCt4PLjMmVabke0iaYstFppUdtQiOEDbnnhX9MH3RRtqp2AoSnaRQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0" + "@wordpress/i18n": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -10228,9 +10960,9 @@ } }, "node_modules/@wordpress/edit-post/node_modules/@wordpress/warning": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.3.0.tgz", - "integrity": "sha512-n82aKCxuGRNwAtSLaycErJuhKgfOc+KtiljyQITPperMh9i8bH6I+JxtYiu+aLMaY5vrVLVb+/kCzKuWVQIKPA==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.5.0.tgz", + "integrity": "sha512-cYM2Vqf2EokJJoWHD5Ry15OUmdsKtDgR8/qxE0sWHUAdSQeoTuJZnqhgYI898cZGxHaZWX2xJCxQa7Qtwl8lqw==", "dev": true, "engines": { "node": ">=18.12.0", @@ -10298,14 +11030,76 @@ "react-dom": "^18.0.0" } }, + "node_modules/@wordpress/editor/node_modules/@wordpress/block-editor": { + "version": "13.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-13.4.0.tgz", + "integrity": "sha512-J2XwsngpxLaue8EROloT6KyRFjCk8JCl/K9UalEkrpYFFj084z7/px6LT6300Maue0ejkN8I3X4/XOe0tgOdbQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@emotion/react": "^11.7.1", + "@emotion/styled": "^11.6.0", + "@react-spring/web": "^9.4.5", + "@wordpress/a11y": "^4.4.0", + "@wordpress/api-fetch": "^7.4.0", + "@wordpress/blob": "^4.4.0", + "@wordpress/blocks": "^13.4.0", + "@wordpress/commands": "^1.4.0", + "@wordpress/components": "^28.4.0", + "@wordpress/compose": "^7.4.0", + "@wordpress/data": "^10.4.0", + "@wordpress/date": "^5.4.0", + "@wordpress/deprecated": "^4.4.0", + "@wordpress/dom": "^4.4.0", + "@wordpress/element": "^6.4.0", + "@wordpress/escape-html": "^3.4.0", + "@wordpress/hooks": "^4.4.0", + "@wordpress/html-entities": "^4.4.0", + "@wordpress/i18n": "^5.4.0", + "@wordpress/icons": "^10.4.0", + "@wordpress/is-shallow-equal": "^5.4.0", + "@wordpress/keyboard-shortcuts": "^5.4.0", + "@wordpress/keycodes": "^4.4.0", + "@wordpress/notices": "^5.4.0", + "@wordpress/preferences": "^4.4.0", + "@wordpress/private-apis": "^1.4.0", + "@wordpress/rich-text": "^7.4.0", + "@wordpress/style-engine": "^2.4.0", + "@wordpress/token-list": "^3.4.0", + "@wordpress/url": "^4.4.0", + "@wordpress/warning": "^3.4.0", + "@wordpress/wordcount": "^4.4.0", + "change-case": "^4.1.2", + "clsx": "^2.1.1", + "colord": "^2.7.0", + "deepmerge": "^4.3.0", + "diff": "^4.0.2", + "fast-deep-equal": "^3.1.3", + "memize": "^2.1.0", + "postcss": "^8.4.21", + "postcss-prefixwrap": "^1.41.0", + "postcss-urlrebase": "^1.4.0", + "react-autosize-textarea": "^7.1.0", + "react-easy-crop": "^5.0.6", + "remove-accents": "^0.5.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, "node_modules/@wordpress/editor/node_modules/@wordpress/keycodes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.3.0.tgz", - "integrity": "sha512-o+L110/Y9ufS2eWVG1gXFs6+jPsMNVZoGJCt4PLjMmVabke0iaYstFppUdtQiOEDbnnhX9MH3RRtqp2AoSnaRQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0" + "@wordpress/i18n": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -10313,9 +11107,9 @@ } }, "node_modules/@wordpress/editor/node_modules/@wordpress/warning": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.3.0.tgz", - "integrity": "sha512-n82aKCxuGRNwAtSLaycErJuhKgfOc+KtiljyQITPperMh9i8bH6I+JxtYiu+aLMaY5vrVLVb+/kCzKuWVQIKPA==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.5.0.tgz", + "integrity": "sha512-cYM2Vqf2EokJJoWHD5Ry15OUmdsKtDgR8/qxE0sWHUAdSQeoTuJZnqhgYI898cZGxHaZWX2xJCxQa7Qtwl8lqw==", "dev": true, "engines": { "node": ">=18.12.0", @@ -10323,15 +11117,15 @@ } }, "node_modules/@wordpress/element": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-6.3.0.tgz", - "integrity": "sha512-DsiqzjuXqxJkLUoLomsGTFFxbSZgk+Lz+2/1yFH+BU3jQ6zeD64+JWv8Lt4+fKU154rV0KpfMwfD/oAC/Lp1zQ==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-6.5.0.tgz", + "integrity": "sha512-N9w3jfceltdDEN71jpaMCXU+jbvec9kredvQIn/6YNiUMarPXWth7DJYU3+mDtbYawnTIvytzGjbj/J+bqqdHg==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", "@types/react": "^18.2.79", "@types/react-dom": "^18.2.25", - "@wordpress/escape-html": "^3.3.0", + "@wordpress/escape-html": "^3.5.0", "change-case": "^4.1.2", "is-plain-object": "^5.0.0", "react": "^18.3.0", @@ -10446,9 +11240,9 @@ } }, "node_modules/@wordpress/escape-html": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-3.3.0.tgz", - "integrity": "sha512-Wu/Fq96E28UGnIO5VQW/aEgCiHWvzrD8izDnP8U0WZSuwIPYcS5iYmRe2UWc7rwyoeY2YXNd6xFjgd7oTOKNCA==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-3.5.0.tgz", + "integrity": "sha512-8dUWTmsDZuqAmBtRgk0JpiIafRKPM4n8tqCr147AugTbP/vyQ7rIzG3M/YCtVSmDr6f/qZ32YU8J7c34RhZ/9g==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -10718,9 +11512,9 @@ } }, "node_modules/@wordpress/hooks": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-4.3.0.tgz", - "integrity": "sha512-bpqwSXGyxPfhuxESKoAtL4ofB3CazzvcwcucTZ0g9Pat3KNuBaloSrPBliqqNOiSLWNH3nmpkaRmv4u89EdKAw==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-4.5.0.tgz", + "integrity": "sha512-wr1l1WM1yobyNGFLRgbLNBGtYIkzAGfmbT2e9zIOvqllRJT4wprYTqqhgovOKHlET5ij/TKdv4tApkGLUIXTsA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -10731,9 +11525,9 @@ } }, "node_modules/@wordpress/html-entities": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/html-entities/-/html-entities-4.3.0.tgz", - "integrity": "sha512-rJDf9KjCuUnFwIwmOdN4FcL7RJnDzPxIdvvMoWXkYd9GseEeRTsY6xIG+fGgVGgYe3HwXDYSFCWTF/x2M9Eerg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/html-entities/-/html-entities-4.5.0.tgz", + "integrity": "sha512-iQo2P1Sc499MxguelJ4aMcF08jnYkOdvb+FAOyOfGCyDjEtNbldRFc2BJ9NmJ/9nmtlwc/IzUzXop0M1gjy9tw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -10744,13 +11538,13 @@ } }, "node_modules/@wordpress/i18n": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-5.3.0.tgz", - "integrity": "sha512-edHKkdZb6jNpbn+LUPu2wo1mKyhT819WJ7kI8hmMcHq82rNwwbMfcGoB3oSaphTphWfhlgxIxLczKOAbWDKudw==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-5.5.0.tgz", + "integrity": "sha512-MtCJIjNHCWs7R77f5Xml1CCnVXqrle4cDpqMU9myx4Cq8ZijqSayX1CTtwtk+Z3/3xa+dBZu5Koe4wiW1yIUSA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/hooks": "^4.3.0", + "@wordpress/hooks": "^4.5.0", "gettext-parser": "^1.3.1", "memize": "^2.1.0", "sprintf-js": "^1.1.1", @@ -10765,14 +11559,14 @@ } }, "node_modules/@wordpress/icons": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/icons/-/icons-10.3.0.tgz", - "integrity": "sha512-d2jOFfLIAxPr+/Bzg7wnRDEDPogMpVefe4cHgIx9kXp/+7DG4KWNJm842qVithjs1wVgSzavzWbFrTtPEZ+Uhw==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/icons/-/icons-10.5.0.tgz", + "integrity": "sha512-BZwKBRKoTef9uW73T+FwK6d4JlcvgdVAaz3LB5dCluXg5PLV5ufMdumAaMxKWq/Ffl92/ddt8CKIdHjxfAZF4A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/element": "^6.3.0", - "@wordpress/primitives": "^4.3.0" + "@wordpress/element": "^6.5.0", + "@wordpress/primitives": "^4.5.0" }, "engines": { "node": ">=18.12.0", @@ -10838,9 +11632,9 @@ } }, "node_modules/@wordpress/is-shallow-equal": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-5.3.0.tgz", - "integrity": "sha512-sZ+fypqjYX0/DTAKsm1G9ND9Wn4d3Ju4lI7SLSmCKdUL5EPY3g/2LpKQKDqljh9m6Ex5NWp2XfU8UVXpkEfbMQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-5.5.0.tgz", + "integrity": "sha512-nkCz45HgMBkjhyxffDgpAgJbfnKyZML94/gHhBtxizHfaNuZ5as7DfEyN1xgebvDiLbOaRU7em1pPAuEhIoTfQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -10886,15 +11680,15 @@ } }, "node_modules/@wordpress/keyboard-shortcuts": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/keyboard-shortcuts/-/keyboard-shortcuts-5.3.0.tgz", - "integrity": "sha512-Zms+SzRekXqLBW0IPxZDhusxix5xm6jBmWfOfc//uCy7xvhZS1FxEYoolfYFB7tXT7xFTQbwVYN99ICI7BeqnQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keyboard-shortcuts/-/keyboard-shortcuts-5.5.0.tgz", + "integrity": "sha512-U+64UvlrWjxnn6YJ5ZW7Oi9EJE9J7aWRGzpCAL8yoRDqiVC/zUzvgnVmo9AoA8jVEBxKUeDFyntckCE2qW0STQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/data": "^10.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/keycodes": "^4.3.0" + "@wordpress/data": "^10.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/keycodes": "^4.5.0" }, "engines": { "node": ">=18.12.0", @@ -10905,13 +11699,13 @@ } }, "node_modules/@wordpress/keyboard-shortcuts/node_modules/@wordpress/keycodes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.3.0.tgz", - "integrity": "sha512-o+L110/Y9ufS2eWVG1gXFs6+jPsMNVZoGJCt4PLjMmVabke0iaYstFppUdtQiOEDbnnhX9MH3RRtqp2AoSnaRQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0" + "@wordpress/i18n": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -10984,14 +11778,14 @@ } }, "node_modules/@wordpress/notices": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/notices/-/notices-5.3.0.tgz", - "integrity": "sha512-1aZVcmy3Aj1nn4jmdQDpVFIB7L40AkhW7maFKhEH0oo2UAiPmqJyGDeby9sD96m2hskwyZzAgI15k+KrEf17LQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/notices/-/notices-5.5.0.tgz", + "integrity": "sha512-QcTbGAyHJ7V8LvSDJttUKCmClIFBQQ2/gk7pTBMBwe+argYQLOVRAQP/+97AnP9KFVtzuENrjbQtsyYeMWaTSw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/a11y": "^4.3.0", - "@wordpress/data": "^10.3.0" + "@wordpress/a11y": "^4.5.0", + "@wordpress/data": "^10.5.0" }, "engines": { "node": ">=18.12.0", @@ -11045,6 +11839,92 @@ "react-dom": "^18.0.0" } }, + "node_modules/@wordpress/patterns/node_modules/@wordpress/block-editor": { + "version": "13.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-13.4.0.tgz", + "integrity": "sha512-J2XwsngpxLaue8EROloT6KyRFjCk8JCl/K9UalEkrpYFFj084z7/px6LT6300Maue0ejkN8I3X4/XOe0tgOdbQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@emotion/react": "^11.7.1", + "@emotion/styled": "^11.6.0", + "@react-spring/web": "^9.4.5", + "@wordpress/a11y": "^4.4.0", + "@wordpress/api-fetch": "^7.4.0", + "@wordpress/blob": "^4.4.0", + "@wordpress/blocks": "^13.4.0", + "@wordpress/commands": "^1.4.0", + "@wordpress/components": "^28.4.0", + "@wordpress/compose": "^7.4.0", + "@wordpress/data": "^10.4.0", + "@wordpress/date": "^5.4.0", + "@wordpress/deprecated": "^4.4.0", + "@wordpress/dom": "^4.4.0", + "@wordpress/element": "^6.4.0", + "@wordpress/escape-html": "^3.4.0", + "@wordpress/hooks": "^4.4.0", + "@wordpress/html-entities": "^4.4.0", + "@wordpress/i18n": "^5.4.0", + "@wordpress/icons": "^10.4.0", + "@wordpress/is-shallow-equal": "^5.4.0", + "@wordpress/keyboard-shortcuts": "^5.4.0", + "@wordpress/keycodes": "^4.4.0", + "@wordpress/notices": "^5.4.0", + "@wordpress/preferences": "^4.4.0", + "@wordpress/private-apis": "^1.4.0", + "@wordpress/rich-text": "^7.4.0", + "@wordpress/style-engine": "^2.4.0", + "@wordpress/token-list": "^3.4.0", + "@wordpress/url": "^4.4.0", + "@wordpress/warning": "^3.4.0", + "@wordpress/wordcount": "^4.4.0", + "change-case": "^4.1.2", + "clsx": "^2.1.1", + "colord": "^2.7.0", + "deepmerge": "^4.3.0", + "diff": "^4.0.2", + "fast-deep-equal": "^3.1.3", + "memize": "^2.1.0", + "postcss": "^8.4.21", + "postcss-prefixwrap": "^1.41.0", + "postcss-urlrebase": "^1.4.0", + "react-autosize-textarea": "^7.1.0", + "react-easy-crop": "^5.0.6", + "remove-accents": "^0.5.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@wordpress/patterns/node_modules/@wordpress/keycodes": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@wordpress/i18n": "^5.5.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, + "node_modules/@wordpress/patterns/node_modules/@wordpress/warning": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.5.0.tgz", + "integrity": "sha512-cYM2Vqf2EokJJoWHD5Ry15OUmdsKtDgR8/qxE0sWHUAdSQeoTuJZnqhgYI898cZGxHaZWX2xJCxQa7Qtwl8lqw==", + "dev": true, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, "node_modules/@wordpress/plugins": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/@wordpress/plugins/-/plugins-7.3.0.tgz", @@ -11087,21 +11967,21 @@ } }, "node_modules/@wordpress/preferences": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/preferences/-/preferences-4.3.0.tgz", - "integrity": "sha512-XTPJYjdz8iy9Sy+B+RAPFwk4KkGPgjogu3mhcMvYLqqKKeVhUt6zImXVNXQbNFGTlCgB+l0b4h4L5EHmJWVDgg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/preferences/-/preferences-4.5.0.tgz", + "integrity": "sha512-cDk+StQGyjwWzyo8dmVfdwYvL45hMd+m3qUNbP29PizJb4jPHBLVg4WTabuFG0I5TEs75zIjDWQsb3HeG//cHw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/a11y": "^4.3.0", - "@wordpress/components": "^28.3.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/data": "^10.3.0", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/icons": "^10.3.0", - "@wordpress/private-apis": "^1.3.0", + "@wordpress/a11y": "^4.5.0", + "@wordpress/components": "^28.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/icons": "^10.5.0", + "@wordpress/private-apis": "^1.5.0", "clsx": "^2.1.1" }, "engines": { @@ -11127,24 +12007,27 @@ } }, "node_modules/@wordpress/primitives": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/primitives/-/primitives-4.3.0.tgz", - "integrity": "sha512-h7wb2Np3n5etOg3j38GN80NEA8NgNdsSF/JJcRhpRf8FQOJd1mnKzj6szVHeKv0G7bvBif0NTgdSUm5M6Nikfg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/primitives/-/primitives-4.5.0.tgz", + "integrity": "sha512-1TYCpCAr2BmYJESlD8v325GgYXSgUbrFtebwgvpMN/28CEwmPN+ORRECV41nPX4yVJ2k0kYzYxzQUGp/78xWsw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/element": "^6.3.0", + "@wordpress/element": "^6.5.0", "clsx": "^2.1.1" }, "engines": { "node": ">=18.12.0", "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0" } }, "node_modules/@wordpress/priority-queue": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-3.3.0.tgz", - "integrity": "sha512-H7dGei1mFqKlz7NLFOGGtVgaBsORRaXeXNwWLI5rE0pI3XfGYd+zxNrG5aBzHw4fPqsITsxecNSaacc9fjqgjQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-3.5.0.tgz", + "integrity": "sha512-ilbG70ZuUJd0UTC7uyLP8zI/ZSN0d4ceG3qwlDx13yQAcjAcuw1Ei1CwzFBsbmI3OS1KkfkDpwZzKOrA+j/00Q==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", @@ -11156,9 +12039,9 @@ } }, "node_modules/@wordpress/private-apis": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/private-apis/-/private-apis-1.3.0.tgz", - "integrity": "sha512-IbtH8ZENAKixSoTBKbmJ2ZCIkxsxqAoWPBtvbNJG9rYdzSk+BExdy/5VGO6Pv5GcUElHT+8uV26W4XxBVNl4UQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/private-apis/-/private-apis-1.5.0.tgz", + "integrity": "sha512-taGW34kyyHMnbmTbWIyOJt7C4KFVCg7F5PNFwJQmS43FESC9BAjPw7VeEDTJ0XNqocH4NNeBJclhFyj82QySTQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -11169,9 +12052,9 @@ } }, "node_modules/@wordpress/redux-routine": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/redux-routine/-/redux-routine-5.3.0.tgz", - "integrity": "sha512-5HGdW8PqIK5fTyg1yo6NL2x1LTxU9vBvgUan/bLxYLX0YNw4+gQUex3djE0dwXNgrdE4mvWvYTcccc+2L59hig==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/redux-routine/-/redux-routine-5.5.0.tgz", + "integrity": "sha512-PvIgq0lI2PLjechCq+pRFIE/xbFwznytupGscD95qks3fFM9jtqVhlgO2oW0pA7C6CIz8zQ0zONFjsQlOaeDKA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", @@ -11215,21 +12098,107 @@ "react-dom": "^18.0.0" } }, + "node_modules/@wordpress/reusable-blocks/node_modules/@wordpress/block-editor": { + "version": "13.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-13.4.0.tgz", + "integrity": "sha512-J2XwsngpxLaue8EROloT6KyRFjCk8JCl/K9UalEkrpYFFj084z7/px6LT6300Maue0ejkN8I3X4/XOe0tgOdbQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@emotion/react": "^11.7.1", + "@emotion/styled": "^11.6.0", + "@react-spring/web": "^9.4.5", + "@wordpress/a11y": "^4.4.0", + "@wordpress/api-fetch": "^7.4.0", + "@wordpress/blob": "^4.4.0", + "@wordpress/blocks": "^13.4.0", + "@wordpress/commands": "^1.4.0", + "@wordpress/components": "^28.4.0", + "@wordpress/compose": "^7.4.0", + "@wordpress/data": "^10.4.0", + "@wordpress/date": "^5.4.0", + "@wordpress/deprecated": "^4.4.0", + "@wordpress/dom": "^4.4.0", + "@wordpress/element": "^6.4.0", + "@wordpress/escape-html": "^3.4.0", + "@wordpress/hooks": "^4.4.0", + "@wordpress/html-entities": "^4.4.0", + "@wordpress/i18n": "^5.4.0", + "@wordpress/icons": "^10.4.0", + "@wordpress/is-shallow-equal": "^5.4.0", + "@wordpress/keyboard-shortcuts": "^5.4.0", + "@wordpress/keycodes": "^4.4.0", + "@wordpress/notices": "^5.4.0", + "@wordpress/preferences": "^4.4.0", + "@wordpress/private-apis": "^1.4.0", + "@wordpress/rich-text": "^7.4.0", + "@wordpress/style-engine": "^2.4.0", + "@wordpress/token-list": "^3.4.0", + "@wordpress/url": "^4.4.0", + "@wordpress/warning": "^3.4.0", + "@wordpress/wordcount": "^4.4.0", + "change-case": "^4.1.2", + "clsx": "^2.1.1", + "colord": "^2.7.0", + "deepmerge": "^4.3.0", + "diff": "^4.0.2", + "fast-deep-equal": "^3.1.3", + "memize": "^2.1.0", + "postcss": "^8.4.21", + "postcss-prefixwrap": "^1.41.0", + "postcss-urlrebase": "^1.4.0", + "react-autosize-textarea": "^7.1.0", + "react-easy-crop": "^5.0.6", + "remove-accents": "^0.5.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/@wordpress/keycodes": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@wordpress/i18n": "^5.5.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/@wordpress/warning": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.5.0.tgz", + "integrity": "sha512-cYM2Vqf2EokJJoWHD5Ry15OUmdsKtDgR8/qxE0sWHUAdSQeoTuJZnqhgYI898cZGxHaZWX2xJCxQa7Qtwl8lqw==", + "dev": true, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, "node_modules/@wordpress/rich-text": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/rich-text/-/rich-text-7.3.0.tgz", - "integrity": "sha512-iL7qEybPOwtMp8WXMQndzfvT2k647ZqIMTj0rji4h2QAp/KaEHyYaIF6YhuQ7v5bSQ/9IAAOy3KGhguIuxIt8A==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/rich-text/-/rich-text-7.5.0.tgz", + "integrity": "sha512-qHeTZNaLbsO6coBph1CD4qn/nfzvJV/DamiCpSgBJ1eQO7u8DdVB8abDxODOOD5hVOLHTOM/OBjFPTVFevNrmw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/a11y": "^4.3.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/data": "^10.3.0", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/escape-html": "^3.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/keycodes": "^4.3.0", + "@wordpress/a11y": "^4.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/escape-html": "^3.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/keycodes": "^4.5.0", "memize": "^2.1.0" }, "engines": { @@ -11241,13 +12210,13 @@ } }, "node_modules/@wordpress/rich-text/node_modules/@wordpress/keycodes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.3.0.tgz", - "integrity": "sha512-o+L110/Y9ufS2eWVG1gXFs6+jPsMNVZoGJCt4PLjMmVabke0iaYstFppUdtQiOEDbnnhX9MH3RRtqp2AoSnaRQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0" + "@wordpress/i18n": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -11887,9 +12856,9 @@ } }, "node_modules/@wordpress/shortcode": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/shortcode/-/shortcode-4.3.0.tgz", - "integrity": "sha512-Ononu3JfP8W/qLNeB46YuGpmqpjj+VyA9EK6pZdmf1/8Gd9Q6L2+HRyp1AEzJzs59p2pLfzvf63T90KSSZjBaQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/shortcode/-/shortcode-4.5.0.tgz", + "integrity": "sha512-Ed0Gh7ZMaz5UkVo6yF5eQY/Nzpv4afxrr8dGjMNQpmUbq92CwaAq8tfj5vT89IV/Ano0F2EQtkcyKEVJ7VPqrw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", @@ -11901,9 +12870,9 @@ } }, "node_modules/@wordpress/style-engine": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/style-engine/-/style-engine-2.3.0.tgz", - "integrity": "sha512-VLnhVPDOZ32cnxFJSQbVkuF8YUd2M33m3bvw28TSvdAZcosN1WpmoEAtn9NhwU2jklvJEFfa1inlzuQ3NW/HEA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/style-engine/-/style-engine-2.5.0.tgz", + "integrity": "sha512-mV6cOtEO5zGg8ZYUNsHDBnywb76Jc+k1Q65PVSNezD+NtZasuASxZGz2J3gEwgNL/1p++JO7JQf9qyoZUs/jZw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", @@ -11954,9 +12923,9 @@ } }, "node_modules/@wordpress/token-list": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/token-list/-/token-list-3.3.0.tgz", - "integrity": "sha512-9IcUUebJ2KBIe371pKonpS0KtTgwDzPJBQIMkPACvw47AL3ZY83sQzBwEqAw+hNstqilOD6n/SQUhIYxzMvdhg==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/token-list/-/token-list-3.5.0.tgz", + "integrity": "sha512-n/a7HYJz3b922qHcs4yyywzuFKZg8Du/xE6KSnPz9EiUVCHthYFJ8m587f9xtgdUDjZKK7fpZZ0yCK/Krwna+Q==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -11967,13 +12936,13 @@ } }, "node_modules/@wordpress/undo-manager": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/undo-manager/-/undo-manager-1.3.0.tgz", - "integrity": "sha512-1XvU3GKpWeKFLCRx/3yEttRbIszD38vfH53XmCq2Y6IbWiyJLUGCnq4kiZjOaxA0o/DcAa4edscPyqmJj+wE+g==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/undo-manager/-/undo-manager-1.5.0.tgz", + "integrity": "sha512-ijvKwnXzKMV9xEcVB4mOIPih6BP5ZnZ1QYsv/EaPV7qlt2zgEevAHGa/FLQMW/lWlGCa5OhUK4tqDV+ZvrjTGw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/is-shallow-equal": "^5.3.0" + "@wordpress/is-shallow-equal": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -11981,9 +12950,9 @@ } }, "node_modules/@wordpress/url": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-4.3.0.tgz", - "integrity": "sha512-2rbpF2OD3rc/Jhmd4Mn9PxXTYGw63hIVMEJWzHs0x/mHmuDZEAn1vZcpDhJkksqtnHMS3BOlTv+Kbk1klxOpCg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-4.5.0.tgz", + "integrity": "sha512-xv/wqUnqNedo9fyiCVJgZnfLtYJbBph30Z2neTFR8Ivy8HA4p74xGqlt8TJceYLeRUrT9EgsMITbHNJMftdNbA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", @@ -12052,10 +13021,96 @@ "react-dom": "^18.0.0" } }, + "node_modules/@wordpress/widgets/node_modules/@wordpress/block-editor": { + "version": "13.4.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-13.4.0.tgz", + "integrity": "sha512-J2XwsngpxLaue8EROloT6KyRFjCk8JCl/K9UalEkrpYFFj084z7/px6LT6300Maue0ejkN8I3X4/XOe0tgOdbQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@emotion/react": "^11.7.1", + "@emotion/styled": "^11.6.0", + "@react-spring/web": "^9.4.5", + "@wordpress/a11y": "^4.4.0", + "@wordpress/api-fetch": "^7.4.0", + "@wordpress/blob": "^4.4.0", + "@wordpress/blocks": "^13.4.0", + "@wordpress/commands": "^1.4.0", + "@wordpress/components": "^28.4.0", + "@wordpress/compose": "^7.4.0", + "@wordpress/data": "^10.4.0", + "@wordpress/date": "^5.4.0", + "@wordpress/deprecated": "^4.4.0", + "@wordpress/dom": "^4.4.0", + "@wordpress/element": "^6.4.0", + "@wordpress/escape-html": "^3.4.0", + "@wordpress/hooks": "^4.4.0", + "@wordpress/html-entities": "^4.4.0", + "@wordpress/i18n": "^5.4.0", + "@wordpress/icons": "^10.4.0", + "@wordpress/is-shallow-equal": "^5.4.0", + "@wordpress/keyboard-shortcuts": "^5.4.0", + "@wordpress/keycodes": "^4.4.0", + "@wordpress/notices": "^5.4.0", + "@wordpress/preferences": "^4.4.0", + "@wordpress/private-apis": "^1.4.0", + "@wordpress/rich-text": "^7.4.0", + "@wordpress/style-engine": "^2.4.0", + "@wordpress/token-list": "^3.4.0", + "@wordpress/url": "^4.4.0", + "@wordpress/warning": "^3.4.0", + "@wordpress/wordcount": "^4.4.0", + "change-case": "^4.1.2", + "clsx": "^2.1.1", + "colord": "^2.7.0", + "deepmerge": "^4.3.0", + "diff": "^4.0.2", + "fast-deep-equal": "^3.1.3", + "memize": "^2.1.0", + "postcss": "^8.4.21", + "postcss-prefixwrap": "^1.41.0", + "postcss-urlrebase": "^1.4.0", + "react-autosize-textarea": "^7.1.0", + "react-easy-crop": "^5.0.6", + "remove-accents": "^0.5.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@wordpress/widgets/node_modules/@wordpress/keycodes": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@wordpress/i18n": "^5.5.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, + "node_modules/@wordpress/widgets/node_modules/@wordpress/warning": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.5.0.tgz", + "integrity": "sha512-cYM2Vqf2EokJJoWHD5Ry15OUmdsKtDgR8/qxE0sWHUAdSQeoTuJZnqhgYI898cZGxHaZWX2xJCxQa7Qtwl8lqw==", + "dev": true, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, "node_modules/@wordpress/wordcount": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/wordcount/-/wordcount-4.3.0.tgz", - "integrity": "sha512-+jTnD4XMRRxljZ6mRif5wMFqiDbIFTc/naeE2CI7mirdsnFriUD3gYmhgLsP71Rckh+9EHZpzQBCbehXU2zX1A==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/wordcount/-/wordcount-4.5.0.tgz", + "integrity": "sha512-LgSA2Mra6e9r15eRUIFNk2TCWnoyNhecPOOWrT061sl9dEvJ92zAjNWILrMa8rnTTX651bnF2HJD1PkivxDVzw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" diff --git a/package.json b/package.json index dd4fd7a5a..541935ba4 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "@typescript-eslint/eslint-plugin": "^6.21.0", "@wordpress/api-fetch": "^7.0.0", "@wordpress/babel-preset-default": "^7.42.0", - "@wordpress/block-editor": "^13.0.0", + "@wordpress/block-editor": "^14.0.0", "@wordpress/blocks": "^13.3.0", "@wordpress/components": "^28.3.0", "@wordpress/compose": "^7.0.0", From 84fabe43c3bebc2d062cd20bf94ab1a9f8fba598 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 07:41:34 +0000 Subject: [PATCH 015/282] build(deps-dev): bump @wordpress/e2e-test-utils from 11.3.0 to 11.5.0 Bumps [@wordpress/e2e-test-utils](https://github.com/WordPress/gutenberg/tree/HEAD/packages/e2e-test-utils) from 11.3.0 to 11.5.0. - [Release notes](https://github.com/WordPress/gutenberg/releases) - [Changelog](https://github.com/WordPress/gutenberg/blob/trunk/packages/e2e-test-utils/CHANGELOG.md) - [Commits](https://github.com/WordPress/gutenberg/commits/@wordpress/e2e-test-utils@11.5.0/packages/e2e-test-utils) --- updated-dependencies: - dependency-name: "@wordpress/e2e-test-utils" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 52 +++++++++++++++++++++++------------------------ package.json | 2 +- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/package-lock.json b/package-lock.json index 40ab6e410..672a52a92 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,7 +34,7 @@ "@wordpress/compose": "^7.0.0", "@wordpress/core-data": "^7.3.0", "@wordpress/data": "^10.3.0", - "@wordpress/e2e-test-utils": "^11.3.0", + "@wordpress/e2e-test-utils": "^11.5.0", "@wordpress/edit-post": "^8.3.0", "@wordpress/editor": "^14.3.0", "@wordpress/element": "^6.2.0", @@ -9384,14 +9384,14 @@ } }, "node_modules/@wordpress/api-fetch": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-7.3.0.tgz", - "integrity": "sha512-VpHG+9cLRZG13V2t1+xXpwuHJCeqiOl0ent9qXzbe6am9DtKSJ3oxiNdZaHjs6tdgGNuN/mTowRi5ceYJZb83Q==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-7.5.0.tgz", + "integrity": "sha512-ShUbXTYaQD9G7rROidMtlByu4i1N8Pj4gB5tIUUg2d0IUwDdXJnABQWI2+ebSXLKIRNaAOrw/Gb5xef08TR0ag==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/url": "^4.3.0" + "@wordpress/i18n": "^5.5.0", + "@wordpress/url": "^4.5.0" }, "engines": { "node": ">=18.12.0", @@ -10042,15 +10042,15 @@ } }, "node_modules/@wordpress/e2e-test-utils": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/e2e-test-utils/-/e2e-test-utils-11.3.0.tgz", - "integrity": "sha512-f4/XJaMhIiqFD2Icfcm8/yAUUbf8XTrrb8z9bJv8k2WMtSSulQ6mGmLnohHzy6anYm/0TVSQtozfKsX6JV8WpA==", + "version": "11.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/e2e-test-utils/-/e2e-test-utils-11.5.0.tgz", + "integrity": "sha512-CLkTQihPD3GRE7c2MvXnAjuMlIh/eseyqU/8Uzz9IrYXU0h1Q0fvHs+Me8kjHKCxuhP/XkYSsr0ihyupF+EupA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/api-fetch": "^7.3.0", - "@wordpress/keycodes": "^4.3.0", - "@wordpress/url": "^4.3.0", + "@wordpress/api-fetch": "^7.5.0", + "@wordpress/keycodes": "^4.5.0", + "@wordpress/url": "^4.5.0", "change-case": "^4.1.2", "form-data": "^4.0.0", "node-fetch": "^2.6.0" @@ -10152,13 +10152,13 @@ } }, "node_modules/@wordpress/e2e-test-utils/node_modules/@wordpress/keycodes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.3.0.tgz", - "integrity": "sha512-o+L110/Y9ufS2eWVG1gXFs6+jPsMNVZoGJCt4PLjMmVabke0iaYstFppUdtQiOEDbnnhX9MH3RRtqp2AoSnaRQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0" + "@wordpress/i18n": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -10718,9 +10718,9 @@ } }, "node_modules/@wordpress/hooks": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-4.3.0.tgz", - "integrity": "sha512-bpqwSXGyxPfhuxESKoAtL4ofB3CazzvcwcucTZ0g9Pat3KNuBaloSrPBliqqNOiSLWNH3nmpkaRmv4u89EdKAw==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-4.5.0.tgz", + "integrity": "sha512-wr1l1WM1yobyNGFLRgbLNBGtYIkzAGfmbT2e9zIOvqllRJT4wprYTqqhgovOKHlET5ij/TKdv4tApkGLUIXTsA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -10744,13 +10744,13 @@ } }, "node_modules/@wordpress/i18n": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-5.3.0.tgz", - "integrity": "sha512-edHKkdZb6jNpbn+LUPu2wo1mKyhT819WJ7kI8hmMcHq82rNwwbMfcGoB3oSaphTphWfhlgxIxLczKOAbWDKudw==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-5.5.0.tgz", + "integrity": "sha512-MtCJIjNHCWs7R77f5Xml1CCnVXqrle4cDpqMU9myx4Cq8ZijqSayX1CTtwtk+Z3/3xa+dBZu5Koe4wiW1yIUSA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/hooks": "^4.3.0", + "@wordpress/hooks": "^4.5.0", "gettext-parser": "^1.3.1", "memize": "^2.1.0", "sprintf-js": "^1.1.1", @@ -11981,9 +11981,9 @@ } }, "node_modules/@wordpress/url": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-4.3.0.tgz", - "integrity": "sha512-2rbpF2OD3rc/Jhmd4Mn9PxXTYGw63hIVMEJWzHs0x/mHmuDZEAn1vZcpDhJkksqtnHMS3BOlTv+Kbk1klxOpCg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-4.5.0.tgz", + "integrity": "sha512-xv/wqUnqNedo9fyiCVJgZnfLtYJbBph30Z2neTFR8Ivy8HA4p74xGqlt8TJceYLeRUrT9EgsMITbHNJMftdNbA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", diff --git a/package.json b/package.json index dd4fd7a5a..dda01312f 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "@wordpress/compose": "^7.0.0", "@wordpress/core-data": "^7.3.0", "@wordpress/data": "^10.3.0", - "@wordpress/e2e-test-utils": "^11.3.0", + "@wordpress/e2e-test-utils": "^11.5.0", "@wordpress/edit-post": "^8.3.0", "@wordpress/editor": "^14.3.0", "@wordpress/element": "^6.2.0", From 19c8d6c93b99bbcce38a691a4247ff7a5ef5de69 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 07:41:55 +0000 Subject: [PATCH 016/282] build(deps-dev): bump typescript from 5.5.3 to 5.5.4 Bumps [typescript](https://github.com/Microsoft/TypeScript) from 5.5.3 to 5.5.4. - [Release notes](https://github.com/Microsoft/TypeScript/releases) - [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml) - [Commits](https://github.com/Microsoft/TypeScript/compare/v5.5.3...v5.5.4) --- updated-dependencies: - dependency-name: typescript dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 40ab6e410..1f8d279b8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -52,7 +52,7 @@ "husky": "^9.0.11", "prettier": "^3.3.2", "ts-loader": "^9.5.1", - "typescript": "^5.5.3" + "typescript": "^5.5.4" }, "engines": { "node": ">=18.12.0", @@ -30744,9 +30744,9 @@ } }, "node_modules/typescript": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", - "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true, "bin": { "tsc": "bin/tsc", diff --git a/package.json b/package.json index dd4fd7a5a..98d40e41f 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,7 @@ "husky": "^9.0.11", "prettier": "^3.3.2", "ts-loader": "^9.5.1", - "typescript": "^5.5.3" + "typescript": "^5.5.4" }, "devDependenciesComments": { "@wordpress/babel-preset-default": "Don't upgrade to v8 or greater until the plugin requires WordPress 6.6. See https://github.com/WordPress/gutenberg/pull/62265/files", From 4fbaacdf1d451db2684b415fbd95ff9d727cf0a7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 07:42:35 +0000 Subject: [PATCH 017/282] build(deps-dev): bump @wordpress/blocks from 13.3.0 to 13.5.0 Bumps [@wordpress/blocks](https://github.com/WordPress/gutenberg/tree/HEAD/packages/blocks) from 13.3.0 to 13.5.0. - [Release notes](https://github.com/WordPress/gutenberg/releases) - [Changelog](https://github.com/WordPress/gutenberg/blob/trunk/packages/blocks/CHANGELOG.md) - [Commits](https://github.com/WordPress/gutenberg/commits/@wordpress/blocks@13.5.0/packages/blocks) --- updated-dependencies: - dependency-name: "@wordpress/blocks" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 247 ++++++++++++++++++++++++---------------------- package.json | 2 +- 2 files changed, 130 insertions(+), 119 deletions(-) diff --git a/package-lock.json b/package-lock.json index 40ab6e410..29f3b32af 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,7 +29,7 @@ "@wordpress/api-fetch": "^7.0.0", "@wordpress/babel-preset-default": "^7.42.0", "@wordpress/block-editor": "^13.0.0", - "@wordpress/blocks": "^13.3.0", + "@wordpress/blocks": "^13.5.0", "@wordpress/components": "^28.3.0", "@wordpress/compose": "^7.0.0", "@wordpress/core-data": "^7.3.0", @@ -9369,14 +9369,14 @@ } }, "node_modules/@wordpress/a11y": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/a11y/-/a11y-4.3.0.tgz", - "integrity": "sha512-kmAE8hshmldudMhtj/RKY7lEwyux5w6zvCTbIj3a6iq0ZMhU3vsxTlCp/vEGLoYdfetwRN4zeJA9jvPki+IOUA==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/a11y/-/a11y-4.5.0.tgz", + "integrity": "sha512-sQmA4kTqu252to6ppVhti2RxSCFcAgWMc3l6rY2kBpj90uK5gtvLKQMr/GvydhildG/OzFSswbk1YBgSPGaudw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/dom-ready": "^4.3.0", - "@wordpress/i18n": "^5.3.0" + "@wordpress/dom-ready": "^4.5.0", + "@wordpress/i18n": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -9399,9 +9399,9 @@ } }, "node_modules/@wordpress/autop": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/autop/-/autop-4.3.0.tgz", - "integrity": "sha512-ml34lWwTPZwD2QYTRcecC94KC/V4SBHaCetlEUz0GPzhyfi48Zku6RCoebMDmayqYlme1iF/4quC4zOA0QLoAg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/autop/-/autop-4.5.0.tgz", + "integrity": "sha512-r68rGyfig+qxonsGQTOOWVpxnmGRYlWgzvDlGRPQbM3KKHA46C7ZS0kYhiZ1RC1RTinLRsu+KX2Y3FbEWcNaWg==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -9456,9 +9456,9 @@ "license": "GPL-2.0-or-later" }, "node_modules/@wordpress/blob": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/blob/-/blob-4.3.0.tgz", - "integrity": "sha512-4BQMpcamwx/2rYGZpvcrmddTuo+hXnDtiylvzP0vAnukJ9p1ae2MGJrWCRNp1qNo/hRbyq8lzA43wgOFxKkp0g==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/blob/-/blob-4.5.0.tgz", + "integrity": "sha512-EVTa4duxIesuRc9p8GWEGb3067v30tEngR+ZF1CoVrboRusJ8WSYtQdmEIvJRgQt3t7WTUtc6P4uAFjONOqU0g==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -9628,9 +9628,9 @@ } }, "node_modules/@wordpress/block-serialization-default-parser": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/block-serialization-default-parser/-/block-serialization-default-parser-5.3.0.tgz", - "integrity": "sha512-H9xXMIqShBdMbt2cRmct+nDy/dzX9last1j3kwJ5Gr0WfvgSLXQOk3p7jnCYYbixgK08VzLvkfqEofg314QSbg==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-serialization-default-parser/-/block-serialization-default-parser-5.5.0.tgz", + "integrity": "sha512-tUQ9LDFXbMvJY+BYI6lPqucwwSWISe9voBdwwYAbHfHcAcS5veYMdZGREOYpXNgmgd+RCI4+j49oy3EwqUUr4w==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -9641,26 +9641,27 @@ } }, "node_modules/@wordpress/blocks": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/blocks/-/blocks-13.3.0.tgz", - "integrity": "sha512-Df0aW+IardBoiWwLopqex450s7HQjP+QRfD4Pi8Skr5ELuVxwPRAJK9Dv4X2eLQyEPIucErIBjgW6tcSXNIhQQ==", + "version": "13.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/blocks/-/blocks-13.5.0.tgz", + "integrity": "sha512-k8XSlVJQZ/HaZKib7HKILwi4MKMH8UxfdsB2j55Ed41v0exkV42wSK12H8IhFx6GXN/iy13m/f0tsIVGM4ZtIQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/autop": "^4.3.0", - "@wordpress/blob": "^4.3.0", - "@wordpress/block-serialization-default-parser": "^5.3.0", - "@wordpress/data": "^10.3.0", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/dom": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/hooks": "^4.3.0", - "@wordpress/html-entities": "^4.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/is-shallow-equal": "^5.3.0", - "@wordpress/private-apis": "^1.3.0", - "@wordpress/rich-text": "^7.3.0", - "@wordpress/shortcode": "^4.3.0", + "@wordpress/autop": "^4.5.0", + "@wordpress/blob": "^4.5.0", + "@wordpress/block-serialization-default-parser": "^5.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/dom": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/hooks": "^4.5.0", + "@wordpress/html-entities": "^4.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/rich-text": "^7.5.0", + "@wordpress/shortcode": "^4.5.0", + "@wordpress/warning": "^3.5.0", "change-case": "^4.1.2", "colord": "^2.7.0", "fast-deep-equal": "^3.1.3", @@ -9681,6 +9682,16 @@ "react": "^18.0.0" } }, + "node_modules/@wordpress/blocks/node_modules/@wordpress/warning": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.5.0.tgz", + "integrity": "sha512-cYM2Vqf2EokJJoWHD5Ry15OUmdsKtDgR8/qxE0sWHUAdSQeoTuJZnqhgYI898cZGxHaZWX2xJCxQa7Qtwl8lqw==", + "dev": true, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, "node_modules/@wordpress/browserslist-config": { "version": "5.41.0", "resolved": "https://registry.npmjs.org/@wordpress/browserslist-config/-/browserslist-config-5.41.0.tgz", @@ -9805,20 +9816,20 @@ } }, "node_modules/@wordpress/compose": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-7.3.0.tgz", - "integrity": "sha512-TtAYdKnqQ/L/nF0+fmlQ1wAvm90X9HRBrAuEMNmkzKhews/5GR0rR3dNSMjlf7C6mNdTO3mkYt6AQf9fvZFoiQ==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-7.5.0.tgz", + "integrity": "sha512-jWRmleIGxmvTIC/1VYtAvq0iRfCkW/AtlNmqoKiyd0Ah5lccWRtxSH5V3Vh1BEkBQRANMWxJpOpRTKDFTcfTvg==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", "@types/mousetrap": "^1.6.8", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/dom": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/is-shallow-equal": "^5.3.0", - "@wordpress/keycodes": "^4.3.0", - "@wordpress/priority-queue": "^3.3.0", - "@wordpress/undo-manager": "^1.3.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/dom": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/keycodes": "^4.5.0", + "@wordpress/priority-queue": "^3.5.0", + "@wordpress/undo-manager": "^1.5.0", "change-case": "^4.1.2", "clipboard": "^2.0.11", "mousetrap": "^1.6.5", @@ -9833,13 +9844,13 @@ } }, "node_modules/@wordpress/compose/node_modules/@wordpress/keycodes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.3.0.tgz", - "integrity": "sha512-o+L110/Y9ufS2eWVG1gXFs6+jPsMNVZoGJCt4PLjMmVabke0iaYstFppUdtQiOEDbnnhX9MH3RRtqp2AoSnaRQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0" + "@wordpress/i18n": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -9913,19 +9924,19 @@ } }, "node_modules/@wordpress/data": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-10.3.0.tgz", - "integrity": "sha512-cImJw4k30coosH6QtiJllxEYr93w8981PPvhGhemMbRQ28MnSA7rbJPv3h2LO9oss5SQH1gU9kwNGAZcF6PMPg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-10.5.0.tgz", + "integrity": "sha512-Y2P5SC0fuTivcfdYmubL3c15WRbE0FJAyYcEfZeJ2C37a2DmBnCBz3uEzGy2kCilz56qMfK0qutAHkfytOpRQw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/is-shallow-equal": "^5.3.0", - "@wordpress/priority-queue": "^3.3.0", - "@wordpress/private-apis": "^1.3.0", - "@wordpress/redux-routine": "^5.3.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/priority-queue": "^3.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/redux-routine": "^5.5.0", "deepmerge": "^4.3.0", "equivalent-key-map": "^0.2.2", "is-plain-object": "^5.0.0", @@ -10002,13 +10013,13 @@ } }, "node_modules/@wordpress/deprecated": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-4.3.0.tgz", - "integrity": "sha512-K2GHXlwjx6GMhZjs52X1MXySCrqzh4IjoqF5IOcydMgWqOIE2++hMuB9Y55qN/Mhsrv/HO8Q1LaTxbEd6BuNJQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-4.5.0.tgz", + "integrity": "sha512-r3xGAM45XTd+z+hnUvLGtSz+Y0ebybuw/cyE0CatksJBGvXez3kiTDaknALkgzjHRZzIGpNu6XTVUoIJs0H39A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/hooks": "^4.3.0" + "@wordpress/hooks": "^4.5.0" }, "engines": { "node": ">=18.12.0", @@ -10016,13 +10027,13 @@ } }, "node_modules/@wordpress/dom": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-4.3.0.tgz", - "integrity": "sha512-sf4h6jVqboRdhe3soyr5bt+Vpz24WG/AIMHm7pGaxfbV5jxx06ZZ8K1RKzhr7jF3wn7IgIc1wmMA+OFzEYqGyw==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-4.5.0.tgz", + "integrity": "sha512-XjnpRbbhZ1hdgv758vSXQacjfy/N0H2oI0oWukrLmlkKDP5ZrGfdziHQ2+KcoW+QDx8pu4JYcUpjmuJLugDStw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/deprecated": "^4.3.0" + "@wordpress/deprecated": "^4.5.0" }, "engines": { "node": ">=18.12.0", @@ -10030,9 +10041,9 @@ } }, "node_modules/@wordpress/dom-ready": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/dom-ready/-/dom-ready-4.3.0.tgz", - "integrity": "sha512-zuLLMIeJt1hZ95R4kdJFcsIaL2eud1kF40VCmwK3mK0qpgXv/1avtGX8lx6DMLL/GGL1yYcJhR13RSKSjxuGEQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom-ready/-/dom-ready-4.5.0.tgz", + "integrity": "sha512-5dALG1lQtoH/Rk7DWFe9DaIF2bQQM5U0x+c1lQnk1cnBJ69AijIcbZMYaMzlgngo4dVF2PnFZ/VKVSUOKghhQQ==", "dependencies": { "@babel/runtime": "^7.16.0" }, @@ -10323,15 +10334,15 @@ } }, "node_modules/@wordpress/element": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-6.3.0.tgz", - "integrity": "sha512-DsiqzjuXqxJkLUoLomsGTFFxbSZgk+Lz+2/1yFH+BU3jQ6zeD64+JWv8Lt4+fKU154rV0KpfMwfD/oAC/Lp1zQ==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-6.5.0.tgz", + "integrity": "sha512-N9w3jfceltdDEN71jpaMCXU+jbvec9kredvQIn/6YNiUMarPXWth7DJYU3+mDtbYawnTIvytzGjbj/J+bqqdHg==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", "@types/react": "^18.2.79", "@types/react-dom": "^18.2.25", - "@wordpress/escape-html": "^3.3.0", + "@wordpress/escape-html": "^3.5.0", "change-case": "^4.1.2", "is-plain-object": "^5.0.0", "react": "^18.3.0", @@ -10446,9 +10457,9 @@ } }, "node_modules/@wordpress/escape-html": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-3.3.0.tgz", - "integrity": "sha512-Wu/Fq96E28UGnIO5VQW/aEgCiHWvzrD8izDnP8U0WZSuwIPYcS5iYmRe2UWc7rwyoeY2YXNd6xFjgd7oTOKNCA==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-3.5.0.tgz", + "integrity": "sha512-8dUWTmsDZuqAmBtRgk0JpiIafRKPM4n8tqCr147AugTbP/vyQ7rIzG3M/YCtVSmDr6f/qZ32YU8J7c34RhZ/9g==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -10718,9 +10729,9 @@ } }, "node_modules/@wordpress/hooks": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-4.3.0.tgz", - "integrity": "sha512-bpqwSXGyxPfhuxESKoAtL4ofB3CazzvcwcucTZ0g9Pat3KNuBaloSrPBliqqNOiSLWNH3nmpkaRmv4u89EdKAw==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-4.5.0.tgz", + "integrity": "sha512-wr1l1WM1yobyNGFLRgbLNBGtYIkzAGfmbT2e9zIOvqllRJT4wprYTqqhgovOKHlET5ij/TKdv4tApkGLUIXTsA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -10731,9 +10742,9 @@ } }, "node_modules/@wordpress/html-entities": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/html-entities/-/html-entities-4.3.0.tgz", - "integrity": "sha512-rJDf9KjCuUnFwIwmOdN4FcL7RJnDzPxIdvvMoWXkYd9GseEeRTsY6xIG+fGgVGgYe3HwXDYSFCWTF/x2M9Eerg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/html-entities/-/html-entities-4.5.0.tgz", + "integrity": "sha512-iQo2P1Sc499MxguelJ4aMcF08jnYkOdvb+FAOyOfGCyDjEtNbldRFc2BJ9NmJ/9nmtlwc/IzUzXop0M1gjy9tw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -10744,13 +10755,13 @@ } }, "node_modules/@wordpress/i18n": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-5.3.0.tgz", - "integrity": "sha512-edHKkdZb6jNpbn+LUPu2wo1mKyhT819WJ7kI8hmMcHq82rNwwbMfcGoB3oSaphTphWfhlgxIxLczKOAbWDKudw==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-5.5.0.tgz", + "integrity": "sha512-MtCJIjNHCWs7R77f5Xml1CCnVXqrle4cDpqMU9myx4Cq8ZijqSayX1CTtwtk+Z3/3xa+dBZu5Koe4wiW1yIUSA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/hooks": "^4.3.0", + "@wordpress/hooks": "^4.5.0", "gettext-parser": "^1.3.1", "memize": "^2.1.0", "sprintf-js": "^1.1.1", @@ -10838,9 +10849,9 @@ } }, "node_modules/@wordpress/is-shallow-equal": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-5.3.0.tgz", - "integrity": "sha512-sZ+fypqjYX0/DTAKsm1G9ND9Wn4d3Ju4lI7SLSmCKdUL5EPY3g/2LpKQKDqljh9m6Ex5NWp2XfU8UVXpkEfbMQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-5.5.0.tgz", + "integrity": "sha512-nkCz45HgMBkjhyxffDgpAgJbfnKyZML94/gHhBtxizHfaNuZ5as7DfEyN1xgebvDiLbOaRU7em1pPAuEhIoTfQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -11142,9 +11153,9 @@ } }, "node_modules/@wordpress/priority-queue": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-3.3.0.tgz", - "integrity": "sha512-H7dGei1mFqKlz7NLFOGGtVgaBsORRaXeXNwWLI5rE0pI3XfGYd+zxNrG5aBzHw4fPqsITsxecNSaacc9fjqgjQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-3.5.0.tgz", + "integrity": "sha512-ilbG70ZuUJd0UTC7uyLP8zI/ZSN0d4ceG3qwlDx13yQAcjAcuw1Ei1CwzFBsbmI3OS1KkfkDpwZzKOrA+j/00Q==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", @@ -11156,9 +11167,9 @@ } }, "node_modules/@wordpress/private-apis": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/private-apis/-/private-apis-1.3.0.tgz", - "integrity": "sha512-IbtH8ZENAKixSoTBKbmJ2ZCIkxsxqAoWPBtvbNJG9rYdzSk+BExdy/5VGO6Pv5GcUElHT+8uV26W4XxBVNl4UQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/private-apis/-/private-apis-1.5.0.tgz", + "integrity": "sha512-taGW34kyyHMnbmTbWIyOJt7C4KFVCg7F5PNFwJQmS43FESC9BAjPw7VeEDTJ0XNqocH4NNeBJclhFyj82QySTQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -11169,9 +11180,9 @@ } }, "node_modules/@wordpress/redux-routine": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/redux-routine/-/redux-routine-5.3.0.tgz", - "integrity": "sha512-5HGdW8PqIK5fTyg1yo6NL2x1LTxU9vBvgUan/bLxYLX0YNw4+gQUex3djE0dwXNgrdE4mvWvYTcccc+2L59hig==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/redux-routine/-/redux-routine-5.5.0.tgz", + "integrity": "sha512-PvIgq0lI2PLjechCq+pRFIE/xbFwznytupGscD95qks3fFM9jtqVhlgO2oW0pA7C6CIz8zQ0zONFjsQlOaeDKA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", @@ -11216,20 +11227,20 @@ } }, "node_modules/@wordpress/rich-text": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/rich-text/-/rich-text-7.3.0.tgz", - "integrity": "sha512-iL7qEybPOwtMp8WXMQndzfvT2k647ZqIMTj0rji4h2QAp/KaEHyYaIF6YhuQ7v5bSQ/9IAAOy3KGhguIuxIt8A==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/rich-text/-/rich-text-7.5.0.tgz", + "integrity": "sha512-qHeTZNaLbsO6coBph1CD4qn/nfzvJV/DamiCpSgBJ1eQO7u8DdVB8abDxODOOD5hVOLHTOM/OBjFPTVFevNrmw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/a11y": "^4.3.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/data": "^10.3.0", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/escape-html": "^3.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/keycodes": "^4.3.0", + "@wordpress/a11y": "^4.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/escape-html": "^3.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/keycodes": "^4.5.0", "memize": "^2.1.0" }, "engines": { @@ -11241,13 +11252,13 @@ } }, "node_modules/@wordpress/rich-text/node_modules/@wordpress/keycodes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.3.0.tgz", - "integrity": "sha512-o+L110/Y9ufS2eWVG1gXFs6+jPsMNVZoGJCt4PLjMmVabke0iaYstFppUdtQiOEDbnnhX9MH3RRtqp2AoSnaRQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0" + "@wordpress/i18n": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -11887,9 +11898,9 @@ } }, "node_modules/@wordpress/shortcode": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/shortcode/-/shortcode-4.3.0.tgz", - "integrity": "sha512-Ononu3JfP8W/qLNeB46YuGpmqpjj+VyA9EK6pZdmf1/8Gd9Q6L2+HRyp1AEzJzs59p2pLfzvf63T90KSSZjBaQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/shortcode/-/shortcode-4.5.0.tgz", + "integrity": "sha512-Ed0Gh7ZMaz5UkVo6yF5eQY/Nzpv4afxrr8dGjMNQpmUbq92CwaAq8tfj5vT89IV/Ano0F2EQtkcyKEVJ7VPqrw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", @@ -11967,13 +11978,13 @@ } }, "node_modules/@wordpress/undo-manager": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/undo-manager/-/undo-manager-1.3.0.tgz", - "integrity": "sha512-1XvU3GKpWeKFLCRx/3yEttRbIszD38vfH53XmCq2Y6IbWiyJLUGCnq4kiZjOaxA0o/DcAa4edscPyqmJj+wE+g==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/undo-manager/-/undo-manager-1.5.0.tgz", + "integrity": "sha512-ijvKwnXzKMV9xEcVB4mOIPih6BP5ZnZ1QYsv/EaPV7qlt2zgEevAHGa/FLQMW/lWlGCa5OhUK4tqDV+ZvrjTGw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/is-shallow-equal": "^5.3.0" + "@wordpress/is-shallow-equal": "^5.5.0" }, "engines": { "node": ">=18.12.0", diff --git a/package.json b/package.json index dd4fd7a5a..cd5b53cab 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "@wordpress/api-fetch": "^7.0.0", "@wordpress/babel-preset-default": "^7.42.0", "@wordpress/block-editor": "^13.0.0", - "@wordpress/blocks": "^13.3.0", + "@wordpress/blocks": "^13.5.0", "@wordpress/components": "^28.3.0", "@wordpress/compose": "^7.0.0", "@wordpress/core-data": "^7.3.0", From faecfdb7aa676ba24353fe95a4f01c273a7d1d2b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 07:43:20 +0000 Subject: [PATCH 018/282] build(deps-dev): bump @wordpress/data from 10.3.0 to 10.5.0 Bumps [@wordpress/data](https://github.com/WordPress/gutenberg/tree/HEAD/packages/data) from 10.3.0 to 10.5.0. - [Release notes](https://github.com/WordPress/gutenberg/releases) - [Changelog](https://github.com/WordPress/gutenberg/blob/trunk/packages/data/CHANGELOG.md) - [Commits](https://github.com/WordPress/gutenberg/commits/@wordpress/data@10.5.0/packages/data) --- updated-dependencies: - dependency-name: "@wordpress/data" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 126 +++++++++++++++++++++++----------------------- package.json | 2 +- 2 files changed, 64 insertions(+), 64 deletions(-) diff --git a/package-lock.json b/package-lock.json index 40ab6e410..5b11e848e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,7 +33,7 @@ "@wordpress/components": "^28.3.0", "@wordpress/compose": "^7.0.0", "@wordpress/core-data": "^7.3.0", - "@wordpress/data": "^10.3.0", + "@wordpress/data": "^10.5.0", "@wordpress/e2e-test-utils": "^11.3.0", "@wordpress/edit-post": "^8.3.0", "@wordpress/editor": "^14.3.0", @@ -9805,20 +9805,20 @@ } }, "node_modules/@wordpress/compose": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-7.3.0.tgz", - "integrity": "sha512-TtAYdKnqQ/L/nF0+fmlQ1wAvm90X9HRBrAuEMNmkzKhews/5GR0rR3dNSMjlf7C6mNdTO3mkYt6AQf9fvZFoiQ==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-7.5.0.tgz", + "integrity": "sha512-jWRmleIGxmvTIC/1VYtAvq0iRfCkW/AtlNmqoKiyd0Ah5lccWRtxSH5V3Vh1BEkBQRANMWxJpOpRTKDFTcfTvg==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", "@types/mousetrap": "^1.6.8", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/dom": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/is-shallow-equal": "^5.3.0", - "@wordpress/keycodes": "^4.3.0", - "@wordpress/priority-queue": "^3.3.0", - "@wordpress/undo-manager": "^1.3.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/dom": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/keycodes": "^4.5.0", + "@wordpress/priority-queue": "^3.5.0", + "@wordpress/undo-manager": "^1.5.0", "change-case": "^4.1.2", "clipboard": "^2.0.11", "mousetrap": "^1.6.5", @@ -9833,13 +9833,13 @@ } }, "node_modules/@wordpress/compose/node_modules/@wordpress/keycodes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.3.0.tgz", - "integrity": "sha512-o+L110/Y9ufS2eWVG1gXFs6+jPsMNVZoGJCt4PLjMmVabke0iaYstFppUdtQiOEDbnnhX9MH3RRtqp2AoSnaRQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0" + "@wordpress/i18n": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -9913,19 +9913,19 @@ } }, "node_modules/@wordpress/data": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-10.3.0.tgz", - "integrity": "sha512-cImJw4k30coosH6QtiJllxEYr93w8981PPvhGhemMbRQ28MnSA7rbJPv3h2LO9oss5SQH1gU9kwNGAZcF6PMPg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-10.5.0.tgz", + "integrity": "sha512-Y2P5SC0fuTivcfdYmubL3c15WRbE0FJAyYcEfZeJ2C37a2DmBnCBz3uEzGy2kCilz56qMfK0qutAHkfytOpRQw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/is-shallow-equal": "^5.3.0", - "@wordpress/priority-queue": "^3.3.0", - "@wordpress/private-apis": "^1.3.0", - "@wordpress/redux-routine": "^5.3.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/priority-queue": "^3.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/redux-routine": "^5.5.0", "deepmerge": "^4.3.0", "equivalent-key-map": "^0.2.2", "is-plain-object": "^5.0.0", @@ -10002,13 +10002,13 @@ } }, "node_modules/@wordpress/deprecated": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-4.3.0.tgz", - "integrity": "sha512-K2GHXlwjx6GMhZjs52X1MXySCrqzh4IjoqF5IOcydMgWqOIE2++hMuB9Y55qN/Mhsrv/HO8Q1LaTxbEd6BuNJQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-4.5.0.tgz", + "integrity": "sha512-r3xGAM45XTd+z+hnUvLGtSz+Y0ebybuw/cyE0CatksJBGvXez3kiTDaknALkgzjHRZzIGpNu6XTVUoIJs0H39A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/hooks": "^4.3.0" + "@wordpress/hooks": "^4.5.0" }, "engines": { "node": ">=18.12.0", @@ -10016,13 +10016,13 @@ } }, "node_modules/@wordpress/dom": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-4.3.0.tgz", - "integrity": "sha512-sf4h6jVqboRdhe3soyr5bt+Vpz24WG/AIMHm7pGaxfbV5jxx06ZZ8K1RKzhr7jF3wn7IgIc1wmMA+OFzEYqGyw==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-4.5.0.tgz", + "integrity": "sha512-XjnpRbbhZ1hdgv758vSXQacjfy/N0H2oI0oWukrLmlkKDP5ZrGfdziHQ2+KcoW+QDx8pu4JYcUpjmuJLugDStw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/deprecated": "^4.3.0" + "@wordpress/deprecated": "^4.5.0" }, "engines": { "node": ">=18.12.0", @@ -10323,15 +10323,15 @@ } }, "node_modules/@wordpress/element": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-6.3.0.tgz", - "integrity": "sha512-DsiqzjuXqxJkLUoLomsGTFFxbSZgk+Lz+2/1yFH+BU3jQ6zeD64+JWv8Lt4+fKU154rV0KpfMwfD/oAC/Lp1zQ==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-6.5.0.tgz", + "integrity": "sha512-N9w3jfceltdDEN71jpaMCXU+jbvec9kredvQIn/6YNiUMarPXWth7DJYU3+mDtbYawnTIvytzGjbj/J+bqqdHg==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", "@types/react": "^18.2.79", "@types/react-dom": "^18.2.25", - "@wordpress/escape-html": "^3.3.0", + "@wordpress/escape-html": "^3.5.0", "change-case": "^4.1.2", "is-plain-object": "^5.0.0", "react": "^18.3.0", @@ -10446,9 +10446,9 @@ } }, "node_modules/@wordpress/escape-html": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-3.3.0.tgz", - "integrity": "sha512-Wu/Fq96E28UGnIO5VQW/aEgCiHWvzrD8izDnP8U0WZSuwIPYcS5iYmRe2UWc7rwyoeY2YXNd6xFjgd7oTOKNCA==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-3.5.0.tgz", + "integrity": "sha512-8dUWTmsDZuqAmBtRgk0JpiIafRKPM4n8tqCr147AugTbP/vyQ7rIzG3M/YCtVSmDr6f/qZ32YU8J7c34RhZ/9g==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -10718,9 +10718,9 @@ } }, "node_modules/@wordpress/hooks": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-4.3.0.tgz", - "integrity": "sha512-bpqwSXGyxPfhuxESKoAtL4ofB3CazzvcwcucTZ0g9Pat3KNuBaloSrPBliqqNOiSLWNH3nmpkaRmv4u89EdKAw==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-4.5.0.tgz", + "integrity": "sha512-wr1l1WM1yobyNGFLRgbLNBGtYIkzAGfmbT2e9zIOvqllRJT4wprYTqqhgovOKHlET5ij/TKdv4tApkGLUIXTsA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -10744,13 +10744,13 @@ } }, "node_modules/@wordpress/i18n": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-5.3.0.tgz", - "integrity": "sha512-edHKkdZb6jNpbn+LUPu2wo1mKyhT819WJ7kI8hmMcHq82rNwwbMfcGoB3oSaphTphWfhlgxIxLczKOAbWDKudw==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-5.5.0.tgz", + "integrity": "sha512-MtCJIjNHCWs7R77f5Xml1CCnVXqrle4cDpqMU9myx4Cq8ZijqSayX1CTtwtk+Z3/3xa+dBZu5Koe4wiW1yIUSA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/hooks": "^4.3.0", + "@wordpress/hooks": "^4.5.0", "gettext-parser": "^1.3.1", "memize": "^2.1.0", "sprintf-js": "^1.1.1", @@ -10838,9 +10838,9 @@ } }, "node_modules/@wordpress/is-shallow-equal": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-5.3.0.tgz", - "integrity": "sha512-sZ+fypqjYX0/DTAKsm1G9ND9Wn4d3Ju4lI7SLSmCKdUL5EPY3g/2LpKQKDqljh9m6Ex5NWp2XfU8UVXpkEfbMQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-5.5.0.tgz", + "integrity": "sha512-nkCz45HgMBkjhyxffDgpAgJbfnKyZML94/gHhBtxizHfaNuZ5as7DfEyN1xgebvDiLbOaRU7em1pPAuEhIoTfQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -11142,9 +11142,9 @@ } }, "node_modules/@wordpress/priority-queue": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-3.3.0.tgz", - "integrity": "sha512-H7dGei1mFqKlz7NLFOGGtVgaBsORRaXeXNwWLI5rE0pI3XfGYd+zxNrG5aBzHw4fPqsITsxecNSaacc9fjqgjQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-3.5.0.tgz", + "integrity": "sha512-ilbG70ZuUJd0UTC7uyLP8zI/ZSN0d4ceG3qwlDx13yQAcjAcuw1Ei1CwzFBsbmI3OS1KkfkDpwZzKOrA+j/00Q==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", @@ -11156,9 +11156,9 @@ } }, "node_modules/@wordpress/private-apis": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/private-apis/-/private-apis-1.3.0.tgz", - "integrity": "sha512-IbtH8ZENAKixSoTBKbmJ2ZCIkxsxqAoWPBtvbNJG9rYdzSk+BExdy/5VGO6Pv5GcUElHT+8uV26W4XxBVNl4UQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/private-apis/-/private-apis-1.5.0.tgz", + "integrity": "sha512-taGW34kyyHMnbmTbWIyOJt7C4KFVCg7F5PNFwJQmS43FESC9BAjPw7VeEDTJ0XNqocH4NNeBJclhFyj82QySTQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -11169,9 +11169,9 @@ } }, "node_modules/@wordpress/redux-routine": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/redux-routine/-/redux-routine-5.3.0.tgz", - "integrity": "sha512-5HGdW8PqIK5fTyg1yo6NL2x1LTxU9vBvgUan/bLxYLX0YNw4+gQUex3djE0dwXNgrdE4mvWvYTcccc+2L59hig==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/redux-routine/-/redux-routine-5.5.0.tgz", + "integrity": "sha512-PvIgq0lI2PLjechCq+pRFIE/xbFwznytupGscD95qks3fFM9jtqVhlgO2oW0pA7C6CIz8zQ0zONFjsQlOaeDKA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", @@ -11967,13 +11967,13 @@ } }, "node_modules/@wordpress/undo-manager": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/undo-manager/-/undo-manager-1.3.0.tgz", - "integrity": "sha512-1XvU3GKpWeKFLCRx/3yEttRbIszD38vfH53XmCq2Y6IbWiyJLUGCnq4kiZjOaxA0o/DcAa4edscPyqmJj+wE+g==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/undo-manager/-/undo-manager-1.5.0.tgz", + "integrity": "sha512-ijvKwnXzKMV9xEcVB4mOIPih6BP5ZnZ1QYsv/EaPV7qlt2zgEevAHGa/FLQMW/lWlGCa5OhUK4tqDV+ZvrjTGw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/is-shallow-equal": "^5.3.0" + "@wordpress/is-shallow-equal": "^5.5.0" }, "engines": { "node": ">=18.12.0", diff --git a/package.json b/package.json index dd4fd7a5a..0896ce2d5 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "@wordpress/components": "^28.3.0", "@wordpress/compose": "^7.0.0", "@wordpress/core-data": "^7.3.0", - "@wordpress/data": "^10.3.0", + "@wordpress/data": "^10.5.0", "@wordpress/e2e-test-utils": "^11.3.0", "@wordpress/edit-post": "^8.3.0", "@wordpress/editor": "^14.3.0", From 1cb7a709cb9f50859ade4302072484a1ca7e64c0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 07:44:40 +0000 Subject: [PATCH 019/282] build(deps-dev): bump @wordpress/wordcount from 4.3.0 to 4.5.0 Bumps [@wordpress/wordcount](https://github.com/WordPress/gutenberg/tree/HEAD/packages/wordcount) from 4.3.0 to 4.5.0. - [Release notes](https://github.com/WordPress/gutenberg/releases) - [Changelog](https://github.com/WordPress/gutenberg/blob/trunk/packages/wordcount/CHANGELOG.md) - [Commits](https://github.com/WordPress/gutenberg/commits/@wordpress/wordcount@4.5.0/packages/wordcount) --- updated-dependencies: - dependency-name: "@wordpress/wordcount" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 40ab6e410..b6a63994e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -46,7 +46,7 @@ "@wordpress/plugins": "^7.3.0", "@wordpress/scripts": "^27.9.0", "@wordpress/url": "^4.2.0", - "@wordpress/wordcount": "^4.3.0", + "@wordpress/wordcount": "^4.5.0", "concurrently": "^8.2.2", "eslint-plugin-jest": "^28.6.0", "husky": "^9.0.11", @@ -12053,9 +12053,9 @@ } }, "node_modules/@wordpress/wordcount": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/wordcount/-/wordcount-4.3.0.tgz", - "integrity": "sha512-+jTnD4XMRRxljZ6mRif5wMFqiDbIFTc/naeE2CI7mirdsnFriUD3gYmhgLsP71Rckh+9EHZpzQBCbehXU2zX1A==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/wordcount/-/wordcount-4.5.0.tgz", + "integrity": "sha512-LgSA2Mra6e9r15eRUIFNk2TCWnoyNhecPOOWrT061sl9dEvJ92zAjNWILrMa8rnTTX651bnF2HJD1PkivxDVzw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" diff --git a/package.json b/package.json index dd4fd7a5a..e4efaa67a 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,7 @@ "@wordpress/plugins": "^7.3.0", "@wordpress/scripts": "^27.9.0", "@wordpress/url": "^4.2.0", - "@wordpress/wordcount": "^4.3.0", + "@wordpress/wordcount": "^4.5.0", "concurrently": "^8.2.2", "eslint-plugin-jest": "^28.6.0", "husky": "^9.0.11", From 803b7e7fb144e2e0cee07f8255c7e8dbfcd28855 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 07:44:56 +0000 Subject: [PATCH 020/282] build(deps-dev): bump husky from 9.0.11 to 9.1.4 Bumps [husky](https://github.com/typicode/husky) from 9.0.11 to 9.1.4. - [Release notes](https://github.com/typicode/husky/releases) - [Commits](https://github.com/typicode/husky/compare/v9.0.11...v9.1.4) --- updated-dependencies: - dependency-name: husky dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 11 +++++------ package.json | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 40ab6e410..2dfaa6b75 100644 --- a/package-lock.json +++ b/package-lock.json @@ -49,7 +49,7 @@ "@wordpress/wordcount": "^4.3.0", "concurrently": "^8.2.2", "eslint-plugin-jest": "^28.6.0", - "husky": "^9.0.11", + "husky": "^9.1.4", "prettier": "^3.3.2", "ts-loader": "^9.5.1", "typescript": "^5.5.3" @@ -18872,13 +18872,12 @@ } }, "node_modules/husky": { - "version": "9.0.11", - "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz", - "integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==", + "version": "9.1.4", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.4.tgz", + "integrity": "sha512-bho94YyReb4JV7LYWRWxZ/xr6TtOTt8cMfmQ39MQYJ7f/YE268s3GdghGwi+y4zAeqewE5zYLvuhV0M0ijsDEA==", "dev": true, - "license": "MIT", "bin": { - "husky": "bin.mjs" + "husky": "bin.js" }, "engines": { "node": ">=18" diff --git a/package.json b/package.json index dd4fd7a5a..f851b9f16 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "@wordpress/wordcount": "^4.3.0", "concurrently": "^8.2.2", "eslint-plugin-jest": "^28.6.0", - "husky": "^9.0.11", + "husky": "^9.1.4", "prettier": "^3.3.2", "ts-loader": "^9.5.1", "typescript": "^5.5.3" From 81b76ba9536795ebf951a1915bc7a9a5e6c13d18 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 07:45:33 +0000 Subject: [PATCH 021/282] build(deps-dev): bump @wordpress/api-fetch from 7.3.0 to 7.5.0 Bumps [@wordpress/api-fetch](https://github.com/WordPress/gutenberg/tree/HEAD/packages/api-fetch) from 7.3.0 to 7.5.0. - [Release notes](https://github.com/WordPress/gutenberg/releases) - [Changelog](https://github.com/WordPress/gutenberg/blob/trunk/packages/api-fetch/CHANGELOG.md) - [Commits](https://github.com/WordPress/gutenberg/commits/@wordpress/api-fetch@7.5.0/packages/api-fetch) --- updated-dependencies: - dependency-name: "@wordpress/api-fetch" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 32 ++++++++++++++++---------------- package.json | 2 +- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/package-lock.json b/package-lock.json index 40ab6e410..fc3aee747 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,7 @@ "@types/wordpress__editor": "^13.6.8", "@types/wordpress__wordcount": "^2.4.5", "@typescript-eslint/eslint-plugin": "^6.21.0", - "@wordpress/api-fetch": "^7.0.0", + "@wordpress/api-fetch": "^7.5.0", "@wordpress/babel-preset-default": "^7.42.0", "@wordpress/block-editor": "^13.0.0", "@wordpress/blocks": "^13.3.0", @@ -9384,14 +9384,14 @@ } }, "node_modules/@wordpress/api-fetch": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-7.3.0.tgz", - "integrity": "sha512-VpHG+9cLRZG13V2t1+xXpwuHJCeqiOl0ent9qXzbe6am9DtKSJ3oxiNdZaHjs6tdgGNuN/mTowRi5ceYJZb83Q==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-7.5.0.tgz", + "integrity": "sha512-ShUbXTYaQD9G7rROidMtlByu4i1N8Pj4gB5tIUUg2d0IUwDdXJnABQWI2+ebSXLKIRNaAOrw/Gb5xef08TR0ag==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/url": "^4.3.0" + "@wordpress/i18n": "^5.5.0", + "@wordpress/url": "^4.5.0" }, "engines": { "node": ">=18.12.0", @@ -10718,9 +10718,9 @@ } }, "node_modules/@wordpress/hooks": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-4.3.0.tgz", - "integrity": "sha512-bpqwSXGyxPfhuxESKoAtL4ofB3CazzvcwcucTZ0g9Pat3KNuBaloSrPBliqqNOiSLWNH3nmpkaRmv4u89EdKAw==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-4.5.0.tgz", + "integrity": "sha512-wr1l1WM1yobyNGFLRgbLNBGtYIkzAGfmbT2e9zIOvqllRJT4wprYTqqhgovOKHlET5ij/TKdv4tApkGLUIXTsA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -10744,13 +10744,13 @@ } }, "node_modules/@wordpress/i18n": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-5.3.0.tgz", - "integrity": "sha512-edHKkdZb6jNpbn+LUPu2wo1mKyhT819WJ7kI8hmMcHq82rNwwbMfcGoB3oSaphTphWfhlgxIxLczKOAbWDKudw==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-5.5.0.tgz", + "integrity": "sha512-MtCJIjNHCWs7R77f5Xml1CCnVXqrle4cDpqMU9myx4Cq8ZijqSayX1CTtwtk+Z3/3xa+dBZu5Koe4wiW1yIUSA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/hooks": "^4.3.0", + "@wordpress/hooks": "^4.5.0", "gettext-parser": "^1.3.1", "memize": "^2.1.0", "sprintf-js": "^1.1.1", @@ -11981,9 +11981,9 @@ } }, "node_modules/@wordpress/url": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-4.3.0.tgz", - "integrity": "sha512-2rbpF2OD3rc/Jhmd4Mn9PxXTYGw63hIVMEJWzHs0x/mHmuDZEAn1vZcpDhJkksqtnHMS3BOlTv+Kbk1klxOpCg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-4.5.0.tgz", + "integrity": "sha512-xv/wqUnqNedo9fyiCVJgZnfLtYJbBph30Z2neTFR8Ivy8HA4p74xGqlt8TJceYLeRUrT9EgsMITbHNJMftdNbA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", diff --git a/package.json b/package.json index dd4fd7a5a..45b422b2f 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "@types/wordpress__editor": "^13.6.8", "@types/wordpress__wordcount": "^2.4.5", "@typescript-eslint/eslint-plugin": "^6.21.0", - "@wordpress/api-fetch": "^7.0.0", + "@wordpress/api-fetch": "^7.5.0", "@wordpress/babel-preset-default": "^7.42.0", "@wordpress/block-editor": "^13.0.0", "@wordpress/blocks": "^13.3.0", From 4cc288980a7ef1bd09456f92a7bebbe246e48299 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 07:45:50 +0000 Subject: [PATCH 022/282] build(deps-dev): bump eslint-plugin-jest from 28.6.0 to 28.8.0 Bumps [eslint-plugin-jest](https://github.com/jest-community/eslint-plugin-jest) from 28.6.0 to 28.8.0. - [Release notes](https://github.com/jest-community/eslint-plugin-jest/releases) - [Changelog](https://github.com/jest-community/eslint-plugin-jest/blob/main/CHANGELOG.md) - [Commits](https://github.com/jest-community/eslint-plugin-jest/compare/v28.6.0...v28.8.0) --- updated-dependencies: - dependency-name: eslint-plugin-jest dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 12 ++++++------ package.json | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 40ab6e410..deeb05d61 100644 --- a/package-lock.json +++ b/package-lock.json @@ -48,7 +48,7 @@ "@wordpress/url": "^4.2.0", "@wordpress/wordcount": "^4.3.0", "concurrently": "^8.2.2", - "eslint-plugin-jest": "^28.6.0", + "eslint-plugin-jest": "^28.8.0", "husky": "^9.0.11", "prettier": "^3.3.2", "ts-loader": "^9.5.1", @@ -16454,18 +16454,18 @@ } }, "node_modules/eslint-plugin-jest": { - "version": "28.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.6.0.tgz", - "integrity": "sha512-YG28E1/MIKwnz+e2H7VwYPzHUYU4aMa19w0yGcwXnnmJH6EfgHahTJ2un3IyraUxNfnz/KUhJAFXNNwWPo12tg==", + "version": "28.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.8.0.tgz", + "integrity": "sha512-Tubj1hooFxCl52G4qQu0edzV/+EZzPUeN8p2NnW5uu4fbDs+Yo7+qDVDc4/oG3FbCqEBmu/OC3LSsyiU22oghw==", "dev": true, "dependencies": { - "@typescript-eslint/utils": "^6.0.0 || ^7.0.0" + "@typescript-eslint/utils": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "engines": { "node": "^16.10.0 || ^18.12.0 || >=20.0.0" }, "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^6.0.0 || ^7.0.0", + "@typescript-eslint/eslint-plugin": "^6.0.0 || ^7.0.0 || ^8.0.0", "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0", "jest": "*" }, diff --git a/package.json b/package.json index dd4fd7a5a..eaec8fe6e 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "@wordpress/url": "^4.2.0", "@wordpress/wordcount": "^4.3.0", "concurrently": "^8.2.2", - "eslint-plugin-jest": "^28.6.0", + "eslint-plugin-jest": "^28.8.0", "husky": "^9.0.11", "prettier": "^3.3.2", "ts-loader": "^9.5.1", From 59480b984a5bca999272697777a28970db603a21 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 07:46:23 +0000 Subject: [PATCH 023/282] build(deps-dev): bump @wordpress/hooks from 4.3.0 to 4.5.0 Bumps [@wordpress/hooks](https://github.com/WordPress/gutenberg/tree/HEAD/packages/hooks) from 4.3.0 to 4.5.0. - [Release notes](https://github.com/WordPress/gutenberg/releases) - [Changelog](https://github.com/WordPress/gutenberg/blob/trunk/packages/hooks/CHANGELOG.md) - [Commits](https://github.com/WordPress/gutenberg/commits/@wordpress/hooks@4.5.0/packages/hooks) --- updated-dependencies: - dependency-name: "@wordpress/hooks" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 40ab6e410..563e922a2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,7 +40,7 @@ "@wordpress/element": "^6.2.0", "@wordpress/env": "^10.3.0", "@wordpress/eslint-plugin": "^20.0.0", - "@wordpress/hooks": "^4.0.0", + "@wordpress/hooks": "^4.5.0", "@wordpress/i18n": "^5.0.0", "@wordpress/icons": "^10.0.0", "@wordpress/plugins": "^7.3.0", @@ -10718,9 +10718,9 @@ } }, "node_modules/@wordpress/hooks": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-4.3.0.tgz", - "integrity": "sha512-bpqwSXGyxPfhuxESKoAtL4ofB3CazzvcwcucTZ0g9Pat3KNuBaloSrPBliqqNOiSLWNH3nmpkaRmv4u89EdKAw==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-4.5.0.tgz", + "integrity": "sha512-wr1l1WM1yobyNGFLRgbLNBGtYIkzAGfmbT2e9zIOvqllRJT4wprYTqqhgovOKHlET5ij/TKdv4tApkGLUIXTsA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" diff --git a/package.json b/package.json index dd4fd7a5a..55baf8fde 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "@wordpress/element": "^6.2.0", "@wordpress/env": "^10.3.0", "@wordpress/eslint-plugin": "^20.0.0", - "@wordpress/hooks": "^4.0.0", + "@wordpress/hooks": "^4.5.0", "@wordpress/i18n": "^5.0.0", "@wordpress/icons": "^10.0.0", "@wordpress/plugins": "^7.3.0", From b144adb1126f354fc9b7aa01c305b8ace2370185 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 07:46:57 +0000 Subject: [PATCH 024/282] build(deps-dev): bump @wordpress/eslint-plugin from 20.0.0 to 20.2.0 Bumps [@wordpress/eslint-plugin](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin) from 20.0.0 to 20.2.0. - [Release notes](https://github.com/WordPress/gutenberg/releases) - [Changelog](https://github.com/WordPress/gutenberg/blob/trunk/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/WordPress/gutenberg/commits/@wordpress/eslint-plugin@20.2.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@wordpress/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 40 ++++++++++++++++++++-------------------- package.json | 2 +- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/package-lock.json b/package-lock.json index 40ab6e410..a06c42a4a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,7 +39,7 @@ "@wordpress/editor": "^14.3.0", "@wordpress/element": "^6.2.0", "@wordpress/env": "^10.3.0", - "@wordpress/eslint-plugin": "^20.0.0", + "@wordpress/eslint-plugin": "^20.2.0", "@wordpress/hooks": "^4.0.0", "@wordpress/i18n": "^5.0.0", "@wordpress/icons": "^10.0.0", @@ -10459,16 +10459,16 @@ } }, "node_modules/@wordpress/eslint-plugin": { - "version": "20.0.0", - "resolved": "https://registry.npmjs.org/@wordpress/eslint-plugin/-/eslint-plugin-20.0.0.tgz", - "integrity": "sha512-rOzkWHX6xjTt7Gmhe/nwlcgQJe4O6bCXkCJKcL+iyBhYABVjCnzneDiVh4bM1cNmL8zUx6/f1ADjmb3Xz9vG0g==", + "version": "20.2.0", + "resolved": "https://registry.npmjs.org/@wordpress/eslint-plugin/-/eslint-plugin-20.2.0.tgz", + "integrity": "sha512-lC8sUkzf4x3ByQHs3xF7X0XxS3SPEYzXho9+NeIgB5Cg0s/PlyWuPQI+4oHVgZI3hzPH76G6ewRtIt27gQRcdw==", "dev": true, "dependencies": { "@babel/eslint-parser": "^7.16.0", "@typescript-eslint/eslint-plugin": "^6.4.1", "@typescript-eslint/parser": "^6.4.1", - "@wordpress/babel-preset-default": "^8.3.0", - "@wordpress/prettier-config": "^4.3.0", + "@wordpress/babel-preset-default": "^8.5.0", + "@wordpress/prettier-config": "^4.5.0", "cosmiconfig": "^7.0.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-import": "^2.25.2", @@ -10607,9 +10607,9 @@ } }, "node_modules/@wordpress/eslint-plugin/node_modules/@wordpress/babel-preset-default": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/babel-preset-default/-/babel-preset-default-8.3.0.tgz", - "integrity": "sha512-lLPZuKdJF6CLS/YUv7c2OkGhplEpKZBQ4YiCQUdbhg8joFZH12QICUxtT2kvoUxLQ22zwLtNMPYTzISClE8zSw==", + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/babel-preset-default/-/babel-preset-default-8.5.0.tgz", + "integrity": "sha512-ra9UWhidrAIoYTuqIIMFs+5LawUis/qDhiB2c3mc9HJUXXQDOvdhww5f9H9SjWqOo1oB9jSuVh4pXtBpcR1E6A==", "dev": true, "dependencies": { "@babel/core": "^7.16.0", @@ -10618,8 +10618,8 @@ "@babel/preset-env": "^7.16.0", "@babel/preset-typescript": "^7.16.0", "@babel/runtime": "^7.16.0", - "@wordpress/browserslist-config": "^6.3.0", - "@wordpress/warning": "^3.3.0", + "@wordpress/browserslist-config": "^6.5.0", + "@wordpress/warning": "^3.5.0", "browserslist": "^4.21.10", "core-js": "^3.31.0", "react": "^18.3.0" @@ -10630,9 +10630,9 @@ } }, "node_modules/@wordpress/eslint-plugin/node_modules/@wordpress/browserslist-config": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/browserslist-config/-/browserslist-config-6.3.0.tgz", - "integrity": "sha512-DDz/Iiax7RQR7cuTdv1ZlAfPgCDijiszg9xE9c2lO/2Hvv7voP/sLKQhdr/mSUzNW9ZXK7/NVIYAXxFd3Eee2A==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/browserslist-config/-/browserslist-config-6.5.0.tgz", + "integrity": "sha512-B5cYN5INRknBjzbNH2qJOq6x66qXS2UoLk5Ebyew1JkW9xzvX1O+eQumjFv65fAN6RNPtomHs8c7BNoD3wAebQ==", "dev": true, "engines": { "node": ">=18.12.0", @@ -10640,9 +10640,9 @@ } }, "node_modules/@wordpress/eslint-plugin/node_modules/@wordpress/warning": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.3.0.tgz", - "integrity": "sha512-n82aKCxuGRNwAtSLaycErJuhKgfOc+KtiljyQITPperMh9i8bH6I+JxtYiu+aLMaY5vrVLVb+/kCzKuWVQIKPA==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.5.0.tgz", + "integrity": "sha512-cYM2Vqf2EokJJoWHD5Ry15OUmdsKtDgR8/qxE0sWHUAdSQeoTuJZnqhgYI898cZGxHaZWX2xJCxQa7Qtwl8lqw==", "dev": true, "engines": { "node": ">=18.12.0", @@ -11114,9 +11114,9 @@ } }, "node_modules/@wordpress/prettier-config": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/prettier-config/-/prettier-config-4.3.0.tgz", - "integrity": "sha512-2OWp2g/e0y2iKh1LZvc+f0pxesI5NYBQSgnJkaXHt6ktc7QaBX3nwYcZQ030TBMxl2hnNclLAPUR85UMSRx0dw==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/prettier-config/-/prettier-config-4.5.0.tgz", + "integrity": "sha512-HxpR4128yfJJs1idQaBJfBffa6P2JXKN7mvx+D/G2UukjjWlXHaCXLO8wuBLnXwXSg4pOq5vfDM/p5TawZd7Zg==", "dev": true, "engines": { "node": ">=18.12.0", diff --git a/package.json b/package.json index dd4fd7a5a..886cc8dd3 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "@wordpress/editor": "^14.3.0", "@wordpress/element": "^6.2.0", "@wordpress/env": "^10.3.0", - "@wordpress/eslint-plugin": "^20.0.0", + "@wordpress/eslint-plugin": "^20.2.0", "@wordpress/hooks": "^4.0.0", "@wordpress/i18n": "^5.0.0", "@wordpress/icons": "^10.0.0", From 6e43ab918450fdece76c651848ab8dd5da9b9975 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 07:47:34 +0000 Subject: [PATCH 025/282] build(deps-dev): bump @wordpress/core-data from 7.3.0 to 7.5.0 Bumps [@wordpress/core-data](https://github.com/WordPress/gutenberg/tree/HEAD/packages/core-data) from 7.3.0 to 7.5.0. - [Release notes](https://github.com/WordPress/gutenberg/releases) - [Changelog](https://github.com/WordPress/gutenberg/blob/trunk/packages/core-data/CHANGELOG.md) - [Commits](https://github.com/WordPress/gutenberg/commits/@wordpress/core-data@7.5.0/packages/core-data) --- updated-dependencies: - dependency-name: "@wordpress/core-data" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 1184 ++++++++++++++++++++++++++++++++------------- package.json | 2 +- 2 files changed, 851 insertions(+), 335 deletions(-) diff --git a/package-lock.json b/package-lock.json index 40ab6e410..d8b518346 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,7 +32,7 @@ "@wordpress/blocks": "^13.3.0", "@wordpress/components": "^28.3.0", "@wordpress/compose": "^7.0.0", - "@wordpress/core-data": "^7.3.0", + "@wordpress/core-data": "^7.5.0", "@wordpress/data": "^10.3.0", "@wordpress/e2e-test-utils": "^11.3.0", "@wordpress/edit-post": "^8.3.0", @@ -9369,14 +9369,14 @@ } }, "node_modules/@wordpress/a11y": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/a11y/-/a11y-4.3.0.tgz", - "integrity": "sha512-kmAE8hshmldudMhtj/RKY7lEwyux5w6zvCTbIj3a6iq0ZMhU3vsxTlCp/vEGLoYdfetwRN4zeJA9jvPki+IOUA==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/a11y/-/a11y-4.5.0.tgz", + "integrity": "sha512-sQmA4kTqu252to6ppVhti2RxSCFcAgWMc3l6rY2kBpj90uK5gtvLKQMr/GvydhildG/OzFSswbk1YBgSPGaudw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/dom-ready": "^4.3.0", - "@wordpress/i18n": "^5.3.0" + "@wordpress/dom-ready": "^4.5.0", + "@wordpress/i18n": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -9384,14 +9384,14 @@ } }, "node_modules/@wordpress/api-fetch": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-7.3.0.tgz", - "integrity": "sha512-VpHG+9cLRZG13V2t1+xXpwuHJCeqiOl0ent9qXzbe6am9DtKSJ3oxiNdZaHjs6tdgGNuN/mTowRi5ceYJZb83Q==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-7.5.0.tgz", + "integrity": "sha512-ShUbXTYaQD9G7rROidMtlByu4i1N8Pj4gB5tIUUg2d0IUwDdXJnABQWI2+ebSXLKIRNaAOrw/Gb5xef08TR0ag==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/url": "^4.3.0" + "@wordpress/i18n": "^5.5.0", + "@wordpress/url": "^4.5.0" }, "engines": { "node": ">=18.12.0", @@ -9399,9 +9399,9 @@ } }, "node_modules/@wordpress/autop": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/autop/-/autop-4.3.0.tgz", - "integrity": "sha512-ml34lWwTPZwD2QYTRcecC94KC/V4SBHaCetlEUz0GPzhyfi48Zku6RCoebMDmayqYlme1iF/4quC4zOA0QLoAg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/autop/-/autop-4.5.0.tgz", + "integrity": "sha512-r68rGyfig+qxonsGQTOOWVpxnmGRYlWgzvDlGRPQbM3KKHA46C7ZS0kYhiZ1RC1RTinLRsu+KX2Y3FbEWcNaWg==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -9456,9 +9456,9 @@ "license": "GPL-2.0-or-later" }, "node_modules/@wordpress/blob": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/blob/-/blob-4.3.0.tgz", - "integrity": "sha512-4BQMpcamwx/2rYGZpvcrmddTuo+hXnDtiylvzP0vAnukJ9p1ae2MGJrWCRNp1qNo/hRbyq8lzA43wgOFxKkp0g==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/blob/-/blob-4.5.0.tgz", + "integrity": "sha512-EVTa4duxIesuRc9p8GWEGb3067v30tEngR+ZF1CoVrboRusJ8WSYtQdmEIvJRgQt3t7WTUtc6P4uAFjONOqU0g==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -9628,9 +9628,9 @@ } }, "node_modules/@wordpress/block-serialization-default-parser": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/block-serialization-default-parser/-/block-serialization-default-parser-5.3.0.tgz", - "integrity": "sha512-H9xXMIqShBdMbt2cRmct+nDy/dzX9last1j3kwJ5Gr0WfvgSLXQOk3p7jnCYYbixgK08VzLvkfqEofg314QSbg==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-serialization-default-parser/-/block-serialization-default-parser-5.5.0.tgz", + "integrity": "sha512-tUQ9LDFXbMvJY+BYI6lPqucwwSWISe9voBdwwYAbHfHcAcS5veYMdZGREOYpXNgmgd+RCI4+j49oy3EwqUUr4w==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -9641,26 +9641,27 @@ } }, "node_modules/@wordpress/blocks": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/blocks/-/blocks-13.3.0.tgz", - "integrity": "sha512-Df0aW+IardBoiWwLopqex450s7HQjP+QRfD4Pi8Skr5ELuVxwPRAJK9Dv4X2eLQyEPIucErIBjgW6tcSXNIhQQ==", + "version": "13.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/blocks/-/blocks-13.5.0.tgz", + "integrity": "sha512-k8XSlVJQZ/HaZKib7HKILwi4MKMH8UxfdsB2j55Ed41v0exkV42wSK12H8IhFx6GXN/iy13m/f0tsIVGM4ZtIQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/autop": "^4.3.0", - "@wordpress/blob": "^4.3.0", - "@wordpress/block-serialization-default-parser": "^5.3.0", - "@wordpress/data": "^10.3.0", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/dom": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/hooks": "^4.3.0", - "@wordpress/html-entities": "^4.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/is-shallow-equal": "^5.3.0", - "@wordpress/private-apis": "^1.3.0", - "@wordpress/rich-text": "^7.3.0", - "@wordpress/shortcode": "^4.3.0", + "@wordpress/autop": "^4.5.0", + "@wordpress/blob": "^4.5.0", + "@wordpress/block-serialization-default-parser": "^5.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/dom": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/hooks": "^4.5.0", + "@wordpress/html-entities": "^4.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/rich-text": "^7.5.0", + "@wordpress/shortcode": "^4.5.0", + "@wordpress/warning": "^3.5.0", "change-case": "^4.1.2", "colord": "^2.7.0", "fast-deep-equal": "^3.1.3", @@ -9681,6 +9682,16 @@ "react": "^18.0.0" } }, + "node_modules/@wordpress/blocks/node_modules/@wordpress/warning": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.5.0.tgz", + "integrity": "sha512-cYM2Vqf2EokJJoWHD5Ry15OUmdsKtDgR8/qxE0sWHUAdSQeoTuJZnqhgYI898cZGxHaZWX2xJCxQa7Qtwl8lqw==", + "dev": true, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, "node_modules/@wordpress/browserslist-config": { "version": "5.41.0", "resolved": "https://registry.npmjs.org/@wordpress/browserslist-config/-/browserslist-config-5.41.0.tgz", @@ -9692,21 +9703,21 @@ } }, "node_modules/@wordpress/commands": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/commands/-/commands-1.3.0.tgz", - "integrity": "sha512-6toFSZTYfNPqHBG2IxuClZ7uZpuXsV7kJRjC+liy3ew1U6vG/Xx9Ps4gvUT1lun6uRsYmftTEqV9GUz2V6IadA==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/commands/-/commands-1.5.0.tgz", + "integrity": "sha512-44BoBnVkdOllkrqXY1lcjdEXzyQrk3WF7hC6IjBgGHhXtdHm4ejn1VthLiAlK2KeA+M/XT5H/x1AiAhpnsrToA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/components": "^28.3.0", - "@wordpress/data": "^10.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/icons": "^10.3.0", - "@wordpress/keyboard-shortcuts": "^5.3.0", - "@wordpress/private-apis": "^1.3.0", + "@wordpress/components": "^28.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/icons": "^10.5.0", + "@wordpress/keyboard-shortcuts": "^5.5.0", + "@wordpress/private-apis": "^1.5.0", "clsx": "^2.1.1", - "cmdk": "^0.2.0" + "cmdk": "^1.0.0" }, "engines": { "node": ">=18.12.0", @@ -9717,215 +9728,717 @@ "react-dom": "^18.0.0" } }, - "node_modules/@wordpress/components": { - "version": "28.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-28.3.0.tgz", - "integrity": "sha512-zLHtxmhbuD7j5f7wOqRu6+KYVWPRpgHsYzxOavWkkiKv0XUvWeYWBIZFM4oy6A1WJqW2nEELcAjIeBX/0UWMig==", + "node_modules/@wordpress/commands/node_modules/@radix-ui/primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.1.tgz", + "integrity": "sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==", "dev": true, "dependencies": { - "@ariakit/react": "^0.3.12", - "@babel/runtime": "^7.16.0", - "@emotion/cache": "^11.7.1", - "@emotion/css": "^11.7.1", - "@emotion/react": "^11.7.1", - "@emotion/serialize": "^1.0.2", - "@emotion/styled": "^11.6.0", - "@emotion/utils": "^1.0.0", - "@floating-ui/react-dom": "^2.0.8", - "@types/gradient-parser": "0.1.3", - "@types/highlight-words-core": "1.2.1", - "@use-gesture/react": "^10.3.1", - "@wordpress/a11y": "^4.3.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/date": "^5.3.0", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/dom": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/escape-html": "^3.3.0", - "@wordpress/hooks": "^4.3.0", - "@wordpress/html-entities": "^4.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/icons": "^10.3.0", - "@wordpress/is-shallow-equal": "^5.3.0", - "@wordpress/keycodes": "^4.3.0", - "@wordpress/primitives": "^4.3.0", - "@wordpress/private-apis": "^1.3.0", - "@wordpress/rich-text": "^7.3.0", - "@wordpress/warning": "^3.3.0", - "change-case": "^4.1.2", - "clsx": "^2.1.1", - "colord": "^2.7.0", - "date-fns": "^3.6.0", - "deepmerge": "^4.3.0", - "downshift": "^6.0.15", - "fast-deep-equal": "^3.1.3", - "framer-motion": "^11.1.9", - "gradient-parser": "^0.1.5", - "highlight-words-core": "^1.2.2", - "is-plain-object": "^5.0.0", - "memize": "^2.1.0", - "path-to-regexp": "^6.2.1", - "re-resizable": "^6.4.0", - "react-colorful": "^5.3.1", - "remove-accents": "^0.5.0", - "use-lilius": "^2.0.5", - "uuid": "^9.0.1" - }, - "engines": { - "node": ">=18.12.0", - "npm": ">=8.19.2" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "@babel/runtime": "^7.13.10" } }, - "node_modules/@wordpress/components/node_modules/@wordpress/keycodes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.3.0.tgz", - "integrity": "sha512-o+L110/Y9ufS2eWVG1gXFs6+jPsMNVZoGJCt4PLjMmVabke0iaYstFppUdtQiOEDbnnhX9MH3RRtqp2AoSnaRQ==", + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-compose-refs": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz", + "integrity": "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==", "dev": true, "dependencies": { - "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0" + "@babel/runtime": "^7.13.10" }, - "engines": { - "node": ">=18.12.0", - "npm": ">=8.19.2" + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@wordpress/components/node_modules/@wordpress/warning": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.3.0.tgz", - "integrity": "sha512-n82aKCxuGRNwAtSLaycErJuhKgfOc+KtiljyQITPperMh9i8bH6I+JxtYiu+aLMaY5vrVLVb+/kCzKuWVQIKPA==", + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-context": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.1.tgz", + "integrity": "sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==", "dev": true, - "engines": { - "node": ">=18.12.0", - "npm": ">=8.19.2" + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@wordpress/compose": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-7.3.0.tgz", - "integrity": "sha512-TtAYdKnqQ/L/nF0+fmlQ1wAvm90X9HRBrAuEMNmkzKhews/5GR0rR3dNSMjlf7C6mNdTO3mkYt6AQf9fvZFoiQ==", + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-dialog": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.0.5.tgz", + "integrity": "sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==", "dev": true, "dependencies": { - "@babel/runtime": "^7.16.0", - "@types/mousetrap": "^1.6.8", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/dom": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/is-shallow-equal": "^5.3.0", - "@wordpress/keycodes": "^4.3.0", - "@wordpress/priority-queue": "^3.3.0", - "@wordpress/undo-manager": "^1.3.0", - "change-case": "^4.1.2", - "clipboard": "^2.0.11", - "mousetrap": "^1.6.5", - "use-memo-one": "^1.1.1" - }, - "engines": { - "node": ">=18.12.0", - "npm": ">=8.19.2" + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.5", + "@radix-ui/react-focus-guards": "1.0.1", + "@radix-ui/react-focus-scope": "1.0.4", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-portal": "1.0.4", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-slot": "1.0.2", + "@radix-ui/react-use-controllable-state": "1.0.1", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.5" }, "peerDependencies": { - "react": "^18.0.0" + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@wordpress/compose/node_modules/@wordpress/keycodes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.3.0.tgz", - "integrity": "sha512-o+L110/Y9ufS2eWVG1gXFs6+jPsMNVZoGJCt4PLjMmVabke0iaYstFppUdtQiOEDbnnhX9MH3RRtqp2AoSnaRQ==", + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.5.tgz", + "integrity": "sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==", "dev": true, "dependencies": { - "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0" + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1", + "@radix-ui/react-use-escape-keydown": "1.0.3" }, - "engines": { - "node": ">=18.12.0", - "npm": ">=8.19.2" + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@wordpress/core-commands": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/core-commands/-/core-commands-1.3.0.tgz", - "integrity": "sha512-Tc9w07UgyFKT6fq0UUxsTmXmRGsULiV25YtAwqxF52XtYxfo+mPMDJgYpNA2l3eKL6EuWR6AzNl8f9pank55oA==", + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-focus-guards": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz", + "integrity": "sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==", "dev": true, "dependencies": { - "@babel/runtime": "^7.16.0", - "@wordpress/block-editor": "^13.3.0", - "@wordpress/commands": "^1.3.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/core-data": "^7.3.0", - "@wordpress/data": "^10.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/html-entities": "^4.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/icons": "^10.3.0", - "@wordpress/private-apis": "^1.3.0", - "@wordpress/router": "^1.3.0", - "@wordpress/url": "^4.3.0" - }, - "engines": { - "node": ">=18.12.0", - "npm": ">=8.19.2" + "@babel/runtime": "^7.13.10" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@wordpress/core-data": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/core-data/-/core-data-7.3.0.tgz", - "integrity": "sha512-qPgb0bWgUQs2QSa4QJGtu2mceC80r4MAbFtZaBYWlv7CQ8qrgx0KJodSaMdezMqBGuQM/+7oS51A6jtR+SKX0g==", + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-focus-scope": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.4.tgz", + "integrity": "sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==", "dev": true, "dependencies": { - "@babel/runtime": "^7.16.0", - "@wordpress/api-fetch": "^7.3.0", - "@wordpress/block-editor": "^13.3.0", - "@wordpress/blocks": "^13.3.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/data": "^10.3.0", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/html-entities": "^4.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/is-shallow-equal": "^5.3.0", - "@wordpress/private-apis": "^1.3.0", - "@wordpress/rich-text": "^7.3.0", - "@wordpress/sync": "^1.3.0", - "@wordpress/undo-manager": "^1.3.0", - "@wordpress/url": "^4.3.0", - "change-case": "^4.1.2", - "equivalent-key-map": "^0.2.2", - "fast-deep-equal": "^3.1.3", - "memize": "^2.1.0", - "uuid": "^9.0.1" - }, - "engines": { - "node": ">=18.12.0", - "npm": ">=8.19.2" + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@wordpress/data": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-10.3.0.tgz", - "integrity": "sha512-cImJw4k30coosH6QtiJllxEYr93w8981PPvhGhemMbRQ28MnSA7rbJPv3h2LO9oss5SQH1gU9kwNGAZcF6PMPg==", + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-id": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.1.tgz", + "integrity": "sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==", "dev": true, "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-layout-effect": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-portal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.4.tgz", + "integrity": "sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-presence": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.1.tgz", + "integrity": "sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-primitive": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz", + "integrity": "sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-slot": "1.0.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-slot": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz", + "integrity": "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz", + "integrity": "sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.1.tgz", + "integrity": "sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz", + "integrity": "sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.1.tgz", + "integrity": "sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/cmdk": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cmdk/-/cmdk-1.0.0.tgz", + "integrity": "sha512-gDzVf0a09TvoJ5jnuPvygTB77+XdOSwEmJ88L6XPFPlv7T3RxbP9jgenfylrAMD0+Le1aO0nVjQUzl2g+vjz5Q==", + "dev": true, + "dependencies": { + "@radix-ui/react-dialog": "1.0.5", + "@radix-ui/react-primitive": "1.0.3" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@wordpress/commands/node_modules/react-remove-scroll": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz", + "integrity": "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==", + "dev": true, + "dependencies": { + "react-remove-scroll-bar": "^2.3.3", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@wordpress/components": { + "version": "28.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-28.5.0.tgz", + "integrity": "sha512-kZPb8MdpGW/Yv/ycJhbf+myb4czkyQ28gb5PY1kT2ABRB07J3oS1/badSLex3x06zD6NPtJt3kInbPUsSF2prQ==", + "dev": true, + "dependencies": { + "@ariakit/react": "^0.4.7", "@babel/runtime": "^7.16.0", + "@emotion/cache": "^11.7.1", + "@emotion/css": "^11.7.1", + "@emotion/react": "^11.7.1", + "@emotion/serialize": "^1.0.2", + "@emotion/styled": "^11.6.0", + "@emotion/utils": "^1.0.0", + "@floating-ui/react-dom": "^2.0.8", + "@types/gradient-parser": "0.1.3", + "@types/highlight-words-core": "1.2.1", + "@use-gesture/react": "^10.3.1", + "@wordpress/a11y": "^4.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/date": "^5.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/dom": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/escape-html": "^3.5.0", + "@wordpress/hooks": "^4.5.0", + "@wordpress/html-entities": "^4.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/icons": "^10.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/keycodes": "^4.5.0", + "@wordpress/primitives": "^4.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/rich-text": "^7.5.0", + "@wordpress/warning": "^3.5.0", + "change-case": "^4.1.2", + "clsx": "^2.1.1", + "colord": "^2.7.0", + "date-fns": "^3.6.0", + "deepmerge": "^4.3.0", + "fast-deep-equal": "^3.1.3", + "framer-motion": "^11.1.9", + "gradient-parser": "^0.1.5", + "highlight-words-core": "^1.2.2", + "is-plain-object": "^5.0.0", + "memize": "^2.1.0", + "path-to-regexp": "^6.2.1", + "re-resizable": "^6.4.0", + "react-colorful": "^5.3.1", + "remove-accents": "^0.5.0", + "use-lilius": "^2.0.5", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@wordpress/components/node_modules/@ariakit/core": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/@ariakit/core/-/core-0.4.8.tgz", + "integrity": "sha512-HQS+9CI7pMqqVlAt5bPGenT0/e65UxXY+PKtgU7Y+0UToBDBRolO5S9+UUSDm8OmJHSnq24owEGm1Mv28l5XCQ==", + "dev": true + }, + "node_modules/@wordpress/components/node_modules/@ariakit/react": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/@ariakit/react/-/react-0.4.8.tgz", + "integrity": "sha512-Bb1vOrp0X52hxi1wE9TEHjjZ/Y08tVq2ZH+RFDwRQB3g04uVwrrhnTccHepC6rsObrDpAOV3/YlJCi4k/lSUaQ==", + "dev": true, + "dependencies": { + "@ariakit/react-core": "0.4.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ariakit" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@wordpress/components/node_modules/@ariakit/react-core": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/@ariakit/react-core/-/react-core-0.4.8.tgz", + "integrity": "sha512-TzsddUWQwWYhrEVWHA/Gf7KCGx8rwFohAHfuljjqidKeZi2kUmuRAImCTG9oga34FWHFf4AdXQbBKclMNt0nrQ==", + "dev": true, + "dependencies": { + "@ariakit/core": "0.4.8", + "@floating-ui/dom": "^1.0.0", + "use-sync-external-store": "^1.2.0" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@wordpress/components/node_modules/@wordpress/keycodes": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@wordpress/i18n": "^5.5.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, + "node_modules/@wordpress/components/node_modules/@wordpress/warning": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.5.0.tgz", + "integrity": "sha512-cYM2Vqf2EokJJoWHD5Ry15OUmdsKtDgR8/qxE0sWHUAdSQeoTuJZnqhgYI898cZGxHaZWX2xJCxQa7Qtwl8lqw==", + "dev": true, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, + "node_modules/@wordpress/compose": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-7.5.0.tgz", + "integrity": "sha512-jWRmleIGxmvTIC/1VYtAvq0iRfCkW/AtlNmqoKiyd0Ah5lccWRtxSH5V3Vh1BEkBQRANMWxJpOpRTKDFTcfTvg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@types/mousetrap": "^1.6.8", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/dom": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/keycodes": "^4.5.0", + "@wordpress/priority-queue": "^3.5.0", + "@wordpress/undo-manager": "^1.5.0", + "change-case": "^4.1.2", + "clipboard": "^2.0.11", + "mousetrap": "^1.6.5", + "use-memo-one": "^1.1.1" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0" + } + }, + "node_modules/@wordpress/compose/node_modules/@wordpress/keycodes": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@wordpress/i18n": "^5.5.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, + "node_modules/@wordpress/core-commands": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@wordpress/core-commands/-/core-commands-1.3.0.tgz", + "integrity": "sha512-Tc9w07UgyFKT6fq0UUxsTmXmRGsULiV25YtAwqxF52XtYxfo+mPMDJgYpNA2l3eKL6EuWR6AzNl8f9pank55oA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@wordpress/block-editor": "^13.3.0", + "@wordpress/commands": "^1.3.0", "@wordpress/compose": "^7.3.0", - "@wordpress/deprecated": "^4.3.0", + "@wordpress/core-data": "^7.3.0", + "@wordpress/data": "^10.3.0", "@wordpress/element": "^6.3.0", - "@wordpress/is-shallow-equal": "^5.3.0", - "@wordpress/priority-queue": "^3.3.0", + "@wordpress/html-entities": "^4.3.0", + "@wordpress/i18n": "^5.3.0", + "@wordpress/icons": "^10.3.0", "@wordpress/private-apis": "^1.3.0", - "@wordpress/redux-routine": "^5.3.0", + "@wordpress/router": "^1.3.0", + "@wordpress/url": "^4.3.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@wordpress/core-data": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/core-data/-/core-data-7.5.0.tgz", + "integrity": "sha512-NzKmf09yUw6ZH6NLRtM8qYci2HrA8dla2SJB4r/mtSpcVilDJL+j/hnuzMpvRJAGA5mWdB2ANnvlXWfG+BVsiA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@wordpress/api-fetch": "^7.5.0", + "@wordpress/block-editor": "^14.0.0", + "@wordpress/blocks": "^13.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/html-entities": "^4.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/rich-text": "^7.5.0", + "@wordpress/sync": "^1.5.0", + "@wordpress/undo-manager": "^1.5.0", + "@wordpress/url": "^4.5.0", + "@wordpress/warning": "^3.5.0", + "change-case": "^4.1.2", + "equivalent-key-map": "^0.2.2", + "fast-deep-equal": "^3.1.3", + "memize": "^2.1.0", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@wordpress/core-data/node_modules/@wordpress/block-editor": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-14.0.0.tgz", + "integrity": "sha512-IODsUPm37DpZxLMcJXidlHeUAvALX+E9edY+z9UGJWP/PvhLCXllCRVQABcuYkPTsraFSF0Yrk9i/7WJF2NkaA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@emotion/react": "^11.7.1", + "@emotion/styled": "^11.6.0", + "@react-spring/web": "^9.4.5", + "@wordpress/a11y": "^4.5.0", + "@wordpress/api-fetch": "^7.5.0", + "@wordpress/blob": "^4.5.0", + "@wordpress/blocks": "^13.5.0", + "@wordpress/commands": "^1.5.0", + "@wordpress/components": "^28.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/date": "^5.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/dom": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/escape-html": "^3.5.0", + "@wordpress/hooks": "^4.5.0", + "@wordpress/html-entities": "^4.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/icons": "^10.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/keyboard-shortcuts": "^5.5.0", + "@wordpress/keycodes": "^4.5.0", + "@wordpress/notices": "^5.5.0", + "@wordpress/preferences": "^4.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/rich-text": "^7.5.0", + "@wordpress/style-engine": "^2.5.0", + "@wordpress/token-list": "^3.5.0", + "@wordpress/url": "^4.5.0", + "@wordpress/warning": "^3.5.0", + "@wordpress/wordcount": "^4.5.0", + "change-case": "^4.1.2", + "clsx": "^2.1.1", + "colord": "^2.7.0", + "deepmerge": "^4.3.0", + "diff": "^4.0.2", + "fast-deep-equal": "^3.1.3", + "memize": "^2.1.0", + "postcss": "^8.4.21", + "postcss-prefixwrap": "^1.41.0", + "postcss-urlrebase": "^1.4.0", + "react-autosize-textarea": "^7.1.0", + "react-easy-crop": "^5.0.6", + "remove-accents": "^0.5.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@wordpress/core-data/node_modules/@wordpress/keycodes": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@wordpress/i18n": "^5.5.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, + "node_modules/@wordpress/core-data/node_modules/@wordpress/warning": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.5.0.tgz", + "integrity": "sha512-cYM2Vqf2EokJJoWHD5Ry15OUmdsKtDgR8/qxE0sWHUAdSQeoTuJZnqhgYI898cZGxHaZWX2xJCxQa7Qtwl8lqw==", + "dev": true, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, + "node_modules/@wordpress/data": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-10.5.0.tgz", + "integrity": "sha512-Y2P5SC0fuTivcfdYmubL3c15WRbE0FJAyYcEfZeJ2C37a2DmBnCBz3uEzGy2kCilz56qMfK0qutAHkfytOpRQw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/priority-queue": "^3.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/redux-routine": "^5.5.0", "deepmerge": "^4.3.0", "equivalent-key-map": "^0.2.2", "is-plain-object": "^5.0.0", @@ -9970,13 +10483,13 @@ } }, "node_modules/@wordpress/date": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/date/-/date-5.3.0.tgz", - "integrity": "sha512-vD0rLQxNlOoFd4n32HohhTif4P1JPW/Igjp0c/O2WZji+eXQM6P54fBu5veKvgwMmXpUn8y0xzgssj3pKAUgCg==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/date/-/date-5.5.0.tgz", + "integrity": "sha512-dIo02TAIuXG/wkcVf+jsyXn64PUVsxs6HwuHanNiDNVZt95QVJ8b7wdJZNIrhTkmVXhIUzYAz5BpuXUC6IZAqg==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/deprecated": "^4.3.0", + "@wordpress/deprecated": "^4.5.0", "moment": "^2.29.4", "moment-timezone": "^0.5.40" }, @@ -10002,13 +10515,13 @@ } }, "node_modules/@wordpress/deprecated": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-4.3.0.tgz", - "integrity": "sha512-K2GHXlwjx6GMhZjs52X1MXySCrqzh4IjoqF5IOcydMgWqOIE2++hMuB9Y55qN/Mhsrv/HO8Q1LaTxbEd6BuNJQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-4.5.0.tgz", + "integrity": "sha512-r3xGAM45XTd+z+hnUvLGtSz+Y0ebybuw/cyE0CatksJBGvXez3kiTDaknALkgzjHRZzIGpNu6XTVUoIJs0H39A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/hooks": "^4.3.0" + "@wordpress/hooks": "^4.5.0" }, "engines": { "node": ">=18.12.0", @@ -10016,13 +10529,13 @@ } }, "node_modules/@wordpress/dom": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-4.3.0.tgz", - "integrity": "sha512-sf4h6jVqboRdhe3soyr5bt+Vpz24WG/AIMHm7pGaxfbV5jxx06ZZ8K1RKzhr7jF3wn7IgIc1wmMA+OFzEYqGyw==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-4.5.0.tgz", + "integrity": "sha512-XjnpRbbhZ1hdgv758vSXQacjfy/N0H2oI0oWukrLmlkKDP5ZrGfdziHQ2+KcoW+QDx8pu4JYcUpjmuJLugDStw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/deprecated": "^4.3.0" + "@wordpress/deprecated": "^4.5.0" }, "engines": { "node": ">=18.12.0", @@ -10030,9 +10543,9 @@ } }, "node_modules/@wordpress/dom-ready": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/dom-ready/-/dom-ready-4.3.0.tgz", - "integrity": "sha512-zuLLMIeJt1hZ95R4kdJFcsIaL2eud1kF40VCmwK3mK0qpgXv/1avtGX8lx6DMLL/GGL1yYcJhR13RSKSjxuGEQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom-ready/-/dom-ready-4.5.0.tgz", + "integrity": "sha512-5dALG1lQtoH/Rk7DWFe9DaIF2bQQM5U0x+c1lQnk1cnBJ69AijIcbZMYaMzlgngo4dVF2PnFZ/VKVSUOKghhQQ==", "dependencies": { "@babel/runtime": "^7.16.0" }, @@ -10323,15 +10836,15 @@ } }, "node_modules/@wordpress/element": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-6.3.0.tgz", - "integrity": "sha512-DsiqzjuXqxJkLUoLomsGTFFxbSZgk+Lz+2/1yFH+BU3jQ6zeD64+JWv8Lt4+fKU154rV0KpfMwfD/oAC/Lp1zQ==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-6.5.0.tgz", + "integrity": "sha512-N9w3jfceltdDEN71jpaMCXU+jbvec9kredvQIn/6YNiUMarPXWth7DJYU3+mDtbYawnTIvytzGjbj/J+bqqdHg==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", "@types/react": "^18.2.79", "@types/react-dom": "^18.2.25", - "@wordpress/escape-html": "^3.3.0", + "@wordpress/escape-html": "^3.5.0", "change-case": "^4.1.2", "is-plain-object": "^5.0.0", "react": "^18.3.0", @@ -10446,9 +10959,9 @@ } }, "node_modules/@wordpress/escape-html": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-3.3.0.tgz", - "integrity": "sha512-Wu/Fq96E28UGnIO5VQW/aEgCiHWvzrD8izDnP8U0WZSuwIPYcS5iYmRe2UWc7rwyoeY2YXNd6xFjgd7oTOKNCA==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-3.5.0.tgz", + "integrity": "sha512-8dUWTmsDZuqAmBtRgk0JpiIafRKPM4n8tqCr147AugTbP/vyQ7rIzG3M/YCtVSmDr6f/qZ32YU8J7c34RhZ/9g==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -10718,9 +11231,9 @@ } }, "node_modules/@wordpress/hooks": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-4.3.0.tgz", - "integrity": "sha512-bpqwSXGyxPfhuxESKoAtL4ofB3CazzvcwcucTZ0g9Pat3KNuBaloSrPBliqqNOiSLWNH3nmpkaRmv4u89EdKAw==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-4.5.0.tgz", + "integrity": "sha512-wr1l1WM1yobyNGFLRgbLNBGtYIkzAGfmbT2e9zIOvqllRJT4wprYTqqhgovOKHlET5ij/TKdv4tApkGLUIXTsA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -10731,9 +11244,9 @@ } }, "node_modules/@wordpress/html-entities": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/html-entities/-/html-entities-4.3.0.tgz", - "integrity": "sha512-rJDf9KjCuUnFwIwmOdN4FcL7RJnDzPxIdvvMoWXkYd9GseEeRTsY6xIG+fGgVGgYe3HwXDYSFCWTF/x2M9Eerg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/html-entities/-/html-entities-4.5.0.tgz", + "integrity": "sha512-iQo2P1Sc499MxguelJ4aMcF08jnYkOdvb+FAOyOfGCyDjEtNbldRFc2BJ9NmJ/9nmtlwc/IzUzXop0M1gjy9tw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -10744,13 +11257,13 @@ } }, "node_modules/@wordpress/i18n": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-5.3.0.tgz", - "integrity": "sha512-edHKkdZb6jNpbn+LUPu2wo1mKyhT819WJ7kI8hmMcHq82rNwwbMfcGoB3oSaphTphWfhlgxIxLczKOAbWDKudw==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-5.5.0.tgz", + "integrity": "sha512-MtCJIjNHCWs7R77f5Xml1CCnVXqrle4cDpqMU9myx4Cq8ZijqSayX1CTtwtk+Z3/3xa+dBZu5Koe4wiW1yIUSA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/hooks": "^4.3.0", + "@wordpress/hooks": "^4.5.0", "gettext-parser": "^1.3.1", "memize": "^2.1.0", "sprintf-js": "^1.1.1", @@ -10765,14 +11278,14 @@ } }, "node_modules/@wordpress/icons": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/icons/-/icons-10.3.0.tgz", - "integrity": "sha512-d2jOFfLIAxPr+/Bzg7wnRDEDPogMpVefe4cHgIx9kXp/+7DG4KWNJm842qVithjs1wVgSzavzWbFrTtPEZ+Uhw==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/icons/-/icons-10.5.0.tgz", + "integrity": "sha512-BZwKBRKoTef9uW73T+FwK6d4JlcvgdVAaz3LB5dCluXg5PLV5ufMdumAaMxKWq/Ffl92/ddt8CKIdHjxfAZF4A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/element": "^6.3.0", - "@wordpress/primitives": "^4.3.0" + "@wordpress/element": "^6.5.0", + "@wordpress/primitives": "^4.5.0" }, "engines": { "node": ">=18.12.0", @@ -10838,9 +11351,9 @@ } }, "node_modules/@wordpress/is-shallow-equal": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-5.3.0.tgz", - "integrity": "sha512-sZ+fypqjYX0/DTAKsm1G9ND9Wn4d3Ju4lI7SLSmCKdUL5EPY3g/2LpKQKDqljh9m6Ex5NWp2XfU8UVXpkEfbMQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-5.5.0.tgz", + "integrity": "sha512-nkCz45HgMBkjhyxffDgpAgJbfnKyZML94/gHhBtxizHfaNuZ5as7DfEyN1xgebvDiLbOaRU7em1pPAuEhIoTfQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -10886,15 +11399,15 @@ } }, "node_modules/@wordpress/keyboard-shortcuts": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/keyboard-shortcuts/-/keyboard-shortcuts-5.3.0.tgz", - "integrity": "sha512-Zms+SzRekXqLBW0IPxZDhusxix5xm6jBmWfOfc//uCy7xvhZS1FxEYoolfYFB7tXT7xFTQbwVYN99ICI7BeqnQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keyboard-shortcuts/-/keyboard-shortcuts-5.5.0.tgz", + "integrity": "sha512-U+64UvlrWjxnn6YJ5ZW7Oi9EJE9J7aWRGzpCAL8yoRDqiVC/zUzvgnVmo9AoA8jVEBxKUeDFyntckCE2qW0STQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/data": "^10.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/keycodes": "^4.3.0" + "@wordpress/data": "^10.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/keycodes": "^4.5.0" }, "engines": { "node": ">=18.12.0", @@ -10905,13 +11418,13 @@ } }, "node_modules/@wordpress/keyboard-shortcuts/node_modules/@wordpress/keycodes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.3.0.tgz", - "integrity": "sha512-o+L110/Y9ufS2eWVG1gXFs6+jPsMNVZoGJCt4PLjMmVabke0iaYstFppUdtQiOEDbnnhX9MH3RRtqp2AoSnaRQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0" + "@wordpress/i18n": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -10984,14 +11497,14 @@ } }, "node_modules/@wordpress/notices": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/notices/-/notices-5.3.0.tgz", - "integrity": "sha512-1aZVcmy3Aj1nn4jmdQDpVFIB7L40AkhW7maFKhEH0oo2UAiPmqJyGDeby9sD96m2hskwyZzAgI15k+KrEf17LQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/notices/-/notices-5.5.0.tgz", + "integrity": "sha512-QcTbGAyHJ7V8LvSDJttUKCmClIFBQQ2/gk7pTBMBwe+argYQLOVRAQP/+97AnP9KFVtzuENrjbQtsyYeMWaTSw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/a11y": "^4.3.0", - "@wordpress/data": "^10.3.0" + "@wordpress/a11y": "^4.5.0", + "@wordpress/data": "^10.5.0" }, "engines": { "node": ">=18.12.0", @@ -11087,21 +11600,21 @@ } }, "node_modules/@wordpress/preferences": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/preferences/-/preferences-4.3.0.tgz", - "integrity": "sha512-XTPJYjdz8iy9Sy+B+RAPFwk4KkGPgjogu3mhcMvYLqqKKeVhUt6zImXVNXQbNFGTlCgB+l0b4h4L5EHmJWVDgg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/preferences/-/preferences-4.5.0.tgz", + "integrity": "sha512-cDk+StQGyjwWzyo8dmVfdwYvL45hMd+m3qUNbP29PizJb4jPHBLVg4WTabuFG0I5TEs75zIjDWQsb3HeG//cHw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/a11y": "^4.3.0", - "@wordpress/components": "^28.3.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/data": "^10.3.0", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/icons": "^10.3.0", - "@wordpress/private-apis": "^1.3.0", + "@wordpress/a11y": "^4.5.0", + "@wordpress/components": "^28.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/icons": "^10.5.0", + "@wordpress/private-apis": "^1.5.0", "clsx": "^2.1.1" }, "engines": { @@ -11127,24 +11640,27 @@ } }, "node_modules/@wordpress/primitives": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/primitives/-/primitives-4.3.0.tgz", - "integrity": "sha512-h7wb2Np3n5etOg3j38GN80NEA8NgNdsSF/JJcRhpRf8FQOJd1mnKzj6szVHeKv0G7bvBif0NTgdSUm5M6Nikfg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/primitives/-/primitives-4.5.0.tgz", + "integrity": "sha512-1TYCpCAr2BmYJESlD8v325GgYXSgUbrFtebwgvpMN/28CEwmPN+ORRECV41nPX4yVJ2k0kYzYxzQUGp/78xWsw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/element": "^6.3.0", + "@wordpress/element": "^6.5.0", "clsx": "^2.1.1" }, "engines": { "node": ">=18.12.0", "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0" } }, "node_modules/@wordpress/priority-queue": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-3.3.0.tgz", - "integrity": "sha512-H7dGei1mFqKlz7NLFOGGtVgaBsORRaXeXNwWLI5rE0pI3XfGYd+zxNrG5aBzHw4fPqsITsxecNSaacc9fjqgjQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-3.5.0.tgz", + "integrity": "sha512-ilbG70ZuUJd0UTC7uyLP8zI/ZSN0d4ceG3qwlDx13yQAcjAcuw1Ei1CwzFBsbmI3OS1KkfkDpwZzKOrA+j/00Q==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", @@ -11156,9 +11672,9 @@ } }, "node_modules/@wordpress/private-apis": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/private-apis/-/private-apis-1.3.0.tgz", - "integrity": "sha512-IbtH8ZENAKixSoTBKbmJ2ZCIkxsxqAoWPBtvbNJG9rYdzSk+BExdy/5VGO6Pv5GcUElHT+8uV26W4XxBVNl4UQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/private-apis/-/private-apis-1.5.0.tgz", + "integrity": "sha512-taGW34kyyHMnbmTbWIyOJt7C4KFVCg7F5PNFwJQmS43FESC9BAjPw7VeEDTJ0XNqocH4NNeBJclhFyj82QySTQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -11169,9 +11685,9 @@ } }, "node_modules/@wordpress/redux-routine": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/redux-routine/-/redux-routine-5.3.0.tgz", - "integrity": "sha512-5HGdW8PqIK5fTyg1yo6NL2x1LTxU9vBvgUan/bLxYLX0YNw4+gQUex3djE0dwXNgrdE4mvWvYTcccc+2L59hig==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/redux-routine/-/redux-routine-5.5.0.tgz", + "integrity": "sha512-PvIgq0lI2PLjechCq+pRFIE/xbFwznytupGscD95qks3fFM9jtqVhlgO2oW0pA7C6CIz8zQ0zONFjsQlOaeDKA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", @@ -11216,20 +11732,20 @@ } }, "node_modules/@wordpress/rich-text": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/rich-text/-/rich-text-7.3.0.tgz", - "integrity": "sha512-iL7qEybPOwtMp8WXMQndzfvT2k647ZqIMTj0rji4h2QAp/KaEHyYaIF6YhuQ7v5bSQ/9IAAOy3KGhguIuxIt8A==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/rich-text/-/rich-text-7.5.0.tgz", + "integrity": "sha512-qHeTZNaLbsO6coBph1CD4qn/nfzvJV/DamiCpSgBJ1eQO7u8DdVB8abDxODOOD5hVOLHTOM/OBjFPTVFevNrmw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/a11y": "^4.3.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/data": "^10.3.0", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/escape-html": "^3.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/keycodes": "^4.3.0", + "@wordpress/a11y": "^4.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/escape-html": "^3.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/keycodes": "^4.5.0", "memize": "^2.1.0" }, "engines": { @@ -11241,13 +11757,13 @@ } }, "node_modules/@wordpress/rich-text/node_modules/@wordpress/keycodes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.3.0.tgz", - "integrity": "sha512-o+L110/Y9ufS2eWVG1gXFs6+jPsMNVZoGJCt4PLjMmVabke0iaYstFppUdtQiOEDbnnhX9MH3RRtqp2AoSnaRQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0" + "@wordpress/i18n": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -11887,9 +12403,9 @@ } }, "node_modules/@wordpress/shortcode": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/shortcode/-/shortcode-4.3.0.tgz", - "integrity": "sha512-Ononu3JfP8W/qLNeB46YuGpmqpjj+VyA9EK6pZdmf1/8Gd9Q6L2+HRyp1AEzJzs59p2pLfzvf63T90KSSZjBaQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/shortcode/-/shortcode-4.5.0.tgz", + "integrity": "sha512-Ed0Gh7ZMaz5UkVo6yF5eQY/Nzpv4afxrr8dGjMNQpmUbq92CwaAq8tfj5vT89IV/Ano0F2EQtkcyKEVJ7VPqrw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", @@ -11901,9 +12417,9 @@ } }, "node_modules/@wordpress/style-engine": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/style-engine/-/style-engine-2.3.0.tgz", - "integrity": "sha512-VLnhVPDOZ32cnxFJSQbVkuF8YUd2M33m3bvw28TSvdAZcosN1WpmoEAtn9NhwU2jklvJEFfa1inlzuQ3NW/HEA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/style-engine/-/style-engine-2.5.0.tgz", + "integrity": "sha512-mV6cOtEO5zGg8ZYUNsHDBnywb76Jc+k1Q65PVSNezD+NtZasuASxZGz2J3gEwgNL/1p++JO7JQf9qyoZUs/jZw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", @@ -11932,14 +12448,14 @@ } }, "node_modules/@wordpress/sync": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/sync/-/sync-1.3.0.tgz", - "integrity": "sha512-up2zDx35LT3xOkx48+pfF+98p1T6q6nsZqQywf3nqbunxLBq+MYNUC7bd3z/Snn2jiCASxAINWMR5jQ1MB4Bqw==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/sync/-/sync-1.5.0.tgz", + "integrity": "sha512-c/p7YQqMjZAKFO3Q8FnikPp5Tm3/Iy4I0M4Rc5ML1VZMy+hwZVKQZ1AyfKfHAjDWv+XprSUVSbXpYL5YcYthlA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", "@types/simple-peer": "^9.11.5", - "@wordpress/url": "^4.3.0", + "@wordpress/url": "^4.5.0", "import-locals": "^2.0.0", "lib0": "^0.2.42", "simple-peer": "^9.11.0", @@ -11954,9 +12470,9 @@ } }, "node_modules/@wordpress/token-list": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/token-list/-/token-list-3.3.0.tgz", - "integrity": "sha512-9IcUUebJ2KBIe371pKonpS0KtTgwDzPJBQIMkPACvw47AL3ZY83sQzBwEqAw+hNstqilOD6n/SQUhIYxzMvdhg==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/token-list/-/token-list-3.5.0.tgz", + "integrity": "sha512-n/a7HYJz3b922qHcs4yyywzuFKZg8Du/xE6KSnPz9EiUVCHthYFJ8m587f9xtgdUDjZKK7fpZZ0yCK/Krwna+Q==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -11967,13 +12483,13 @@ } }, "node_modules/@wordpress/undo-manager": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/undo-manager/-/undo-manager-1.3.0.tgz", - "integrity": "sha512-1XvU3GKpWeKFLCRx/3yEttRbIszD38vfH53XmCq2Y6IbWiyJLUGCnq4kiZjOaxA0o/DcAa4edscPyqmJj+wE+g==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/undo-manager/-/undo-manager-1.5.0.tgz", + "integrity": "sha512-ijvKwnXzKMV9xEcVB4mOIPih6BP5ZnZ1QYsv/EaPV7qlt2zgEevAHGa/FLQMW/lWlGCa5OhUK4tqDV+ZvrjTGw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/is-shallow-equal": "^5.3.0" + "@wordpress/is-shallow-equal": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -11981,9 +12497,9 @@ } }, "node_modules/@wordpress/url": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-4.3.0.tgz", - "integrity": "sha512-2rbpF2OD3rc/Jhmd4Mn9PxXTYGw63hIVMEJWzHs0x/mHmuDZEAn1vZcpDhJkksqtnHMS3BOlTv+Kbk1klxOpCg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-4.5.0.tgz", + "integrity": "sha512-xv/wqUnqNedo9fyiCVJgZnfLtYJbBph30Z2neTFR8Ivy8HA4p74xGqlt8TJceYLeRUrT9EgsMITbHNJMftdNbA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", @@ -12053,9 +12569,9 @@ } }, "node_modules/@wordpress/wordcount": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/wordcount/-/wordcount-4.3.0.tgz", - "integrity": "sha512-+jTnD4XMRRxljZ6mRif5wMFqiDbIFTc/naeE2CI7mirdsnFriUD3gYmhgLsP71Rckh+9EHZpzQBCbehXU2zX1A==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/wordcount/-/wordcount-4.5.0.tgz", + "integrity": "sha512-LgSA2Mra6e9r15eRUIFNk2TCWnoyNhecPOOWrT061sl9dEvJ92zAjNWILrMa8rnTTX651bnF2HJD1PkivxDVzw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" diff --git a/package.json b/package.json index dd4fd7a5a..f1e355bb9 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "@wordpress/blocks": "^13.3.0", "@wordpress/components": "^28.3.0", "@wordpress/compose": "^7.0.0", - "@wordpress/core-data": "^7.3.0", + "@wordpress/core-data": "^7.5.0", "@wordpress/data": "^10.3.0", "@wordpress/e2e-test-utils": "^11.3.0", "@wordpress/edit-post": "^8.3.0", From 457dd9e698efff86e386aabed70def1f5badccde Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 07:48:07 +0000 Subject: [PATCH 026/282] build(deps-dev): bump @wordpress/i18n from 5.3.0 to 5.5.0 Bumps [@wordpress/i18n](https://github.com/WordPress/gutenberg/tree/HEAD/packages/i18n) from 5.3.0 to 5.5.0. - [Release notes](https://github.com/WordPress/gutenberg/releases) - [Changelog](https://github.com/WordPress/gutenberg/blob/trunk/packages/i18n/CHANGELOG.md) - [Commits](https://github.com/WordPress/gutenberg/commits/@wordpress/i18n@5.5.0/packages/i18n) --- updated-dependencies: - dependency-name: "@wordpress/i18n" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 16 ++++++++-------- package.json | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 40ab6e410..5086d319a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,7 +41,7 @@ "@wordpress/env": "^10.3.0", "@wordpress/eslint-plugin": "^20.0.0", "@wordpress/hooks": "^4.0.0", - "@wordpress/i18n": "^5.0.0", + "@wordpress/i18n": "^5.5.0", "@wordpress/icons": "^10.0.0", "@wordpress/plugins": "^7.3.0", "@wordpress/scripts": "^27.9.0", @@ -10718,9 +10718,9 @@ } }, "node_modules/@wordpress/hooks": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-4.3.0.tgz", - "integrity": "sha512-bpqwSXGyxPfhuxESKoAtL4ofB3CazzvcwcucTZ0g9Pat3KNuBaloSrPBliqqNOiSLWNH3nmpkaRmv4u89EdKAw==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-4.5.0.tgz", + "integrity": "sha512-wr1l1WM1yobyNGFLRgbLNBGtYIkzAGfmbT2e9zIOvqllRJT4wprYTqqhgovOKHlET5ij/TKdv4tApkGLUIXTsA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -10744,13 +10744,13 @@ } }, "node_modules/@wordpress/i18n": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-5.3.0.tgz", - "integrity": "sha512-edHKkdZb6jNpbn+LUPu2wo1mKyhT819WJ7kI8hmMcHq82rNwwbMfcGoB3oSaphTphWfhlgxIxLczKOAbWDKudw==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-5.5.0.tgz", + "integrity": "sha512-MtCJIjNHCWs7R77f5Xml1CCnVXqrle4cDpqMU9myx4Cq8ZijqSayX1CTtwtk+Z3/3xa+dBZu5Koe4wiW1yIUSA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/hooks": "^4.3.0", + "@wordpress/hooks": "^4.5.0", "gettext-parser": "^1.3.1", "memize": "^2.1.0", "sprintf-js": "^1.1.1", diff --git a/package.json b/package.json index dd4fd7a5a..5934f4115 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "@wordpress/env": "^10.3.0", "@wordpress/eslint-plugin": "^20.0.0", "@wordpress/hooks": "^4.0.0", - "@wordpress/i18n": "^5.0.0", + "@wordpress/i18n": "^5.5.0", "@wordpress/icons": "^10.0.0", "@wordpress/plugins": "^7.3.0", "@wordpress/scripts": "^27.9.0", From 9568ac2c854edbb353e42df0ea4717f26e61925d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 07:48:22 +0000 Subject: [PATCH 027/282] build(deps-dev): bump @testing-library/jest-dom from 6.4.6 to 6.4.8 Bumps [@testing-library/jest-dom](https://github.com/testing-library/jest-dom) from 6.4.6 to 6.4.8. - [Release notes](https://github.com/testing-library/jest-dom/releases) - [Changelog](https://github.com/testing-library/jest-dom/blob/main/CHANGELOG.md) - [Commits](https://github.com/testing-library/jest-dom/compare/v6.4.6...v6.4.8) --- updated-dependencies: - dependency-name: "@testing-library/jest-dom" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 32 ++++---------------------------- package.json | 2 +- 2 files changed, 5 insertions(+), 29 deletions(-) diff --git a/package-lock.json b/package-lock.json index 40ab6e410..1c9fd2704 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "lodash.debounce": "^4.0.8" }, "devDependencies": { - "@testing-library/jest-dom": "^6.4.6", + "@testing-library/jest-dom": "^6.4.8", "@testing-library/react": "^16.0.0", "@types/jest": "^29.5.12", "@types/jest-environment-puppeteer": "^5.0.6", @@ -5302,9 +5302,9 @@ } }, "node_modules/@testing-library/jest-dom": { - "version": "6.4.6", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.4.6.tgz", - "integrity": "sha512-8qpnGVincVDLEcQXWaHOf6zmlbwTKc6Us6PPu4CRnPXCzo2OGBS5cwgMMOWdxDpEz1mkbvXHpEy99M5Yvt682w==", + "version": "6.4.8", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.4.8.tgz", + "integrity": "sha512-JD0G+Zc38f5MBHA4NgxQMR5XtO5Jx9g86jqturNTt2WUfRmLDIY7iKkWHDCCTiDuFMre6nxAD5wHw9W5kI4rGw==", "dev": true, "dependencies": { "@adobe/css-tools": "^4.4.0", @@ -5320,30 +5320,6 @@ "node": ">=14", "npm": ">=6", "yarn": ">=1" - }, - "peerDependencies": { - "@jest/globals": ">= 28", - "@types/bun": "latest", - "@types/jest": ">= 28", - "jest": ">= 28", - "vitest": ">= 0.32" - }, - "peerDependenciesMeta": { - "@jest/globals": { - "optional": true - }, - "@types/bun": { - "optional": true - }, - "@types/jest": { - "optional": true - }, - "jest": { - "optional": true - }, - "vitest": { - "optional": true - } } }, "node_modules/@testing-library/jest-dom/node_modules/ansi-styles": { diff --git a/package.json b/package.json index dd4fd7a5a..2fa3c0820 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "lodash.debounce": "^4.0.8" }, "devDependencies": { - "@testing-library/jest-dom": "^6.4.6", + "@testing-library/jest-dom": "^6.4.8", "@testing-library/react": "^16.0.0", "@types/jest": "^29.5.12", "@types/jest-environment-puppeteer": "^5.0.6", From ff2bab8c6b0733adf32ee591bd1575be8c69c9fc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 07:49:03 +0000 Subject: [PATCH 028/282] build(deps-dev): bump @wordpress/editor from 14.3.0 to 14.5.0 Bumps [@wordpress/editor](https://github.com/WordPress/gutenberg/tree/HEAD/packages/editor) from 14.3.0 to 14.5.0. - [Release notes](https://github.com/WordPress/gutenberg/releases) - [Changelog](https://github.com/WordPress/gutenberg/blob/trunk/packages/editor/CHANGELOG.md) - [Commits](https://github.com/WordPress/gutenberg/commits/@wordpress/editor@14.5.0/packages/editor) --- updated-dependencies: - dependency-name: "@wordpress/editor" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 1756 +++++++++++++++++++++++++++++++++------------ package.json | 2 +- 2 files changed, 1279 insertions(+), 479 deletions(-) diff --git a/package-lock.json b/package-lock.json index 40ab6e410..272c752e9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,7 +36,7 @@ "@wordpress/data": "^10.3.0", "@wordpress/e2e-test-utils": "^11.3.0", "@wordpress/edit-post": "^8.3.0", - "@wordpress/editor": "^14.3.0", + "@wordpress/editor": "^14.5.0", "@wordpress/element": "^6.2.0", "@wordpress/env": "^10.3.0", "@wordpress/eslint-plugin": "^20.0.0", @@ -9369,14 +9369,14 @@ } }, "node_modules/@wordpress/a11y": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/a11y/-/a11y-4.3.0.tgz", - "integrity": "sha512-kmAE8hshmldudMhtj/RKY7lEwyux5w6zvCTbIj3a6iq0ZMhU3vsxTlCp/vEGLoYdfetwRN4zeJA9jvPki+IOUA==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/a11y/-/a11y-4.5.0.tgz", + "integrity": "sha512-sQmA4kTqu252to6ppVhti2RxSCFcAgWMc3l6rY2kBpj90uK5gtvLKQMr/GvydhildG/OzFSswbk1YBgSPGaudw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/dom-ready": "^4.3.0", - "@wordpress/i18n": "^5.3.0" + "@wordpress/dom-ready": "^4.5.0", + "@wordpress/i18n": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -9384,14 +9384,14 @@ } }, "node_modules/@wordpress/api-fetch": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-7.3.0.tgz", - "integrity": "sha512-VpHG+9cLRZG13V2t1+xXpwuHJCeqiOl0ent9qXzbe6am9DtKSJ3oxiNdZaHjs6tdgGNuN/mTowRi5ceYJZb83Q==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-7.5.0.tgz", + "integrity": "sha512-ShUbXTYaQD9G7rROidMtlByu4i1N8Pj4gB5tIUUg2d0IUwDdXJnABQWI2+ebSXLKIRNaAOrw/Gb5xef08TR0ag==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/url": "^4.3.0" + "@wordpress/i18n": "^5.5.0", + "@wordpress/url": "^4.5.0" }, "engines": { "node": ">=18.12.0", @@ -9399,9 +9399,9 @@ } }, "node_modules/@wordpress/autop": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/autop/-/autop-4.3.0.tgz", - "integrity": "sha512-ml34lWwTPZwD2QYTRcecC94KC/V4SBHaCetlEUz0GPzhyfi48Zku6RCoebMDmayqYlme1iF/4quC4zOA0QLoAg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/autop/-/autop-4.5.0.tgz", + "integrity": "sha512-r68rGyfig+qxonsGQTOOWVpxnmGRYlWgzvDlGRPQbM3KKHA46C7ZS0kYhiZ1RC1RTinLRsu+KX2Y3FbEWcNaWg==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -9456,9 +9456,9 @@ "license": "GPL-2.0-or-later" }, "node_modules/@wordpress/blob": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/blob/-/blob-4.3.0.tgz", - "integrity": "sha512-4BQMpcamwx/2rYGZpvcrmddTuo+hXnDtiylvzP0vAnukJ9p1ae2MGJrWCRNp1qNo/hRbyq8lzA43wgOFxKkp0g==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/blob/-/blob-4.5.0.tgz", + "integrity": "sha512-EVTa4duxIesuRc9p8GWEGb3067v30tEngR+ZF1CoVrboRusJ8WSYtQdmEIvJRgQt3t7WTUtc6P4uAFjONOqU0g==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -9628,9 +9628,9 @@ } }, "node_modules/@wordpress/block-serialization-default-parser": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/block-serialization-default-parser/-/block-serialization-default-parser-5.3.0.tgz", - "integrity": "sha512-H9xXMIqShBdMbt2cRmct+nDy/dzX9last1j3kwJ5Gr0WfvgSLXQOk3p7jnCYYbixgK08VzLvkfqEofg314QSbg==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-serialization-default-parser/-/block-serialization-default-parser-5.5.0.tgz", + "integrity": "sha512-tUQ9LDFXbMvJY+BYI6lPqucwwSWISe9voBdwwYAbHfHcAcS5veYMdZGREOYpXNgmgd+RCI4+j49oy3EwqUUr4w==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -9641,26 +9641,27 @@ } }, "node_modules/@wordpress/blocks": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/blocks/-/blocks-13.3.0.tgz", - "integrity": "sha512-Df0aW+IardBoiWwLopqex450s7HQjP+QRfD4Pi8Skr5ELuVxwPRAJK9Dv4X2eLQyEPIucErIBjgW6tcSXNIhQQ==", + "version": "13.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/blocks/-/blocks-13.5.0.tgz", + "integrity": "sha512-k8XSlVJQZ/HaZKib7HKILwi4MKMH8UxfdsB2j55Ed41v0exkV42wSK12H8IhFx6GXN/iy13m/f0tsIVGM4ZtIQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/autop": "^4.3.0", - "@wordpress/blob": "^4.3.0", - "@wordpress/block-serialization-default-parser": "^5.3.0", - "@wordpress/data": "^10.3.0", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/dom": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/hooks": "^4.3.0", - "@wordpress/html-entities": "^4.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/is-shallow-equal": "^5.3.0", - "@wordpress/private-apis": "^1.3.0", - "@wordpress/rich-text": "^7.3.0", - "@wordpress/shortcode": "^4.3.0", + "@wordpress/autop": "^4.5.0", + "@wordpress/blob": "^4.5.0", + "@wordpress/block-serialization-default-parser": "^5.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/dom": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/hooks": "^4.5.0", + "@wordpress/html-entities": "^4.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/rich-text": "^7.5.0", + "@wordpress/shortcode": "^4.5.0", + "@wordpress/warning": "^3.5.0", "change-case": "^4.1.2", "colord": "^2.7.0", "fast-deep-equal": "^3.1.3", @@ -9681,6 +9682,16 @@ "react": "^18.0.0" } }, + "node_modules/@wordpress/blocks/node_modules/@wordpress/warning": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.5.0.tgz", + "integrity": "sha512-cYM2Vqf2EokJJoWHD5Ry15OUmdsKtDgR8/qxE0sWHUAdSQeoTuJZnqhgYI898cZGxHaZWX2xJCxQa7Qtwl8lqw==", + "dev": true, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, "node_modules/@wordpress/browserslist-config": { "version": "5.41.0", "resolved": "https://registry.npmjs.org/@wordpress/browserslist-config/-/browserslist-config-5.41.0.tgz", @@ -9692,21 +9703,21 @@ } }, "node_modules/@wordpress/commands": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/commands/-/commands-1.3.0.tgz", - "integrity": "sha512-6toFSZTYfNPqHBG2IxuClZ7uZpuXsV7kJRjC+liy3ew1U6vG/Xx9Ps4gvUT1lun6uRsYmftTEqV9GUz2V6IadA==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/commands/-/commands-1.5.0.tgz", + "integrity": "sha512-44BoBnVkdOllkrqXY1lcjdEXzyQrk3WF7hC6IjBgGHhXtdHm4ejn1VthLiAlK2KeA+M/XT5H/x1AiAhpnsrToA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/components": "^28.3.0", - "@wordpress/data": "^10.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/icons": "^10.3.0", - "@wordpress/keyboard-shortcuts": "^5.3.0", - "@wordpress/private-apis": "^1.3.0", + "@wordpress/components": "^28.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/icons": "^10.5.0", + "@wordpress/keyboard-shortcuts": "^5.5.0", + "@wordpress/private-apis": "^1.5.0", "clsx": "^2.1.1", - "cmdk": "^0.2.0" + "cmdk": "^1.0.0" }, "engines": { "node": ">=18.12.0", @@ -9717,215 +9728,717 @@ "react-dom": "^18.0.0" } }, - "node_modules/@wordpress/components": { - "version": "28.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-28.3.0.tgz", - "integrity": "sha512-zLHtxmhbuD7j5f7wOqRu6+KYVWPRpgHsYzxOavWkkiKv0XUvWeYWBIZFM4oy6A1WJqW2nEELcAjIeBX/0UWMig==", + "node_modules/@wordpress/commands/node_modules/@radix-ui/primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.1.tgz", + "integrity": "sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==", "dev": true, "dependencies": { - "@ariakit/react": "^0.3.12", - "@babel/runtime": "^7.16.0", - "@emotion/cache": "^11.7.1", - "@emotion/css": "^11.7.1", - "@emotion/react": "^11.7.1", - "@emotion/serialize": "^1.0.2", - "@emotion/styled": "^11.6.0", - "@emotion/utils": "^1.0.0", - "@floating-ui/react-dom": "^2.0.8", - "@types/gradient-parser": "0.1.3", - "@types/highlight-words-core": "1.2.1", - "@use-gesture/react": "^10.3.1", - "@wordpress/a11y": "^4.3.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/date": "^5.3.0", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/dom": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/escape-html": "^3.3.0", - "@wordpress/hooks": "^4.3.0", - "@wordpress/html-entities": "^4.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/icons": "^10.3.0", - "@wordpress/is-shallow-equal": "^5.3.0", - "@wordpress/keycodes": "^4.3.0", - "@wordpress/primitives": "^4.3.0", - "@wordpress/private-apis": "^1.3.0", - "@wordpress/rich-text": "^7.3.0", - "@wordpress/warning": "^3.3.0", - "change-case": "^4.1.2", - "clsx": "^2.1.1", - "colord": "^2.7.0", - "date-fns": "^3.6.0", - "deepmerge": "^4.3.0", - "downshift": "^6.0.15", - "fast-deep-equal": "^3.1.3", - "framer-motion": "^11.1.9", - "gradient-parser": "^0.1.5", - "highlight-words-core": "^1.2.2", - "is-plain-object": "^5.0.0", - "memize": "^2.1.0", - "path-to-regexp": "^6.2.1", - "re-resizable": "^6.4.0", - "react-colorful": "^5.3.1", - "remove-accents": "^0.5.0", - "use-lilius": "^2.0.5", - "uuid": "^9.0.1" - }, - "engines": { - "node": ">=18.12.0", - "npm": ">=8.19.2" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "@babel/runtime": "^7.13.10" } }, - "node_modules/@wordpress/components/node_modules/@wordpress/keycodes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.3.0.tgz", - "integrity": "sha512-o+L110/Y9ufS2eWVG1gXFs6+jPsMNVZoGJCt4PLjMmVabke0iaYstFppUdtQiOEDbnnhX9MH3RRtqp2AoSnaRQ==", + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-compose-refs": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz", + "integrity": "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==", "dev": true, "dependencies": { - "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0" + "@babel/runtime": "^7.13.10" }, - "engines": { - "node": ">=18.12.0", - "npm": ">=8.19.2" - } - }, - "node_modules/@wordpress/components/node_modules/@wordpress/warning": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.3.0.tgz", - "integrity": "sha512-n82aKCxuGRNwAtSLaycErJuhKgfOc+KtiljyQITPperMh9i8bH6I+JxtYiu+aLMaY5vrVLVb+/kCzKuWVQIKPA==", - "dev": true, - "engines": { - "node": ">=18.12.0", - "npm": ">=8.19.2" + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@wordpress/compose": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-7.3.0.tgz", - "integrity": "sha512-TtAYdKnqQ/L/nF0+fmlQ1wAvm90X9HRBrAuEMNmkzKhews/5GR0rR3dNSMjlf7C6mNdTO3mkYt6AQf9fvZFoiQ==", + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-context": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.1.tgz", + "integrity": "sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==", "dev": true, "dependencies": { - "@babel/runtime": "^7.16.0", - "@types/mousetrap": "^1.6.8", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/dom": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/is-shallow-equal": "^5.3.0", - "@wordpress/keycodes": "^4.3.0", - "@wordpress/priority-queue": "^3.3.0", - "@wordpress/undo-manager": "^1.3.0", - "change-case": "^4.1.2", - "clipboard": "^2.0.11", - "mousetrap": "^1.6.5", - "use-memo-one": "^1.1.1" - }, - "engines": { - "node": ">=18.12.0", - "npm": ">=8.19.2" + "@babel/runtime": "^7.13.10" }, "peerDependencies": { - "react": "^18.0.0" + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@wordpress/compose/node_modules/@wordpress/keycodes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.3.0.tgz", - "integrity": "sha512-o+L110/Y9ufS2eWVG1gXFs6+jPsMNVZoGJCt4PLjMmVabke0iaYstFppUdtQiOEDbnnhX9MH3RRtqp2AoSnaRQ==", + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-dialog": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.0.5.tgz", + "integrity": "sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==", "dev": true, "dependencies": { - "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0" + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.5", + "@radix-ui/react-focus-guards": "1.0.1", + "@radix-ui/react-focus-scope": "1.0.4", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-portal": "1.0.4", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-slot": "1.0.2", + "@radix-ui/react-use-controllable-state": "1.0.1", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.5" }, - "engines": { - "node": ">=18.12.0", - "npm": ">=8.19.2" + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@wordpress/core-commands": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/core-commands/-/core-commands-1.3.0.tgz", - "integrity": "sha512-Tc9w07UgyFKT6fq0UUxsTmXmRGsULiV25YtAwqxF52XtYxfo+mPMDJgYpNA2l3eKL6EuWR6AzNl8f9pank55oA==", + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.5.tgz", + "integrity": "sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==", "dev": true, "dependencies": { - "@babel/runtime": "^7.16.0", - "@wordpress/block-editor": "^13.3.0", - "@wordpress/commands": "^1.3.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/core-data": "^7.3.0", - "@wordpress/data": "^10.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/html-entities": "^4.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/icons": "^10.3.0", - "@wordpress/private-apis": "^1.3.0", - "@wordpress/router": "^1.3.0", - "@wordpress/url": "^4.3.0" - }, - "engines": { - "node": ">=18.12.0", - "npm": ">=8.19.2" + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1", + "@radix-ui/react-use-escape-keydown": "1.0.3" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@wordpress/core-data": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/core-data/-/core-data-7.3.0.tgz", - "integrity": "sha512-qPgb0bWgUQs2QSa4QJGtu2mceC80r4MAbFtZaBYWlv7CQ8qrgx0KJodSaMdezMqBGuQM/+7oS51A6jtR+SKX0g==", + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-focus-guards": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz", + "integrity": "sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==", "dev": true, "dependencies": { - "@babel/runtime": "^7.16.0", - "@wordpress/api-fetch": "^7.3.0", - "@wordpress/block-editor": "^13.3.0", - "@wordpress/blocks": "^13.3.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/data": "^10.3.0", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/html-entities": "^4.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/is-shallow-equal": "^5.3.0", - "@wordpress/private-apis": "^1.3.0", - "@wordpress/rich-text": "^7.3.0", - "@wordpress/sync": "^1.3.0", - "@wordpress/undo-manager": "^1.3.0", - "@wordpress/url": "^4.3.0", - "change-case": "^4.1.2", - "equivalent-key-map": "^0.2.2", - "fast-deep-equal": "^3.1.3", - "memize": "^2.1.0", - "uuid": "^9.0.1" - }, - "engines": { - "node": ">=18.12.0", - "npm": ">=8.19.2" + "@babel/runtime": "^7.13.10" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@wordpress/data": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-10.3.0.tgz", - "integrity": "sha512-cImJw4k30coosH6QtiJllxEYr93w8981PPvhGhemMbRQ28MnSA7rbJPv3h2LO9oss5SQH1gU9kwNGAZcF6PMPg==", + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-focus-scope": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.4.tgz", + "integrity": "sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==", "dev": true, "dependencies": { - "@babel/runtime": "^7.16.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/deprecated": "^4.3.0", + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-id": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.1.tgz", + "integrity": "sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-layout-effect": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-portal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.4.tgz", + "integrity": "sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-presence": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.1.tgz", + "integrity": "sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-primitive": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz", + "integrity": "sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-slot": "1.0.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-slot": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz", + "integrity": "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz", + "integrity": "sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.1.tgz", + "integrity": "sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz", + "integrity": "sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.1.tgz", + "integrity": "sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/cmdk": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cmdk/-/cmdk-1.0.0.tgz", + "integrity": "sha512-gDzVf0a09TvoJ5jnuPvygTB77+XdOSwEmJ88L6XPFPlv7T3RxbP9jgenfylrAMD0+Le1aO0nVjQUzl2g+vjz5Q==", + "dev": true, + "dependencies": { + "@radix-ui/react-dialog": "1.0.5", + "@radix-ui/react-primitive": "1.0.3" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@wordpress/commands/node_modules/react-remove-scroll": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz", + "integrity": "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==", + "dev": true, + "dependencies": { + "react-remove-scroll-bar": "^2.3.3", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@wordpress/components": { + "version": "28.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-28.5.0.tgz", + "integrity": "sha512-kZPb8MdpGW/Yv/ycJhbf+myb4czkyQ28gb5PY1kT2ABRB07J3oS1/badSLex3x06zD6NPtJt3kInbPUsSF2prQ==", + "dev": true, + "dependencies": { + "@ariakit/react": "^0.4.7", + "@babel/runtime": "^7.16.0", + "@emotion/cache": "^11.7.1", + "@emotion/css": "^11.7.1", + "@emotion/react": "^11.7.1", + "@emotion/serialize": "^1.0.2", + "@emotion/styled": "^11.6.0", + "@emotion/utils": "^1.0.0", + "@floating-ui/react-dom": "^2.0.8", + "@types/gradient-parser": "0.1.3", + "@types/highlight-words-core": "1.2.1", + "@use-gesture/react": "^10.3.1", + "@wordpress/a11y": "^4.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/date": "^5.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/dom": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/escape-html": "^3.5.0", + "@wordpress/hooks": "^4.5.0", + "@wordpress/html-entities": "^4.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/icons": "^10.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/keycodes": "^4.5.0", + "@wordpress/primitives": "^4.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/rich-text": "^7.5.0", + "@wordpress/warning": "^3.5.0", + "change-case": "^4.1.2", + "clsx": "^2.1.1", + "colord": "^2.7.0", + "date-fns": "^3.6.0", + "deepmerge": "^4.3.0", + "fast-deep-equal": "^3.1.3", + "framer-motion": "^11.1.9", + "gradient-parser": "^0.1.5", + "highlight-words-core": "^1.2.2", + "is-plain-object": "^5.0.0", + "memize": "^2.1.0", + "path-to-regexp": "^6.2.1", + "re-resizable": "^6.4.0", + "react-colorful": "^5.3.1", + "remove-accents": "^0.5.0", + "use-lilius": "^2.0.5", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@wordpress/components/node_modules/@ariakit/core": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/@ariakit/core/-/core-0.4.8.tgz", + "integrity": "sha512-HQS+9CI7pMqqVlAt5bPGenT0/e65UxXY+PKtgU7Y+0UToBDBRolO5S9+UUSDm8OmJHSnq24owEGm1Mv28l5XCQ==", + "dev": true + }, + "node_modules/@wordpress/components/node_modules/@ariakit/react": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/@ariakit/react/-/react-0.4.8.tgz", + "integrity": "sha512-Bb1vOrp0X52hxi1wE9TEHjjZ/Y08tVq2ZH+RFDwRQB3g04uVwrrhnTccHepC6rsObrDpAOV3/YlJCi4k/lSUaQ==", + "dev": true, + "dependencies": { + "@ariakit/react-core": "0.4.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ariakit" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@wordpress/components/node_modules/@ariakit/react-core": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/@ariakit/react-core/-/react-core-0.4.8.tgz", + "integrity": "sha512-TzsddUWQwWYhrEVWHA/Gf7KCGx8rwFohAHfuljjqidKeZi2kUmuRAImCTG9oga34FWHFf4AdXQbBKclMNt0nrQ==", + "dev": true, + "dependencies": { + "@ariakit/core": "0.4.8", + "@floating-ui/dom": "^1.0.0", + "use-sync-external-store": "^1.2.0" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@wordpress/components/node_modules/@wordpress/keycodes": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@wordpress/i18n": "^5.5.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, + "node_modules/@wordpress/components/node_modules/@wordpress/warning": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.5.0.tgz", + "integrity": "sha512-cYM2Vqf2EokJJoWHD5Ry15OUmdsKtDgR8/qxE0sWHUAdSQeoTuJZnqhgYI898cZGxHaZWX2xJCxQa7Qtwl8lqw==", + "dev": true, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, + "node_modules/@wordpress/compose": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-7.5.0.tgz", + "integrity": "sha512-jWRmleIGxmvTIC/1VYtAvq0iRfCkW/AtlNmqoKiyd0Ah5lccWRtxSH5V3Vh1BEkBQRANMWxJpOpRTKDFTcfTvg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@types/mousetrap": "^1.6.8", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/dom": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/keycodes": "^4.5.0", + "@wordpress/priority-queue": "^3.5.0", + "@wordpress/undo-manager": "^1.5.0", + "change-case": "^4.1.2", + "clipboard": "^2.0.11", + "mousetrap": "^1.6.5", + "use-memo-one": "^1.1.1" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0" + } + }, + "node_modules/@wordpress/compose/node_modules/@wordpress/keycodes": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@wordpress/i18n": "^5.5.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, + "node_modules/@wordpress/core-commands": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@wordpress/core-commands/-/core-commands-1.3.0.tgz", + "integrity": "sha512-Tc9w07UgyFKT6fq0UUxsTmXmRGsULiV25YtAwqxF52XtYxfo+mPMDJgYpNA2l3eKL6EuWR6AzNl8f9pank55oA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@wordpress/block-editor": "^13.3.0", + "@wordpress/commands": "^1.3.0", + "@wordpress/compose": "^7.3.0", + "@wordpress/core-data": "^7.3.0", + "@wordpress/data": "^10.3.0", "@wordpress/element": "^6.3.0", - "@wordpress/is-shallow-equal": "^5.3.0", - "@wordpress/priority-queue": "^3.3.0", + "@wordpress/html-entities": "^4.3.0", + "@wordpress/i18n": "^5.3.0", + "@wordpress/icons": "^10.3.0", "@wordpress/private-apis": "^1.3.0", - "@wordpress/redux-routine": "^5.3.0", + "@wordpress/router": "^1.3.0", + "@wordpress/url": "^4.3.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@wordpress/core-data": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/core-data/-/core-data-7.5.0.tgz", + "integrity": "sha512-NzKmf09yUw6ZH6NLRtM8qYci2HrA8dla2SJB4r/mtSpcVilDJL+j/hnuzMpvRJAGA5mWdB2ANnvlXWfG+BVsiA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@wordpress/api-fetch": "^7.5.0", + "@wordpress/block-editor": "^14.0.0", + "@wordpress/blocks": "^13.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/html-entities": "^4.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/rich-text": "^7.5.0", + "@wordpress/sync": "^1.5.0", + "@wordpress/undo-manager": "^1.5.0", + "@wordpress/url": "^4.5.0", + "@wordpress/warning": "^3.5.0", + "change-case": "^4.1.2", + "equivalent-key-map": "^0.2.2", + "fast-deep-equal": "^3.1.3", + "memize": "^2.1.0", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@wordpress/core-data/node_modules/@wordpress/block-editor": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-14.0.0.tgz", + "integrity": "sha512-IODsUPm37DpZxLMcJXidlHeUAvALX+E9edY+z9UGJWP/PvhLCXllCRVQABcuYkPTsraFSF0Yrk9i/7WJF2NkaA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@emotion/react": "^11.7.1", + "@emotion/styled": "^11.6.0", + "@react-spring/web": "^9.4.5", + "@wordpress/a11y": "^4.5.0", + "@wordpress/api-fetch": "^7.5.0", + "@wordpress/blob": "^4.5.0", + "@wordpress/blocks": "^13.5.0", + "@wordpress/commands": "^1.5.0", + "@wordpress/components": "^28.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/date": "^5.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/dom": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/escape-html": "^3.5.0", + "@wordpress/hooks": "^4.5.0", + "@wordpress/html-entities": "^4.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/icons": "^10.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/keyboard-shortcuts": "^5.5.0", + "@wordpress/keycodes": "^4.5.0", + "@wordpress/notices": "^5.5.0", + "@wordpress/preferences": "^4.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/rich-text": "^7.5.0", + "@wordpress/style-engine": "^2.5.0", + "@wordpress/token-list": "^3.5.0", + "@wordpress/url": "^4.5.0", + "@wordpress/warning": "^3.5.0", + "@wordpress/wordcount": "^4.5.0", + "change-case": "^4.1.2", + "clsx": "^2.1.1", + "colord": "^2.7.0", + "deepmerge": "^4.3.0", + "diff": "^4.0.2", + "fast-deep-equal": "^3.1.3", + "memize": "^2.1.0", + "postcss": "^8.4.21", + "postcss-prefixwrap": "^1.41.0", + "postcss-urlrebase": "^1.4.0", + "react-autosize-textarea": "^7.1.0", + "react-easy-crop": "^5.0.6", + "remove-accents": "^0.5.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@wordpress/core-data/node_modules/@wordpress/keycodes": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@wordpress/i18n": "^5.5.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, + "node_modules/@wordpress/core-data/node_modules/@wordpress/warning": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.5.0.tgz", + "integrity": "sha512-cYM2Vqf2EokJJoWHD5Ry15OUmdsKtDgR8/qxE0sWHUAdSQeoTuJZnqhgYI898cZGxHaZWX2xJCxQa7Qtwl8lqw==", + "dev": true, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, + "node_modules/@wordpress/data": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-10.5.0.tgz", + "integrity": "sha512-Y2P5SC0fuTivcfdYmubL3c15WRbE0FJAyYcEfZeJ2C37a2DmBnCBz3uEzGy2kCilz56qMfK0qutAHkfytOpRQw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/priority-queue": "^3.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/redux-routine": "^5.5.0", "deepmerge": "^4.3.0", "equivalent-key-map": "^0.2.2", "is-plain-object": "^5.0.0", @@ -9943,21 +10456,22 @@ } }, "node_modules/@wordpress/dataviews": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@wordpress/dataviews/-/dataviews-3.0.0.tgz", - "integrity": "sha512-UlNeB0hS6ooGEXcJTP8c6az25Ku5t4kz4B+mnaiBd9HpisBOIaLtTRaDgtS0ioKm+nhvLjGwDQlVuNRMZXW7mQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@wordpress/dataviews/-/dataviews-4.1.0.tgz", + "integrity": "sha512-8lumuvMiVZgz4cYRv3hY4kmVeG7cNk+JtvRoEb0ysre0k6QEl/SZFinEge0eMfpsdvCdagFv4le/n7CXidEB2g==", "dev": true, "dependencies": { - "@ariakit/react": "^0.3.12", + "@ariakit/react": "^0.4.7", "@babel/runtime": "^7.16.0", - "@wordpress/components": "^28.3.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/data": "^10.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/icons": "^10.3.0", - "@wordpress/primitives": "^4.3.0", - "@wordpress/private-apis": "^1.3.0", + "@wordpress/components": "^28.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/icons": "^10.5.0", + "@wordpress/primitives": "^4.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/warning": "^3.5.0", "clsx": "^2.1.1", "remove-accents": "^0.5.0" }, @@ -9969,14 +10483,62 @@ "react": "^18.0.0" } }, + "node_modules/@wordpress/dataviews/node_modules/@ariakit/core": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/@ariakit/core/-/core-0.4.8.tgz", + "integrity": "sha512-HQS+9CI7pMqqVlAt5bPGenT0/e65UxXY+PKtgU7Y+0UToBDBRolO5S9+UUSDm8OmJHSnq24owEGm1Mv28l5XCQ==", + "dev": true + }, + "node_modules/@wordpress/dataviews/node_modules/@ariakit/react": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/@ariakit/react/-/react-0.4.8.tgz", + "integrity": "sha512-Bb1vOrp0X52hxi1wE9TEHjjZ/Y08tVq2ZH+RFDwRQB3g04uVwrrhnTccHepC6rsObrDpAOV3/YlJCi4k/lSUaQ==", + "dev": true, + "dependencies": { + "@ariakit/react-core": "0.4.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ariakit" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@wordpress/dataviews/node_modules/@ariakit/react-core": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/@ariakit/react-core/-/react-core-0.4.8.tgz", + "integrity": "sha512-TzsddUWQwWYhrEVWHA/Gf7KCGx8rwFohAHfuljjqidKeZi2kUmuRAImCTG9oga34FWHFf4AdXQbBKclMNt0nrQ==", + "dev": true, + "dependencies": { + "@ariakit/core": "0.4.8", + "@floating-ui/dom": "^1.0.0", + "use-sync-external-store": "^1.2.0" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@wordpress/dataviews/node_modules/@wordpress/warning": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.5.0.tgz", + "integrity": "sha512-cYM2Vqf2EokJJoWHD5Ry15OUmdsKtDgR8/qxE0sWHUAdSQeoTuJZnqhgYI898cZGxHaZWX2xJCxQa7Qtwl8lqw==", + "dev": true, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, "node_modules/@wordpress/date": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/date/-/date-5.3.0.tgz", - "integrity": "sha512-vD0rLQxNlOoFd4n32HohhTif4P1JPW/Igjp0c/O2WZji+eXQM6P54fBu5veKvgwMmXpUn8y0xzgssj3pKAUgCg==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/date/-/date-5.5.0.tgz", + "integrity": "sha512-dIo02TAIuXG/wkcVf+jsyXn64PUVsxs6HwuHanNiDNVZt95QVJ8b7wdJZNIrhTkmVXhIUzYAz5BpuXUC6IZAqg==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/deprecated": "^4.3.0", + "@wordpress/deprecated": "^4.5.0", "moment": "^2.29.4", "moment-timezone": "^0.5.40" }, @@ -10002,13 +10564,13 @@ } }, "node_modules/@wordpress/deprecated": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-4.3.0.tgz", - "integrity": "sha512-K2GHXlwjx6GMhZjs52X1MXySCrqzh4IjoqF5IOcydMgWqOIE2++hMuB9Y55qN/Mhsrv/HO8Q1LaTxbEd6BuNJQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-4.5.0.tgz", + "integrity": "sha512-r3xGAM45XTd+z+hnUvLGtSz+Y0ebybuw/cyE0CatksJBGvXez3kiTDaknALkgzjHRZzIGpNu6XTVUoIJs0H39A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/hooks": "^4.3.0" + "@wordpress/hooks": "^4.5.0" }, "engines": { "node": ">=18.12.0", @@ -10016,13 +10578,13 @@ } }, "node_modules/@wordpress/dom": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-4.3.0.tgz", - "integrity": "sha512-sf4h6jVqboRdhe3soyr5bt+Vpz24WG/AIMHm7pGaxfbV5jxx06ZZ8K1RKzhr7jF3wn7IgIc1wmMA+OFzEYqGyw==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-4.5.0.tgz", + "integrity": "sha512-XjnpRbbhZ1hdgv758vSXQacjfy/N0H2oI0oWukrLmlkKDP5ZrGfdziHQ2+KcoW+QDx8pu4JYcUpjmuJLugDStw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/deprecated": "^4.3.0" + "@wordpress/deprecated": "^4.5.0" }, "engines": { "node": ">=18.12.0", @@ -10030,9 +10592,9 @@ } }, "node_modules/@wordpress/dom-ready": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/dom-ready/-/dom-ready-4.3.0.tgz", - "integrity": "sha512-zuLLMIeJt1hZ95R4kdJFcsIaL2eud1kF40VCmwK3mK0qpgXv/1avtGX8lx6DMLL/GGL1yYcJhR13RSKSjxuGEQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom-ready/-/dom-ready-4.5.0.tgz", + "integrity": "sha512-5dALG1lQtoH/Rk7DWFe9DaIF2bQQM5U0x+c1lQnk1cnBJ69AijIcbZMYaMzlgngo4dVF2PnFZ/VKVSUOKghhQQ==", "dependencies": { "@babel/runtime": "^7.16.0" }, @@ -10238,55 +10800,118 @@ } }, "node_modules/@wordpress/editor": { - "version": "14.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/editor/-/editor-14.3.0.tgz", - "integrity": "sha512-OdT3V9eQrWBKvC3/HJFeDt/tphsdgq1cZ/p5n4dyH/hkssprvXTPQebu6TJM9G3v+Rm/GgpM9T3NieUOaBQHgA==", + "version": "14.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/editor/-/editor-14.5.0.tgz", + "integrity": "sha512-6fsUiaTrluTiq403OZkaeHj8thclgrOYB2cQ/BoHg9OkUFOAae4cns0+LU+o8BobSY4KGX99v/WT4SMtg4h3TQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/a11y": "^4.3.0", - "@wordpress/api-fetch": "^7.3.0", - "@wordpress/blob": "^4.3.0", - "@wordpress/block-editor": "^13.3.0", - "@wordpress/blocks": "^13.3.0", - "@wordpress/commands": "^1.3.0", - "@wordpress/components": "^28.3.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/core-data": "^7.3.0", - "@wordpress/data": "^10.3.0", - "@wordpress/dataviews": "^3.0.0", - "@wordpress/date": "^5.3.0", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/dom": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/hooks": "^4.3.0", - "@wordpress/html-entities": "^4.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/icons": "^10.3.0", - "@wordpress/interface": "^6.3.0", - "@wordpress/keyboard-shortcuts": "^5.3.0", - "@wordpress/keycodes": "^4.3.0", - "@wordpress/media-utils": "^5.3.0", - "@wordpress/notices": "^5.3.0", - "@wordpress/patterns": "^2.3.0", - "@wordpress/plugins": "^7.3.0", - "@wordpress/preferences": "^4.3.0", - "@wordpress/private-apis": "^1.3.0", - "@wordpress/reusable-blocks": "^5.3.0", - "@wordpress/rich-text": "^7.3.0", - "@wordpress/server-side-render": "^5.3.0", - "@wordpress/url": "^4.3.0", - "@wordpress/warning": "^3.3.0", - "@wordpress/wordcount": "^4.3.0", + "@wordpress/a11y": "^4.5.0", + "@wordpress/api-fetch": "^7.5.0", + "@wordpress/blob": "^4.5.0", + "@wordpress/block-editor": "^14.0.0", + "@wordpress/blocks": "^13.5.0", + "@wordpress/commands": "^1.5.0", + "@wordpress/components": "^28.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/core-data": "^7.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/dataviews": "^4.1.0", + "@wordpress/date": "^5.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/dom": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/hooks": "^4.5.0", + "@wordpress/html-entities": "^4.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/icons": "^10.5.0", + "@wordpress/interface": "^6.5.0", + "@wordpress/keyboard-shortcuts": "^5.5.0", + "@wordpress/keycodes": "^4.5.0", + "@wordpress/media-utils": "^5.5.0", + "@wordpress/notices": "^5.5.0", + "@wordpress/patterns": "^2.5.0", + "@wordpress/plugins": "^7.5.0", + "@wordpress/preferences": "^4.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/reusable-blocks": "^5.5.0", + "@wordpress/rich-text": "^7.5.0", + "@wordpress/server-side-render": "^5.5.0", + "@wordpress/url": "^4.5.0", + "@wordpress/warning": "^3.5.0", + "@wordpress/wordcount": "^4.5.0", + "change-case": "^4.1.2", + "client-zip": "^2.4.5", + "clsx": "^2.1.1", + "date-fns": "^3.6.0", + "deepmerge": "^4.3.0", + "fast-deep-equal": "^3.1.3", + "is-plain-object": "^5.0.0", + "memize": "^2.1.0", + "react-autosize-textarea": "^7.1.0", + "remove-accents": "^0.5.0", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@wordpress/editor/node_modules/@wordpress/block-editor": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-14.0.0.tgz", + "integrity": "sha512-IODsUPm37DpZxLMcJXidlHeUAvALX+E9edY+z9UGJWP/PvhLCXllCRVQABcuYkPTsraFSF0Yrk9i/7WJF2NkaA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@emotion/react": "^11.7.1", + "@emotion/styled": "^11.6.0", + "@react-spring/web": "^9.4.5", + "@wordpress/a11y": "^4.5.0", + "@wordpress/api-fetch": "^7.5.0", + "@wordpress/blob": "^4.5.0", + "@wordpress/blocks": "^13.5.0", + "@wordpress/commands": "^1.5.0", + "@wordpress/components": "^28.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/date": "^5.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/dom": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/escape-html": "^3.5.0", + "@wordpress/hooks": "^4.5.0", + "@wordpress/html-entities": "^4.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/icons": "^10.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/keyboard-shortcuts": "^5.5.0", + "@wordpress/keycodes": "^4.5.0", + "@wordpress/notices": "^5.5.0", + "@wordpress/preferences": "^4.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/rich-text": "^7.5.0", + "@wordpress/style-engine": "^2.5.0", + "@wordpress/token-list": "^3.5.0", + "@wordpress/url": "^4.5.0", + "@wordpress/warning": "^3.5.0", + "@wordpress/wordcount": "^4.5.0", "change-case": "^4.1.2", - "client-zip": "^2.4.5", "clsx": "^2.1.1", - "date-fns": "^3.6.0", + "colord": "^2.7.0", "deepmerge": "^4.3.0", + "diff": "^4.0.2", "fast-deep-equal": "^3.1.3", - "is-plain-object": "^5.0.0", "memize": "^2.1.0", + "postcss": "^8.4.21", + "postcss-prefixwrap": "^1.41.0", + "postcss-urlrebase": "^1.4.0", "react-autosize-textarea": "^7.1.0", + "react-easy-crop": "^5.0.6", "remove-accents": "^0.5.0" }, "engines": { @@ -10299,13 +10924,13 @@ } }, "node_modules/@wordpress/editor/node_modules/@wordpress/keycodes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.3.0.tgz", - "integrity": "sha512-o+L110/Y9ufS2eWVG1gXFs6+jPsMNVZoGJCt4PLjMmVabke0iaYstFppUdtQiOEDbnnhX9MH3RRtqp2AoSnaRQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0" + "@wordpress/i18n": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -10313,9 +10938,9 @@ } }, "node_modules/@wordpress/editor/node_modules/@wordpress/warning": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.3.0.tgz", - "integrity": "sha512-n82aKCxuGRNwAtSLaycErJuhKgfOc+KtiljyQITPperMh9i8bH6I+JxtYiu+aLMaY5vrVLVb+/kCzKuWVQIKPA==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.5.0.tgz", + "integrity": "sha512-cYM2Vqf2EokJJoWHD5Ry15OUmdsKtDgR8/qxE0sWHUAdSQeoTuJZnqhgYI898cZGxHaZWX2xJCxQa7Qtwl8lqw==", "dev": true, "engines": { "node": ">=18.12.0", @@ -10323,15 +10948,15 @@ } }, "node_modules/@wordpress/element": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-6.3.0.tgz", - "integrity": "sha512-DsiqzjuXqxJkLUoLomsGTFFxbSZgk+Lz+2/1yFH+BU3jQ6zeD64+JWv8Lt4+fKU154rV0KpfMwfD/oAC/Lp1zQ==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-6.5.0.tgz", + "integrity": "sha512-N9w3jfceltdDEN71jpaMCXU+jbvec9kredvQIn/6YNiUMarPXWth7DJYU3+mDtbYawnTIvytzGjbj/J+bqqdHg==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", "@types/react": "^18.2.79", "@types/react-dom": "^18.2.25", - "@wordpress/escape-html": "^3.3.0", + "@wordpress/escape-html": "^3.5.0", "change-case": "^4.1.2", "is-plain-object": "^5.0.0", "react": "^18.3.0", @@ -10446,9 +11071,9 @@ } }, "node_modules/@wordpress/escape-html": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-3.3.0.tgz", - "integrity": "sha512-Wu/Fq96E28UGnIO5VQW/aEgCiHWvzrD8izDnP8U0WZSuwIPYcS5iYmRe2UWc7rwyoeY2YXNd6xFjgd7oTOKNCA==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-3.5.0.tgz", + "integrity": "sha512-8dUWTmsDZuqAmBtRgk0JpiIafRKPM4n8tqCr147AugTbP/vyQ7rIzG3M/YCtVSmDr6f/qZ32YU8J7c34RhZ/9g==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -10718,9 +11343,9 @@ } }, "node_modules/@wordpress/hooks": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-4.3.0.tgz", - "integrity": "sha512-bpqwSXGyxPfhuxESKoAtL4ofB3CazzvcwcucTZ0g9Pat3KNuBaloSrPBliqqNOiSLWNH3nmpkaRmv4u89EdKAw==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-4.5.0.tgz", + "integrity": "sha512-wr1l1WM1yobyNGFLRgbLNBGtYIkzAGfmbT2e9zIOvqllRJT4wprYTqqhgovOKHlET5ij/TKdv4tApkGLUIXTsA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -10731,9 +11356,9 @@ } }, "node_modules/@wordpress/html-entities": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/html-entities/-/html-entities-4.3.0.tgz", - "integrity": "sha512-rJDf9KjCuUnFwIwmOdN4FcL7RJnDzPxIdvvMoWXkYd9GseEeRTsY6xIG+fGgVGgYe3HwXDYSFCWTF/x2M9Eerg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/html-entities/-/html-entities-4.5.0.tgz", + "integrity": "sha512-iQo2P1Sc499MxguelJ4aMcF08jnYkOdvb+FAOyOfGCyDjEtNbldRFc2BJ9NmJ/9nmtlwc/IzUzXop0M1gjy9tw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -10744,13 +11369,13 @@ } }, "node_modules/@wordpress/i18n": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-5.3.0.tgz", - "integrity": "sha512-edHKkdZb6jNpbn+LUPu2wo1mKyhT819WJ7kI8hmMcHq82rNwwbMfcGoB3oSaphTphWfhlgxIxLczKOAbWDKudw==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-5.5.0.tgz", + "integrity": "sha512-MtCJIjNHCWs7R77f5Xml1CCnVXqrle4cDpqMU9myx4Cq8ZijqSayX1CTtwtk+Z3/3xa+dBZu5Koe4wiW1yIUSA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/hooks": "^4.3.0", + "@wordpress/hooks": "^4.5.0", "gettext-parser": "^1.3.1", "memize": "^2.1.0", "sprintf-js": "^1.1.1", @@ -10765,14 +11390,14 @@ } }, "node_modules/@wordpress/icons": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/icons/-/icons-10.3.0.tgz", - "integrity": "sha512-d2jOFfLIAxPr+/Bzg7wnRDEDPogMpVefe4cHgIx9kXp/+7DG4KWNJm842qVithjs1wVgSzavzWbFrTtPEZ+Uhw==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/icons/-/icons-10.5.0.tgz", + "integrity": "sha512-BZwKBRKoTef9uW73T+FwK6d4JlcvgdVAaz3LB5dCluXg5PLV5ufMdumAaMxKWq/Ffl92/ddt8CKIdHjxfAZF4A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/element": "^6.3.0", - "@wordpress/primitives": "^4.3.0" + "@wordpress/element": "^6.5.0", + "@wordpress/primitives": "^4.5.0" }, "engines": { "node": ">=18.12.0", @@ -10808,24 +11433,24 @@ } }, "node_modules/@wordpress/interface": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/interface/-/interface-6.3.0.tgz", - "integrity": "sha512-ThMYuQL1cXWRXePe8C49V6d5oiwBBEXaF9XAp57AfduVL2Um5ZHBJ6ZXd1yWIjZ4dUWPOagWiVSGcWq1PgQYrw==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/interface/-/interface-6.5.0.tgz", + "integrity": "sha512-FLvXDb7namO6yCc/OipcEHauqCq1MKWSSLbnVBPlXDaTvoaw9LkU5JACI//yFemIe4v5RjKQ7fdXouccixosng==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/a11y": "^4.3.0", - "@wordpress/components": "^28.3.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/data": "^10.3.0", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/icons": "^10.3.0", - "@wordpress/plugins": "^7.3.0", - "@wordpress/preferences": "^4.3.0", - "@wordpress/private-apis": "^1.3.0", - "@wordpress/viewport": "^6.3.0", + "@wordpress/a11y": "^4.5.0", + "@wordpress/components": "^28.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/icons": "^10.5.0", + "@wordpress/plugins": "^7.5.0", + "@wordpress/preferences": "^4.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/viewport": "^6.5.0", "clsx": "^2.1.1" }, "engines": { @@ -10838,9 +11463,9 @@ } }, "node_modules/@wordpress/is-shallow-equal": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-5.3.0.tgz", - "integrity": "sha512-sZ+fypqjYX0/DTAKsm1G9ND9Wn4d3Ju4lI7SLSmCKdUL5EPY3g/2LpKQKDqljh9m6Ex5NWp2XfU8UVXpkEfbMQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-5.5.0.tgz", + "integrity": "sha512-nkCz45HgMBkjhyxffDgpAgJbfnKyZML94/gHhBtxizHfaNuZ5as7DfEyN1xgebvDiLbOaRU7em1pPAuEhIoTfQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -10886,15 +11511,15 @@ } }, "node_modules/@wordpress/keyboard-shortcuts": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/keyboard-shortcuts/-/keyboard-shortcuts-5.3.0.tgz", - "integrity": "sha512-Zms+SzRekXqLBW0IPxZDhusxix5xm6jBmWfOfc//uCy7xvhZS1FxEYoolfYFB7tXT7xFTQbwVYN99ICI7BeqnQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keyboard-shortcuts/-/keyboard-shortcuts-5.5.0.tgz", + "integrity": "sha512-U+64UvlrWjxnn6YJ5ZW7Oi9EJE9J7aWRGzpCAL8yoRDqiVC/zUzvgnVmo9AoA8jVEBxKUeDFyntckCE2qW0STQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/data": "^10.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/keycodes": "^4.3.0" + "@wordpress/data": "^10.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/keycodes": "^4.5.0" }, "engines": { "node": ">=18.12.0", @@ -10905,13 +11530,13 @@ } }, "node_modules/@wordpress/keyboard-shortcuts/node_modules/@wordpress/keycodes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.3.0.tgz", - "integrity": "sha512-o+L110/Y9ufS2eWVG1gXFs6+jPsMNVZoGJCt4PLjMmVabke0iaYstFppUdtQiOEDbnnhX9MH3RRtqp2AoSnaRQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0" + "@wordpress/i18n": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -10967,16 +11592,16 @@ } }, "node_modules/@wordpress/media-utils": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/media-utils/-/media-utils-5.3.0.tgz", - "integrity": "sha512-OXWr5oirWs8bTRqjaFxZQYVDHQFFkvCwdTwF2pGtsw+dmvp04sU4Sye1XEsjLyiWmihQw3MxcuzrgCyoxNIrxA==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/media-utils/-/media-utils-5.5.0.tgz", + "integrity": "sha512-jrbM+lw6s2b5+CAOXs6K+NYGoZY0Yggu4X73RrKeYG9Vwmg23oMP742nZwztVGMuyr06Yh/1Ym7Amgfrd3cKqA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/api-fetch": "^7.3.0", - "@wordpress/blob": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/i18n": "^5.3.0" + "@wordpress/api-fetch": "^7.5.0", + "@wordpress/blob": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/i18n": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -10984,14 +11609,14 @@ } }, "node_modules/@wordpress/notices": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/notices/-/notices-5.3.0.tgz", - "integrity": "sha512-1aZVcmy3Aj1nn4jmdQDpVFIB7L40AkhW7maFKhEH0oo2UAiPmqJyGDeby9sD96m2hskwyZzAgI15k+KrEf17LQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/notices/-/notices-5.5.0.tgz", + "integrity": "sha512-QcTbGAyHJ7V8LvSDJttUKCmClIFBQQ2/gk7pTBMBwe+argYQLOVRAQP/+97AnP9KFVtzuENrjbQtsyYeMWaTSw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/a11y": "^4.3.0", - "@wordpress/data": "^10.3.0" + "@wordpress/a11y": "^4.5.0", + "@wordpress/data": "^10.5.0" }, "engines": { "node": ">=18.12.0", @@ -11015,26 +11640,88 @@ } }, "node_modules/@wordpress/patterns": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/patterns/-/patterns-2.3.0.tgz", - "integrity": "sha512-1/0RfkZ88oKbtm062ggicMyUSEy/bBpGbn4DFqgWnQbCUcNUL/A7WWWkg5rNgQcTSY4VG+2BOE5rNJQFhtsUdg==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/patterns/-/patterns-2.5.0.tgz", + "integrity": "sha512-jL41tCIShAUg017kGLSpD39L9zSWyepIiWZe+U0gD9FZo42c8aAMUmKTy4pwUI3hv67x0ZpvtcR5KegOJlZKfw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/a11y": "^4.3.0", - "@wordpress/block-editor": "^13.3.0", - "@wordpress/blocks": "^13.3.0", - "@wordpress/components": "^28.3.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/core-data": "^7.3.0", - "@wordpress/data": "^10.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/html-entities": "^4.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/icons": "^10.3.0", - "@wordpress/notices": "^5.3.0", - "@wordpress/private-apis": "^1.3.0", - "@wordpress/url": "^4.3.0" + "@wordpress/a11y": "^4.5.0", + "@wordpress/block-editor": "^14.0.0", + "@wordpress/blocks": "^13.5.0", + "@wordpress/components": "^28.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/core-data": "^7.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/html-entities": "^4.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/icons": "^10.5.0", + "@wordpress/notices": "^5.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/url": "^4.5.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@wordpress/patterns/node_modules/@wordpress/block-editor": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-14.0.0.tgz", + "integrity": "sha512-IODsUPm37DpZxLMcJXidlHeUAvALX+E9edY+z9UGJWP/PvhLCXllCRVQABcuYkPTsraFSF0Yrk9i/7WJF2NkaA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@emotion/react": "^11.7.1", + "@emotion/styled": "^11.6.0", + "@react-spring/web": "^9.4.5", + "@wordpress/a11y": "^4.5.0", + "@wordpress/api-fetch": "^7.5.0", + "@wordpress/blob": "^4.5.0", + "@wordpress/blocks": "^13.5.0", + "@wordpress/commands": "^1.5.0", + "@wordpress/components": "^28.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/date": "^5.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/dom": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/escape-html": "^3.5.0", + "@wordpress/hooks": "^4.5.0", + "@wordpress/html-entities": "^4.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/icons": "^10.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/keyboard-shortcuts": "^5.5.0", + "@wordpress/keycodes": "^4.5.0", + "@wordpress/notices": "^5.5.0", + "@wordpress/preferences": "^4.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/rich-text": "^7.5.0", + "@wordpress/style-engine": "^2.5.0", + "@wordpress/token-list": "^3.5.0", + "@wordpress/url": "^4.5.0", + "@wordpress/warning": "^3.5.0", + "@wordpress/wordcount": "^4.5.0", + "change-case": "^4.1.2", + "clsx": "^2.1.1", + "colord": "^2.7.0", + "deepmerge": "^4.3.0", + "diff": "^4.0.2", + "fast-deep-equal": "^3.1.3", + "memize": "^2.1.0", + "postcss": "^8.4.21", + "postcss-prefixwrap": "^1.41.0", + "postcss-urlrebase": "^1.4.0", + "react-autosize-textarea": "^7.1.0", + "react-easy-crop": "^5.0.6", + "remove-accents": "^0.5.0" }, "engines": { "node": ">=18.12.0", @@ -11045,19 +11732,43 @@ "react-dom": "^18.0.0" } }, + "node_modules/@wordpress/patterns/node_modules/@wordpress/keycodes": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@wordpress/i18n": "^5.5.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, + "node_modules/@wordpress/patterns/node_modules/@wordpress/warning": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.5.0.tgz", + "integrity": "sha512-cYM2Vqf2EokJJoWHD5Ry15OUmdsKtDgR8/qxE0sWHUAdSQeoTuJZnqhgYI898cZGxHaZWX2xJCxQa7Qtwl8lqw==", + "dev": true, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, "node_modules/@wordpress/plugins": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/plugins/-/plugins-7.3.0.tgz", - "integrity": "sha512-3XdjSXTUoboJSePJ/RYUmkJmi30cnCewtA0oYakszejvJpTkuL2JQsDezsJy8e4uDH3D8mhM6LkOYFLPAVvhwQ==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/plugins/-/plugins-7.5.0.tgz", + "integrity": "sha512-1bvoT+Shi6FdrVgHqzzMyb3tF82eaSpvuRQsVYYPLCZnfEztDhdfuhgWD/M7oh2Mbxd4kkV1HWbMAKCbop/8/g==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/components": "^28.3.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/hooks": "^4.3.0", - "@wordpress/icons": "^10.3.0", - "@wordpress/is-shallow-equal": "^5.3.0", + "@wordpress/components": "^28.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/hooks": "^4.5.0", + "@wordpress/icons": "^10.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", "memize": "^2.0.1" }, "engines": { @@ -11087,21 +11798,21 @@ } }, "node_modules/@wordpress/preferences": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/preferences/-/preferences-4.3.0.tgz", - "integrity": "sha512-XTPJYjdz8iy9Sy+B+RAPFwk4KkGPgjogu3mhcMvYLqqKKeVhUt6zImXVNXQbNFGTlCgB+l0b4h4L5EHmJWVDgg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/preferences/-/preferences-4.5.0.tgz", + "integrity": "sha512-cDk+StQGyjwWzyo8dmVfdwYvL45hMd+m3qUNbP29PizJb4jPHBLVg4WTabuFG0I5TEs75zIjDWQsb3HeG//cHw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/a11y": "^4.3.0", - "@wordpress/components": "^28.3.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/data": "^10.3.0", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/icons": "^10.3.0", - "@wordpress/private-apis": "^1.3.0", + "@wordpress/a11y": "^4.5.0", + "@wordpress/components": "^28.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/icons": "^10.5.0", + "@wordpress/private-apis": "^1.5.0", "clsx": "^2.1.1" }, "engines": { @@ -11127,24 +11838,27 @@ } }, "node_modules/@wordpress/primitives": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/primitives/-/primitives-4.3.0.tgz", - "integrity": "sha512-h7wb2Np3n5etOg3j38GN80NEA8NgNdsSF/JJcRhpRf8FQOJd1mnKzj6szVHeKv0G7bvBif0NTgdSUm5M6Nikfg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/primitives/-/primitives-4.5.0.tgz", + "integrity": "sha512-1TYCpCAr2BmYJESlD8v325GgYXSgUbrFtebwgvpMN/28CEwmPN+ORRECV41nPX4yVJ2k0kYzYxzQUGp/78xWsw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/element": "^6.3.0", + "@wordpress/element": "^6.5.0", "clsx": "^2.1.1" }, "engines": { "node": ">=18.12.0", "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0" } }, "node_modules/@wordpress/priority-queue": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-3.3.0.tgz", - "integrity": "sha512-H7dGei1mFqKlz7NLFOGGtVgaBsORRaXeXNwWLI5rE0pI3XfGYd+zxNrG5aBzHw4fPqsITsxecNSaacc9fjqgjQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-3.5.0.tgz", + "integrity": "sha512-ilbG70ZuUJd0UTC7uyLP8zI/ZSN0d4ceG3qwlDx13yQAcjAcuw1Ei1CwzFBsbmI3OS1KkfkDpwZzKOrA+j/00Q==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", @@ -11156,9 +11870,9 @@ } }, "node_modules/@wordpress/private-apis": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/private-apis/-/private-apis-1.3.0.tgz", - "integrity": "sha512-IbtH8ZENAKixSoTBKbmJ2ZCIkxsxqAoWPBtvbNJG9rYdzSk+BExdy/5VGO6Pv5GcUElHT+8uV26W4XxBVNl4UQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/private-apis/-/private-apis-1.5.0.tgz", + "integrity": "sha512-taGW34kyyHMnbmTbWIyOJt7C4KFVCg7F5PNFwJQmS43FESC9BAjPw7VeEDTJ0XNqocH4NNeBJclhFyj82QySTQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -11169,9 +11883,9 @@ } }, "node_modules/@wordpress/redux-routine": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/redux-routine/-/redux-routine-5.3.0.tgz", - "integrity": "sha512-5HGdW8PqIK5fTyg1yo6NL2x1LTxU9vBvgUan/bLxYLX0YNw4+gQUex3djE0dwXNgrdE4mvWvYTcccc+2L59hig==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/redux-routine/-/redux-routine-5.5.0.tgz", + "integrity": "sha512-PvIgq0lI2PLjechCq+pRFIE/xbFwznytupGscD95qks3fFM9jtqVhlgO2oW0pA7C6CIz8zQ0zONFjsQlOaeDKA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", @@ -11188,23 +11902,85 @@ } }, "node_modules/@wordpress/reusable-blocks": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/reusable-blocks/-/reusable-blocks-5.3.0.tgz", - "integrity": "sha512-D8LoreqqrwUw6OimQyLooW1oWNpVuSK8ZyJNG135lUhqzVEEGvgcofbAk03QiSqaryyjKwDyD5qmJ8G1hmG/AA==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/reusable-blocks/-/reusable-blocks-5.5.0.tgz", + "integrity": "sha512-lpin5UU7+RpgrpKjG65LHJWfbPWWDXdDDFsAkB6yNbbVamR0R9BMeFKzjPxKSfue7bRrmq2L7l9g9HneZcuvEQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/block-editor": "^13.3.0", - "@wordpress/blocks": "^13.3.0", - "@wordpress/components": "^28.3.0", - "@wordpress/core-data": "^7.3.0", - "@wordpress/data": "^10.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/icons": "^10.3.0", - "@wordpress/notices": "^5.3.0", - "@wordpress/private-apis": "^1.3.0", - "@wordpress/url": "^4.3.0" + "@wordpress/block-editor": "^14.0.0", + "@wordpress/blocks": "^13.5.0", + "@wordpress/components": "^28.5.0", + "@wordpress/core-data": "^7.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/icons": "^10.5.0", + "@wordpress/notices": "^5.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/url": "^4.5.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/@wordpress/block-editor": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-14.0.0.tgz", + "integrity": "sha512-IODsUPm37DpZxLMcJXidlHeUAvALX+E9edY+z9UGJWP/PvhLCXllCRVQABcuYkPTsraFSF0Yrk9i/7WJF2NkaA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@emotion/react": "^11.7.1", + "@emotion/styled": "^11.6.0", + "@react-spring/web": "^9.4.5", + "@wordpress/a11y": "^4.5.0", + "@wordpress/api-fetch": "^7.5.0", + "@wordpress/blob": "^4.5.0", + "@wordpress/blocks": "^13.5.0", + "@wordpress/commands": "^1.5.0", + "@wordpress/components": "^28.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/date": "^5.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/dom": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/escape-html": "^3.5.0", + "@wordpress/hooks": "^4.5.0", + "@wordpress/html-entities": "^4.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/icons": "^10.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/keyboard-shortcuts": "^5.5.0", + "@wordpress/keycodes": "^4.5.0", + "@wordpress/notices": "^5.5.0", + "@wordpress/preferences": "^4.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/rich-text": "^7.5.0", + "@wordpress/style-engine": "^2.5.0", + "@wordpress/token-list": "^3.5.0", + "@wordpress/url": "^4.5.0", + "@wordpress/warning": "^3.5.0", + "@wordpress/wordcount": "^4.5.0", + "change-case": "^4.1.2", + "clsx": "^2.1.1", + "colord": "^2.7.0", + "deepmerge": "^4.3.0", + "diff": "^4.0.2", + "fast-deep-equal": "^3.1.3", + "memize": "^2.1.0", + "postcss": "^8.4.21", + "postcss-prefixwrap": "^1.41.0", + "postcss-urlrebase": "^1.4.0", + "react-autosize-textarea": "^7.1.0", + "react-easy-crop": "^5.0.6", + "remove-accents": "^0.5.0" }, "engines": { "node": ">=18.12.0", @@ -11215,21 +11991,45 @@ "react-dom": "^18.0.0" } }, + "node_modules/@wordpress/reusable-blocks/node_modules/@wordpress/keycodes": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.16.0", + "@wordpress/i18n": "^5.5.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, + "node_modules/@wordpress/reusable-blocks/node_modules/@wordpress/warning": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.5.0.tgz", + "integrity": "sha512-cYM2Vqf2EokJJoWHD5Ry15OUmdsKtDgR8/qxE0sWHUAdSQeoTuJZnqhgYI898cZGxHaZWX2xJCxQa7Qtwl8lqw==", + "dev": true, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, "node_modules/@wordpress/rich-text": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/rich-text/-/rich-text-7.3.0.tgz", - "integrity": "sha512-iL7qEybPOwtMp8WXMQndzfvT2k647ZqIMTj0rji4h2QAp/KaEHyYaIF6YhuQ7v5bSQ/9IAAOy3KGhguIuxIt8A==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/rich-text/-/rich-text-7.5.0.tgz", + "integrity": "sha512-qHeTZNaLbsO6coBph1CD4qn/nfzvJV/DamiCpSgBJ1eQO7u8DdVB8abDxODOOD5hVOLHTOM/OBjFPTVFevNrmw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/a11y": "^4.3.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/data": "^10.3.0", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/escape-html": "^3.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/keycodes": "^4.3.0", + "@wordpress/a11y": "^4.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/escape-html": "^3.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/keycodes": "^4.5.0", "memize": "^2.1.0" }, "engines": { @@ -11241,13 +12041,13 @@ } }, "node_modules/@wordpress/rich-text/node_modules/@wordpress/keycodes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.3.0.tgz", - "integrity": "sha512-o+L110/Y9ufS2eWVG1gXFs6+jPsMNVZoGJCt4PLjMmVabke0iaYstFppUdtQiOEDbnnhX9MH3RRtqp2AoSnaRQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0" + "@wordpress/i18n": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -11860,21 +12660,21 @@ } }, "node_modules/@wordpress/server-side-render": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/server-side-render/-/server-side-render-5.3.0.tgz", - "integrity": "sha512-DlD0DL1/rIsLlENv68LLaDHbWH+uIJ21H+8T1QTZGYwtgdAfiNKuaadexIKfcGFq+yjGdRk0ugYWBIKMe2WuJg==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/server-side-render/-/server-side-render-5.5.0.tgz", + "integrity": "sha512-k+ns+sQE6xJhoJ9mxwEmCTPVAedvPh1l1gkS0IlG8ST+cZbDiAPerfvVtlywrhsKz65w2VHK9HEBf7nkg1ivSA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/api-fetch": "^7.3.0", - "@wordpress/blocks": "^13.3.0", - "@wordpress/components": "^28.3.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/data": "^10.3.0", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/url": "^4.3.0", + "@wordpress/api-fetch": "^7.5.0", + "@wordpress/blocks": "^13.5.0", + "@wordpress/components": "^28.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/url": "^4.5.0", "fast-deep-equal": "^3.1.3" }, "engines": { @@ -11887,9 +12687,9 @@ } }, "node_modules/@wordpress/shortcode": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/shortcode/-/shortcode-4.3.0.tgz", - "integrity": "sha512-Ononu3JfP8W/qLNeB46YuGpmqpjj+VyA9EK6pZdmf1/8Gd9Q6L2+HRyp1AEzJzs59p2pLfzvf63T90KSSZjBaQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/shortcode/-/shortcode-4.5.0.tgz", + "integrity": "sha512-Ed0Gh7ZMaz5UkVo6yF5eQY/Nzpv4afxrr8dGjMNQpmUbq92CwaAq8tfj5vT89IV/Ano0F2EQtkcyKEVJ7VPqrw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", @@ -11901,9 +12701,9 @@ } }, "node_modules/@wordpress/style-engine": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/style-engine/-/style-engine-2.3.0.tgz", - "integrity": "sha512-VLnhVPDOZ32cnxFJSQbVkuF8YUd2M33m3bvw28TSvdAZcosN1WpmoEAtn9NhwU2jklvJEFfa1inlzuQ3NW/HEA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/style-engine/-/style-engine-2.5.0.tgz", + "integrity": "sha512-mV6cOtEO5zGg8ZYUNsHDBnywb76Jc+k1Q65PVSNezD+NtZasuASxZGz2J3gEwgNL/1p++JO7JQf9qyoZUs/jZw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", @@ -11932,14 +12732,14 @@ } }, "node_modules/@wordpress/sync": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/sync/-/sync-1.3.0.tgz", - "integrity": "sha512-up2zDx35LT3xOkx48+pfF+98p1T6q6nsZqQywf3nqbunxLBq+MYNUC7bd3z/Snn2jiCASxAINWMR5jQ1MB4Bqw==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/sync/-/sync-1.5.0.tgz", + "integrity": "sha512-c/p7YQqMjZAKFO3Q8FnikPp5Tm3/Iy4I0M4Rc5ML1VZMy+hwZVKQZ1AyfKfHAjDWv+XprSUVSbXpYL5YcYthlA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", "@types/simple-peer": "^9.11.5", - "@wordpress/url": "^4.3.0", + "@wordpress/url": "^4.5.0", "import-locals": "^2.0.0", "lib0": "^0.2.42", "simple-peer": "^9.11.0", @@ -11954,9 +12754,9 @@ } }, "node_modules/@wordpress/token-list": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/token-list/-/token-list-3.3.0.tgz", - "integrity": "sha512-9IcUUebJ2KBIe371pKonpS0KtTgwDzPJBQIMkPACvw47AL3ZY83sQzBwEqAw+hNstqilOD6n/SQUhIYxzMvdhg==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/token-list/-/token-list-3.5.0.tgz", + "integrity": "sha512-n/a7HYJz3b922qHcs4yyywzuFKZg8Du/xE6KSnPz9EiUVCHthYFJ8m587f9xtgdUDjZKK7fpZZ0yCK/Krwna+Q==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -11967,13 +12767,13 @@ } }, "node_modules/@wordpress/undo-manager": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/undo-manager/-/undo-manager-1.3.0.tgz", - "integrity": "sha512-1XvU3GKpWeKFLCRx/3yEttRbIszD38vfH53XmCq2Y6IbWiyJLUGCnq4kiZjOaxA0o/DcAa4edscPyqmJj+wE+g==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/undo-manager/-/undo-manager-1.5.0.tgz", + "integrity": "sha512-ijvKwnXzKMV9xEcVB4mOIPih6BP5ZnZ1QYsv/EaPV7qlt2zgEevAHGa/FLQMW/lWlGCa5OhUK4tqDV+ZvrjTGw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/is-shallow-equal": "^5.3.0" + "@wordpress/is-shallow-equal": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -11981,9 +12781,9 @@ } }, "node_modules/@wordpress/url": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-4.3.0.tgz", - "integrity": "sha512-2rbpF2OD3rc/Jhmd4Mn9PxXTYGw63hIVMEJWzHs0x/mHmuDZEAn1vZcpDhJkksqtnHMS3BOlTv+Kbk1klxOpCg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-4.5.0.tgz", + "integrity": "sha512-xv/wqUnqNedo9fyiCVJgZnfLtYJbBph30Z2neTFR8Ivy8HA4p74xGqlt8TJceYLeRUrT9EgsMITbHNJMftdNbA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", @@ -11995,15 +12795,15 @@ } }, "node_modules/@wordpress/viewport": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/viewport/-/viewport-6.3.0.tgz", - "integrity": "sha512-2DCh0pSYY4zrSFvrGqGgB3tEkp/RdJhj1Lkoy52m47jIK0Q31Up+b/dJz7GpR4xmQ7Hw3ibAjGgAJj+vbSOvZw==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/viewport/-/viewport-6.5.0.tgz", + "integrity": "sha512-kIBe26eQI1kcVF1kR983qX0P4r+NAO0yuiyLQcfqPc04P74icWiIbqnHWnKXJIxRIrM3UQBX0cvvhntQbjR8fg==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/data": "^10.3.0", - "@wordpress/element": "^6.3.0" + "@wordpress/compose": "^7.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/element": "^6.5.0" }, "engines": { "node": ">=18.12.0", @@ -12053,9 +12853,9 @@ } }, "node_modules/@wordpress/wordcount": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/wordcount/-/wordcount-4.3.0.tgz", - "integrity": "sha512-+jTnD4XMRRxljZ6mRif5wMFqiDbIFTc/naeE2CI7mirdsnFriUD3gYmhgLsP71Rckh+9EHZpzQBCbehXU2zX1A==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/wordcount/-/wordcount-4.5.0.tgz", + "integrity": "sha512-LgSA2Mra6e9r15eRUIFNk2TCWnoyNhecPOOWrT061sl9dEvJ92zAjNWILrMa8rnTTX651bnF2HJD1PkivxDVzw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" diff --git a/package.json b/package.json index dd4fd7a5a..102939811 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "@wordpress/data": "^10.3.0", "@wordpress/e2e-test-utils": "^11.3.0", "@wordpress/edit-post": "^8.3.0", - "@wordpress/editor": "^14.3.0", + "@wordpress/editor": "^14.5.0", "@wordpress/element": "^6.2.0", "@wordpress/env": "^10.3.0", "@wordpress/eslint-plugin": "^20.0.0", From 7f8221dad6879afe4efac303ab15ac4f3eb3912a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 07:49:58 +0000 Subject: [PATCH 029/282] build(deps-dev): bump @wordpress/env from 10.3.0 to 10.5.0 Bumps [@wordpress/env](https://github.com/WordPress/gutenberg/tree/HEAD/packages/env) from 10.3.0 to 10.5.0. - [Release notes](https://github.com/WordPress/gutenberg/releases) - [Changelog](https://github.com/WordPress/gutenberg/blob/trunk/packages/env/CHANGELOG.md) - [Commits](https://github.com/WordPress/gutenberg/commits/@wordpress/env@10.5.0/packages/env) --- updated-dependencies: - dependency-name: "@wordpress/env" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 40ab6e410..8f79de839 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,7 +38,7 @@ "@wordpress/edit-post": "^8.3.0", "@wordpress/editor": "^14.3.0", "@wordpress/element": "^6.2.0", - "@wordpress/env": "^10.3.0", + "@wordpress/env": "^10.5.0", "@wordpress/eslint-plugin": "^20.0.0", "@wordpress/hooks": "^4.0.0", "@wordpress/i18n": "^5.0.0", @@ -10343,9 +10343,9 @@ } }, "node_modules/@wordpress/env": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/env/-/env-10.3.0.tgz", - "integrity": "sha512-tfEYfXp+4c09btYwNovfBRDDCD25L6Dasg6ODkYw0g+gg5DXsYvaq7tQDeAAzqwtTpzeKi4DOidNsVoA4FR6Rg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/env/-/env-10.5.0.tgz", + "integrity": "sha512-Hx+fi6qTEAuycznulkuMi4d5RDPZ6lPPAxaylpCwXNX2hgx5jrrpgnY4Zn0chBgZMpShO7BbA+zNDq2E6evvTw==", "dev": true, "dependencies": { "chalk": "^4.0.0", diff --git a/package.json b/package.json index dd4fd7a5a..f94ad5c61 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "@wordpress/edit-post": "^8.3.0", "@wordpress/editor": "^14.3.0", "@wordpress/element": "^6.2.0", - "@wordpress/env": "^10.3.0", + "@wordpress/env": "^10.5.0", "@wordpress/eslint-plugin": "^20.0.0", "@wordpress/hooks": "^4.0.0", "@wordpress/i18n": "^5.0.0", From 28c7c864bccff10f49129b913d4f15f3163f80fe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 07:50:32 +0000 Subject: [PATCH 030/282] build(deps): bump @wordpress/dom-ready from 4.3.0 to 4.5.0 Bumps [@wordpress/dom-ready](https://github.com/WordPress/gutenberg/tree/HEAD/packages/dom-ready) from 4.3.0 to 4.5.0. - [Release notes](https://github.com/WordPress/gutenberg/releases) - [Changelog](https://github.com/WordPress/gutenberg/blob/trunk/packages/dom-ready/CHANGELOG.md) - [Commits](https://github.com/WordPress/gutenberg/commits/@wordpress/dom-ready@4.5.0/packages/dom-ready) --- updated-dependencies: - dependency-name: "@wordpress/dom-ready" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 40ab6e410..d4de4ca63 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "GPL-2.0-or-later", "dependencies": { "@types/js-cookie": "^3.0.6", - "@wordpress/dom-ready": "^4.3.0", + "@wordpress/dom-ready": "^4.5.0", "js-cookie": "^3.0.5", "lodash.debounce": "^4.0.8" }, @@ -10030,9 +10030,9 @@ } }, "node_modules/@wordpress/dom-ready": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/dom-ready/-/dom-ready-4.3.0.tgz", - "integrity": "sha512-zuLLMIeJt1hZ95R4kdJFcsIaL2eud1kF40VCmwK3mK0qpgXv/1avtGX8lx6DMLL/GGL1yYcJhR13RSKSjxuGEQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom-ready/-/dom-ready-4.5.0.tgz", + "integrity": "sha512-5dALG1lQtoH/Rk7DWFe9DaIF2bQQM5U0x+c1lQnk1cnBJ69AijIcbZMYaMzlgngo4dVF2PnFZ/VKVSUOKghhQQ==", "dependencies": { "@babel/runtime": "^7.16.0" }, diff --git a/package.json b/package.json index dd4fd7a5a..60b464e92 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ ], "dependencies": { "@types/js-cookie": "^3.0.6", - "@wordpress/dom-ready": "^4.3.0", + "@wordpress/dom-ready": "^4.5.0", "js-cookie": "^3.0.5", "lodash.debounce": "^4.0.8" }, From d6f0375339a0ac148dab550fbcd64d8860a16ba5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 07:51:09 +0000 Subject: [PATCH 031/282] build(deps-dev): bump @wordpress/plugins from 7.3.0 to 7.5.0 Bumps [@wordpress/plugins](https://github.com/WordPress/gutenberg/tree/HEAD/packages/plugins) from 7.3.0 to 7.5.0. - [Release notes](https://github.com/WordPress/gutenberg/releases) - [Changelog](https://github.com/WordPress/gutenberg/blob/trunk/packages/plugins/CHANGELOG.md) - [Commits](https://github.com/WordPress/gutenberg/commits/@wordpress/plugins@7.5.0/packages/plugins) --- updated-dependencies: - dependency-name: "@wordpress/plugins" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 320 ++++++++++++++++++++++++++-------------------- package.json | 2 +- 2 files changed, 181 insertions(+), 141 deletions(-) diff --git a/package-lock.json b/package-lock.json index 40ab6e410..4f14fa7a7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,7 +43,7 @@ "@wordpress/hooks": "^4.0.0", "@wordpress/i18n": "^5.0.0", "@wordpress/icons": "^10.0.0", - "@wordpress/plugins": "^7.3.0", + "@wordpress/plugins": "^7.5.0", "@wordpress/scripts": "^27.9.0", "@wordpress/url": "^4.2.0", "@wordpress/wordcount": "^4.3.0", @@ -9369,14 +9369,14 @@ } }, "node_modules/@wordpress/a11y": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/a11y/-/a11y-4.3.0.tgz", - "integrity": "sha512-kmAE8hshmldudMhtj/RKY7lEwyux5w6zvCTbIj3a6iq0ZMhU3vsxTlCp/vEGLoYdfetwRN4zeJA9jvPki+IOUA==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/a11y/-/a11y-4.5.0.tgz", + "integrity": "sha512-sQmA4kTqu252to6ppVhti2RxSCFcAgWMc3l6rY2kBpj90uK5gtvLKQMr/GvydhildG/OzFSswbk1YBgSPGaudw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/dom-ready": "^4.3.0", - "@wordpress/i18n": "^5.3.0" + "@wordpress/dom-ready": "^4.5.0", + "@wordpress/i18n": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -9718,12 +9718,12 @@ } }, "node_modules/@wordpress/components": { - "version": "28.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-28.3.0.tgz", - "integrity": "sha512-zLHtxmhbuD7j5f7wOqRu6+KYVWPRpgHsYzxOavWkkiKv0XUvWeYWBIZFM4oy6A1WJqW2nEELcAjIeBX/0UWMig==", + "version": "28.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-28.5.0.tgz", + "integrity": "sha512-kZPb8MdpGW/Yv/ycJhbf+myb4czkyQ28gb5PY1kT2ABRB07J3oS1/badSLex3x06zD6NPtJt3kInbPUsSF2prQ==", "dev": true, "dependencies": { - "@ariakit/react": "^0.3.12", + "@ariakit/react": "^0.4.7", "@babel/runtime": "^7.16.0", "@emotion/cache": "^11.7.1", "@emotion/css": "^11.7.1", @@ -9735,29 +9735,28 @@ "@types/gradient-parser": "0.1.3", "@types/highlight-words-core": "1.2.1", "@use-gesture/react": "^10.3.1", - "@wordpress/a11y": "^4.3.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/date": "^5.3.0", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/dom": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/escape-html": "^3.3.0", - "@wordpress/hooks": "^4.3.0", - "@wordpress/html-entities": "^4.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/icons": "^10.3.0", - "@wordpress/is-shallow-equal": "^5.3.0", - "@wordpress/keycodes": "^4.3.0", - "@wordpress/primitives": "^4.3.0", - "@wordpress/private-apis": "^1.3.0", - "@wordpress/rich-text": "^7.3.0", - "@wordpress/warning": "^3.3.0", + "@wordpress/a11y": "^4.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/date": "^5.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/dom": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/escape-html": "^3.5.0", + "@wordpress/hooks": "^4.5.0", + "@wordpress/html-entities": "^4.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/icons": "^10.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/keycodes": "^4.5.0", + "@wordpress/primitives": "^4.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/rich-text": "^7.5.0", + "@wordpress/warning": "^3.5.0", "change-case": "^4.1.2", "clsx": "^2.1.1", "colord": "^2.7.0", "date-fns": "^3.6.0", "deepmerge": "^4.3.0", - "downshift": "^6.0.15", "fast-deep-equal": "^3.1.3", "framer-motion": "^11.1.9", "gradient-parser": "^0.1.5", @@ -9780,14 +9779,52 @@ "react-dom": "^18.0.0" } }, + "node_modules/@wordpress/components/node_modules/@ariakit/core": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/@ariakit/core/-/core-0.4.8.tgz", + "integrity": "sha512-HQS+9CI7pMqqVlAt5bPGenT0/e65UxXY+PKtgU7Y+0UToBDBRolO5S9+UUSDm8OmJHSnq24owEGm1Mv28l5XCQ==", + "dev": true + }, + "node_modules/@wordpress/components/node_modules/@ariakit/react": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/@ariakit/react/-/react-0.4.8.tgz", + "integrity": "sha512-Bb1vOrp0X52hxi1wE9TEHjjZ/Y08tVq2ZH+RFDwRQB3g04uVwrrhnTccHepC6rsObrDpAOV3/YlJCi4k/lSUaQ==", + "dev": true, + "dependencies": { + "@ariakit/react-core": "0.4.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ariakit" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@wordpress/components/node_modules/@ariakit/react-core": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/@ariakit/react-core/-/react-core-0.4.8.tgz", + "integrity": "sha512-TzsddUWQwWYhrEVWHA/Gf7KCGx8rwFohAHfuljjqidKeZi2kUmuRAImCTG9oga34FWHFf4AdXQbBKclMNt0nrQ==", + "dev": true, + "dependencies": { + "@ariakit/core": "0.4.8", + "@floating-ui/dom": "^1.0.0", + "use-sync-external-store": "^1.2.0" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/@wordpress/components/node_modules/@wordpress/keycodes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.3.0.tgz", - "integrity": "sha512-o+L110/Y9ufS2eWVG1gXFs6+jPsMNVZoGJCt4PLjMmVabke0iaYstFppUdtQiOEDbnnhX9MH3RRtqp2AoSnaRQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0" + "@wordpress/i18n": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -9795,9 +9832,9 @@ } }, "node_modules/@wordpress/components/node_modules/@wordpress/warning": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.3.0.tgz", - "integrity": "sha512-n82aKCxuGRNwAtSLaycErJuhKgfOc+KtiljyQITPperMh9i8bH6I+JxtYiu+aLMaY5vrVLVb+/kCzKuWVQIKPA==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.5.0.tgz", + "integrity": "sha512-cYM2Vqf2EokJJoWHD5Ry15OUmdsKtDgR8/qxE0sWHUAdSQeoTuJZnqhgYI898cZGxHaZWX2xJCxQa7Qtwl8lqw==", "dev": true, "engines": { "node": ">=18.12.0", @@ -9805,20 +9842,20 @@ } }, "node_modules/@wordpress/compose": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-7.3.0.tgz", - "integrity": "sha512-TtAYdKnqQ/L/nF0+fmlQ1wAvm90X9HRBrAuEMNmkzKhews/5GR0rR3dNSMjlf7C6mNdTO3mkYt6AQf9fvZFoiQ==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-7.5.0.tgz", + "integrity": "sha512-jWRmleIGxmvTIC/1VYtAvq0iRfCkW/AtlNmqoKiyd0Ah5lccWRtxSH5V3Vh1BEkBQRANMWxJpOpRTKDFTcfTvg==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", "@types/mousetrap": "^1.6.8", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/dom": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/is-shallow-equal": "^5.3.0", - "@wordpress/keycodes": "^4.3.0", - "@wordpress/priority-queue": "^3.3.0", - "@wordpress/undo-manager": "^1.3.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/dom": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/keycodes": "^4.5.0", + "@wordpress/priority-queue": "^3.5.0", + "@wordpress/undo-manager": "^1.5.0", "change-case": "^4.1.2", "clipboard": "^2.0.11", "mousetrap": "^1.6.5", @@ -9833,13 +9870,13 @@ } }, "node_modules/@wordpress/compose/node_modules/@wordpress/keycodes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.3.0.tgz", - "integrity": "sha512-o+L110/Y9ufS2eWVG1gXFs6+jPsMNVZoGJCt4PLjMmVabke0iaYstFppUdtQiOEDbnnhX9MH3RRtqp2AoSnaRQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0" + "@wordpress/i18n": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -9913,19 +9950,19 @@ } }, "node_modules/@wordpress/data": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-10.3.0.tgz", - "integrity": "sha512-cImJw4k30coosH6QtiJllxEYr93w8981PPvhGhemMbRQ28MnSA7rbJPv3h2LO9oss5SQH1gU9kwNGAZcF6PMPg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-10.5.0.tgz", + "integrity": "sha512-Y2P5SC0fuTivcfdYmubL3c15WRbE0FJAyYcEfZeJ2C37a2DmBnCBz3uEzGy2kCilz56qMfK0qutAHkfytOpRQw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/is-shallow-equal": "^5.3.0", - "@wordpress/priority-queue": "^3.3.0", - "@wordpress/private-apis": "^1.3.0", - "@wordpress/redux-routine": "^5.3.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/priority-queue": "^3.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/redux-routine": "^5.5.0", "deepmerge": "^4.3.0", "equivalent-key-map": "^0.2.2", "is-plain-object": "^5.0.0", @@ -9970,13 +10007,13 @@ } }, "node_modules/@wordpress/date": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/date/-/date-5.3.0.tgz", - "integrity": "sha512-vD0rLQxNlOoFd4n32HohhTif4P1JPW/Igjp0c/O2WZji+eXQM6P54fBu5veKvgwMmXpUn8y0xzgssj3pKAUgCg==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/date/-/date-5.5.0.tgz", + "integrity": "sha512-dIo02TAIuXG/wkcVf+jsyXn64PUVsxs6HwuHanNiDNVZt95QVJ8b7wdJZNIrhTkmVXhIUzYAz5BpuXUC6IZAqg==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/deprecated": "^4.3.0", + "@wordpress/deprecated": "^4.5.0", "moment": "^2.29.4", "moment-timezone": "^0.5.40" }, @@ -10002,13 +10039,13 @@ } }, "node_modules/@wordpress/deprecated": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-4.3.0.tgz", - "integrity": "sha512-K2GHXlwjx6GMhZjs52X1MXySCrqzh4IjoqF5IOcydMgWqOIE2++hMuB9Y55qN/Mhsrv/HO8Q1LaTxbEd6BuNJQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-4.5.0.tgz", + "integrity": "sha512-r3xGAM45XTd+z+hnUvLGtSz+Y0ebybuw/cyE0CatksJBGvXez3kiTDaknALkgzjHRZzIGpNu6XTVUoIJs0H39A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/hooks": "^4.3.0" + "@wordpress/hooks": "^4.5.0" }, "engines": { "node": ">=18.12.0", @@ -10016,13 +10053,13 @@ } }, "node_modules/@wordpress/dom": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-4.3.0.tgz", - "integrity": "sha512-sf4h6jVqboRdhe3soyr5bt+Vpz24WG/AIMHm7pGaxfbV5jxx06ZZ8K1RKzhr7jF3wn7IgIc1wmMA+OFzEYqGyw==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-4.5.0.tgz", + "integrity": "sha512-XjnpRbbhZ1hdgv758vSXQacjfy/N0H2oI0oWukrLmlkKDP5ZrGfdziHQ2+KcoW+QDx8pu4JYcUpjmuJLugDStw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/deprecated": "^4.3.0" + "@wordpress/deprecated": "^4.5.0" }, "engines": { "node": ">=18.12.0", @@ -10030,9 +10067,9 @@ } }, "node_modules/@wordpress/dom-ready": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/dom-ready/-/dom-ready-4.3.0.tgz", - "integrity": "sha512-zuLLMIeJt1hZ95R4kdJFcsIaL2eud1kF40VCmwK3mK0qpgXv/1avtGX8lx6DMLL/GGL1yYcJhR13RSKSjxuGEQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom-ready/-/dom-ready-4.5.0.tgz", + "integrity": "sha512-5dALG1lQtoH/Rk7DWFe9DaIF2bQQM5U0x+c1lQnk1cnBJ69AijIcbZMYaMzlgngo4dVF2PnFZ/VKVSUOKghhQQ==", "dependencies": { "@babel/runtime": "^7.16.0" }, @@ -10323,15 +10360,15 @@ } }, "node_modules/@wordpress/element": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-6.3.0.tgz", - "integrity": "sha512-DsiqzjuXqxJkLUoLomsGTFFxbSZgk+Lz+2/1yFH+BU3jQ6zeD64+JWv8Lt4+fKU154rV0KpfMwfD/oAC/Lp1zQ==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-6.5.0.tgz", + "integrity": "sha512-N9w3jfceltdDEN71jpaMCXU+jbvec9kredvQIn/6YNiUMarPXWth7DJYU3+mDtbYawnTIvytzGjbj/J+bqqdHg==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", "@types/react": "^18.2.79", "@types/react-dom": "^18.2.25", - "@wordpress/escape-html": "^3.3.0", + "@wordpress/escape-html": "^3.5.0", "change-case": "^4.1.2", "is-plain-object": "^5.0.0", "react": "^18.3.0", @@ -10446,9 +10483,9 @@ } }, "node_modules/@wordpress/escape-html": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-3.3.0.tgz", - "integrity": "sha512-Wu/Fq96E28UGnIO5VQW/aEgCiHWvzrD8izDnP8U0WZSuwIPYcS5iYmRe2UWc7rwyoeY2YXNd6xFjgd7oTOKNCA==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-3.5.0.tgz", + "integrity": "sha512-8dUWTmsDZuqAmBtRgk0JpiIafRKPM4n8tqCr147AugTbP/vyQ7rIzG3M/YCtVSmDr6f/qZ32YU8J7c34RhZ/9g==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -10718,9 +10755,9 @@ } }, "node_modules/@wordpress/hooks": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-4.3.0.tgz", - "integrity": "sha512-bpqwSXGyxPfhuxESKoAtL4ofB3CazzvcwcucTZ0g9Pat3KNuBaloSrPBliqqNOiSLWNH3nmpkaRmv4u89EdKAw==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-4.5.0.tgz", + "integrity": "sha512-wr1l1WM1yobyNGFLRgbLNBGtYIkzAGfmbT2e9zIOvqllRJT4wprYTqqhgovOKHlET5ij/TKdv4tApkGLUIXTsA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -10731,9 +10768,9 @@ } }, "node_modules/@wordpress/html-entities": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/html-entities/-/html-entities-4.3.0.tgz", - "integrity": "sha512-rJDf9KjCuUnFwIwmOdN4FcL7RJnDzPxIdvvMoWXkYd9GseEeRTsY6xIG+fGgVGgYe3HwXDYSFCWTF/x2M9Eerg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/html-entities/-/html-entities-4.5.0.tgz", + "integrity": "sha512-iQo2P1Sc499MxguelJ4aMcF08jnYkOdvb+FAOyOfGCyDjEtNbldRFc2BJ9NmJ/9nmtlwc/IzUzXop0M1gjy9tw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -10744,13 +10781,13 @@ } }, "node_modules/@wordpress/i18n": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-5.3.0.tgz", - "integrity": "sha512-edHKkdZb6jNpbn+LUPu2wo1mKyhT819WJ7kI8hmMcHq82rNwwbMfcGoB3oSaphTphWfhlgxIxLczKOAbWDKudw==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-5.5.0.tgz", + "integrity": "sha512-MtCJIjNHCWs7R77f5Xml1CCnVXqrle4cDpqMU9myx4Cq8ZijqSayX1CTtwtk+Z3/3xa+dBZu5Koe4wiW1yIUSA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/hooks": "^4.3.0", + "@wordpress/hooks": "^4.5.0", "gettext-parser": "^1.3.1", "memize": "^2.1.0", "sprintf-js": "^1.1.1", @@ -10765,14 +10802,14 @@ } }, "node_modules/@wordpress/icons": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/icons/-/icons-10.3.0.tgz", - "integrity": "sha512-d2jOFfLIAxPr+/Bzg7wnRDEDPogMpVefe4cHgIx9kXp/+7DG4KWNJm842qVithjs1wVgSzavzWbFrTtPEZ+Uhw==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/icons/-/icons-10.5.0.tgz", + "integrity": "sha512-BZwKBRKoTef9uW73T+FwK6d4JlcvgdVAaz3LB5dCluXg5PLV5ufMdumAaMxKWq/Ffl92/ddt8CKIdHjxfAZF4A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/element": "^6.3.0", - "@wordpress/primitives": "^4.3.0" + "@wordpress/element": "^6.5.0", + "@wordpress/primitives": "^4.5.0" }, "engines": { "node": ">=18.12.0", @@ -10838,9 +10875,9 @@ } }, "node_modules/@wordpress/is-shallow-equal": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-5.3.0.tgz", - "integrity": "sha512-sZ+fypqjYX0/DTAKsm1G9ND9Wn4d3Ju4lI7SLSmCKdUL5EPY3g/2LpKQKDqljh9m6Ex5NWp2XfU8UVXpkEfbMQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-5.5.0.tgz", + "integrity": "sha512-nkCz45HgMBkjhyxffDgpAgJbfnKyZML94/gHhBtxizHfaNuZ5as7DfEyN1xgebvDiLbOaRU7em1pPAuEhIoTfQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -11046,18 +11083,18 @@ } }, "node_modules/@wordpress/plugins": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/plugins/-/plugins-7.3.0.tgz", - "integrity": "sha512-3XdjSXTUoboJSePJ/RYUmkJmi30cnCewtA0oYakszejvJpTkuL2JQsDezsJy8e4uDH3D8mhM6LkOYFLPAVvhwQ==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/plugins/-/plugins-7.5.0.tgz", + "integrity": "sha512-1bvoT+Shi6FdrVgHqzzMyb3tF82eaSpvuRQsVYYPLCZnfEztDhdfuhgWD/M7oh2Mbxd4kkV1HWbMAKCbop/8/g==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/components": "^28.3.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/hooks": "^4.3.0", - "@wordpress/icons": "^10.3.0", - "@wordpress/is-shallow-equal": "^5.3.0", + "@wordpress/components": "^28.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/hooks": "^4.5.0", + "@wordpress/icons": "^10.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", "memize": "^2.0.1" }, "engines": { @@ -11127,24 +11164,27 @@ } }, "node_modules/@wordpress/primitives": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/primitives/-/primitives-4.3.0.tgz", - "integrity": "sha512-h7wb2Np3n5etOg3j38GN80NEA8NgNdsSF/JJcRhpRf8FQOJd1mnKzj6szVHeKv0G7bvBif0NTgdSUm5M6Nikfg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/primitives/-/primitives-4.5.0.tgz", + "integrity": "sha512-1TYCpCAr2BmYJESlD8v325GgYXSgUbrFtebwgvpMN/28CEwmPN+ORRECV41nPX4yVJ2k0kYzYxzQUGp/78xWsw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/element": "^6.3.0", + "@wordpress/element": "^6.5.0", "clsx": "^2.1.1" }, "engines": { "node": ">=18.12.0", "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0" } }, "node_modules/@wordpress/priority-queue": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-3.3.0.tgz", - "integrity": "sha512-H7dGei1mFqKlz7NLFOGGtVgaBsORRaXeXNwWLI5rE0pI3XfGYd+zxNrG5aBzHw4fPqsITsxecNSaacc9fjqgjQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-3.5.0.tgz", + "integrity": "sha512-ilbG70ZuUJd0UTC7uyLP8zI/ZSN0d4ceG3qwlDx13yQAcjAcuw1Ei1CwzFBsbmI3OS1KkfkDpwZzKOrA+j/00Q==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", @@ -11156,9 +11196,9 @@ } }, "node_modules/@wordpress/private-apis": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/private-apis/-/private-apis-1.3.0.tgz", - "integrity": "sha512-IbtH8ZENAKixSoTBKbmJ2ZCIkxsxqAoWPBtvbNJG9rYdzSk+BExdy/5VGO6Pv5GcUElHT+8uV26W4XxBVNl4UQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/private-apis/-/private-apis-1.5.0.tgz", + "integrity": "sha512-taGW34kyyHMnbmTbWIyOJt7C4KFVCg7F5PNFwJQmS43FESC9BAjPw7VeEDTJ0XNqocH4NNeBJclhFyj82QySTQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -11169,9 +11209,9 @@ } }, "node_modules/@wordpress/redux-routine": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/redux-routine/-/redux-routine-5.3.0.tgz", - "integrity": "sha512-5HGdW8PqIK5fTyg1yo6NL2x1LTxU9vBvgUan/bLxYLX0YNw4+gQUex3djE0dwXNgrdE4mvWvYTcccc+2L59hig==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/redux-routine/-/redux-routine-5.5.0.tgz", + "integrity": "sha512-PvIgq0lI2PLjechCq+pRFIE/xbFwznytupGscD95qks3fFM9jtqVhlgO2oW0pA7C6CIz8zQ0zONFjsQlOaeDKA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", @@ -11216,20 +11256,20 @@ } }, "node_modules/@wordpress/rich-text": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/rich-text/-/rich-text-7.3.0.tgz", - "integrity": "sha512-iL7qEybPOwtMp8WXMQndzfvT2k647ZqIMTj0rji4h2QAp/KaEHyYaIF6YhuQ7v5bSQ/9IAAOy3KGhguIuxIt8A==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/rich-text/-/rich-text-7.5.0.tgz", + "integrity": "sha512-qHeTZNaLbsO6coBph1CD4qn/nfzvJV/DamiCpSgBJ1eQO7u8DdVB8abDxODOOD5hVOLHTOM/OBjFPTVFevNrmw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/a11y": "^4.3.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/data": "^10.3.0", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/escape-html": "^3.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/keycodes": "^4.3.0", + "@wordpress/a11y": "^4.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/escape-html": "^3.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/keycodes": "^4.5.0", "memize": "^2.1.0" }, "engines": { @@ -11241,13 +11281,13 @@ } }, "node_modules/@wordpress/rich-text/node_modules/@wordpress/keycodes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.3.0.tgz", - "integrity": "sha512-o+L110/Y9ufS2eWVG1gXFs6+jPsMNVZoGJCt4PLjMmVabke0iaYstFppUdtQiOEDbnnhX9MH3RRtqp2AoSnaRQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0" + "@wordpress/i18n": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -11967,13 +12007,13 @@ } }, "node_modules/@wordpress/undo-manager": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/undo-manager/-/undo-manager-1.3.0.tgz", - "integrity": "sha512-1XvU3GKpWeKFLCRx/3yEttRbIszD38vfH53XmCq2Y6IbWiyJLUGCnq4kiZjOaxA0o/DcAa4edscPyqmJj+wE+g==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/undo-manager/-/undo-manager-1.5.0.tgz", + "integrity": "sha512-ijvKwnXzKMV9xEcVB4mOIPih6BP5ZnZ1QYsv/EaPV7qlt2zgEevAHGa/FLQMW/lWlGCa5OhUK4tqDV+ZvrjTGw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/is-shallow-equal": "^5.3.0" + "@wordpress/is-shallow-equal": "^5.5.0" }, "engines": { "node": ">=18.12.0", diff --git a/package.json b/package.json index dd4fd7a5a..50e752fff 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "@wordpress/hooks": "^4.0.0", "@wordpress/i18n": "^5.0.0", "@wordpress/icons": "^10.0.0", - "@wordpress/plugins": "^7.3.0", + "@wordpress/plugins": "^7.5.0", "@wordpress/scripts": "^27.9.0", "@wordpress/url": "^4.2.0", "@wordpress/wordcount": "^4.3.0", From b96e94271040c0d3c366286a544694257fa6b1c8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 07:51:25 +0000 Subject: [PATCH 032/282] build(deps-dev): bump prettier from 3.3.2 to 3.3.3 Bumps [prettier](https://github.com/prettier/prettier) from 3.3.2 to 3.3.3. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/3.3.2...3.3.3) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 40ab6e410..8eb9125e6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -50,7 +50,7 @@ "concurrently": "^8.2.2", "eslint-plugin-jest": "^28.6.0", "husky": "^9.0.11", - "prettier": "^3.3.2", + "prettier": "^3.3.3", "ts-loader": "^9.5.1", "typescript": "^5.5.3" }, @@ -26826,9 +26826,9 @@ } }, "node_modules/prettier": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", - "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" diff --git a/package.json b/package.json index dd4fd7a5a..04d64b352 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "concurrently": "^8.2.2", "eslint-plugin-jest": "^28.6.0", "husky": "^9.0.11", - "prettier": "^3.3.2", + "prettier": "^3.3.3", "ts-loader": "^9.5.1", "typescript": "^5.5.3" }, From 6bdd349776a4c9a66ad495a8ac18f791ddfac402 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 07:52:01 +0000 Subject: [PATCH 033/282] build(deps-dev): bump @wordpress/url from 4.3.0 to 4.5.0 Bumps [@wordpress/url](https://github.com/WordPress/gutenberg/tree/HEAD/packages/url) from 4.3.0 to 4.5.0. - [Release notes](https://github.com/WordPress/gutenberg/releases) - [Changelog](https://github.com/WordPress/gutenberg/blob/trunk/packages/url/CHANGELOG.md) - [Commits](https://github.com/WordPress/gutenberg/commits/@wordpress/url@4.5.0/packages/url) --- updated-dependencies: - dependency-name: "@wordpress/url" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 40ab6e410..7cbd41c05 100644 --- a/package-lock.json +++ b/package-lock.json @@ -45,7 +45,7 @@ "@wordpress/icons": "^10.0.0", "@wordpress/plugins": "^7.3.0", "@wordpress/scripts": "^27.9.0", - "@wordpress/url": "^4.2.0", + "@wordpress/url": "^4.5.0", "@wordpress/wordcount": "^4.3.0", "concurrently": "^8.2.2", "eslint-plugin-jest": "^28.6.0", @@ -11981,9 +11981,9 @@ } }, "node_modules/@wordpress/url": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-4.3.0.tgz", - "integrity": "sha512-2rbpF2OD3rc/Jhmd4Mn9PxXTYGw63hIVMEJWzHs0x/mHmuDZEAn1vZcpDhJkksqtnHMS3BOlTv+Kbk1klxOpCg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-4.5.0.tgz", + "integrity": "sha512-xv/wqUnqNedo9fyiCVJgZnfLtYJbBph30Z2neTFR8Ivy8HA4p74xGqlt8TJceYLeRUrT9EgsMITbHNJMftdNbA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", diff --git a/package.json b/package.json index dd4fd7a5a..306229460 100644 --- a/package.json +++ b/package.json @@ -73,7 +73,7 @@ "@wordpress/icons": "^10.0.0", "@wordpress/plugins": "^7.3.0", "@wordpress/scripts": "^27.9.0", - "@wordpress/url": "^4.2.0", + "@wordpress/url": "^4.5.0", "@wordpress/wordcount": "^4.3.0", "concurrently": "^8.2.2", "eslint-plugin-jest": "^28.6.0", From a1cdc80f62d384b86d0f72a6779a9056c6d283fe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 07:52:37 +0000 Subject: [PATCH 034/282] build(deps-dev): bump @wordpress/compose from 7.3.0 to 7.5.0 Bumps [@wordpress/compose](https://github.com/WordPress/gutenberg/tree/HEAD/packages/compose) from 7.3.0 to 7.5.0. - [Release notes](https://github.com/WordPress/gutenberg/releases) - [Changelog](https://github.com/WordPress/gutenberg/blob/trunk/packages/compose/CHANGELOG.md) - [Commits](https://github.com/WordPress/gutenberg/commits/@wordpress/compose@7.5.0/packages/compose) --- updated-dependencies: - dependency-name: "@wordpress/compose" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 94 +++++++++++++++++++++++------------------------ package.json | 2 +- 2 files changed, 48 insertions(+), 48 deletions(-) diff --git a/package-lock.json b/package-lock.json index 40ab6e410..71f87f953 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,7 +31,7 @@ "@wordpress/block-editor": "^13.0.0", "@wordpress/blocks": "^13.3.0", "@wordpress/components": "^28.3.0", - "@wordpress/compose": "^7.0.0", + "@wordpress/compose": "^7.5.0", "@wordpress/core-data": "^7.3.0", "@wordpress/data": "^10.3.0", "@wordpress/e2e-test-utils": "^11.3.0", @@ -9805,20 +9805,20 @@ } }, "node_modules/@wordpress/compose": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-7.3.0.tgz", - "integrity": "sha512-TtAYdKnqQ/L/nF0+fmlQ1wAvm90X9HRBrAuEMNmkzKhews/5GR0rR3dNSMjlf7C6mNdTO3mkYt6AQf9fvZFoiQ==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/compose/-/compose-7.5.0.tgz", + "integrity": "sha512-jWRmleIGxmvTIC/1VYtAvq0iRfCkW/AtlNmqoKiyd0Ah5lccWRtxSH5V3Vh1BEkBQRANMWxJpOpRTKDFTcfTvg==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", "@types/mousetrap": "^1.6.8", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/dom": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/is-shallow-equal": "^5.3.0", - "@wordpress/keycodes": "^4.3.0", - "@wordpress/priority-queue": "^3.3.0", - "@wordpress/undo-manager": "^1.3.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/dom": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/keycodes": "^4.5.0", + "@wordpress/priority-queue": "^3.5.0", + "@wordpress/undo-manager": "^1.5.0", "change-case": "^4.1.2", "clipboard": "^2.0.11", "mousetrap": "^1.6.5", @@ -9833,13 +9833,13 @@ } }, "node_modules/@wordpress/compose/node_modules/@wordpress/keycodes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.3.0.tgz", - "integrity": "sha512-o+L110/Y9ufS2eWVG1gXFs6+jPsMNVZoGJCt4PLjMmVabke0iaYstFppUdtQiOEDbnnhX9MH3RRtqp2AoSnaRQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.3.0" + "@wordpress/i18n": "^5.5.0" }, "engines": { "node": ">=18.12.0", @@ -10002,13 +10002,13 @@ } }, "node_modules/@wordpress/deprecated": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-4.3.0.tgz", - "integrity": "sha512-K2GHXlwjx6GMhZjs52X1MXySCrqzh4IjoqF5IOcydMgWqOIE2++hMuB9Y55qN/Mhsrv/HO8Q1LaTxbEd6BuNJQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/deprecated/-/deprecated-4.5.0.tgz", + "integrity": "sha512-r3xGAM45XTd+z+hnUvLGtSz+Y0ebybuw/cyE0CatksJBGvXez3kiTDaknALkgzjHRZzIGpNu6XTVUoIJs0H39A==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/hooks": "^4.3.0" + "@wordpress/hooks": "^4.5.0" }, "engines": { "node": ">=18.12.0", @@ -10016,13 +10016,13 @@ } }, "node_modules/@wordpress/dom": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-4.3.0.tgz", - "integrity": "sha512-sf4h6jVqboRdhe3soyr5bt+Vpz24WG/AIMHm7pGaxfbV5jxx06ZZ8K1RKzhr7jF3wn7IgIc1wmMA+OFzEYqGyw==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom/-/dom-4.5.0.tgz", + "integrity": "sha512-XjnpRbbhZ1hdgv758vSXQacjfy/N0H2oI0oWukrLmlkKDP5ZrGfdziHQ2+KcoW+QDx8pu4JYcUpjmuJLugDStw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/deprecated": "^4.3.0" + "@wordpress/deprecated": "^4.5.0" }, "engines": { "node": ">=18.12.0", @@ -10323,15 +10323,15 @@ } }, "node_modules/@wordpress/element": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-6.3.0.tgz", - "integrity": "sha512-DsiqzjuXqxJkLUoLomsGTFFxbSZgk+Lz+2/1yFH+BU3jQ6zeD64+JWv8Lt4+fKU154rV0KpfMwfD/oAC/Lp1zQ==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-6.5.0.tgz", + "integrity": "sha512-N9w3jfceltdDEN71jpaMCXU+jbvec9kredvQIn/6YNiUMarPXWth7DJYU3+mDtbYawnTIvytzGjbj/J+bqqdHg==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", "@types/react": "^18.2.79", "@types/react-dom": "^18.2.25", - "@wordpress/escape-html": "^3.3.0", + "@wordpress/escape-html": "^3.5.0", "change-case": "^4.1.2", "is-plain-object": "^5.0.0", "react": "^18.3.0", @@ -10446,9 +10446,9 @@ } }, "node_modules/@wordpress/escape-html": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-3.3.0.tgz", - "integrity": "sha512-Wu/Fq96E28UGnIO5VQW/aEgCiHWvzrD8izDnP8U0WZSuwIPYcS5iYmRe2UWc7rwyoeY2YXNd6xFjgd7oTOKNCA==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-3.5.0.tgz", + "integrity": "sha512-8dUWTmsDZuqAmBtRgk0JpiIafRKPM4n8tqCr147AugTbP/vyQ7rIzG3M/YCtVSmDr6f/qZ32YU8J7c34RhZ/9g==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -10718,9 +10718,9 @@ } }, "node_modules/@wordpress/hooks": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-4.3.0.tgz", - "integrity": "sha512-bpqwSXGyxPfhuxESKoAtL4ofB3CazzvcwcucTZ0g9Pat3KNuBaloSrPBliqqNOiSLWNH3nmpkaRmv4u89EdKAw==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-4.5.0.tgz", + "integrity": "sha512-wr1l1WM1yobyNGFLRgbLNBGtYIkzAGfmbT2e9zIOvqllRJT4wprYTqqhgovOKHlET5ij/TKdv4tApkGLUIXTsA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -10744,13 +10744,13 @@ } }, "node_modules/@wordpress/i18n": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-5.3.0.tgz", - "integrity": "sha512-edHKkdZb6jNpbn+LUPu2wo1mKyhT819WJ7kI8hmMcHq82rNwwbMfcGoB3oSaphTphWfhlgxIxLczKOAbWDKudw==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-5.5.0.tgz", + "integrity": "sha512-MtCJIjNHCWs7R77f5Xml1CCnVXqrle4cDpqMU9myx4Cq8ZijqSayX1CTtwtk+Z3/3xa+dBZu5Koe4wiW1yIUSA==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/hooks": "^4.3.0", + "@wordpress/hooks": "^4.5.0", "gettext-parser": "^1.3.1", "memize": "^2.1.0", "sprintf-js": "^1.1.1", @@ -10838,9 +10838,9 @@ } }, "node_modules/@wordpress/is-shallow-equal": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-5.3.0.tgz", - "integrity": "sha512-sZ+fypqjYX0/DTAKsm1G9ND9Wn4d3Ju4lI7SLSmCKdUL5EPY3g/2LpKQKDqljh9m6Ex5NWp2XfU8UVXpkEfbMQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/is-shallow-equal/-/is-shallow-equal-5.5.0.tgz", + "integrity": "sha512-nkCz45HgMBkjhyxffDgpAgJbfnKyZML94/gHhBtxizHfaNuZ5as7DfEyN1xgebvDiLbOaRU7em1pPAuEhIoTfQ==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0" @@ -11142,9 +11142,9 @@ } }, "node_modules/@wordpress/priority-queue": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-3.3.0.tgz", - "integrity": "sha512-H7dGei1mFqKlz7NLFOGGtVgaBsORRaXeXNwWLI5rE0pI3XfGYd+zxNrG5aBzHw4fPqsITsxecNSaacc9fjqgjQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-3.5.0.tgz", + "integrity": "sha512-ilbG70ZuUJd0UTC7uyLP8zI/ZSN0d4ceG3qwlDx13yQAcjAcuw1Ei1CwzFBsbmI3OS1KkfkDpwZzKOrA+j/00Q==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", @@ -11967,13 +11967,13 @@ } }, "node_modules/@wordpress/undo-manager": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/undo-manager/-/undo-manager-1.3.0.tgz", - "integrity": "sha512-1XvU3GKpWeKFLCRx/3yEttRbIszD38vfH53XmCq2Y6IbWiyJLUGCnq4kiZjOaxA0o/DcAa4edscPyqmJj+wE+g==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/undo-manager/-/undo-manager-1.5.0.tgz", + "integrity": "sha512-ijvKwnXzKMV9xEcVB4mOIPih6BP5ZnZ1QYsv/EaPV7qlt2zgEevAHGa/FLQMW/lWlGCa5OhUK4tqDV+ZvrjTGw==", "dev": true, "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/is-shallow-equal": "^5.3.0" + "@wordpress/is-shallow-equal": "^5.5.0" }, "engines": { "node": ">=18.12.0", diff --git a/package.json b/package.json index dd4fd7a5a..de26d5279 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "@wordpress/block-editor": "^13.0.0", "@wordpress/blocks": "^13.3.0", "@wordpress/components": "^28.3.0", - "@wordpress/compose": "^7.0.0", + "@wordpress/compose": "^7.5.0", "@wordpress/core-data": "^7.3.0", "@wordpress/data": "^10.3.0", "@wordpress/e2e-test-utils": "^11.3.0", From 521e533a15216eeaf0e1f39e907b690faddd5858 Mon Sep 17 00:00:00 2001 From: Alex Cicovic <23142906+acicovic@users.noreply.github.com> Date: Mon, 19 Aug 2024 10:19:35 +0300 Subject: [PATCH 035/282] Fix type error --- .../components/parsely-recommendations-inspector-controls.tsx | 2 +- src/blocks/recommendations/models/RecommendationsAttributes.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/blocks/recommendations/components/parsely-recommendations-inspector-controls.tsx b/src/blocks/recommendations/components/parsely-recommendations-inspector-controls.tsx index 93df478ee..d1859191b 100644 --- a/src/blocks/recommendations/components/parsely-recommendations-inspector-controls.tsx +++ b/src/blocks/recommendations/components/parsely-recommendations-inspector-controls.tsx @@ -97,7 +97,7 @@ export const ParselyRecommendationsInspectorControls = ( { value: 'pub_date', }, ] } - onChange={ ( value: string ): void => setAttributes( { sort: value } ) } + onChange={ ( value ): void => setAttributes( { sort: value } ) } /> diff --git a/src/blocks/recommendations/models/RecommendationsAttributes.ts b/src/blocks/recommendations/models/RecommendationsAttributes.ts index 9abd8a934..9de5f8138 100644 --- a/src/blocks/recommendations/models/RecommendationsAttributes.ts +++ b/src/blocks/recommendations/models/RecommendationsAttributes.ts @@ -3,6 +3,6 @@ export interface RecommendationsAttributes { limit: number; openlinksinnewtab: boolean; showimages: boolean; - sort: string; + sort: 'score' | 'pub_date'; title: string; } From 8004895b60e8513bde495b0e1bab684eba30531a Mon Sep 17 00:00:00 2001 From: Alex Cicovic <23142906+acicovic@users.noreply.github.com> Date: Mon, 19 Aug 2024 10:45:12 +0300 Subject: [PATCH 036/282] sync package.json and package-lock --- package-lock.json | 485 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 485 insertions(+) diff --git a/package-lock.json b/package-lock.json index 29a4afafc..26575bef9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9704,6 +9704,402 @@ "react-dom": "^18.0.0" } }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.1.tgz", + "integrity": "sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-compose-refs": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz", + "integrity": "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-context": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.1.tgz", + "integrity": "sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-dialog": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.0.5.tgz", + "integrity": "sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.5", + "@radix-ui/react-focus-guards": "1.0.1", + "@radix-ui/react-focus-scope": "1.0.4", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-portal": "1.0.4", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-slot": "1.0.2", + "@radix-ui/react-use-controllable-state": "1.0.1", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.5" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.5.tgz", + "integrity": "sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1", + "@radix-ui/react-use-escape-keydown": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-focus-guards": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz", + "integrity": "sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-focus-scope": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.4.tgz", + "integrity": "sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-id": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.1.tgz", + "integrity": "sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-layout-effect": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-portal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.4.tgz", + "integrity": "sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-presence": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.1.tgz", + "integrity": "sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-primitive": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz", + "integrity": "sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-slot": "1.0.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-slot": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz", + "integrity": "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz", + "integrity": "sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.1.tgz", + "integrity": "sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz", + "integrity": "sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.1.tgz", + "integrity": "sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@wordpress/commands/node_modules/cmdk": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cmdk/-/cmdk-1.0.0.tgz", + "integrity": "sha512-gDzVf0a09TvoJ5jnuPvygTB77+XdOSwEmJ88L6XPFPlv7T3RxbP9jgenfylrAMD0+Le1aO0nVjQUzl2g+vjz5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@radix-ui/react-dialog": "1.0.5", + "@radix-ui/react-primitive": "1.0.3" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@wordpress/commands/node_modules/react-remove-scroll": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz", + "integrity": "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==", + "dev": true, + "license": "MIT", + "dependencies": { + "react-remove-scroll-bar": "^2.3.3", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@wordpress/components": { "version": "28.5.0", "resolved": "https://registry.npmjs.org/@wordpress/components/-/components-28.5.0.tgz", @@ -9937,6 +10333,95 @@ "react-dom": "^18.0.0" } }, + "node_modules/@wordpress/core-data/node_modules/@wordpress/block-editor": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-14.0.0.tgz", + "integrity": "sha512-IODsUPm37DpZxLMcJXidlHeUAvALX+E9edY+z9UGJWP/PvhLCXllCRVQABcuYkPTsraFSF0Yrk9i/7WJF2NkaA==", + "dev": true, + "license": "GPL-2.0-or-later", + "dependencies": { + "@babel/runtime": "^7.16.0", + "@emotion/react": "^11.7.1", + "@emotion/styled": "^11.6.0", + "@react-spring/web": "^9.4.5", + "@wordpress/a11y": "^4.5.0", + "@wordpress/api-fetch": "^7.5.0", + "@wordpress/blob": "^4.5.0", + "@wordpress/blocks": "^13.5.0", + "@wordpress/commands": "^1.5.0", + "@wordpress/components": "^28.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/date": "^5.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/dom": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/escape-html": "^3.5.0", + "@wordpress/hooks": "^4.5.0", + "@wordpress/html-entities": "^4.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/icons": "^10.5.0", + "@wordpress/is-shallow-equal": "^5.5.0", + "@wordpress/keyboard-shortcuts": "^5.5.0", + "@wordpress/keycodes": "^4.5.0", + "@wordpress/notices": "^5.5.0", + "@wordpress/preferences": "^4.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/rich-text": "^7.5.0", + "@wordpress/style-engine": "^2.5.0", + "@wordpress/token-list": "^3.5.0", + "@wordpress/url": "^4.5.0", + "@wordpress/warning": "^3.5.0", + "@wordpress/wordcount": "^4.5.0", + "change-case": "^4.1.2", + "clsx": "^2.1.1", + "colord": "^2.7.0", + "deepmerge": "^4.3.0", + "diff": "^4.0.2", + "fast-deep-equal": "^3.1.3", + "memize": "^2.1.0", + "postcss": "^8.4.21", + "postcss-prefixwrap": "^1.41.0", + "postcss-urlrebase": "^1.4.0", + "react-autosize-textarea": "^7.1.0", + "react-easy-crop": "^5.0.6", + "remove-accents": "^0.5.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@wordpress/core-data/node_modules/@wordpress/keycodes": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", + "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", + "dev": true, + "license": "GPL-2.0-or-later", + "dependencies": { + "@babel/runtime": "^7.16.0", + "@wordpress/i18n": "^5.5.0" + }, + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, + "node_modules/@wordpress/core-data/node_modules/@wordpress/warning": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.5.0.tgz", + "integrity": "sha512-cYM2Vqf2EokJJoWHD5Ry15OUmdsKtDgR8/qxE0sWHUAdSQeoTuJZnqhgYI898cZGxHaZWX2xJCxQa7Qtwl8lqw==", + "dev": true, + "license": "GPL-2.0-or-later", + "engines": { + "node": ">=18.12.0", + "npm": ">=8.19.2" + } + }, "node_modules/@wordpress/data": { "version": "10.5.0", "resolved": "https://registry.npmjs.org/@wordpress/data/-/data-10.5.0.tgz", From 822fc6d01daed63791119f70e9dd033fc4007a76 Mon Sep 17 00:00:00 2001 From: Alex Cicovic <23142906+acicovic@users.noreply.github.com> Date: Mon, 19 Aug 2024 18:45:56 +0300 Subject: [PATCH 037/282] bump @wordpress/edit-post from 8.3.0 to 8.5.0 --- package-lock.json | 586 ++++++++++------------------------------------ package.json | 2 +- 2 files changed, 129 insertions(+), 459 deletions(-) diff --git a/package-lock.json b/package-lock.json index 13a6f6c55..1a2845614 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,7 +35,7 @@ "@wordpress/core-data": "^7.5.0", "@wordpress/data": "^10.5.0", "@wordpress/e2e-test-utils": "^11.5.0", - "@wordpress/edit-post": "^8.3.0", + "@wordpress/edit-post": "^8.5.0", "@wordpress/editor": "^14.5.0", "@wordpress/element": "^6.5.0", "@wordpress/env": "^10.5.0", @@ -4159,6 +4159,7 @@ "resolved": "https://registry.npmjs.org/@preact/signals/-/signals-1.3.0.tgz", "integrity": "sha512-EOMeg42SlLS72dhoq6Vjq08havnLseWmPQ8A0YsgIAqMgWgx7V1a39+Pxo6i7SY5NwJtH4849JogFq3M67AzWg==", "dev": true, + "license": "MIT", "dependencies": { "@preact/signals-core": "^1.7.0" }, @@ -4171,10 +4172,11 @@ } }, "node_modules/@preact/signals-core": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@preact/signals-core/-/signals-core-1.7.0.tgz", - "integrity": "sha512-bEZLgmJGSBVP5PUPDowhPW3bVdMmp9Tr5OEl+SQK+8Tv9T7UsIfyN905cfkmmeqw8z4xp8T6zrl4M1uj9+HAfg==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@preact/signals-core/-/signals-core-1.8.0.tgz", + "integrity": "sha512-OBvUsRZqNmjzCZXWLxkZfhcgT+Fk8DDcT/8vD6a1xhDemodyy87UJRJfASMuSD8FaAIeGgGm85ydXhm7lr4fyA==", "dev": true, + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/preact" @@ -9534,45 +9536,46 @@ } }, "node_modules/@wordpress/block-library": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/block-library/-/block-library-9.3.0.tgz", - "integrity": "sha512-ffm47zghDA0Un8poGN5wmj3Cz+TotC0bxtCB3IsxdWzloMEzrOYoAokAMeZunuJ63hciqI+K/Oiwzu7M+uAy/A==", + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/block-library/-/block-library-9.5.0.tgz", + "integrity": "sha512-GjZtQzSDZQDg14dJdgEzj7Y2i4xdhVyr/avaIKmecdoKBLT0wuStf83H7XBxuR+ijf0DXPel6fGce5KUEJ4SiQ==", "dev": true, + "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/a11y": "^4.3.0", - "@wordpress/api-fetch": "^7.3.0", - "@wordpress/autop": "^4.3.0", - "@wordpress/blob": "^4.3.0", - "@wordpress/block-editor": "^13.3.0", - "@wordpress/blocks": "^13.3.0", - "@wordpress/components": "^28.3.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/core-data": "^7.3.0", - "@wordpress/data": "^10.3.0", - "@wordpress/date": "^5.3.0", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/dom": "^4.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/escape-html": "^3.3.0", - "@wordpress/hooks": "^4.3.0", - "@wordpress/html-entities": "^4.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/icons": "^10.3.0", - "@wordpress/interactivity": "^6.3.0", - "@wordpress/interactivity-router": "^2.3.0", - "@wordpress/keyboard-shortcuts": "^5.3.0", - "@wordpress/keycodes": "^4.3.0", - "@wordpress/notices": "^5.3.0", - "@wordpress/patterns": "^2.3.0", - "@wordpress/primitives": "^4.3.0", - "@wordpress/private-apis": "^1.3.0", - "@wordpress/reusable-blocks": "^5.3.0", - "@wordpress/rich-text": "^7.3.0", - "@wordpress/server-side-render": "^5.3.0", - "@wordpress/url": "^4.3.0", - "@wordpress/viewport": "^6.3.0", - "@wordpress/wordcount": "^4.3.0", + "@wordpress/a11y": "^4.5.0", + "@wordpress/api-fetch": "^7.5.0", + "@wordpress/autop": "^4.5.0", + "@wordpress/blob": "^4.5.0", + "@wordpress/block-editor": "^14.0.0", + "@wordpress/blocks": "^13.5.0", + "@wordpress/components": "^28.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/core-data": "^7.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/date": "^5.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/dom": "^4.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/escape-html": "^3.5.0", + "@wordpress/hooks": "^4.5.0", + "@wordpress/html-entities": "^4.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/icons": "^10.5.0", + "@wordpress/interactivity": "^6.5.0", + "@wordpress/interactivity-router": "^2.5.0", + "@wordpress/keyboard-shortcuts": "^5.5.0", + "@wordpress/keycodes": "^4.5.0", + "@wordpress/notices": "^5.5.0", + "@wordpress/patterns": "^2.5.0", + "@wordpress/primitives": "^4.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/reusable-blocks": "^5.5.0", + "@wordpress/rich-text": "^7.5.0", + "@wordpress/server-side-render": "^5.5.0", + "@wordpress/url": "^4.5.0", + "@wordpress/viewport": "^6.5.0", + "@wordpress/wordcount": "^4.5.0", "change-case": "^4.1.2", "clsx": "^2.1.1", "colord": "^2.7.0", @@ -9592,69 +9595,6 @@ "react-dom": "^18.0.0" } }, - "node_modules/@wordpress/block-library/node_modules/@wordpress/block-editor": { - "version": "13.4.0", - "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-13.4.0.tgz", - "integrity": "sha512-J2XwsngpxLaue8EROloT6KyRFjCk8JCl/K9UalEkrpYFFj084z7/px6LT6300Maue0ejkN8I3X4/XOe0tgOdbQ==", - "dev": true, - "license": "GPL-2.0-or-later", - "dependencies": { - "@babel/runtime": "^7.16.0", - "@emotion/react": "^11.7.1", - "@emotion/styled": "^11.6.0", - "@react-spring/web": "^9.4.5", - "@wordpress/a11y": "^4.4.0", - "@wordpress/api-fetch": "^7.4.0", - "@wordpress/blob": "^4.4.0", - "@wordpress/blocks": "^13.4.0", - "@wordpress/commands": "^1.4.0", - "@wordpress/components": "^28.4.0", - "@wordpress/compose": "^7.4.0", - "@wordpress/data": "^10.4.0", - "@wordpress/date": "^5.4.0", - "@wordpress/deprecated": "^4.4.0", - "@wordpress/dom": "^4.4.0", - "@wordpress/element": "^6.4.0", - "@wordpress/escape-html": "^3.4.0", - "@wordpress/hooks": "^4.4.0", - "@wordpress/html-entities": "^4.4.0", - "@wordpress/i18n": "^5.4.0", - "@wordpress/icons": "^10.4.0", - "@wordpress/is-shallow-equal": "^5.4.0", - "@wordpress/keyboard-shortcuts": "^5.4.0", - "@wordpress/keycodes": "^4.4.0", - "@wordpress/notices": "^5.4.0", - "@wordpress/preferences": "^4.4.0", - "@wordpress/private-apis": "^1.4.0", - "@wordpress/rich-text": "^7.4.0", - "@wordpress/style-engine": "^2.4.0", - "@wordpress/token-list": "^3.4.0", - "@wordpress/url": "^4.4.0", - "@wordpress/warning": "^3.4.0", - "@wordpress/wordcount": "^4.4.0", - "change-case": "^4.1.2", - "clsx": "^2.1.1", - "colord": "^2.7.0", - "deepmerge": "^4.3.0", - "diff": "^4.0.2", - "fast-deep-equal": "^3.1.3", - "memize": "^2.1.0", - "postcss": "^8.4.21", - "postcss-prefixwrap": "^1.41.0", - "postcss-urlrebase": "^1.4.0", - "react-autosize-textarea": "^7.1.0", - "react-easy-crop": "^5.0.6", - "remove-accents": "^0.5.0" - }, - "engines": { - "node": ">=18.12.0", - "npm": ">=8.19.2" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, "node_modules/@wordpress/block-library/node_modules/@wordpress/keycodes": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", @@ -9670,17 +9610,6 @@ "npm": ">=8.19.2" } }, - "node_modules/@wordpress/block-library/node_modules/@wordpress/warning": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.5.0.tgz", - "integrity": "sha512-cYM2Vqf2EokJJoWHD5Ry15OUmdsKtDgR8/qxE0sWHUAdSQeoTuJZnqhgYI898cZGxHaZWX2xJCxQa7Qtwl8lqw==", - "dev": true, - "license": "GPL-2.0-or-later", - "engines": { - "node": ">=18.12.0", - "npm": ">=8.19.2" - } - }, "node_modules/@wordpress/block-serialization-default-parser": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/@wordpress/block-serialization-default-parser/-/block-serialization-default-parser-5.5.0.tgz", @@ -10345,87 +10274,25 @@ } }, "node_modules/@wordpress/core-commands": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/core-commands/-/core-commands-1.3.0.tgz", - "integrity": "sha512-Tc9w07UgyFKT6fq0UUxsTmXmRGsULiV25YtAwqxF52XtYxfo+mPMDJgYpNA2l3eKL6EuWR6AzNl8f9pank55oA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.16.0", - "@wordpress/block-editor": "^13.3.0", - "@wordpress/commands": "^1.3.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/core-data": "^7.3.0", - "@wordpress/data": "^10.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/html-entities": "^4.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/icons": "^10.3.0", - "@wordpress/private-apis": "^1.3.0", - "@wordpress/router": "^1.3.0", - "@wordpress/url": "^4.3.0" - }, - "engines": { - "node": ">=18.12.0", - "npm": ">=8.19.2" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@wordpress/core-commands/node_modules/@wordpress/block-editor": { - "version": "13.4.0", - "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-13.4.0.tgz", - "integrity": "sha512-J2XwsngpxLaue8EROloT6KyRFjCk8JCl/K9UalEkrpYFFj084z7/px6LT6300Maue0ejkN8I3X4/XOe0tgOdbQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/core-commands/-/core-commands-1.5.0.tgz", + "integrity": "sha512-KS3LJzdfiGxrlUmYHpojThp/hKIbg2Eqb57AVFdx4CXepQuuicrtbfMzWKl5p4ziKN/oi42diLBlWDsBv99NNA==", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", - "@emotion/react": "^11.7.1", - "@emotion/styled": "^11.6.0", - "@react-spring/web": "^9.4.5", - "@wordpress/a11y": "^4.4.0", - "@wordpress/api-fetch": "^7.4.0", - "@wordpress/blob": "^4.4.0", - "@wordpress/blocks": "^13.4.0", - "@wordpress/commands": "^1.4.0", - "@wordpress/components": "^28.4.0", - "@wordpress/compose": "^7.4.0", - "@wordpress/data": "^10.4.0", - "@wordpress/date": "^5.4.0", - "@wordpress/deprecated": "^4.4.0", - "@wordpress/dom": "^4.4.0", - "@wordpress/element": "^6.4.0", - "@wordpress/escape-html": "^3.4.0", - "@wordpress/hooks": "^4.4.0", - "@wordpress/html-entities": "^4.4.0", - "@wordpress/i18n": "^5.4.0", - "@wordpress/icons": "^10.4.0", - "@wordpress/is-shallow-equal": "^5.4.0", - "@wordpress/keyboard-shortcuts": "^5.4.0", - "@wordpress/keycodes": "^4.4.0", - "@wordpress/notices": "^5.4.0", - "@wordpress/preferences": "^4.4.0", - "@wordpress/private-apis": "^1.4.0", - "@wordpress/rich-text": "^7.4.0", - "@wordpress/style-engine": "^2.4.0", - "@wordpress/token-list": "^3.4.0", - "@wordpress/url": "^4.4.0", - "@wordpress/warning": "^3.4.0", - "@wordpress/wordcount": "^4.4.0", - "change-case": "^4.1.2", - "clsx": "^2.1.1", - "colord": "^2.7.0", - "deepmerge": "^4.3.0", - "diff": "^4.0.2", - "fast-deep-equal": "^3.1.3", - "memize": "^2.1.0", - "postcss": "^8.4.21", - "postcss-prefixwrap": "^1.41.0", - "postcss-urlrebase": "^1.4.0", - "react-autosize-textarea": "^7.1.0", - "react-easy-crop": "^5.0.6", - "remove-accents": "^0.5.0" + "@wordpress/block-editor": "^14.0.0", + "@wordpress/commands": "^1.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/core-data": "^7.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/html-entities": "^4.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/icons": "^10.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/router": "^1.5.0", + "@wordpress/url": "^4.5.0" }, "engines": { "node": ">=18.12.0", @@ -10436,32 +10303,6 @@ "react-dom": "^18.0.0" } }, - "node_modules/@wordpress/core-commands/node_modules/@wordpress/keycodes": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", - "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", - "dev": true, - "license": "GPL-2.0-or-later", - "dependencies": { - "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.5.0" - }, - "engines": { - "node": ">=18.12.0", - "npm": ">=8.19.2" - } - }, - "node_modules/@wordpress/core-commands/node_modules/@wordpress/warning": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.5.0.tgz", - "integrity": "sha512-cYM2Vqf2EokJJoWHD5Ry15OUmdsKtDgR8/qxE0sWHUAdSQeoTuJZnqhgYI898cZGxHaZWX2xJCxQa7Qtwl8lqw==", - "dev": true, - "license": "GPL-2.0-or-later", - "engines": { - "node": ">=18.12.0", - "npm": ">=8.19.2" - } - }, "node_modules/@wordpress/core-data": { "version": "7.5.0", "resolved": "https://registry.npmjs.org/@wordpress/core-data/-/core-data-7.5.0.tgz", @@ -10814,106 +10655,44 @@ } }, "node_modules/@wordpress/edit-post": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/edit-post/-/edit-post-8.3.0.tgz", - "integrity": "sha512-wCmxUfa2NeE60O8fGWFEcp7SKXVdgBBxVlbUdiB8UWiDpC6k/o2Fvvwniwgk7gmYzPbB5OrKgbYb7W+VDS3QaQ==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.16.0", - "@wordpress/a11y": "^4.3.0", - "@wordpress/api-fetch": "^7.3.0", - "@wordpress/block-editor": "^13.3.0", - "@wordpress/block-library": "^9.3.0", - "@wordpress/blocks": "^13.3.0", - "@wordpress/commands": "^1.3.0", - "@wordpress/components": "^28.3.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/core-commands": "^1.3.0", - "@wordpress/core-data": "^7.3.0", - "@wordpress/data": "^10.3.0", - "@wordpress/deprecated": "^4.3.0", - "@wordpress/dom": "^4.3.0", - "@wordpress/editor": "^14.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/hooks": "^4.3.0", - "@wordpress/html-entities": "^4.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/icons": "^10.3.0", - "@wordpress/keyboard-shortcuts": "^5.3.0", - "@wordpress/keycodes": "^4.3.0", - "@wordpress/notices": "^5.3.0", - "@wordpress/plugins": "^7.3.0", - "@wordpress/preferences": "^4.3.0", - "@wordpress/private-apis": "^1.3.0", - "@wordpress/url": "^4.3.0", - "@wordpress/viewport": "^6.3.0", - "@wordpress/warning": "^3.3.0", - "@wordpress/widgets": "^4.3.0", - "clsx": "^2.1.1", - "memize": "^2.1.0" - }, - "engines": { - "node": ">=18.12.0", - "npm": ">=8.19.2" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@wordpress/edit-post/node_modules/@wordpress/block-editor": { - "version": "13.4.0", - "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-13.4.0.tgz", - "integrity": "sha512-J2XwsngpxLaue8EROloT6KyRFjCk8JCl/K9UalEkrpYFFj084z7/px6LT6300Maue0ejkN8I3X4/XOe0tgOdbQ==", + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/edit-post/-/edit-post-8.5.0.tgz", + "integrity": "sha512-u0LWFT5iTXz4U0bTUvSMIQP3+BjUN7Sf36XRDzmyKkTeQC8vz0Lw/I4A6CeTJFhjhLNPzahBW5TXUj1Y26XRGA==", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", - "@emotion/react": "^11.7.1", - "@emotion/styled": "^11.6.0", - "@react-spring/web": "^9.4.5", - "@wordpress/a11y": "^4.4.0", - "@wordpress/api-fetch": "^7.4.0", - "@wordpress/blob": "^4.4.0", - "@wordpress/blocks": "^13.4.0", - "@wordpress/commands": "^1.4.0", - "@wordpress/components": "^28.4.0", - "@wordpress/compose": "^7.4.0", - "@wordpress/data": "^10.4.0", - "@wordpress/date": "^5.4.0", - "@wordpress/deprecated": "^4.4.0", - "@wordpress/dom": "^4.4.0", - "@wordpress/element": "^6.4.0", - "@wordpress/escape-html": "^3.4.0", - "@wordpress/hooks": "^4.4.0", - "@wordpress/html-entities": "^4.4.0", - "@wordpress/i18n": "^5.4.0", - "@wordpress/icons": "^10.4.0", - "@wordpress/is-shallow-equal": "^5.4.0", - "@wordpress/keyboard-shortcuts": "^5.4.0", - "@wordpress/keycodes": "^4.4.0", - "@wordpress/notices": "^5.4.0", - "@wordpress/preferences": "^4.4.0", - "@wordpress/private-apis": "^1.4.0", - "@wordpress/rich-text": "^7.4.0", - "@wordpress/style-engine": "^2.4.0", - "@wordpress/token-list": "^3.4.0", - "@wordpress/url": "^4.4.0", - "@wordpress/warning": "^3.4.0", - "@wordpress/wordcount": "^4.4.0", - "change-case": "^4.1.2", + "@wordpress/a11y": "^4.5.0", + "@wordpress/api-fetch": "^7.5.0", + "@wordpress/block-editor": "^14.0.0", + "@wordpress/block-library": "^9.5.0", + "@wordpress/blocks": "^13.5.0", + "@wordpress/commands": "^1.5.0", + "@wordpress/components": "^28.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/core-commands": "^1.5.0", + "@wordpress/core-data": "^7.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/deprecated": "^4.5.0", + "@wordpress/dom": "^4.5.0", + "@wordpress/editor": "^14.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/hooks": "^4.5.0", + "@wordpress/html-entities": "^4.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/icons": "^10.5.0", + "@wordpress/keyboard-shortcuts": "^5.5.0", + "@wordpress/keycodes": "^4.5.0", + "@wordpress/notices": "^5.5.0", + "@wordpress/plugins": "^7.5.0", + "@wordpress/preferences": "^4.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/url": "^4.5.0", + "@wordpress/viewport": "^6.5.0", + "@wordpress/warning": "^3.5.0", + "@wordpress/widgets": "^4.5.0", "clsx": "^2.1.1", - "colord": "^2.7.0", - "deepmerge": "^4.3.0", - "diff": "^4.0.2", - "fast-deep-equal": "^3.1.3", - "memize": "^2.1.0", - "postcss": "^8.4.21", - "postcss-prefixwrap": "^1.41.0", - "postcss-urlrebase": "^1.4.0", - "react-autosize-textarea": "^7.1.0", - "react-easy-crop": "^5.0.6", - "remove-accents": "^0.5.0" + "memize": "^2.1.0" }, "engines": { "node": ">=18.12.0", @@ -11494,13 +11273,13 @@ } }, "node_modules/@wordpress/interactivity": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/interactivity/-/interactivity-6.3.0.tgz", - "integrity": "sha512-zlDsgMUAx6pPm04mEL98IhjNd82jisAeOO1jRejJfXFii+HJNC3GAbqTvoYVI0NhprvAOwYsn6ABrEERyPWt0w==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/interactivity/-/interactivity-6.5.0.tgz", + "integrity": "sha512-njxbzxBFfNDhiob0UKGTNvJAyKNEmHcZ9eN7Fb1Gl8jAFnMHWbG3D6dJt7Z/E8/W7aMOjRJn/OmNhhupNHkuMw==", "dev": true, + "license": "GPL-2.0-or-later", "dependencies": { "@preact/signals": "^1.2.2", - "deepsignal": "^1.4.0", "preact": "^10.19.3" }, "engines": { @@ -11509,12 +11288,13 @@ } }, "node_modules/@wordpress/interactivity-router": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/interactivity-router/-/interactivity-router-2.3.0.tgz", - "integrity": "sha512-YgRqGfOGfNdYEKS5pk4gb8LbsNKImPsb3T+b2UnonRvamhZZhosPAGyJrToXXWq5HKzgBpqgAnRiJ7dmR4eG4A==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/interactivity-router/-/interactivity-router-2.5.0.tgz", + "integrity": "sha512-8IukvNdtdHG3Dyzv9epfi6ZKg+Lv5W1a9wT6ueIRYHpmKY0Zvcsq/Oy0RnnsDFIBLNlsz6HTaVwNwPzOWwJEBA==", "dev": true, + "license": "GPL-2.0-or-later", "dependencies": { - "@wordpress/interactivity": "^6.3.0" + "@wordpress/interactivity": "^6.5.0" }, "engines": { "node": ">=18.12.0", @@ -11972,15 +11752,16 @@ } }, "node_modules/@wordpress/router": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/router/-/router-1.3.0.tgz", - "integrity": "sha512-NJGdPrxJWdP00Iv6sFBdNS5ZuPbC76gxpiS75BWYeEr9Wd2MxiF4yVpIZUFkHdit7Hr9Rhah7HOsqp4T4qdIPg==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/router/-/router-1.5.0.tgz", + "integrity": "sha512-ckCStZLGLP3HpEaquOJTup3E9KngFbBj98tjNjtj6lL+dZnC0dwG59FPfN3tGNksbE9kVCRArMqojIPXHfEIlg==", "dev": true, + "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", - "@wordpress/element": "^6.3.0", - "@wordpress/private-apis": "^1.3.0", - "@wordpress/url": "^4.3.0", + "@wordpress/element": "^6.5.0", + "@wordpress/private-apis": "^1.5.0", + "@wordpress/url": "^4.5.0", "history": "^5.3.0" }, "engines": { @@ -12741,87 +12522,25 @@ } }, "node_modules/@wordpress/widgets": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@wordpress/widgets/-/widgets-4.3.0.tgz", - "integrity": "sha512-x61x5m3mMeD4/KN9grfswiYbpp/SKKn0Q5ci8lI3bdGXuKIaUPqcon0D55F1n+58P4+FvlGLefFEuNOf/Ls2Ug==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.16.0", - "@wordpress/api-fetch": "^7.3.0", - "@wordpress/block-editor": "^13.3.0", - "@wordpress/blocks": "^13.3.0", - "@wordpress/components": "^28.3.0", - "@wordpress/compose": "^7.3.0", - "@wordpress/core-data": "^7.3.0", - "@wordpress/data": "^10.3.0", - "@wordpress/element": "^6.3.0", - "@wordpress/i18n": "^5.3.0", - "@wordpress/icons": "^10.3.0", - "@wordpress/notices": "^5.3.0", - "clsx": "^2.1.1" - }, - "engines": { - "node": ">=18.12.0", - "npm": ">=8.19.2" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@wordpress/widgets/node_modules/@wordpress/block-editor": { - "version": "13.4.0", - "resolved": "https://registry.npmjs.org/@wordpress/block-editor/-/block-editor-13.4.0.tgz", - "integrity": "sha512-J2XwsngpxLaue8EROloT6KyRFjCk8JCl/K9UalEkrpYFFj084z7/px6LT6300Maue0ejkN8I3X4/XOe0tgOdbQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/widgets/-/widgets-4.5.0.tgz", + "integrity": "sha512-8HLny/s1UEeeE25t07mQrrYan56L854Q8ZZPJ2P+8Rmb98J+yy/bvrTtFVm4MFFFFY7fCEoylltEPXPzITgEEQ==", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { "@babel/runtime": "^7.16.0", - "@emotion/react": "^11.7.1", - "@emotion/styled": "^11.6.0", - "@react-spring/web": "^9.4.5", - "@wordpress/a11y": "^4.4.0", - "@wordpress/api-fetch": "^7.4.0", - "@wordpress/blob": "^4.4.0", - "@wordpress/blocks": "^13.4.0", - "@wordpress/commands": "^1.4.0", - "@wordpress/components": "^28.4.0", - "@wordpress/compose": "^7.4.0", - "@wordpress/data": "^10.4.0", - "@wordpress/date": "^5.4.0", - "@wordpress/deprecated": "^4.4.0", - "@wordpress/dom": "^4.4.0", - "@wordpress/element": "^6.4.0", - "@wordpress/escape-html": "^3.4.0", - "@wordpress/hooks": "^4.4.0", - "@wordpress/html-entities": "^4.4.0", - "@wordpress/i18n": "^5.4.0", - "@wordpress/icons": "^10.4.0", - "@wordpress/is-shallow-equal": "^5.4.0", - "@wordpress/keyboard-shortcuts": "^5.4.0", - "@wordpress/keycodes": "^4.4.0", - "@wordpress/notices": "^5.4.0", - "@wordpress/preferences": "^4.4.0", - "@wordpress/private-apis": "^1.4.0", - "@wordpress/rich-text": "^7.4.0", - "@wordpress/style-engine": "^2.4.0", - "@wordpress/token-list": "^3.4.0", - "@wordpress/url": "^4.4.0", - "@wordpress/warning": "^3.4.0", - "@wordpress/wordcount": "^4.4.0", - "change-case": "^4.1.2", - "clsx": "^2.1.1", - "colord": "^2.7.0", - "deepmerge": "^4.3.0", - "diff": "^4.0.2", - "fast-deep-equal": "^3.1.3", - "memize": "^2.1.0", - "postcss": "^8.4.21", - "postcss-prefixwrap": "^1.41.0", - "postcss-urlrebase": "^1.4.0", - "react-autosize-textarea": "^7.1.0", - "react-easy-crop": "^5.0.6", - "remove-accents": "^0.5.0" + "@wordpress/api-fetch": "^7.5.0", + "@wordpress/block-editor": "^14.0.0", + "@wordpress/blocks": "^13.5.0", + "@wordpress/components": "^28.5.0", + "@wordpress/compose": "^7.5.0", + "@wordpress/core-data": "^7.5.0", + "@wordpress/data": "^10.5.0", + "@wordpress/element": "^6.5.0", + "@wordpress/i18n": "^5.5.0", + "@wordpress/icons": "^10.5.0", + "@wordpress/notices": "^5.5.0", + "clsx": "^2.1.1" }, "engines": { "node": ">=18.12.0", @@ -12832,32 +12551,6 @@ "react-dom": "^18.0.0" } }, - "node_modules/@wordpress/widgets/node_modules/@wordpress/keycodes": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", - "integrity": "sha512-5kCxbP+xqAr0pwftdvnM+oAqGa6r0IQoct9TyvqXE2hdE9Cnu5RlnVG30Ki7/3d1KoMRBh00nFoS2RzpWbOq+A==", - "dev": true, - "license": "GPL-2.0-or-later", - "dependencies": { - "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^5.5.0" - }, - "engines": { - "node": ">=18.12.0", - "npm": ">=8.19.2" - } - }, - "node_modules/@wordpress/widgets/node_modules/@wordpress/warning": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/@wordpress/warning/-/warning-3.5.0.tgz", - "integrity": "sha512-cYM2Vqf2EokJJoWHD5Ry15OUmdsKtDgR8/qxE0sWHUAdSQeoTuJZnqhgYI898cZGxHaZWX2xJCxQa7Qtwl8lqw==", - "dev": true, - "license": "GPL-2.0-or-later", - "engines": { - "node": ">=18.12.0", - "npm": ">=8.19.2" - } - }, "node_modules/@wordpress/wordcount": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/@wordpress/wordcount/-/wordcount-4.5.0.tgz", @@ -16167,32 +15860,6 @@ "node": ">=0.10.0" } }, - "node_modules/deepsignal": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/deepsignal/-/deepsignal-1.5.0.tgz", - "integrity": "sha512-bFywDpBUUWMs576H2dgLFLLFuQ/UWXbzHfKD98MZTfGsl7+twIzvz4ihCNrRrZ/Emz3kqJaNIAp5eBWUEWhnAw==", - "dev": true, - "peerDependencies": { - "@preact/signals": "^1.1.4", - "@preact/signals-core": "^1.5.1", - "@preact/signals-react": "^1.3.8 || ^2.0.0", - "preact": "^10.16.0" - }, - "peerDependenciesMeta": { - "@preact/signals": { - "optional": true - }, - "@preact/signals-core": { - "optional": true - }, - "@preact/signals-react": { - "optional": true - }, - "preact": { - "optional": true - } - } - }, "node_modules/default-gateway": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", @@ -18215,6 +17882,7 @@ "resolved": "https://registry.npmjs.org/fast-average-color/-/fast-average-color-9.4.0.tgz", "integrity": "sha512-bvM8vV6YwK07dPbzFz77zJaBcfF6ABVfgNwaxVgXc2G+o0e/tzLCF9WU8Ryp1r0Nkk6JuJNsWCzbb4cLOMlB+Q==", "dev": true, + "license": "MIT", "engines": { "node": ">= 12" } @@ -19399,6 +19067,7 @@ "resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz", "integrity": "sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/runtime": "^7.7.6" } @@ -27611,10 +27280,11 @@ "license": "MIT" }, "node_modules/preact": { - "version": "10.22.1", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.22.1.tgz", - "integrity": "sha512-jRYbDDgMpIb5LHq3hkI0bbl+l/TQ9UnkdQ0ww+lp+4MMOdqaUYdFc5qeyP+IV8FAd/2Em7drVPeKdQxsiWCf/A==", + "version": "10.23.2", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.23.2.tgz", + "integrity": "sha512-kKYfePf9rzKnxOAKDpsWhg/ysrHPqT+yQ7UW4JjdnqjFIeNUnNcEJvhuA8fDenxAGWzUqtd51DfVg7xp/8T9NA==", "dev": true, + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/preact" diff --git a/package.json b/package.json index ee5d872fa..b6042dba3 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "@wordpress/core-data": "^7.5.0", "@wordpress/data": "^10.5.0", "@wordpress/e2e-test-utils": "^11.5.0", - "@wordpress/edit-post": "^8.3.0", + "@wordpress/edit-post": "^8.5.0", "@wordpress/editor": "^14.5.0", "@wordpress/element": "^6.5.0", "@wordpress/env": "^10.5.0", From d47777d27a7123824358c68226acae7b62fbdfb3 Mon Sep 17 00:00:00 2001 From: Alex Cicovic <23142906+acicovic@users.noreply.github.com> Date: Thu, 22 Aug 2024 14:57:51 +0300 Subject: [PATCH 038/282] Add integration tests for the Permissions class --- tests/Integration/PermissionsTest.php | 369 ++++++++++++++++++++++++++ 1 file changed, 369 insertions(+) create mode 100644 tests/Integration/PermissionsTest.php diff --git a/tests/Integration/PermissionsTest.php b/tests/Integration/PermissionsTest.php new file mode 100644 index 000000000..2f24d8e53 --- /dev/null +++ b/tests/Integration/PermissionsTest.php @@ -0,0 +1,369 @@ + $default_edit_posts_caps_array + */ + private $default_edit_posts_caps_array = array( + 'administrator' => 'Administrator', + 'editor' => 'Editor', + 'author' => 'Author', + 'contributor' => 'Contributor', + ); + + /** + * The Content Helper features to be tested by this integration test. + * + * @since 3.17.0 + * @var array $features_to_test + */ + private $features_to_test = array( + 'excerpt_suggestions', + 'smart_linking', + 'title_suggestions', + ); + + /** + * Setup method called before each test. + * + * @since 3.17.0 + */ + public function set_up(): void { + parent::set_up(); + + $this->set_current_user_to_admin(); + } + + /** + * Verifies that get_user_roles_with_edit_posts_cap() returns the expected + * results. + * + * @since 3.17.0 + * + * @covers \Parsely\Permissions::get_user_roles_with_edit_posts_cap + */ + public function test_get_user_roles_with_edit_posts_capability(): void { + self::assertSame( + $this->default_edit_posts_caps_array, + Permissions::get_user_roles_with_edit_posts_cap() + ); + } + + /** + * Verifies that get_user_roles_with_edit_posts_cap() returns the expected + * results when a custom User Role exists. + * + * @since 3.17.0 + * + * @covers \Parsely\Permissions::get_user_roles_with_edit_posts_cap + */ + public function test_get_custom_user_roles_with_edit_posts_capability(): void { + global $wp_roles; + + // Test custom User Role with edit_posts capability. + $wp_roles->add_role( 'test_role', 'Test Role', array( 'edit_posts' => true ) ); + self::assertSame( + array_merge( + $this->default_edit_posts_caps_array, + array( 'test_role' => 'Test Role' ) + ), + Permissions::get_user_roles_with_edit_posts_cap() + ); + + // Test custom User Role without edit_posts capability. + $wp_roles->remove_cap( 'test_role', 'edit_posts' ); + self::assertSame( + $this->default_edit_posts_caps_array, + Permissions::get_user_roles_with_edit_posts_cap() + ); + + // Cleanup. + $wp_roles->remove_role( 'test_role' ); + } + + /** + * Verifies that permissions are correct when an allowed User Role tries to + * access enabled Content Helper features. + * + * @since 3.17.0 + * + * @covers \Parsely\Permissions::current_user_can_use_pch_feature + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + */ + public function test_allowed_user_role_attempts_to_access_enabled_pch_features(): void { + $user_allowed = Permissions::build_pch_permissions_settings_array( + true, + array( 'administrator' ) + ); + + foreach ( $this->features_to_test as $feature ) { + self::assertTrue( + Permissions::current_user_can_use_pch_feature( + $feature, + $user_allowed + ) + ); + + $this->assert_current_user_access_to_pch_feature_with_filter( + $feature, + $user_allowed + ); + + $this->assert_current_user_access_to_pch_feature_with_unset_options( + $feature, + $user_allowed + ); + } + } + + /** + * Verifies that permissions are correct when a disallowed User Role tries + * to access enabled Content Helper features. + * + * @since 3.17.0 + * + * @covers \Parsely\Permissions::current_user_can_use_pch_feature + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + */ + public function test_disallowed_user_role_attempts_to_access_enabled_pch_features(): void { + $user_disallowed = Permissions::build_pch_permissions_settings_array( + true, + array( 'editor' ) + ); + + foreach ( $this->features_to_test as $feature ) { + self::assertFalse( + Permissions::current_user_can_use_pch_feature( + $feature, + $user_disallowed + ) + ); + + $this->assert_current_user_access_to_pch_feature_with_filter( + $feature, + $user_disallowed + ); + + $this->assert_current_user_access_to_pch_feature_with_unset_options( + $feature, + $user_disallowed + ); + } + } + + /** + * Verifies that permissions are correct when an allowed User Role tries to + * access disabled Content Helper features. + * + * @since 3.17.0 + * + * @covers \Parsely\Permissions::current_user_can_use_pch_feature + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + */ + public function test_allowed_user_role_attempts_to_access_disabled_pch_features(): void { + $features_disabled = Permissions::build_pch_permissions_settings_array( + false, + array( 'administrator' ) + ); + + foreach ( $this->features_to_test as $feature ) { + self::assertFalse( + Permissions::current_user_can_use_pch_feature( + $feature, + $features_disabled + ) + ); + + $this->assert_current_user_access_to_pch_feature_with_filter( + $feature, + $features_disabled + ); + + $this->assert_current_user_access_to_pch_feature_with_unset_options( + $feature, + $features_disabled + ); + } + } + + /** + * Verifies that permissions are correct when a disallowed User Role tries + * to access disabled Content Helper features. + * + * @since 3.17.0 + * + * @covers \Parsely\Permissions::current_user_can_use_pch_feature + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + */ + public function test_disallowed_user_role_attempts_to_access_disabled_pch_features(): void { + $user_disallowed_features_disabled = Permissions::build_pch_permissions_settings_array( + false, + array( 'editor' ) + ); + + foreach ( $this->features_to_test as $feature ) { + self::assertFalse( + Permissions::current_user_can_use_pch_feature( + $feature, + $user_disallowed_features_disabled + ) + ); + + $this->assert_current_user_access_to_pch_feature_with_filter( + $feature, + $user_disallowed_features_disabled + ); + + $this->assert_current_user_access_to_pch_feature_with_unset_options( + $feature, + $user_disallowed_features_disabled + ); + } + } + + /** + * Asserts whether the current user can use a Content Helper feature, depending + * on the value of the wp_parsely_current_user_can_use_pch_feature filter. + * + * @since 3.17.0 + * + * @param string $feature The feature to check access for. + * @param Parsely_Options_Content_Helper $pch_options The passed options. + */ + public function assert_current_user_access_to_pch_feature_with_filter( + string $feature, + $pch_options + ): void { + // Filter set to true. + add_filter( 'wp_parsely_current_user_can_use_pch_feature', '__return_true' ); + self::assertTrue( + Permissions::current_user_can_use_pch_feature( + $feature, + $pch_options + ) + ); + remove_filter( 'wp_parsely_current_user_can_use_pch_feature', '__return_true' ); + + // Filter set to false. + add_filter( 'wp_parsely_current_user_can_use_pch_feature', '__return_false' ); + self::assertFalse( + Permissions::current_user_can_use_pch_feature( + $feature, + $pch_options + ) + ); + remove_filter( 'wp_parsely_current_user_can_use_pch_feature', '__return_false' ); + } + + /** + * Verifies that the result of current_user_can_use_pch_feature() is false, + * when an invalid feature name is passed. + * + * @since 3.17.0 + * + * @covers \Parsely\Permissions::current_user_can_use_pch_feature + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + */ + public function test_current_user_attempts_to_access_pch_feature_with_invalid_feature_name(): void { + $user_allowed = Permissions::build_pch_permissions_settings_array( + true, + array( 'administrator' ) + ); + + self::assertFalse( + Permissions::current_user_can_use_pch_feature( + 'invalid_feature', + $user_allowed + ) + ); + + // Filter set to true. + add_filter( 'wp_parsely_current_user_can_use_pch_feature', '__return_true' ); + self::assertFalse( + Permissions::current_user_can_use_pch_feature( + 'invalid_feature', + $user_allowed + ) + ); + remove_filter( 'wp_parsely_current_user_can_use_pch_feature', '__return_true' ); + + // Filter set to false. + add_filter( 'wp_parsely_current_user_can_use_pch_feature', '__return_false' ); + self::assertFalse( + Permissions::current_user_can_use_pch_feature( + 'invalid_feature', + $user_allowed + ) + ); + remove_filter( 'wp_parsely_current_user_can_use_pch_feature', '__return_false' ); + } + + /** + * Asserts the result of current_user_can_use_pch_feature(), when the + * options are unset. + * + * @since 3.17.0 + * + * @param string $feature The feature to check access for. + * @param Parsely_Options_Content_Helper $pch_options The passed options. + */ + public function assert_current_user_access_to_pch_feature_with_unset_options( + string $feature, + $pch_options + ): void { + unset( $pch_options[ $feature ] ); + + self::assertFalse( + Permissions::current_user_can_use_pch_feature( + $feature, + $pch_options // @phpstan-ignore-line + ) + ); + + // Filter set to true. + add_filter( 'wp_parsely_current_user_can_use_pch_feature', '__return_true' ); + self::assertFalse( + Permissions::current_user_can_use_pch_feature( + $feature, + $pch_options // @phpstan-ignore-line + ) + ); + remove_filter( 'wp_parsely_current_user_can_use_pch_feature', '__return_true' ); + + // Filter set to false. + add_filter( 'wp_parsely_current_user_can_use_pch_feature', '__return_false' ); + self::assertFalse( + Permissions::current_user_can_use_pch_feature( + $feature, + $pch_options // @phpstan-ignore-line + ) + ); + remove_filter( 'wp_parsely_current_user_can_use_pch_feature', '__return_false' ); + } +} From d56cfac389f958a2a8cf21bee86c94838f2c1bba Mon Sep 17 00:00:00 2001 From: Alex Cicovic <23142906+acicovic@users.noreply.github.com> Date: Thu, 22 Aug 2024 15:06:31 +0300 Subject: [PATCH 039/282] Settings_Page: Remove duplicate phpstan-import-type declaration --- src/UI/class-settings-page.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/UI/class-settings-page.php b/src/UI/class-settings-page.php index 0a0c4ab53..3e5563bc0 100644 --- a/src/UI/class-settings-page.php +++ b/src/UI/class-settings-page.php @@ -23,8 +23,6 @@ * * @since 3.0.0 * - * @phpstan-import-type Parsely_Options from Parsely - * * @phpstan-type Setting_Arguments array{ * add_fieldset?: bool, * legend?: string, From 9e074ae22a07a4037f3fdb303ef6b4dbe12947ec Mon Sep 17 00:00:00 2001 From: Henrique Mouta Date: Thu, 22 Aug 2024 14:23:59 +0100 Subject: [PATCH 040/282] Add new Rest API base classes --- src/rest-api/class-base-api-controller.php | 149 ++++++++++ src/rest-api/class-base-endpoint.php | 305 +++++++++++++++++++++ src/rest-api/class-rest-api-controller.php | 68 +++++ 3 files changed, 522 insertions(+) create mode 100644 src/rest-api/class-base-api-controller.php create mode 100644 src/rest-api/class-base-endpoint.php create mode 100644 src/rest-api/class-rest-api-controller.php diff --git a/src/rest-api/class-base-api-controller.php b/src/rest-api/class-base-api-controller.php new file mode 100644 index 000000000..8e6693ea5 --- /dev/null +++ b/src/rest-api/class-base-api-controller.php @@ -0,0 +1,149 @@ +parsely = $parsely; + $this->endpoints = array(); + + if ( static::NAMESPACE === false ) { + throw new \UnexpectedValueException( 'The API controller must define a namespace.' ); + } + } + + /** + * Initialize the API controller. + * + * This method should be overridden by child classes and used to register + * endpoints. + * + * @return void + */ + abstract protected function init(): void; + + /** + * Register a single endpoint. + * + * @since 3.17.0 + * + * @param Base_Endpoint $endpoint The endpoint to register. + */ + protected function register_endpoint( Base_Endpoint $endpoint ): void { + $this->endpoints[] = $endpoint; + $endpoint->init(); + } + + /** + * Register multiple endpoints. + * + * @since 3.17.0 + * + * @param Base_Endpoint[] $endpoints The endpoints to register. + */ + protected function register_endpoints( array $endpoints ): void { + foreach ( $endpoints as $endpoint ) { + $this->register_endpoint( $endpoint ); + } + } + + /** + * Returns the namespace for the API. + * + * If a version is defined, it will be appended to the namespace. + * + * @since 3.17.0 + * @return string + */ + public function get_namespace(): string { + $namespace = static::NAMESPACE; + + if ( false === $namespace ) { + return ''; + } + + if ( '' !== static::VERSION ) { + $namespace .= '/' . static::VERSION; + } + + return $namespace; + } + + /** + * Prefix a route with the route prefix. + * + * @since 3.17.0 + * + * @param string $route The route to prefix. + * @return string The prefixed route. + */ + public function prefix_route( string $route ): string { + if ( '' === static::ROUTE_PREFIX ) { + return $route; + } + + return static::ROUTE_PREFIX . '/' . $route; + } +} diff --git a/src/rest-api/class-base-endpoint.php b/src/rest-api/class-base-endpoint.php new file mode 100644 index 000000000..e5cacc96f --- /dev/null +++ b/src/rest-api/class-base-endpoint.php @@ -0,0 +1,305 @@ + + */ + protected $registered_routes = array(); + + /** + * Constructor. + * + * @since 3.17.0 + * + * @param Base_API_Controller $controller The REST API controller. + */ + public function __construct( Base_API_Controller $controller ) { + $this->api_controller = $controller; + $this->parsely = $controller->parsely; + } + + /** + * Initialize the API endpoint, by registering the routes. + * + * Allows for the endpoint to be disabled via the + * `wp_parsely_api_{endpoint}_endpoint_enabled` filter. + * + * @since 3.17.0 + * + * @throws UnexpectedValueException If the ENDPOINT constant is not defined. + */ + public function init(): void { + if ( false === static::ENDPOINT ) { + throw new UnexpectedValueException( 'ENDPOINT constant must be defined in child class.' ); + } + + /** + * Filter to enable/disable the endpoint. + * + * @return bool + */ + $filter_name = 'wp_parsely_api_' . + Utils::convert_endpoint_to_filter_key( static::ENDPOINT ) . + '_endpoint_enabled'; + if ( ! apply_filters( $filter_name, true ) ) { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound + return; + } + + // Register the routes. + add_action( 'rest_api_init', array( $this, 'register_routes' ) ); + } + + /** + * Registers the routes for the endpoint. + * + * This method should be overridden by child classes and used to register + * the routes for the endpoint. + * + * @since 3.17.0 + */ + abstract public function register_routes(): void; + + /** + * Registers a REST route. + * + * @param string $route The route to register. + * @param string[] $methods Array with the allowed methods. + * @param callable $callback Callback function to call when the endpoint is hit. + * @param array $args The endpoint arguments definition. + * + * @return void + * @since 3.17.0 + */ + public function register_rest_route( string $route, array $methods, callable $callback, array $args = array() ): void { + // Trim any possible slashes from the route + // . + $route = trim( $route, '/' ); + // Store the route for later reference. + $this->registered_routes[] = $route; + + // Create the full route for the endpoint. + $route = $this->get_endpoint() . '/' . $route; + + // Register the route. + register_rest_route( + $this->api_controller->get_namespace(), + $this->api_controller->prefix_route( $route ), + array( + array( + 'methods' => $methods, + 'callback' => $callback, + 'permission_callback' => array( $this, 'is_available_to_current_user' ), + 'args' => $args, + 'show_in_index' => ! is_wp_error( $this->is_available_to_current_user() ), + ), + ) + ); + } + + /** + * Returns the endpoint name. + * + * @since 3.17.0 + * + * @return string + */ + public function get_endpoint(): string { + if ( false === static::ENDPOINT ) { + return ''; + } + return static::ENDPOINT; + } + + + /** + * Returns the full endpoint path for a given route. + * + * @since 3.17.0 + * + * @param string $route The route. + * @return string + */ + public function get_full_endpoint( string $route = '' ): string { + $route = $this->get_endpoint() . '/' . $route; + + return '/' . + $this->api_controller->get_namespace() . + '/' . + $this->api_controller->prefix_route( $route ); + } + + /** + * Returns the registered routes. + * + * @since 3.17.0 + * + * @return array + */ + public function get_registered_routes(): array { + return $this->registered_routes; + } + + /** + * Returns whether the endpoint is available for access by the current + * user. + * + * @since 3.14.0 Replaced `is_public_endpoint`, `user_capability` and `permission_callback()`. + * @since 3.16.0 Added the `$request` parameter. + * @since 3.17.0 Moved to the new API structure. + * + * @param WP_REST_Request|null $request The request object. + * @return WP_Error|bool True if the endpoint is available. + */ + public function is_available_to_current_user( ?WP_REST_Request $request = null ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found + + // Validate the API key and secret. + $api_key_validation = $this->validate_apikey_and_secret(); + if ( is_wp_error( $api_key_validation ) ) { + return $api_key_validation; + } + + // Validate the user capability. + $capability = static::DEFAULT_ACCESS_CAPABILITY; + return current_user_can( + // phpcs:ignore WordPress.WP.Capabilities.Undetermined + $this->apply_capability_filters( $capability ) + ); + } + + /** + * Returns the user capability allowing access to the endpoint, after having + * applied capability filters. + * + * `DEFAULT_ACCESS_CAPABILITY` is not passed here by default, to allow for + * a more explicit declaration in child classes. + * + * @since 3.14.0 + * @since 3.17.0 Moved to the new API structure. + * + * @param string $capability The original capability allowing access. + * @return string The capability allowing access after applying the filters. + * @throws UnexpectedValueException If the ENDPOINT constant is not defined. + */ + public function apply_capability_filters( string $capability ): string { + /** + * Filter to change the default user capability for all private endpoints. + * + * @var string + */ + $default_user_capability = apply_filters( + 'wp_parsely_user_capability_for_all_private_apis', + $capability + ); + + if ( false === static::ENDPOINT ) { + throw new UnexpectedValueException( 'ENDPOINT constant must be defined in child class.' ); + } + + /** + * Filter to change the user capability for the specific endpoint. + * + * @var string + */ + $endpoint_specific_user_capability = apply_filters( + 'wp_parsely_user_capability_for_' . + Utils::convert_endpoint_to_filter_key( static::ENDPOINT ) . + '_api', + $default_user_capability + ); + + return $endpoint_specific_user_capability; + } + + /** + * Validates that the Site ID and secret are set. + * If the API secret is not required, it will not be validated. + * + * @since 3.13.0 + * + * @param bool $require_api_secret Specifies if the API Secret is required. + * @return WP_Error|bool + */ + public function validate_apikey_and_secret( bool $require_api_secret = true ) { + if ( false === $this->parsely->site_id_is_set() ) { + return new WP_Error( + 'parsely_site_id_not_set', + __( 'A Parse.ly Site ID must be set in site options to use this endpoint', 'wp-parsely' ), + array( 'status' => 403 ) + ); + } + + if ( $require_api_secret && false === $this->parsely->api_secret_is_set() ) { + return new WP_Error( + 'parsely_api_secret_not_set', + __( 'A Parse.ly API Secret must be set in site options to use this endpoint', 'wp-parsely' ), + array( 'status' => 403 ) + ); + } + + return true; + } +} diff --git a/src/rest-api/class-rest-api-controller.php b/src/rest-api/class-rest-api-controller.php new file mode 100644 index 000000000..b47850f42 --- /dev/null +++ b/src/rest-api/class-rest-api-controller.php @@ -0,0 +1,68 @@ +parsely ), + ); + + // Initialize the controllers. + foreach ( $controllers as $controller ) { + $controller->init(); + } + + $this->controllers = $controllers; + } +} From 6ad9d44df95871395dc140a513ca5d25ccc5c78c Mon Sep 17 00:00:00 2001 From: Henrique Mouta Date: Thu, 22 Aug 2024 14:24:58 +0100 Subject: [PATCH 041/282] Implement the Content Helper API namespace --- src/Models/class-smart-link.php | 4 +- .../class-content-helper-controller.php | 47 ++ .../class-endpoint-excerpt-generator.php | 162 ++++ .../class-endpoint-smart-linking.php | 713 ++++++++++++++++++ .../class-endpoint-title-suggestions.php | 160 ++++ .../trait-content-helper-feature.php | 69 ++ wp-parsely.php | 6 + 7 files changed, 1160 insertions(+), 1 deletion(-) create mode 100644 src/rest-api/content-helper/class-content-helper-controller.php create mode 100644 src/rest-api/content-helper/class-endpoint-excerpt-generator.php create mode 100644 src/rest-api/content-helper/class-endpoint-smart-linking.php create mode 100644 src/rest-api/content-helper/class-endpoint-title-suggestions.php create mode 100644 src/rest-api/content-helper/trait-content-helper-feature.php diff --git a/src/Models/class-smart-link.php b/src/Models/class-smart-link.php index 009998a63..469a00bee 100644 --- a/src/Models/class-smart-link.php +++ b/src/Models/class-smart-link.php @@ -127,7 +127,9 @@ public function __construct( int $offset, int $post_id = 0 ) { - $this->set_href( $href ); + if ( '' !== $href ) { + $this->set_href( $href ); + } // Set the title to be the destination post title if the destination post ID is set. if ( 0 !== $this->destination_post_id ) { diff --git a/src/rest-api/content-helper/class-content-helper-controller.php b/src/rest-api/content-helper/class-content-helper-controller.php new file mode 100644 index 000000000..5e58f9a0e --- /dev/null +++ b/src/rest-api/content-helper/class-content-helper-controller.php @@ -0,0 +1,47 @@ +register_endpoints( $endpoints ); + } +} diff --git a/src/rest-api/content-helper/class-endpoint-excerpt-generator.php b/src/rest-api/content-helper/class-endpoint-excerpt-generator.php new file mode 100644 index 000000000..f2fbaeb2a --- /dev/null +++ b/src/rest-api/content-helper/class-endpoint-excerpt-generator.php @@ -0,0 +1,162 @@ +suggest_brief_api = new Suggest_Brief_API( $this->parsely ); + } + + /** + * Returns the name of the feature associated with the current endpoint. + * + * @since 3.17.0 + * + * @return string The feature name. + */ + public function get_pch_feature_name(): string { + return 'excerpt_suggestions'; + } + + /** + * Registers the routes for the endpoint. + * + * This method should be overridden by child classes and used to register + * the routes for the endpoint. + * + * @since 3.17.0 + */ + public function register_routes(): void { + /** + * POST /excerpt-generator/generate + * Generates an excerpt for the given content. + */ + $this->register_rest_route( + 'generate', + array( 'POST' ), + array( $this, 'generate_excerpt' ), + array( + 'content' => array( + 'description' => __( 'The text to generate the excerpt from.', 'wp-parsely' ), + 'type' => 'string', + 'required' => true, + ), + 'title' => array( + 'description' => __( 'The title of the content.', 'wp-parsely' ), + 'type' => 'string', + 'required' => true, + ), + 'persona' => array( + 'description' => __( 'The persona of the content.', 'wp-parsely' ), + 'type' => 'string', + 'required' => false, + 'default' => 'journalist', + ), + 'style' => array( + 'description' => __( 'The style of the content.', 'wp-parsely' ), + 'type' => 'string', + 'required' => false, + 'default' => 'neutral', + ), + ) + ); + } + + /** + * API Endpoint: POST /excerpt-generator/generate + * + * Generates an excerpt for the passed content. + * + * @since 3.17.0 + * + * @param WP_REST_Request $request The request object. + * @return WP_REST_Response|WP_Error The response object. + */ + public function generate_excerpt( WP_REST_Request $request ) { + /** + * The post content to be sent to the API. + * + * @var string $post_content + */ + $post_content = $request->get_param( 'content' ); + + /** + * The post title to be sent to the API. + * + * @var string $post_title + */ + $post_title = $request->get_param( 'title' ); + + /** + * The persona to be sent to the API. + * + * @var string $persona + */ + $persona = $request->get_param( 'persona' ); + + /** + * The style to be sent to the API. + * + * @var string $style + */ + $style = $request->get_param( 'style' ); + + $response = $this->suggest_brief_api->get_suggestion( $post_title, $post_content, $persona, $style ); + + if ( is_wp_error( $response ) ) { + return $response; + } + + return new WP_REST_Response( array( 'data' => $response ), 200 ); + } +} diff --git a/src/rest-api/content-helper/class-endpoint-smart-linking.php b/src/rest-api/content-helper/class-endpoint-smart-linking.php new file mode 100644 index 000000000..902bc8d47 --- /dev/null +++ b/src/rest-api/content-helper/class-endpoint-smart-linking.php @@ -0,0 +1,713 @@ +suggest_linked_reference_api = new Suggest_Linked_Reference_API( $this->parsely ); + } + + /** + * Returns the name of the feature associated with the current endpoint. + * + * @since 3.17.0 + * + * @return string The feature name. + */ + public function get_pch_feature_name(): string { + return 'smart_linking'; + } + + /** + * Registers the routes for the endpoint. + * + * @since 3.17.0 + */ + public function register_routes(): void { + /** + * GET /smart-linking/generate + * Generates smart links for a post. + */ + $this->register_rest_route( + 'generate', + array( 'POST' ), + array( $this, 'generate_smart_links' ), + array( + 'content' => array( + 'required' => true, + 'type' => 'string', + 'description' => __( 'The text to generate smart links for.', 'wp-parsely' ), + ), + 'max_links' => array( + 'type' => 'integer', + 'description' => __( 'The maximum number of smart links to generate.', 'wp-parsely' ), + 'default' => 10, + ), + 'url_exclusion_list' => array( + 'type' => 'array', + 'description' => __( 'The list of URLs to exclude from the smart links.', 'wp-parsely' ), + 'validate_callback' => array( $this, 'validate_url_exclusion_list' ), + ), + ) + ); + + + /** + * GET /smart-linking/{post_id}/get + * Gets the smart links for a post. + */ + $this->register_rest_route( + '(?P\d+)/get', + array( 'GET' ), + array( $this, 'get_smart_links' ), + array( + 'post_id' => array( + 'required' => true, + 'description' => __( 'The post ID.', 'wp-parsely' ), + 'validate_callback' => array( $this, 'validate_post_id' ), + ), + ) + ); + + /** + * POST /smart-linking/{post_id}/add + * Adds a smart link to a post. + */ + $this->register_rest_route( + '(?P\d+)/add', + array( 'POST' ), + array( $this, 'add_smart_link' ), + array( + 'post_id' => array( + 'required' => true, + 'description' => __( 'The post ID.', 'wp-parsely' ), + 'validate_callback' => array( $this, 'validate_post_id' ), + ), + 'link' => array( + 'required' => true, + 'type' => 'object', + 'description' => __( 'The smart link data to add.', 'wp-parsely' ), + 'validate_callback' => array( $this, 'validate_smart_link_params' ), + ), + 'update' => array( + 'type' => 'boolean', + 'description' => __( 'Whether to update the existing smart link.', 'wp-parsely' ), + 'default' => false, + ), + ) + ); + + /** + * POST /smart-linking/{post_id}/add-multiple + * Adds multiple smart links to a post. + */ + $this->register_rest_route( + '(?P\d+)/add-multiple', + array( 'POST' ), + array( $this, 'add_multiple_smart_links' ), + array( + 'post_id' => array( + 'required' => true, + 'description' => __( 'The post ID.', 'wp-parsely' ), + 'validate_callback' => array( $this, 'validate_post_id' ), + ), + 'links' => array( + 'required' => true, + 'type' => 'array', + 'description' => __( 'The multiple smart links data to add.', 'wp-parsely' ), + 'validate_callback' => array( $this, 'validate_multiple_smart_links' ), + ), + 'update' => array( + 'type' => 'boolean', + 'description' => __( 'Whether to update the existing smart links.', 'wp-parsely' ), + 'default' => false, + ), + ) + ); + + /** + * POST /smart-linking/{post_id}/set + * Updates the smart links of a given post and removes the ones that are not in the request. + */ + $this->register_rest_route( + '(?P\d+)/set', + array( 'POST' ), + array( $this, 'set_smart_links' ), + array( + 'post_id' => array( + 'required' => true, + 'description' => __( 'The post ID.', 'wp-parsely' ), + 'validate_callback' => array( $this, 'validate_post_id' ), + ), + 'links' => array( + 'required' => true, + 'type' => 'array', + 'description' => __( 'The smart links data to set.', 'wp-parsely' ), + 'validate_callback' => array( $this, 'validate_multiple_smart_links' ), + ), + ) + ); + + /** + * POST /smart-linking/url-to-post-type + * Converts a URL to a post type. + */ + $this->register_rest_route( + 'url-to-post-type', + array( 'POST' ), + array( $this, 'url_to_post_type' ) + ); + } + + /** + * API Endpoint: GET /smart-linking/generate. + * + * Generates smart links for a post. + * + * @since 3.16.0 + * + * @param WP_REST_Request $request The request object. + * @return WP_REST_Response|WP_Error The response object. + */ + public function generate_smart_links( WP_REST_Request $request ) { + /** + * The text to generate smart links for. + * + * @var string $post_content + */ + $post_content = $request->get_param( 'content' ); + + /** + * The maximum number of smart links to generate. + * + * @var int $max_links + */ + $max_links = $request->get_param( 'max_links' ); + + /** + * The URL exclusion list. + * + * @var array $url_exclusion_list + */ + $url_exclusion_list = $request->get_param( 'url_exclusion_list' ) ?? array(); + + $response = $this->suggest_linked_reference_api->get_links( + $post_content, + 4, // TODO: will be removed after API refactoring. + $max_links, + $url_exclusion_list + ); + + if ( is_wp_error( $response ) ) { + return $response; + } + + $smart_links = array_map( + function ( Smart_Link $link ) { + return $link->to_array(); + }, + $response + ); + + return new WP_REST_Response( array( 'data' => $smart_links ), 200 ); + } + + /** + * API Endpoint: GET /smart-linking/{post_id}/get. + * + * Gets the smart links for a post. + * + * @since 3.16.0 + * + * @param WP_REST_Request $request The request object. + * @return WP_REST_Response The response object. + */ + public function get_smart_links( WP_REST_Request $request ): WP_REST_Response { + /** + * The post object. + * + * @var WP_Post $post + */ + $post = $request->get_param( 'post' ); + + $outbound_links = Smart_Link::get_outbound_smart_links( $post->ID ); + $inbound_links = Smart_Link::get_inbound_smart_links( $post->ID ); + + $response = array( + 'outbound' => $this->serialize_smart_links( $outbound_links ), + 'inbound' => $this->serialize_smart_links( $inbound_links ), + ); + + return new WP_REST_Response( array( 'data' => $response ), 200 ); + } + + + /** + * API Endpoint: POST /smart-linking/{post_id}/add. + * + * Adds a smart link to a post. + * If the update parameter is set to true, the existing smart link will be updated. + * + * @since 3.16.0 + * + * @param WP_REST_Request $request The request object. + * @return WP_REST_Response The response object. + */ + public function add_smart_link( WP_REST_Request $request ): WP_REST_Response { + /** + * The Smart Link model. + * + * @var Smart_Link $smart_link + */ + $smart_link = $request->get_param( 'smart_link' ); + $should_update = $request->get_param( 'update' ) === true; + + if ( $smart_link->exists() && ! $should_update ) { + return new WP_REST_Response( + array( + 'error' => array( + 'name' => 'smart_link_exists', + 'message' => __( 'Smart link already exists.', 'wp-parsely' ), + ), + ), + 409 // HTTP Conflict. + ); + } + + // The smart link properties are set in the validate callback. + $saved = $smart_link->save(); + if ( ! $saved ) { + return new WP_REST_Response( + array( + 'error' => array( + 'name' => 'add_smart_link_failed', + 'message' => __( 'Failed to add the smart link.', 'wp-parsely' ), + ), + ), + 500 + ); + } + + return new WP_REST_Response( + array( + 'data' => json_decode( $smart_link->serialize() ), + ), + 200 + ); + } + + /** + * API Endpoint: POST /smart-linking/{post_id}/add_multiple. + * + * Adds multiple smart links to a post. + * + * @since 3.16.0 + * + * @param WP_REST_Request $request The request object. + * @return WP_REST_Response The response object. + */ + public function add_multiple_smart_links( WP_REST_Request $request ): WP_REST_Response { + /** + * Array of Smart Link models. + * + * @var Smart_Link[] $smart_links + */ + $smart_links = $request->get_param( 'smart_links' ); + $should_update = $request->get_param( 'update' ) === true; + + $added_links = array(); + $updated_links = array(); + $failed_links = array(); + + foreach ( $smart_links as $smart_link ) { + if ( $smart_link->exists() && ! $should_update ) { + $failed_links[] = $smart_link; + continue; + } + + $updated_link = $smart_link->exists() && $should_update; + + // The smart link properties are set in the validate callback. + $saved = $smart_link->save(); + + if ( ! $saved ) { + $failed_links[] = $smart_link; + continue; + } + + if ( $updated_link ) { + $updated_links[] = $smart_link; + } else { + $added_links[] = $smart_link; + } + } + + // If no link was added, return an error response. + if ( count( $added_links ) === 0 && count( $updated_links ) === 0 ) { + return new WP_REST_Response( + array( + 'error' => array( + 'name' => 'add_smart_link_failed', + 'message' => __( 'Failed to add all the smart links.', 'wp-parsely' ), + ), + ), + 500 + ); + } + + $response = array(); + if ( count( $added_links ) > 0 ) { + $response['added'] = $this->serialize_smart_links( $added_links ); + } + if ( count( $failed_links ) > 0 ) { + $response['failed'] = $this->serialize_smart_links( $failed_links ); + } + if ( count( $updated_links ) > 0 ) { + $response['updated'] = $this->serialize_smart_links( $updated_links ); + } + + return new WP_REST_Response( array( 'data' => $response ), 200 ); + } + + /** + * API Endpoint: POST /smart-linking/{post_id}/set. + * + * Updates the smart links of a given post and removes the ones that are not in the request. + * + * @since 3.16.0 + * + * @param WP_REST_Request $request The request object. + * @return WP_REST_Response The response object. + */ + public function set_smart_links( WP_REST_Request $request ): WP_REST_Response { + /** + * The post object. + * + * @var WP_Post $post + */ + $post = $request->get_param( 'post' ); + + /** + * Array of Smart Link models provided in the request. + * + * @var Smart_Link[] $smart_links + */ + $smart_links = $request->get_param( 'smart_links' ); + + // Get the current stored smart links. + $existing_links = Smart_Link::get_outbound_smart_links( $post->ID ); + $removed_links = array(); + + foreach ( $existing_links as $existing_link ) { + $found = false; + foreach ( $smart_links as $smart_link ) { + if ( $smart_link->get_uid() === $existing_link->get_uid() ) { + $found = true; + break; + } + } + + if ( ! $found ) { + $removed_links[] = $existing_link; + $existing_link->delete(); + } + } + + $saved_links = array(); + $failed_links = array(); + + foreach ( $smart_links as $smart_link ) { + // The smart link properties are set in the validate callback. + $saved = $smart_link->save(); + + if ( ! $saved ) { + $failed_links[] = $smart_link; + continue; + } + + $saved_links[] = $smart_link; + } + + $response = array( + 'saved' => $this->serialize_smart_links( $saved_links ), + 'removed' => $this->serialize_smart_links( $removed_links ), + ); + + if ( count( $failed_links ) > 0 ) { + $response['failed'] = $this->serialize_smart_links( $failed_links ); + } + + return new WP_REST_Response( array( 'data' => $response ), 200 ); + } + + + /** + * API Endpoint: POST /smart-linking/url-to-post-type. + * + * Converts a URL to a post type. + * + * @since 3.16.0 + * + * @param WP_REST_Request $request The request object. + * @return WP_REST_Response The response object. + */ + public function url_to_post_type( WP_REST_Request $request ): WP_REST_Response { + $url = $request->get_param( 'url' ); + + if ( ! is_string( $url ) ) { + return new WP_REST_Response( + array( + 'error' => array( + 'name' => 'invalid_request', + 'message' => __( 'Invalid request body.', 'wp-parsely' ), + ), + ), + 400 + ); + } + + $post_id = 0; + $cache = wp_cache_get( $url, 'wp_parsely_smart_link_url_to_postid' ); + + if ( is_integer( $cache ) ) { + $post_id = $cache; + } elseif ( function_exists( 'wpcom_vip_url_to_postid' ) ) { + $post_id = wpcom_vip_url_to_postid( $url ); + } else { + // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.url_to_postid_url_to_postid + $post_id = url_to_postid( $url ); + wp_cache_set( $url, $post_id, 'wp_parsely_smart_link_url_to_postid' ); + } + + $response = array( + 'data' => array( + 'post_id' => false, + 'post_type' => false, + ), + ); + + if ( 0 !== $post_id ) { + $response['data']['post_id'] = $post_id; + $response['data']['post_type'] = get_post_type( $post_id ); + } + + return new WP_REST_Response( $response, 200 ); + } + + /** + * Validates the post ID parameter. + * + * The callback sets the post object in the request object if the parameter is valid. + * + * @since 3.16.0 + * @access private + * + * @param string $param The parameter value. + * @param WP_REST_Request $request The request object. + * @return bool Whether the parameter is valid. + */ + public function validate_post_id( string $param, WP_REST_Request $request ): bool { + if ( ! is_numeric( $param ) ) { + return false; + } + + $param = filter_var( $param, FILTER_VALIDATE_INT ); + + if ( false === $param ) { + return false; + } + + // Validate if the post ID exists. + $post = get_post( $param ); + // Set the post attribute in the request. + $request->set_param( 'post', $post ); + + return null !== $post; + } + + /** + * Validates the URL exclusion list parameter. + * + * The callback sets the URL exclusion list in the request object if the parameter is valid. + * + * @since 3.16.0 + * @access private + * + * @param mixed $param The parameter value. + * @param WP_REST_Request $request The request object. + * @return true|WP_Error Whether the parameter is valid. + */ + public function validate_url_exclusion_list( $param, WP_REST_Request $request ) { + if ( ! is_array( $param ) ) { + return new WP_Error( 'invalid_url_exclusion_list', __( 'The URL exclusion list must be an array.', 'wp-parsely' ) ); + } + + $valid_urls = array_filter( + $param, + function ( $url ) { + return is_string( $url ) && false !== filter_var( $url, FILTER_VALIDATE_URL ); + } + ); + + $request->set_param( 'url_exclusion_list', $valid_urls ); + + return true; + } + + /** + * Validates the smart link parameters. + * + * The callback sets the smart link object in the request object if the parameters are valid. + * + * @since 3.16.0 + * @access private + * + * @param array $params The parameters. + * @param WP_REST_Request $request The request object. + * @return bool Whether the parameters are valid. + */ + public function validate_smart_link_params( array $params, WP_REST_Request $request ): bool { + $required_params = array( 'uid', 'href', 'title', 'text', 'offset' ); + + foreach ( $required_params as $param ) { + if ( ! isset( $params[ $param ] ) ) { + return false; + } + } + + $encoded_data = wp_json_encode( $params ); + if ( false === $encoded_data ) { + return false; + } + + $post_id = $request->get_param( 'post_id' ); + if ( ! is_numeric( $post_id ) ) { + return false; + } + + if ( ! is_string( $params['uid'] ) ) { + return false; + } + + // Try to get the smart link from the UID. + $smart_link = Smart_Link::get_smart_link( $params['uid'], intval( $post_id ) ); + if ( $smart_link->exists() ) { + // Update the smart link with the new data. + $smart_link->set_href( $params['href'] ); + $smart_link->title = $params['title']; + $smart_link->text = $params['text']; + $smart_link->offset = $params['offset']; + } else { + /** + * The Smart Link model. + * + * @var Smart_Link $smart_link + */ + $smart_link = Smart_Link::deserialize( $encoded_data ); + $smart_link->set_source_post_id( intval( $post_id ) ); + } + + // Set the smart link attribute in the request. + $request->set_param( 'smart_link', $smart_link ); + + return true; + } + + /** + * Validates the multiple smart link parameters. + * + * The callback sets the smart links object in the request object if the parameters are valid. + * + * @since 3.16.0 + * @access private + * + * @param array> $param The parameter value. + * @param WP_REST_Request $request The request object. + * @return bool Whether the parameter is valid. + */ + public function validate_multiple_smart_links( array $param, WP_REST_Request $request ): bool { + $smart_links = array(); + + foreach ( $param as $link ) { + if ( $this->validate_smart_link_params( $link, $request ) ) { + $smart_link = $request->get_param( 'smart_link' ); + $smart_links[] = $smart_link; + } else { + return false; + } + } + $request->set_param( 'smart_link', null ); + $request->set_param( 'smart_links', $smart_links ); + + return true; + } + + /** + * Serializes an array of Smart Links. + * + * @since 3.16.0 + * + * @param Smart_Link[] $links The Smart Links to serialize. + * @return array The serialized Smart Links. + */ + private function serialize_smart_links( array $links ): array { + return array_map( + function ( Smart_Link $link ) { + return json_decode( $link->serialize(), true ); + }, + $links + ); + } +} diff --git a/src/rest-api/content-helper/class-endpoint-title-suggestions.php b/src/rest-api/content-helper/class-endpoint-title-suggestions.php new file mode 100644 index 000000000..1f05f4411 --- /dev/null +++ b/src/rest-api/content-helper/class-endpoint-title-suggestions.php @@ -0,0 +1,160 @@ +suggest_headline_api = new Suggest_Headline_API( $this->parsely ); + } + + /** + * Returns the name of the feature associated with the current endpoint. + * + * @since 3.17.0 + * + * @return string + */ + public function get_pch_feature_name(): string { + return 'title_suggestions'; + } + + /** + * Registers the routes for the endpoint. + * + * This method should be overridden by child classes and used to register + * the routes for the endpoint. + * + * @since 3.17.0 + */ + public function register_routes(): void { + /** + * POST /title-suggestions/generate + * Generates titles for the given content. + */ + $this->register_rest_route( + 'generate', + array( 'POST' ), + array( $this, 'generate_titles' ), + array( + 'content' => array( + 'description' => __( 'The content for which to generate titles.', 'wp-parsely' ), + 'required' => true, + 'type' => 'string', + ), + 'limit' => array( + 'description' => __( 'The maximum number of titles to generate.', 'wp-parsely' ), + 'required' => false, + 'type' => 'integer', + 'default' => 3, + ), + 'style' => array( + 'description' => __( 'The style of the titles to generate.', 'wp-parsely' ), + 'required' => false, + 'type' => 'string', + 'default' => 'neutral', + ), + 'persona' => array( + 'description' => __( 'The persona of the titles to generate.', 'wp-parsely' ), + 'required' => false, + 'type' => 'string', + 'default' => 'journalist', + ), + ) + ); + } + + /** + * API Endpoint: POST /title-suggestions/generate + * + * Generates titles for the given content. + * + * @since 3.17.0 + * + * @param WP_REST_Request $request The request object. + * @return WP_REST_Response|\WP_Error The response object or a WP_Error object on failure. + */ + public function generate_titles( WP_REST_Request $request ) { + /** + * The post content to be sent to the API. + * + * @var string $post_content + */ + $post_content = $request->get_param( 'content' ); + + /** + * The maximum number of titles to generate. + * + * @var int $limit + */ + $limit = $request->get_param( 'limit' ); + + /** + * The style of the titles to generate. + * + * @var string $style + */ + $style = $request->get_param( 'style' ); + + /** + * The tone of the titles to generate. + * + * @var string $persona + */ + $persona = $request->get_param( 'persona' ); + + if ( 0 === $limit ) { + $limit = 3; + } + + $response = $this->suggest_headline_api->get_titles( $post_content, $limit, $persona, $style ); + + if ( is_wp_error( $response ) ) { + return $response; + } + + return new WP_REST_Response( array( 'data' => $response ), 200 ); + } +} diff --git a/src/rest-api/content-helper/trait-content-helper-feature.php b/src/rest-api/content-helper/trait-content-helper-feature.php new file mode 100644 index 000000000..b30338365 --- /dev/null +++ b/src/rest-api/content-helper/trait-content-helper-feature.php @@ -0,0 +1,69 @@ +get_pch_feature_name(), + $this->parsely->get_options()['content_helper'] + ); + } + + /** + * Checks if the endpoint is available to the current user. + * + * Overrides the method in the Base_Endpoint class to check if the + * current user has permission to use the feature. + * + * @param WP_REST_Request|null $request The request object. + * + * @return bool|WP_Error True if the endpoint is available. + * @since 3.17.0 + */ + public function is_available_to_current_user( WP_REST_Request $request = null ) { + $can_use_feature = $this->is_pch_feature_enabled_for_user(); + + if ( ! $can_use_feature ) { + return new WP_Error( 'ch_access_to_feature_disabled', '', array( 'status' => 403 ) ); + } + + return parent::is_available_to_current_user( $request ); + } +} diff --git a/wp-parsely.php b/wp-parsely.php index ab26ee73c..bff6aad66 100644 --- a/wp-parsely.php +++ b/wp-parsely.php @@ -54,6 +54,7 @@ use Parsely\RemoteAPI\Related_API; use Parsely\RemoteAPI\Remote_API_Cache; use Parsely\RemoteAPI\WordPress_Cache; +use Parsely\REST_API\REST_API_Controller; use Parsely\UI\Admin_Bar; use Parsely\UI\Admin_Warning; use Parsely\UI\Metadata_Renderer; @@ -124,6 +125,11 @@ function parsely_wp_admin_early_register(): void { $network_admin_sites_list = new Network_Admin_Sites_List( $GLOBALS['parsely'] ); $network_admin_sites_list->run(); + + // START OF PARSE.LY REST API REFACTOR (TODO: make the rest of the plugin use this). + $rest_api_controller = new REST_API_Controller( $GLOBALS['parsely'] ); + $rest_api_controller->init(); + // END OF PARSE.LY REST API REFACTOR. } add_action( 'rest_api_init', __NAMESPACE__ . '\\parsely_rest_api_init' ); From 73302360fcd30bad3ee4bfd37555232ebb6a92c2 Mon Sep 17 00:00:00 2001 From: Henrique Mouta Date: Thu, 22 Aug 2024 14:25:40 +0100 Subject: [PATCH 042/282] Add tests for the new REST API classes --- .../ContentHelperDashboardWidgetTest.php | 2 +- .../ContentHelperFeatureTest.php | 2 +- .../ContentHelperPostListStatsTest.php | 2 +- .../RestAPI/BaseAPIControllerTest.php | 182 +++++++ .../Integration/RestAPI/BaseEndpointTest.php | 483 ++++++++++++++++++ .../ContentHelperControllerTest.php | 99 ++++ .../ContentHelperFeatureTestTrait.php | 293 +++++++++++ .../EndpointExcerptGeneratorTest.php | 193 +++++++ .../EndpointSmartLinkingTest.php | 420 +++++++++++++++ .../EndpointTitleSuggestionsTest.php | 194 +++++++ .../RestAPI/RestAPIControllerTest.php | 58 +++ tests/Integration/ScriptsTest.php | 10 +- tests/Integration/TestCase.php | 12 +- 13 files changed, 1936 insertions(+), 14 deletions(-) create mode 100644 tests/Integration/RestAPI/BaseAPIControllerTest.php create mode 100644 tests/Integration/RestAPI/BaseEndpointTest.php create mode 100644 tests/Integration/RestAPI/ContentHelper/ContentHelperControllerTest.php create mode 100644 tests/Integration/RestAPI/ContentHelper/ContentHelperFeatureTestTrait.php create mode 100644 tests/Integration/RestAPI/ContentHelper/EndpointExcerptGeneratorTest.php create mode 100644 tests/Integration/RestAPI/ContentHelper/EndpointSmartLinkingTest.php create mode 100644 tests/Integration/RestAPI/ContentHelper/EndpointTitleSuggestionsTest.php create mode 100644 tests/Integration/RestAPI/RestAPIControllerTest.php diff --git a/tests/Integration/ContentHelper/ContentHelperDashboardWidgetTest.php b/tests/Integration/ContentHelper/ContentHelperDashboardWidgetTest.php index cfb9f5d8e..fb63354cc 100644 --- a/tests/Integration/ContentHelper/ContentHelperDashboardWidgetTest.php +++ b/tests/Integration/ContentHelper/ContentHelperDashboardWidgetTest.php @@ -45,7 +45,7 @@ protected function assert_enqueued_status( array $additional_args = array() ): void { $feature = new Dashboard_Widget( $GLOBALS['parsely'] ); - $this->set_current_user_to( $user_login, $user_role ); + self::set_current_user_to( $user_login, $user_role ); parent::set_filters( $feature::get_feature_filter_name(), diff --git a/tests/Integration/ContentHelper/ContentHelperFeatureTest.php b/tests/Integration/ContentHelper/ContentHelperFeatureTest.php index 977a968ba..da6dd0e31 100644 --- a/tests/Integration/ContentHelper/ContentHelperFeatureTest.php +++ b/tests/Integration/ContentHelper/ContentHelperFeatureTest.php @@ -61,7 +61,7 @@ protected function assert_enqueued_status_default( string $user_login, string $user_role ): void { - $this->set_current_user_to( $user_login, $user_role ); + self::set_current_user_to( $user_login, $user_role ); self::set_filters( $feature::get_feature_filter_name(), diff --git a/tests/Integration/ContentHelper/ContentHelperPostListStatsTest.php b/tests/Integration/ContentHelper/ContentHelperPostListStatsTest.php index 7ea57fc8c..9b817413e 100644 --- a/tests/Integration/ContentHelper/ContentHelperPostListStatsTest.php +++ b/tests/Integration/ContentHelper/ContentHelperPostListStatsTest.php @@ -85,7 +85,7 @@ protected function assert_enqueued_status( string $user_role, array $additional_args = array() ): void { - $this->set_current_user_to( $user_login, $user_role ); + self::set_current_user_to( $user_login, $user_role ); parent::set_filters( Post_List_Stats::get_feature_filter_name(), diff --git a/tests/Integration/RestAPI/BaseAPIControllerTest.php b/tests/Integration/RestAPI/BaseAPIControllerTest.php new file mode 100644 index 000000000..cc9835bce --- /dev/null +++ b/tests/Integration/RestAPI/BaseAPIControllerTest.php @@ -0,0 +1,182 @@ +test_controller = new class($parsely) extends Base_API_Controller { + public const NAMESPACE = 'test'; + public const VERSION = 'v1'; + + /** + * Initialize the test controller. + * + * @since 3.17.0 + */ + protected function init(): void {} + + /** + * Expose the protected method for testing. + * + * @param Base_Endpoint[] $endpoints The endpoints to register. + */ + public function testable_register_endpoints( array $endpoints ): void { + $this->register_endpoints( $endpoints ); + } + + /** + * Expose the protected method for testing. + * + * @param Base_Endpoint $endpoint The endpoint to register. + */ + public function testable_register_endpoint( Base_Endpoint $endpoint ): void { + $this->register_endpoint( $endpoint ); + } + }; + } + + /** + * Test that the constructor throws an exception if the NAMESPACE is not defined. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Base_API_Controller::__construct + */ + public function test_constructor_throws_exception_without_namespace(): void { + self::expectException( \UnexpectedValueException::class ); + self::expectExceptionMessage( 'The API controller must define a namespace.' ); + + $parsely = self::createMock( Parsely::class ); + + // Use an anonymous class to avoid implementing abstract methods. + new class($parsely) extends Base_API_Controller { + /** + * Initialize the test controller. + * + * @since 3.17.0 + */ + protected function init(): void {} + }; + } + + /** + * Test the get_namespace method. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Base_API_Controller::get_namespace + * @uses \Parsely\REST_API\Base_API_Controller::__construct + */ + public function test_get_namespace(): void { + self::assertEquals( 'test/v1', $this->test_controller->get_namespace() ); + } + + /** + * Test the prefix_route method. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_API_Controller::__construct + */ + public function test_prefix_route(): void { + self::assertEquals( 'my-route', $this->test_controller->prefix_route( 'my-route' ) ); + $parsely = self::createMock( Parsely::class ); + + $controller_with_prefix = new class($parsely) extends Base_API_Controller { + public const NAMESPACE = 'test'; + public const ROUTE_PREFIX = 'prefix'; + + /** + * Initialize the test controller. + * + * @since 3.17.0 + */ + protected function init(): void {} + }; + + self::assertEquals( 'prefix/my-route', $controller_with_prefix->prefix_route( 'my-route' ) ); + } + + /** + * Test that endpoints are registered correctly. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Base_API_Controller::register_endpoint + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::register_endpoint + */ + public function test_register_endpoint(): void { + $parsely = self::createMock( Parsely::class ); + $endpoint = self::createMock( Base_Endpoint::class ); + $endpoint->expects( self::once() )->method( 'init' ); + + $this->test_controller->testable_register_endpoint( $endpoint ); // @phpstan-ignore-line + + self::assertCount( 1, $this->test_controller->endpoints ); + self::assertSame( $endpoint, $this->test_controller->endpoints[0] ); + } + + /** + * Test that multiple endpoints are registered correctly using a helper method. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Base_API_Controller::register_endpoints + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::register_endpoint + * @uses \Parsely\REST_API\Base_API_Controller::register_endpoints + */ + public function test_register_multiple_endpoints(): void { + $endpoint1 = self::createMock( Base_Endpoint::class ); + $endpoint1->expects( self::once() )->method( 'init' ); + + $endpoint2 = self::createMock( Base_Endpoint::class ); + $endpoint2->expects( self::once() )->method( 'init' ); + + $this->test_controller->testable_register_endpoints( array( $endpoint1, $endpoint2 ) ); // @phpstan-ignore-line + + self::assertCount( 2, $this->test_controller->endpoints ); + self::assertSame( $endpoint1, $this->test_controller->endpoints[0] ); + self::assertSame( $endpoint2, $this->test_controller->endpoints[1] ); + } +} diff --git a/tests/Integration/RestAPI/BaseEndpointTest.php b/tests/Integration/RestAPI/BaseEndpointTest.php new file mode 100644 index 000000000..e9b1e6f85 --- /dev/null +++ b/tests/Integration/RestAPI/BaseEndpointTest.php @@ -0,0 +1,483 @@ +parsely ) { + $this->parsely = new Parsely(); + } + + // Create API controller, if not already created (by an inherited class). + if ( null === $this->api_controller ) { + $this->api_controller = new REST_API_Controller( $this->parsely ); + } + + parent::__construct(); + } + + /** + * Set up the test environment. + * + * @since 3.17.0 + */ + public function set_up(): void { + parent::set_up(); + TestCase::set_options(); + $this->set_current_user_to_admin(); + + $this->wp_rest_server_global_backup = $GLOBALS['wp_rest_server'] ?? null; + + // Create a concrete class for testing purposes. + $this->test_endpoint = new class($this->api_controller) extends Base_Endpoint { + protected const ENDPOINT = 'test-endpoint'; + + /** + * Register the test route. + * + * @since 3.17.0 + */ + public function register_routes(): void { + $this->register_rest_route( + '/test-route', + array( 'GET' ), + array( $this, 'get_test_data' ) + ); + } + + /** + * Get test data. + * + * @since 3.17.0 + * + * @param WP_REST_Request $request The request object. + * @return array + */ + public function get_test_data( WP_REST_Request $request ): array { + return array( 'data' => 'test' ); + } + }; + + $this->initialize_rest_endpoint(); + } + + /** + * Tear down the test environment. + * + * @since 3.17.0 + */ + public function tear_down(): void { + remove_action( 'plugins_loaded', $this->rest_api_init_proxy ); + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound + $GLOBALS['wp_rest_server'] = $this->wp_rest_server_global_backup; + + parent::tear_down(); + } + + /** + * Return the test endpoint instance. + * + * @since 3.17.0 + * + * @return Base_Endpoint + */ + public function get_endpoint(): Base_Endpoint { + return $this->test_endpoint; + } + + /** + * Test the init method throws an exception if ENDPOINT is not defined. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests + * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::set_managed_options + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_init_throws_exception_without_endpoint(): void { + self::expectException( UnexpectedValueException::class ); + self::expectExceptionMessage( 'ENDPOINT constant must be defined in child class.' ); + + // Create an endpoint with no ENDPOINT constant defined. + $endpoint_without_endpoint = new class($this->api_controller) extends Base_Endpoint { + /** + * Register the routes. + * + * @since 3.17.0 + */ + public function register_routes(): void { + // Mock method for testing. + } + }; + + $endpoint_without_endpoint->init(); + } + + /** + * Test that the route is correctly registered in WordPress. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Base_Endpoint::init + * @covers \Parsely\REST_API\Base_Endpoint::register_routes + * @covers \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_namespace + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::set_managed_options + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + */ + public function test_route_is_registered(): void { + $routes = rest_get_server()->get_routes(); + + // Check that the namespace route is registered. + $expected_namespace = '/' . $this->api_controller->get_namespace(); + self::assertArrayHasKey( $expected_namespace, $routes ); + + // Check that the test route is registered. + $expected_route = $this->get_endpoint()->get_full_endpoint( 'test-route' ); + self::assertArrayHasKey( $expected_route, $routes ); + + // Check that the route is associated with the correct method. + $route_data = $routes[ $expected_route ]; + self::assertArrayHasKey( 'GET', $route_data[0]['methods'] ); + } + + /** + * Test that the route is correctly registered in WordPress, depending on the filter. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Base_Endpoint::init + * @covers \Parsely\REST_API\Base_Endpoint::register_routes + * @covers \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @covers \Parsely\REST_API\Base_Endpoint::get_registered_routes + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::set_managed_options + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::current_user_can_use_pch_feature + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_namespace + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::get_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_endpoint_is_registered_based_on_filter(): void { + $filter_name = 'wp_parsely_api_' . + \Parsely\Utils\Utils::convert_endpoint_to_filter_key( $this->get_endpoint()->get_endpoint() ) . + '_endpoint_enabled'; + + // Test when the filter allows the endpoint to be enabled. + add_filter( $filter_name, '__return_true' ); + $this->get_endpoint()->init(); + $routes = rest_get_server()->get_routes(); + $registered_routes = $this->get_endpoint()->get_registered_routes(); + + // Assert that the routes are registered when the filter returns true. + foreach ( $registered_routes as $route ) { + self::assertArrayHasKey( $this->get_endpoint()->get_full_endpoint( $route ), $routes ); + } + + // Reset the environment. + $this->tear_down(); + + // Now test when the filter disables the endpoint. + remove_all_filters( $filter_name ); + add_filter( $filter_name, '__return_false' ); + $this->get_endpoint()->init(); + $routes = rest_get_server()->get_routes(); + $registered_routes = $this->get_endpoint()->get_registered_routes(); + + // Assert that the route is NOT registered when the filter returns false. + foreach ( $registered_routes as $route ) { + self::assertArrayNotHasKey( $this->get_endpoint()->get_full_endpoint( $route ), $routes ); + } + } + + /** + * Test is_available_to_current_user returns WP_Error if API key or secret is not set. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @covers \Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests + * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::set_managed_options + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Permissions::current_user_can_use_pch_feature + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_is_available_to_current_user_returns_error_site_id_not_set(): void { + TestCase::set_options( + array( + 'apikey' => '', + 'api_secret' => '', + ) + ); + + $result = $this->get_endpoint()->is_available_to_current_user(); + + self::assertInstanceOf( WP_Error::class, $result ); + self::assertEquals( 'parsely_site_id_not_set', $result->get_error_code() ); + } + + /** + * Test is_available_to_current_user returns WP_Error if API key or secret is not set. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @covers \Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::set_managed_options + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Permissions::current_user_can_use_pch_feature + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_is_available_to_current_user_returns_error_api_secret_not_set(): void { + TestCase::set_options( + array( + 'apikey' => 'test-apikey', + 'api_secret' => '', + ) + ); + + $result = $this->get_endpoint()->is_available_to_current_user(); + + self::assertInstanceOf( WP_Error::class, $result ); + self::assertEquals( 'parsely_api_secret_not_set', $result->get_error_code() ); + } + + /** + * Test apply_capability_filters method. + * + * @covers \Parsely\REST_API\Base_Endpoint::apply_capability_filters + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests + * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::set_managed_options + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::init + */ + public function test_apply_capability_filters(): void { + add_filter( + 'wp_parsely_user_capability_for_all_private_apis', + function () { + return 'edit_posts'; + } + ); + + $result = $this->get_endpoint()->apply_capability_filters( 'publish_posts' ); + self::assertEquals( 'edit_posts', $result ); + } + + /** + * Test validate_apikey_and_secret returns true when API key and secret are set. + * + * @covers \Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::set_managed_options + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_validate_api_key_and_secret_returns_true(): void { + TestCase::set_options( + array( + 'apikey' => 'test-apikey', + 'api_secret' => 'test-secret', + ) + ); + + $result = $this->get_endpoint()->validate_apikey_and_secret(); + + self::assertTrue( $result ); + } + + /** + * Sets the value of a protected or private property on a given object using reflection. + * + * This method is useful for testing purposes where you need to modify or inject dependencies + * into protected or private properties of a class. + * + * @since 3.17.0 + * + * @param object $obj The object instance on which the property should be set. + * @param string $property_name The name of the property to be set. + * @param mixed $value The value to set on the property. + * + * @throws ReflectionException If the property does not exist. + */ + protected function set_protected_property( $obj, string $property_name, $value ): void { + $reflection = new \ReflectionClass( $obj ); + $property = $reflection->getProperty( $property_name ); + $property->setAccessible( true ); + $property->setValue( $obj, $value ); + } + + /** + * Initialize the REST endpoint. + * + * @since 3.17.0 + */ + protected function initialize_rest_endpoint(): void { + // Initialize the endpoint when the plugins are loaded. + $this->rest_api_init_proxy = function () { + $this->get_endpoint()->init(); + }; + add_action( 'plugins_loaded', $this->rest_api_init_proxy ); + + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound + do_action( 'plugins_loaded' ); + } +} diff --git a/tests/Integration/RestAPI/ContentHelper/ContentHelperControllerTest.php b/tests/Integration/RestAPI/ContentHelper/ContentHelperControllerTest.php new file mode 100644 index 000000000..87380d31d --- /dev/null +++ b/tests/Integration/RestAPI/ContentHelper/ContentHelperControllerTest.php @@ -0,0 +1,99 @@ +content_helper_controller = new Content_Helper_Controller( $parsely ); + } + + /** + * Test the constructor sets up the correct namespace and version. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Content_Helper\Content_Helper_Controller::__construct + * @uses \Parsely\REST_API\Content_Helper\Content_Helper_Controller::get_namespace + */ + public function test_constructor_sets_up_namespace_and_version(): void { + self::assertEquals( 'wp-parsely/v2', $this->content_helper_controller->get_namespace() ); + } + + /** + * Test that the route prefix is set correctly. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Content_Helper\Content_Helper_Controller::ROUTE_PREFIX + */ + public function test_route_prefix(): void { + self::assertEquals( 'content-helper', Content_Helper_Controller::ROUTE_PREFIX ); + } + + /** + * Test that the init method registers the correct endpoints. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Content_Helper\Content_Helper_Controller::init + * @uses \Parsely\REST_API\Content_Helper\Content_Helper_Controller::register_endpoints + * @uses Parsely\Endpoints\Base_Endpoint::__construct + * @uses Parsely\REST_API\Base_API_Controller::__construct + * @uses Parsely\REST_API\Base_API_Controller::register_endpoint + * @uses Parsely\REST_API\Base_Endpoint::__construct + * @uses Parsely\REST_API\Base_Endpoint::init + * @uses Parsely\REST_API\Content_Helper\Excerpt_Generator_Endpoint::__construct + * @uses Parsely\REST_API\Content_Helper\Smart_Linking_Endpoint::__construct + * @uses Parsely\REST_API\Content_Helper\Title_Suggestions_Endpoint::__construct + * @uses Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_init_registers_endpoints(): void { + $this->content_helper_controller->init(); + + self::assertCount( 3, $this->content_helper_controller->endpoints ); + self::assertInstanceOf( Endpoint_Smart_Linking::class, $this->content_helper_controller->endpoints[0] ); + self::assertInstanceOf( Endpoint_Excerpt_Generator::class, $this->content_helper_controller->endpoints[1] ); + self::assertInstanceOf( Endpoint_Title_Suggestions::class, $this->content_helper_controller->endpoints[2] ); + } +} diff --git a/tests/Integration/RestAPI/ContentHelper/ContentHelperFeatureTestTrait.php b/tests/Integration/RestAPI/ContentHelper/ContentHelperFeatureTestTrait.php new file mode 100644 index 000000000..47615307f --- /dev/null +++ b/tests/Integration/RestAPI/ContentHelper/ContentHelperFeatureTestTrait.php @@ -0,0 +1,293 @@ +enable_feature(); + $this->set_current_user_to_admin(); + + // Assert that the endpoint is available to the current user. + self::assertTrue( $this->get_endpoint()->is_available_to_current_user( new WP_REST_Request() ) ); + } + + /** + * Test that the endpoint is not available to the current user. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Content_Helper\Content_Helper_Feature::is_available_to_current_user + * @uses Parsely\Endpoints\Base_Endpoint::__construct + * @uses Parsely\Parsely::__construct + * @uses Parsely\Parsely::allow_parsely_remote_requests + * @uses Parsely\Parsely::api_secret_is_set + * @uses Parsely\Parsely::are_credentials_managed + * @uses Parsely\Parsely::get_managed_credentials + * @uses Parsely\Parsely::get_options + * @uses Parsely\Parsely::set_default_content_helper_settings_values + * @uses Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses Parsely\Parsely::set_managed_options + * @uses Parsely\Parsely::site_id_is_set + * @uses Parsely\Permissions::build_pch_permissions_settings_array + * @uses Parsely\Permissions::current_user_can_use_pch_feature + * @uses Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses Parsely\REST_API\Base_API_Controller::__construct + * @uses Parsely\REST_API\Base_Endpoint::__construct + * @uses Parsely\REST_API\Base_Endpoint::init + * @uses Parsely\REST_API\Base_Endpoint::apply_capability_filters + * @uses Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @uses Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret + * @uses Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_is_available_to_current_user_returns_error_if_feature_disabled(): void { + $this->disable_feature(); + $this->set_current_user_to_admin(); + + // Assert that the endpoint is not available to the current user. + self::assertInstanceOf( WP_Error::class, $this->get_endpoint()->is_available_to_current_user( new WP_REST_Request() ) ); + } + + /** + * Test that the endpoint is available to the current user, since the user has the required role. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Content_Helper\Content_Helper_Feature::is_available_to_current_user + * @uses Parsely\Endpoints\Base_Endpoint::__construct + * @uses Parsely\Parsely::__construct + * @uses Parsely\Parsely::allow_parsely_remote_requests + * @uses Parsely\Parsely::api_secret_is_set + * @uses Parsely\Parsely::are_credentials_managed + * @uses Parsely\Parsely::get_managed_credentials + * @uses Parsely\Parsely::get_options + * @uses Parsely\Parsely::set_default_content_helper_settings_values + * @uses Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses Parsely\Parsely::set_managed_options + * @uses Parsely\Parsely::site_id_is_set + * @uses Parsely\Permissions::build_pch_permissions_settings_array + * @uses Parsely\Permissions::current_user_can_use_pch_feature + * @uses Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses Parsely\REST_API\Base_API_Controller::__construct + * @uses Parsely\REST_API\Base_Endpoint::__construct + * @uses Parsely\REST_API\Base_Endpoint::init + * @uses Parsely\REST_API\Base_Endpoint::apply_capability_filters + * @uses Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @uses Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret + * @uses Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_is_available_to_current_user_returns_true_if_has_permissions(): void { + $this->set_feature_options( + array( + 'enabled' => true, + 'allowed_user_roles' => array( 'administrator' ), + ) + ); + + // Assert that the endpoint is available to the current user. + $this->set_current_user_to_admin(); + self::assertTrue( $this->get_endpoint()->is_available_to_current_user( new WP_REST_Request() ) ); + + // Assert that the endpoint is not available to the current user. + $this->set_current_user_to_contributor(); + self::assertInstanceOf( WP_Error::class, $this->get_endpoint()->is_available_to_current_user( new WP_REST_Request() ) ); + } + + /** + * Test that the endpoint is not available to the current user, since the user does not have the + * required role. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Content_Helper\Content_Helper_Feature::is_available_to_current_user + * @uses Parsely\Endpoints\Base_Endpoint::__construct + * @uses Parsely\Parsely::__construct + * @uses Parsely\Parsely::allow_parsely_remote_requests + * @uses Parsely\Parsely::api_secret_is_set + * @uses Parsely\Parsely::are_credentials_managed + * @uses Parsely\Parsely::get_managed_credentials + * @uses Parsely\Parsely::get_options + * @uses Parsely\Parsely::set_default_content_helper_settings_values + * @uses Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses Parsely\Parsely::set_managed_options + * @uses Parsely\Parsely::site_id_is_set + * @uses Parsely\Permissions::build_pch_permissions_settings_array + * @uses Parsely\Permissions::current_user_can_use_pch_feature + * @uses Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses Parsely\REST_API\Base_API_Controller::__construct + * @uses Parsely\REST_API\Base_Endpoint::__construct + * @uses Parsely\REST_API\Base_Endpoint::init + * @uses Parsely\REST_API\Base_Endpoint::apply_capability_filters + * @uses Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @uses Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret + * @uses Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_is_available_to_current_user_returns_error_if_no_permissions(): void { + $this->set_current_user_to_contributor(); + + $this->set_feature_options( + array( + 'enabled' => true, + 'allowed_user_roles' => array( 'administrator' ), + ) + ); + + // Assert that the endpoint is not available to the current user. + self::assertInstanceOf( WP_Error::class, $this->get_endpoint()->is_available_to_current_user( new WP_REST_Request() ) ); + } + + + /** + * Test that the endpoint is not available to the current user, since the user is not logged in. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Content_Helper\Content_Helper_Feature::is_available_to_current_user + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests + * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::set_managed_options + * @uses \Parsely\Permissions::current_user_can_use_pch_feature + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_is_available_to_current_user_returns_error_if_no_user(): void { + $this->enable_feature(); + // Set the current user to a non-logged in user. + wp_set_current_user( 0 ); + + // Assert that the endpoint is not available to the current user. + self::assertInstanceOf( WP_Error::class, $this->get_endpoint()->is_available_to_current_user( new WP_REST_Request() ) ); + } + + /** + * You need to implement this method in your test class + * to return the endpoint instance being tested. + * + * @since 3.17.0 + * + * @return Base_Endpoint + */ + abstract protected function get_endpoint(): Base_Endpoint; + + /** + * Set the specific feature options. + * + * @since 3.17.0 + * + * @param array $options The options to set. + */ + private function set_feature_options( array $options ): void { + $feature_name = $this->get_endpoint()->get_pch_feature_name(); + + TestCase::set_options( + array( + 'apikey' => 'test', + 'api_secret' => 'test', + 'content_helper' => array( + 'ai_features_enabled' => true, + $feature_name => $options, + ), + ) + ); + } + + /** + * Disable the specific feature. + * + * @since 3.17.0 + */ + private function disable_feature(): void { + $this->set_feature_options( + array( + 'enabled' => false, + 'allowed_user_roles' => array(), + ) + ); + } + + /** + * Enable the specific feature. + * + * @since 3.17.0 + */ + private function enable_feature(): void { + $valid_roles = array_keys( Permissions::get_user_roles_with_edit_posts_cap() ); + + $this->set_feature_options( + array( + 'enabled' => true, + 'allowed_user_roles' => $valid_roles, + ) + ); + } + + /** + * Set the current user to an administrator. + * + * @since 3.17.0 + */ + abstract protected function set_current_user_to_admin(): void; + + /** + * Set the current user to a contributor. + * + * @since 3.17.0 + */ + abstract protected function set_current_user_to_contributor(): void; +} diff --git a/tests/Integration/RestAPI/ContentHelper/EndpointExcerptGeneratorTest.php b/tests/Integration/RestAPI/ContentHelper/EndpointExcerptGeneratorTest.php new file mode 100644 index 000000000..2fe8e904c --- /dev/null +++ b/tests/Integration/RestAPI/ContentHelper/EndpointExcerptGeneratorTest.php @@ -0,0 +1,193 @@ +api_controller = new Content_Helper_Controller( $this->parsely ); + $this->endpoint = new Endpoint_Excerpt_Generator( $this->api_controller ); + + parent::set_up(); + } + + /** + * Get the test endpoint instance. + * + * @since 3.17.0 + * + * @return Endpoint_Excerpt_Generator + */ + public function get_endpoint(): \Parsely\REST_API\Base_Endpoint { + return $this->endpoint; + } + + /** + * Test that the endpoint is correctly registered. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Content_Helper\Endpoint_Excerpt_Generator::register_routes + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::set_managed_options + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::current_user_can_use_pch_feature + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_namespace + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::get_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_route_is_registered(): void { + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound + do_action( 'plugins_loaded' ); + $routes = rest_get_server()->get_routes(); + + // Check that the excerpt-generator/generate route is registered. + $expected_route = $this->get_endpoint()->get_full_endpoint( 'generate' ); + self::assertArrayHasKey( $expected_route, $routes ); + + // Check that the route is associated with the POST method. + $route_data = $routes[ $expected_route ]; + self::assertArrayHasKey( 'POST', $route_data[0]['methods'] ); + } + + /** + * Test that the generate_excerpt method returns a valid response. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Content_Helper\Endpoint_Excerpt_Generator::generate_excerpt + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests + * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::set_managed_options + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_Endpoint::__construct + */ + public function test_generate_excerpt_returns_valid_response(): void { + // Mock the Suggest_Brief_API to control the response. + $mock_suggest_api = $this->createMock( Suggest_Brief_API::class ); + $mock_suggest_api->expects( self::once() ) + ->method( 'get_suggestion' ) + ->willReturn( array( 'summary' => 'This is a test excerpt.' ) ); + + $this->set_protected_property( $this->get_endpoint(), 'suggest_brief_api', $mock_suggest_api ); + + // Create a mock request. + $request = new WP_REST_Request( 'POST', '/excerpt-generator/generate' ); + $request->set_param( 'content', 'Test content' ); + $request->set_param( 'title', 'Test title' ); + $request->set_param( 'persona', 'journalist' ); + $request->set_param( 'style', 'neutral' ); + + // Call the generate_excerpt method. + $response = $this->get_endpoint()->generate_excerpt( $request ); + + // Assert that the response is a WP_REST_Response and contains the correct data. + self::assertInstanceOf( WP_REST_Response::class, $response ); + + /** + * The response data. + * + * @var array> $data The response data. + */ + $data = $response->get_data(); + self::assertArrayHasKey( 'data', $data ); + self::assertEquals( 'This is a test excerpt.', $data['data']['summary'] ); + } + + /** + * Test that the generate_excerpt method returns an error if Suggest_Brief_API fails. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Content_Helper\Endpoint_Excerpt_Generator::generate_excerpt + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests + * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::set_managed_options + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_Endpoint::__construct + */ + public function test_generate_excerpt_returns_error_on_failure(): void { + // Mock the Suggest_Brief_API to simulate a failure. + $mock_suggest_api = $this->createMock( Suggest_Brief_API::class ); + $mock_suggest_api->expects( self::once() ) + ->method( 'get_suggestion' ) + ->willReturn( new WP_Error( 'api_error', 'API request failed' ) ); + + $this->set_protected_property( $this->get_endpoint(), 'suggest_brief_api', $mock_suggest_api ); + + // Create a mock request. + $request = new WP_REST_Request( 'POST', '/excerpt-generator/generate' ); + $request->set_param( 'content', 'Test content' ); + $request->set_param( 'title', 'Test title' ); + $request->set_param( 'persona', 'journalist' ); + $request->set_param( 'style', 'neutral' ); + + // Call the generate_excerpt method. + $response = $this->get_endpoint()->generate_excerpt( $request ); + + // Assert that the response is a WP_Error. + self::assertInstanceOf( WP_Error::class, $response ); + self::assertEquals( 'api_error', $response->get_error_code() ); + } +} diff --git a/tests/Integration/RestAPI/ContentHelper/EndpointSmartLinkingTest.php b/tests/Integration/RestAPI/ContentHelper/EndpointSmartLinkingTest.php new file mode 100644 index 000000000..476f3a8c7 --- /dev/null +++ b/tests/Integration/RestAPI/ContentHelper/EndpointSmartLinkingTest.php @@ -0,0 +1,420 @@ +api_controller = new Content_Helper_Controller( $this->parsely ); + $this->endpoint = new Endpoint_Smart_Linking( $this->api_controller ); + + parent::set_up(); + + // Setup fake API key and secret. + TestCase::set_options( + array( + 'apikey' => 'test-apikey', + 'api_secret' => 'test-secret', + ) + ); + } + + /** + * Get the test endpoint instance. + * + * @since 3.17.0 + * + * @return Endpoint_Smart_Linking + */ + public function get_endpoint(): \Parsely\REST_API\Base_Endpoint { + return $this->endpoint; + } + + /** + * Test that the endpoint is correctly registered. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Content_Helper\Endpoint_Smart_Linking::register_routes + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::set_managed_options + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::current_user_can_use_pch_feature + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_namespace + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::get_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_route_is_registered(): void { + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound + do_action( 'plugins_loaded' ); + $routes = rest_get_server()->get_routes(); + + // Check that the smart-linking/generate route is registered. + $expected_route = $this->get_endpoint()->get_full_endpoint( 'generate' ); + self::assertArrayHasKey( $expected_route, $routes ); + + // Check that the route is associated with the POST method. + $route_data = $routes[ $expected_route ]; + self::assertArrayHasKey( 'POST', $route_data[0]['methods'] ); + } + + /** + * Test that the generate_smart_links method returns a valid response. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Content_Helper\Endpoint_Smart_Linking::generate_smart_links + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests + * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::set_managed_options + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_Endpoint::__construct + */ + public function test_generate_smart_links_returns_valid_response(): void { + // Mock the Suggest_Linked_Reference_API to control the response. + $mock_suggest_api = $this->createMock( Suggest_Linked_Reference_API::class ); + $mock_suggest_api->expects( self::once() ) + ->method( 'get_links' ) + ->willReturn( + array( + new Smart_Link( 'link1', 'http://example.com/1', 'Example 1', 0, 0 ), + new Smart_Link( 'link2', 'http://example.com/2', 'Example 2', 0, 1 ), + ) + ); + + $this->set_protected_property( $this->get_endpoint(), 'suggest_linked_reference_api', $mock_suggest_api ); + + // Create a mock request. + $request = new WP_REST_Request( 'POST', '/smart-linking/generate' ); + $request->set_param( 'content', 'Test content' ); + $request->set_param( 'max_links', 2 ); + $request->set_param( 'url_exclusion_list', array( 'http://excluded.com' ) ); + + // Call the generate_smart_links method. + $response = $this->get_endpoint()->generate_smart_links( $request ); + + // Assert that the response is a WP_REST_Response and contains the correct data. + self::assertInstanceOf( WP_REST_Response::class, $response ); + + /** + * The response data. + * + * @var array> $data The response data. + */ + $data = $response->get_data(); + self::assertArrayHasKey( 'data', $data ); + self::assertCount( 2, $data['data'] ); + } + + /** + * Test that the generate_smart_links method returns an error if Suggest_Linked_Reference_API fails. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Content_Helper\Endpoint_Smart_Linking::generate_smart_links + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests + * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::set_managed_options + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_Endpoint::__construct + */ + public function test_generate_smart_links_returns_error_on_failure(): void { + // Mock the Suggest_Linked_Reference_API to simulate a failure. + $mock_suggest_api = $this->createMock( Suggest_Linked_Reference_API::class ); + $mock_suggest_api->expects( self::once() ) + ->method( 'get_links' ) + ->willReturn( new WP_Error( 'api_error', 'API request failed' ) ); + + $this->set_protected_property( $this->get_endpoint(), 'suggest_linked_reference_api', $mock_suggest_api ); + + // Create a mock request. + $request = new WP_REST_Request( 'POST', '/smart-linking/generate' ); + $request->set_param( 'content', 'Test content' ); + $request->set_param( 'max_links', 2 ); + $request->set_param( 'url_exclusion_list', array( 'http://excluded.com' ) ); + + // Call the generate_smart_links method. + $response = $this->get_endpoint()->generate_smart_links( $request ); + + // Assert that the response is a WP_Error. + self::assertInstanceOf( WP_Error::class, $response ); + self::assertEquals( 'api_error', $response->get_error_code() ); + } + + /** + * Test that the add_smart_link method returns a valid response when adding a new smart link. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Content_Helper\Endpoint_Smart_Linking::add_smart_link + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Models\Base_Model::__construct + * @uses \Parsely\Models\Base_Model::serialize + * @uses \Parsely\Models\Smart_Link::__construct + * @uses \Parsely\Models\Smart_Link::deserialize + * @uses \Parsely\Models\Smart_Link::exists + * @uses \Parsely\Models\Smart_Link::generate_uid + * @uses \Parsely\Models\Smart_Link::get_post_id_by_url + * @uses \Parsely\Models\Smart_Link::get_smart_link + * @uses \Parsely\Models\Smart_Link::get_smart_link_object_by_uid + * @uses \Parsely\Models\Smart_Link::load + * @uses \Parsely\Models\Smart_Link::save + * @uses \Parsely\Models\Smart_Link::set_href + * @uses \Parsely\Models\Smart_Link::set_source_post_id + * @uses \Parsely\Models\Smart_Link::set_uid + * @uses \Parsely\Models\Smart_Link::to_array + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::current_user_can_use_pch_feature + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_namespace + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters + * @uses \Parsely\REST_API\Base_Endpoint::get_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_add_smart_link_returns_valid_response(): void { + // Create mocked post. + $post = WP_UnitTestCase_Base::factory()->post->create_and_get(); + self::assertNotWPError( $post ); + $post_id = $post->ID; // @phpstan-ignore-line + + // Create a mock request. + $request = new WP_REST_Request( 'POST', $this->get_endpoint()->get_full_endpoint( $post_id . '/add' ) ); + + $smart_link_data = array( + 'uid' => md5( 'link1' ), + 'href' => 'http://example.com/1', + 'title' => 'Example 1', + 'text' => 'Example 1', + 'offset' => 0, + ); + $request->set_param( 'link', $smart_link_data ); + + // Dispatch the request. + $response = rest_get_server()->dispatch( $request ); + + // Assert that the response is a WP_REST_Response and contains the correct data. + self::assertInstanceOf( WP_REST_Response::class, $response ); + + /** + * The response data. + * + * @var array> $data The response data. + */ + $data = $response->get_data(); + + self::assertNotTrue( $response->is_error() ); + + self::assertArrayHasKey( 'data', $data ); + self::assertIsObject( $data['data'] ); + + $smart_link_attributes = array( + 'smart_link_id', + 'uid', + 'href', + 'text', + 'offset', + 'applied', + 'source', + 'destination', + ); + + foreach ( $smart_link_attributes as $attribute ) { + self::assertObjectHasProperty( $attribute, $data['data'] ); + } + } + + /** + * Tests that the add_multiple_smart_links method returns a valid response when adding multiple smart links. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Content_Helper\Endpoint_Smart_Linking::add_multiple_smart_links + * + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Models\Base_Model::__construct + * @uses \Parsely\Models\Base_Model::serialize + * @uses \Parsely\Models\Smart_Link::__construct + * @uses \Parsely\Models\Smart_Link::deserialize + * @uses \Parsely\Models\Smart_Link::exists + * @uses \Parsely\Models\Smart_Link::generate_uid + * @uses \Parsely\Models\Smart_Link::get_post_id_by_url + * @uses \Parsely\Models\Smart_Link::get_smart_link + * @uses \Parsely\Models\Smart_Link::get_smart_link_object_by_uid + * @uses \Parsely\Models\Smart_Link::load + * @uses \Parsely\Models\Smart_Link::save + * @uses \Parsely\Models\Smart_Link::set_href + * @uses \Parsely\Models\Smart_Link::set_source_post_id + * @uses \Parsely\Models\Smart_Link::set_uid + * @uses \Parsely\Models\Smart_Link::to_array + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::current_user_can_use_pch_feature + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_namespace + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters + * @uses \Parsely\REST_API\Base_Endpoint::get_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_add_multiple_smart_links_returns_valid_response(): void { + // Create mocked post. + $post = WP_UnitTestCase_Base::factory()->post->create_and_get(); + self::assertNotWPError( $post ); + $post_id = $post->ID; // @phpstan-ignore-line + + // Create a mock request. + $request = new WP_REST_Request( 'POST', $this->get_endpoint()->get_full_endpoint( $post_id . '/add-multiple' ) ); + + $smart_links_data = array( + array( + 'uid' => md5( 'link1' ), + 'href' => 'http://example.com/1', + 'title' => 'Example 1', + 'text' => 'Example 1', + 'offset' => 0, + ), + array( + 'uid' => md5( 'link2' ), + 'href' => 'http://example.com/2', + 'title' => 'Example 2', + 'text' => 'Example 2', + 'offset' => 0, + ), + array( + 'uid' => md5( 'link3' ), + 'href' => 'http://example.com/3', + 'title' => 'Example 3', + 'text' => 'Example 3', + 'offset' => 0, + ), + ); + $request->set_param( 'links', $smart_links_data ); + + // Dispatch the request. + $response = rest_get_server()->dispatch( $request ); + + // Assert that the response is a WP_REST_Response and contains the correct data. + self::assertInstanceOf( WP_REST_Response::class, $response ); + + /** + * The response data. + * + * @var array> $data The response data. + */ + $data = $response->get_data(); + + self::assertNotTrue( $response->is_error() ); + + self::assertArrayHasKey( 'data', $data ); + self::assertArrayHasKey( 'added', $data['data'] ); + self::assertIsArray( $data['data']['added'] ); + self::assertCount( 3, $data['data']['added'] ); + + $smart_link_attributes = array( + 'smart_link_id', + 'uid', + 'href', + 'text', + 'offset', + 'applied', + 'source', + 'destination', + ); + + foreach ( $data['data']['added'] as $smart_link ) { + foreach ( $smart_link_attributes as $attribute ) { + self::assertArrayHasKey( $attribute, $smart_link ); + } + } + } +} diff --git a/tests/Integration/RestAPI/ContentHelper/EndpointTitleSuggestionsTest.php b/tests/Integration/RestAPI/ContentHelper/EndpointTitleSuggestionsTest.php new file mode 100644 index 000000000..9e94182cf --- /dev/null +++ b/tests/Integration/RestAPI/ContentHelper/EndpointTitleSuggestionsTest.php @@ -0,0 +1,194 @@ +api_controller = new Content_Helper_Controller( $this->parsely ); + $this->endpoint = new Endpoint_Title_Suggestions( $this->api_controller ); + + parent::set_up(); + } + + /** + * Get the test endpoint instance. + * + * @return Endpoint_Title_Suggestions + * @since 3.17.0 + */ + public function get_endpoint(): \Parsely\REST_API\Base_Endpoint { + return $this->endpoint; + } + + /** + * Test that the endpoint is correctly registered. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Content_Helper\Endpoint_Title_Suggestions::register_routes + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::set_managed_options + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::current_user_can_use_pch_feature + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_namespace + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::get_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_route_is_registered(): void { + $routes = rest_get_server()->get_routes(); + + // Check that the title-suggestions/generate route is registered. + $expected_route = $this->get_endpoint()->get_full_endpoint( 'generate' ); + self::assertArrayHasKey( $expected_route, $routes ); + + // Check that the route is associated with the POST method. + $route_data = $routes[ $expected_route ]; + self::assertArrayHasKey( 'POST', $route_data[0]['methods'] ); + } + + /** + * Test that the generate_titles method returns a valid response. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Content_Helper\Endpoint_Title_Suggestions::generate_titles + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests + * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::set_managed_options + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_generate_titles_returns_valid_response(): void { + // Mock the Suggest_Headline_API to control the response. + $mock_suggest_api = $this->createMock( Suggest_Headline_API::class ); + $mock_suggest_api->expects( self::once() ) + ->method( 'get_titles' ) + ->willReturn( array( 'title1', 'title2', 'title3' ) ); + + $this->set_protected_property( $this->get_endpoint(), 'suggest_headline_api', $mock_suggest_api ); + + // Create a mock request. + $request = new WP_REST_Request( 'POST', '/title-suggestions/generate' ); + $request->set_param( 'content', 'Test content' ); + $request->set_param( 'limit', 3 ); + $request->set_param( 'style', 'neutral' ); + $request->set_param( 'persona', 'journalist' ); + + // Call the generate_titles method. + $response = $this->get_endpoint()->generate_titles( $request ); + + // Assert that the response is a WP_REST_Response and contains the correct data. + self::assertInstanceOf( WP_REST_Response::class, $response ); + + /** + * The response data. + * + * @var array $data The response data. + */ + $data = $response->get_data(); + self::assertArrayHasKey( 'data', $data ); + self::assertEquals( array( 'title1', 'title2', 'title3' ), $data['data'] ); + } + + /** + * Test that the generate_titles method returns an error if Suggest_Headline_API fails. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Content_Helper\Endpoint_Title_Suggestions::generate_titles + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests + * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::set_managed_options + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_generate_titles_returns_error_on_failure(): void { + // Mock the Suggest_Headline_API to simulate a failure. + $mock_suggest_api = $this->createMock( Suggest_Headline_API::class ); + $mock_suggest_api->expects( self::once() ) + ->method( 'get_titles' ) + ->willReturn( new WP_Error( 'api_error', 'API request failed' ) ); + + $this->set_protected_property( $this->get_endpoint(), 'suggest_headline_api', $mock_suggest_api ); + + // Create a mock request. + $request = new WP_REST_Request( 'POST', '/title-suggestions/generate' ); + $request->set_param( 'content', 'Test content' ); + $request->set_param( 'limit', 3 ); + $request->set_param( 'style', 'neutral' ); + $request->set_param( 'persona', 'journalist' ); + + // Call the generate_titles method. + $response = $this->get_endpoint()->generate_titles( $request ); + + // Assert that the response is a WP_Error. + self::assertInstanceOf( WP_Error::class, $response ); + self::assertEquals( 'api_error', $response->get_error_code() ); + } +} diff --git a/tests/Integration/RestAPI/RestAPIControllerTest.php b/tests/Integration/RestAPI/RestAPIControllerTest.php new file mode 100644 index 000000000..0a8968691 --- /dev/null +++ b/tests/Integration/RestAPI/RestAPIControllerTest.php @@ -0,0 +1,58 @@ +test_controller = new REST_API_Controller( $parsely ); + } + + /** + * Test the constructor sets up the correct namespace and version. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\REST_API_Controller::__construct + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + */ + public function test_constructor_sets_up_namespace_and_version(): void { + self::assertEquals( 'wp-parsely/v2', $this->test_controller->get_namespace() ); + } +} diff --git a/tests/Integration/ScriptsTest.php b/tests/Integration/ScriptsTest.php index 7f598df63..7eabab3f6 100644 --- a/tests/Integration/ScriptsTest.php +++ b/tests/Integration/ScriptsTest.php @@ -347,7 +347,7 @@ public function test_track_logged_in_users(): void { 'track_authenticated_users' => true, ) ); - $new_user_id = $this->create_test_user( 'bill_brasky' ); + $new_user_id = self::create_test_user( 'bill_brasky' ); wp_set_current_user( $new_user_id ); $this->go_to_new_post(); self::$scripts->register_scripts(); @@ -390,10 +390,10 @@ public function test_do_not_track_logged_in_users_multisite(): void { } // Set up users and blogs. - $first_blog_admin = $this->create_test_user( 'optimus_prime' ); - $second_blog_admin = $this->create_test_user( 'megatron' ); - $first_blog = $this->create_test_blog( 'autobots', $first_blog_admin ); - $second_blog = $this->create_test_blog( 'decepticons', $second_blog_admin ); + $first_blog_admin = self::create_test_user( 'optimus_prime' ); + $second_blog_admin = self::create_test_user( 'megatron' ); + $first_blog = self::create_test_blog( 'autobots', $first_blog_admin ); + $second_blog = self::create_test_blog( 'decepticons', $second_blog_admin ); // These custom options will be used for both blogs. $custom_options = array( diff --git a/tests/Integration/TestCase.php b/tests/Integration/TestCase.php index c2bc79058..1f0ede347 100644 --- a/tests/Integration/TestCase.php +++ b/tests/Integration/TestCase.php @@ -100,7 +100,7 @@ public function create_test_category( string $name ): int { * @param string $user_role The user's role. Default is subscriber. * @return int The newly created user's ID. */ - public function create_test_user( string $user_login, string $user_role = 'subscriber' ): int { + public static function create_test_user( string $user_login, string $user_role = 'subscriber' ): int { /** @var int */ return self::factory()->user->create( array( @@ -427,15 +427,15 @@ public function go_to_new_post( string $post_status = 'publish' ): int { * @param string $user_login The user's login. * @param string $user_role The user's role. */ - public function set_current_user_to( string $user_login, string $user_role ): void { + public static function set_current_user_to( string $user_login, string $user_role ): void { $user = get_user_by( 'login', $user_login ); if ( false === $user ) { - $user_id = $this->create_test_user( $user_login, $user_role ); + $user_id = self::create_test_user( $user_login, $user_role ); $user = get_user_by( 'id', $user_id ); } if ( false === $user ) { - $this::fail( 'Invalid user.' ); + self::fail( 'Invalid user.' ); } wp_set_current_user( $user->ID ); @@ -445,14 +445,14 @@ public function set_current_user_to( string $user_login, string $user_role ): vo * Changes the current user to the built-in admin account. */ public function set_current_user_to_admin(): void { - $this->set_current_user_to( 'admin', 'administrator' ); + self::set_current_user_to( 'admin', 'administrator' ); } /** * Changes the current user to a contributor account. */ public function set_current_user_to_contributor(): void { - $this->set_current_user_to( 'test_contributor', 'contributor' ); + self::set_current_user_to( 'test_contributor', 'contributor' ); } /** From e5000322ff87303be3c8b2e7f7db2b7803d6c474 Mon Sep 17 00:00:00 2001 From: Henrique Mouta Date: Thu, 22 Aug 2024 14:33:17 +0100 Subject: [PATCH 043/282] Update UI providers to use the new API endpoints --- build/content-helper/editor-sidebar.asset.php | 2 +- build/content-helper/editor-sidebar.js | 4 ++-- build/content-helper/excerpt-generator.asset.php | 2 +- build/content-helper/excerpt-generator.js | 2 +- .../editor-sidebar/smart-linking/provider.ts | 14 +++++++------- .../editor-sidebar/title-suggestions/provider.ts | 2 +- src/content-helper/excerpt-generator/provider.ts | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/build/content-helper/editor-sidebar.asset.php b/build/content-helper/editor-sidebar.asset.php index a585d85b1..9aedc4547 100644 --- a/build/content-helper/editor-sidebar.asset.php +++ b/build/content-helper/editor-sidebar.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-dom-ready', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-plugins', 'wp-primitives', 'wp-url'), 'version' => 'cd18a7b42cbf7a260800'); + array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-dom-ready', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-plugins', 'wp-primitives', 'wp-url'), 'version' => '6a5829c6e4ff7bf83951'); diff --git a/build/content-helper/editor-sidebar.js b/build/content-helper/editor-sidebar.js index b096ce75c..c44b4e693 100644 --- a/build/content-helper/editor-sidebar.js +++ b/build/content-helper/editor-sidebar.js @@ -1,5 +1,5 @@ !function(){"use strict";var e={20:function(e,t,n){var r=n(609),i=Symbol.for("react.element"),s=Symbol.for("react.fragment"),o=Object.prototype.hasOwnProperty,a=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function c(e,t,n){var r,s={},c=null,u=null;for(r in void 0!==n&&(c=""+n),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(u=t.ref),t)o.call(t,r)&&!l.hasOwnProperty(r)&&(s[r]=t[r]);if(e&&e.defaultProps)for(r in t=e.defaultProps)void 0===s[r]&&(s[r]=t[r]);return{$$typeof:i,type:e,key:c,ref:u,props:s,_owner:a.current}}t.Fragment=s,t.jsx=c,t.jsxs=c},848:function(e,t,n){e.exports=n(20)},609:function(e){e.exports=window.React}},t={};function n(r){var i=t[r];if(void 0!==i)return i.exports;var s=t[r]={exports:{}};return e[r](s,s.exports,n),s.exports}n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,{a:t}),t},n.d=function(e,t){for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},function(){n.d({},{_:function(){return ur}});var e,t,r,i,s,o,a,l,c,u,d,p=n(848),f=window.wp.components,h=window.wp.data,v=window.wp.domReady,g=n.n(v);void 0!==window.wp&&(null!==(t=null===(e=window.wp.editor)||void 0===e?void 0:e.PluginDocumentSettingPanel)&&void 0!==t||(null!==(i=null===(r=window.wp.editPost)||void 0===r?void 0:r.PluginDocumentSettingPanel)&&void 0!==i||(null===(s=window.wp.editSite)||void 0===s||s.PluginDocumentSettingPanel)),d=null!==(a=null===(o=window.wp.editor)||void 0===o?void 0:o.PluginSidebar)&&void 0!==a?a:null!==(c=null===(l=window.wp.editPost)||void 0===l?void 0:l.PluginSidebar)&&void 0!==c?c:null===(u=window.wp.editSite)||void 0===u?void 0:u.PluginSidebar);var y,m,w,b=window.wp.element,_=window.wp.i18n,x=window.wp.primitives,k=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{fillRule:"evenodd",d:"M11.25 5h1.5v15h-1.5V5zM6 10h1.5v10H6V10zm12 4h-1.5v6H18v-6z",clipRule:"evenodd"})}),S=window.wp.plugins,P=function(){function e(){this._tkq=[],this.isLoaded=!1,this.isEnabled=!1,"undefined"!=typeof wpParselyTracksTelemetry&&(this.isEnabled=!0,this.loadTrackingLibrary())}return e.getInstance=function(){return window.wpParselyTelemetryInstance||Object.defineProperty(window,"wpParselyTelemetryInstance",{value:new e,writable:!1,configurable:!1,enumerable:!1}),window.wpParselyTelemetryInstance},e.prototype.loadTrackingLibrary=function(){var e=this,t=document.createElement("script");t.async=!0,t.src="//stats.wp.com/w.js",t.onload=function(){e.isLoaded=!0,e._tkq=window._tkq||[]},document.head.appendChild(t)},e.trackEvent=function(t){return n=this,r=arguments,s=function(t,n){var r;return void 0===n&&(n={}),function(e,t){var n,r,i,s,o={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return s={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function a(a){return function(l){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;s&&(s=0,a[0]&&(o=0)),o;)try{if(n=1,r&&(i=2&a[0]?r.return:a[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,a[1])).done)return i;switch(r=0,i&&(a=[2&a[0],i.value]),a[0]){case 0:case 1:i=a;break;case 4:return o.label++,{value:a[1],done:!1};case 5:o.label++,r=a[1],a=[0];continue;case 7:a=o.ops.pop(),o.trys.pop();continue;default:if(!((i=(i=o.trys).length>0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]=1e4&&(clearInterval(s),n("Telemetry library not loaded"))}),100);else n("Telemetry not enabled")}))},e.prototype.trackEvent=function(t,n){var r;this.isLoaded?(0!==t.indexOf(e.TRACKS_PREFIX)&&(t=e.TRACKS_PREFIX+t),this.isEventNameValid(t)?(n=this.prepareProperties(n),null===(r=this._tkq)||void 0===r||r.push(["recordEvent",t,n])):console.error("Error tracking event: Invalid event name")):console.error("Error tracking event: Telemetry not loaded")},e.prototype.isTelemetryEnabled=function(){return this.isEnabled},e.prototype.isProprietyValid=function(t){return e.PROPERTY_REGEX.test(t)},e.prototype.isEventNameValid=function(t){return e.EVENT_NAME_REGEX.test(t)},e.prototype.prepareProperties=function(e){return(e=this.sanitizeProperties(e)).parsely_version=wpParselyTracksTelemetry.version,wpParselyTracksTelemetry.user&&(e._ut=wpParselyTracksTelemetry.user.type,e._ui=wpParselyTracksTelemetry.user.id),wpParselyTracksTelemetry.vipgo_env&&(e.vipgo_env=wpParselyTracksTelemetry.vipgo_env),this.sanitizeProperties(e)},e.prototype.sanitizeProperties=function(e){var t=this,n={};return Object.keys(e).forEach((function(r){t.isProprietyValid(r)&&(n[r]=e[r])})),n},e.TRACKS_PREFIX="wpparsely_",e.EVENT_NAME_REGEX=/^(([a-z0-9]+)_){2}([a-z0-9_]+)$/,e.PROPERTY_REGEX=/^[a-z_][a-z0-9_]*$/,e}(),j=(P.trackEvent,function(){return(0,p.jsx)(f.SVG,{"aria-hidden":"true",version:"1.1",viewBox:"0 0 15 15",width:"15",height:"15",xmlns:"http://www.w3.org/2000/svg",children:(0,p.jsx)(f.Path,{d:"M0 14.0025V11.0025L7.5 3.5025L10.5 6.5025L3 14.0025H0ZM12 5.0025L13.56 3.4425C14.15 2.8525 14.15 1.9025 13.56 1.3225L12.68 0.4425C12.09 -0.1475 11.14 -0.1475 10.56 0.4425L9 2.0025L12 5.0025Z"})})}),T=function(e){var t=e.size,n=void 0===t?24:t,r=e.className,i=void 0===r?"wp-parsely-icon":r;return(0,p.jsxs)(f.SVG,{className:i,height:n,viewBox:"0 0 60 65",width:n,xmlns:"http://www.w3.org/2000/svg",children:[(0,p.jsx)(f.Path,{fill:"#5ba745",d:"M23.72,51.53c0-.18,0-.34-.06-.52a13.11,13.11,0,0,0-2.1-5.53A14.74,14.74,0,0,0,19.12,43c-.27-.21-.5-.11-.51.22l-.24,3.42c0,.33-.38.35-.49,0l-1.5-4.8a1.4,1.4,0,0,0-.77-.78,23.91,23.91,0,0,0-3.1-.84c-1.38-.24-3.39-.39-3.39-.39-.34,0-.45.21-.25.49l2.06,3.76c.2.27,0,.54-.29.33l-4.51-3.6a3.68,3.68,0,0,0-2.86-.48c-1,.16-2.44.46-2.44.46a.68.68,0,0,0-.39.25.73.73,0,0,0-.14.45S.41,43,.54,44a3.63,3.63,0,0,0,1.25,2.62L6.48,50c.28.2.09.49-.23.37l-4.18-.94c-.32-.12-.5,0-.4.37,0,0,.69,1.89,1.31,3.16a24,24,0,0,0,1.66,2.74,1.34,1.34,0,0,0,1,.52l5,.13c.33,0,.41.38.1.48L7.51,58c-.31.1-.34.35-.07.55a14.29,14.29,0,0,0,3.05,1.66,13.09,13.09,0,0,0,5.9.5,25.13,25.13,0,0,0,4.34-1,9.55,9.55,0,0,1-.08-1.2,9.32,9.32,0,0,1,3.07-6.91"}),(0,p.jsx)(f.Path,{fill:"#5ba745",d:"M59.7,41.53a.73.73,0,0,0-.14-.45.68.68,0,0,0-.39-.25s-1.43-.3-2.44-.46a3.64,3.64,0,0,0-2.86.48l-4.51,3.6c-.26.21-.49-.06-.29-.33l2.06-3.76c.2-.28.09-.49-.25-.49,0,0-2,.15-3.39.39a23.91,23.91,0,0,0-3.1.84,1.4,1.4,0,0,0-.77.78l-1.5,4.8c-.11.32-.48.3-.49,0l-.24-3.42c0-.33-.24-.43-.51-.22a14.74,14.74,0,0,0-2.44,2.47A13.11,13.11,0,0,0,36.34,51c0,.18,0,.34-.06.52a9.26,9.26,0,0,1,3,8.1,24.1,24.1,0,0,0,4.34,1,13.09,13.09,0,0,0,5.9-.5,14.29,14.29,0,0,0,3.05-1.66c.27-.2.24-.45-.07-.55l-3.22-1.17c-.31-.1-.23-.47.1-.48l5-.13a1.38,1.38,0,0,0,1-.52A24.6,24.6,0,0,0,57,52.92c.61-1.27,1.31-3.16,1.31-3.16.1-.33-.08-.49-.4-.37l-4.18.94c-.32.12-.51-.17-.23-.37l4.69-3.34A3.63,3.63,0,0,0,59.46,44c.13-1,.24-2.47.24-2.47"}),(0,p.jsx)(f.Path,{fill:"#5ba745",d:"M46.5,25.61c0-.53-.35-.72-.8-.43l-4.86,2.66c-.45.28-.56-.27-.23-.69l4.66-6.23a2,2,0,0,0,.28-1.68,36.51,36.51,0,0,0-2.19-4.89,34,34,0,0,0-2.81-3.94c-.33-.41-.74-.35-.91.16l-2.28,5.68c-.16.5-.6.48-.59-.05l.28-8.93a2.54,2.54,0,0,0-.66-1.64S35,4.27,33.88,3.27,30.78.69,30.78.69a1.29,1.29,0,0,0-1.54,0s-1.88,1.49-3.12,2.59-2.48,2.35-2.48,2.35A2.5,2.5,0,0,0,23,7.27l.27,8.93c0,.53-.41.55-.58.05l-2.29-5.69c-.17-.5-.57-.56-.91-.14a35.77,35.77,0,0,0-3,4.2,35.55,35.55,0,0,0-2,4.62,2,2,0,0,0,.27,1.67l4.67,6.24c.33.42.23,1-.22.69l-4.87-2.66c-.45-.29-.82-.1-.82.43a18.6,18.6,0,0,0,.83,5.07,20.16,20.16,0,0,0,5.37,7.77c3.19,3,5.93,7.8,7.45,11.08A9.6,9.6,0,0,1,30,49.09a9.31,9.31,0,0,1,2.86.45c1.52-3.28,4.26-8.11,7.44-11.09a20.46,20.46,0,0,0,5.09-7,19,19,0,0,0,1.11-5.82"}),(0,p.jsx)(f.Path,{fill:"#5ba745",d:"M36.12,58.44A6.12,6.12,0,1,1,30,52.32a6.11,6.11,0,0,1,6.12,6.12"})]})},L=function(){return L=Object.assign||function(e){for(var t,n=1,r=arguments.length;nhere.',"wp-parsely"):s.code===$.ParselySuggestionsApiOpenAiError||s.code===$.ParselySuggestionsApiOpenAiUnavailable?s.message=(0,_.__)("The Parse.ly API returned an internal server error. Please retry with a different input, or try again later.","wp-parsely"):s.code===$.HttpRequestFailed&&s.message.includes("cURL error 28")?s.message=(0,_.__)("The Parse.ly API did not respond in a timely manner. Please try again later.","wp-parsely"):s.code===$.ParselySuggestionsApiSchemaError?s.message=(0,_.__)("The Parse.ly API returned a validation error. Please try again with different parameters.","wp-parsely"):s.code===$.ParselySuggestionsApiNoData?s.message=(0,_.__)("The Parse.ly API couldn't find any relevant data to fulfill the request. Please retry with a different input.","wp-parsely"):s.code===$.ParselySuggestionsApiOpenAiSchema?s.message=(0,_.__)("The Parse.ly API returned an incorrect response. Please try again later.","wp-parsely"):s.code===$.ParselySuggestionsApiAuthUnavailable&&(s.message=(0,_.__)("The Parse.ly API is currently unavailable. Please try again later.","wp-parsely")),s}return re(t,e),t.prototype.Message=function(e){return void 0===e&&(e=null),[$.PluginCredentialsNotSetMessageDetected,$.PluginSettingsSiteIdNotSet,$.PluginSettingsApiSecretNotSet].includes(this.code)?K(e):(this.code===$.FetchError&&(this.hint=this.Hint((0,_.__)("This error can sometimes be caused by ad-blockers or browser tracking protections. Please add this site to any applicable allow lists and try again.","wp-parsely"))),this.code!==$.ParselyApiForbidden&&this.code!==$.ParselySuggestionsApiNoAuthentication||(this.hint=this.Hint((0,_.__)("Please ensure that the Site ID and API Secret given in the plugin's settings are correct.","wp-parsely"))),this.code===$.HttpRequestFailed&&(this.hint=this.Hint((0,_.__)("The Parse.ly API cannot be reached. Please verify that you are online.","wp-parsely"))),(0,p.jsx)(W,{className:null==e?void 0:e.className,testId:"error",children:"

".concat(this.message,"

").concat(this.hint?this.hint:"")}))},t.prototype.Hint=function(e){return'

'.concat((0,_.__)("Hint:","wp-parsely")," ").concat(e,"

")},t.prototype.createErrorSnackbar=function(){//.test(this.message)||(0,h.dispatch)("core/notices").createNotice("error",this.message,{type:"snackbar"})},t}(Error),se=function(e){var t=e.isDetectingEnabled,n=e.onLinkChange,r=e.onLinkRemove,i=e.onLinkAdd,s=e.debounceValue,o=void 0===s?500:s,a=(0,h.useSelect)((function(e){return{blocks:(0,e("core/block-editor").getBlocks)()}}),[]).blocks,l=(0,b.useRef)(a),c=(0,b.useRef)(t);return(0,b.useEffect)((function(){var e=(0,z.debounce)((function(){for(var t=[],s=0;s0)return r(e.innerBlocks,t[s].innerBlocks);if(JSON.stringify(e)!==JSON.stringify(t[s])){var o=t[s],a=i.parseFromString(e.attributes.content||"","text/html"),l=i.parseFromString((null==o?void 0:o.attributes.content)||"","text/html"),c=Array.from(a.querySelectorAll("a[data-smartlink]")),u=Array.from(l.querySelectorAll("a[data-smartlink]")),d=c.filter((function(e){return!u.some((function(t){return t.dataset.smartlink===e.dataset.smartlink}))})),p=u.filter((function(e){return!c.some((function(t){return t.dataset.smartlink===e.dataset.smartlink}))})),f=c.filter((function(e){var t=u.find((function(t){return t.dataset.smartlink===e.dataset.smartlink}));return t&&t.outerHTML!==e.outerHTML}));(d.length>0||p.length>0||f.length>0)&&n.push({block:e,prevBlock:o,addedLinks:d,removedLinks:p,changedLinks:f})}}}))};return r(e,t),n}(a,l.current);o.length>0&&(o.forEach((function(e){e.changedLinks.length>0&&n&&n(e),e.addedLinks.length>0&&i&&i(e),e.removedLinks.length>0&&r&&r(e)})),l.current=a)}),o);return e(t),function(){e.cancel()}}),[a,o,t,i,n,r]),null},oe=function(e){var t=e.value,n=e.onChange,r=e.max,i=e.min,s=e.suffix,o=e.size,a=e.label,l=e.initialPosition,c=e.disabled,u=e.className;return(0,p.jsxs)("div",{className:"parsely-inputrange-control ".concat(u||""),children:[(0,p.jsx)(f.__experimentalHeading,{className:"parsely-inputrange-control__label",level:3,children:a}),(0,p.jsxs)("div",{className:"parsely-inputrange-control__controls",children:[(0,p.jsx)(f.__experimentalNumberControl,{disabled:c,value:t,suffix:(0,p.jsx)(f.__experimentalInputControlSuffixWrapper,{children:s}),size:null!=o?o:"__unstable-large",min:i,max:r,onChange:function(e){var t=parseInt(e,10);isNaN(t)||n(t)}}),(0,p.jsx)(f.RangeControl,{disabled:c,value:t,showTooltip:!1,initialPosition:l,onChange:function(e){n(e)},withInputField:!1,min:i,max:r})]})]})},ae=function(e,t,n,r){return new(n||(n=Promise))((function(i,s){function o(e){try{l(r.next(e))}catch(e){s(e)}}function a(e){try{l(r.throw(e))}catch(e){s(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(o,a)}l((r=r.apply(e,t||[])).next())}))},le=function(e,t){var n,r,i,s,o={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return s={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function a(a){return function(l){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;s&&(s=0,a[0]&&(o=0)),o;)try{if(n=1,r&&(i=2&a[0]?r.return:a[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,a[1])).done)return i;switch(r=0,i&&(a=[2&a[0],i.value]),a[0]){case 0:case 1:i=a;break;case 4:return o.label++,{value:a[1],done:!1};case 5:o.label++,r=a[1],a=[0];continue;case 7:a=o.ops.pop(),o.trys.pop();continue;default:if(!((i=(i=o.trys).length>0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]

","\n\x3c!-- /wp:paragraph --\x3e");t&&h((0,Q.parse)(n))}),[s]),(0,p.jsxs)("div",{className:"smart-linking-review-suggestion",children:[(0,p.jsx)(f.KeyboardShortcuts,{shortcuts:{left:o,right:a,up:o,down:a}}),(0,p.jsx)("div",{className:"review-suggestion-post-title",children:null===(t=s.post_data)||void 0===t?void 0:t.title}),(0,p.jsxs)("div",{className:"review-suggestion-preview",children:[!(null===(n=s.post_data)||void 0===n?void 0:n.is_first_paragraph)&&(0,p.jsx)($e,{topOrBottom:"top"}),(0,p.jsx)(Ze,{block:d[0],link:s,useOriginalBlock:!0}),!(null===(r=s.post_data)||void 0===r?void 0:r.is_last_paragraph)&&(0,p.jsx)($e,{topOrBottom:"bottom"})]}),(0,p.jsx)(f.__experimentalDivider,{}),(0,p.jsx)(We,{link:s}),(0,p.jsxs)("div",{className:"review-controls",children:[(0,p.jsx)(f.Tooltip,{shortcut:"←",text:(0,_.__)("Previous","wp-parsely"),children:(0,p.jsx)(f.Button,{disabled:!l,className:"wp-parsely-review-suggestion-previous",onClick:o,icon:He,children:(0,_.__)("Previous","wp-parsely")})}),(0,p.jsx)("div",{className:"reviews-controls-middle",children:(0,p.jsx)(f.Button,{target:"_blank",href:(null===(i=s.post_data)||void 0===i?void 0:i.edit_link)+"&smart-link="+s.uid,variant:"secondary",onClick:function(){P.trackEvent("smart_linking_open_in_editor_pressed",{type:"inbound",uid:s.uid})},children:(0,_.__)("Open in the Editor","wp-parsely")})}),(0,p.jsx)(f.Tooltip,{shortcut:"→",text:(0,_.__)("Next","wp-parsely"),children:(0,p.jsxs)(f.Button,{disabled:!c,onClick:a,className:"wp-parsely-review-suggestion-next",children:[(0,_.__)("Next","wp-parsely"),(0,p.jsx)(X,{icon:ze})]})})]})]})},Ye=function(e){var t=e.size,n=void 0===t?24:t,r=e.className,i=void 0===r?"wp-parsely-icon":r;return(0,p.jsxs)(f.SVG,{xmlns:"http://www.w3.org/2000/svg",className:i,width:n,height:n,viewBox:"0 0 24 24",fill:"none",children:[(0,p.jsx)(f.Path,{d:"M8.18983 5.90381L8.83642 7.54325L10.4758 8.18983L8.83642 8.8364L8.18983 10.4759L7.54324 8.8364L5.90381 8.18983L7.54324 7.54325L8.18983 5.90381Z"}),(0,p.jsx)(f.Path,{d:"M15.048 5.90381L15.9101 8.08972L18.0961 8.95186L15.9101 9.81397L15.048 11.9999L14.1859 9.81397L12 8.95186L14.1859 8.08972L15.048 5.90381Z"}),(0,p.jsx)(f.Path,{d:"M11.238 10.4761L12.3157 13.2085L15.048 14.2861L12.3157 15.3638L11.238 18.0962L10.1603 15.3638L7.42798 14.2861L10.1603 13.2085L11.238 10.4761Z"})]})},Je=function(e,t,n){if(n||2===arguments.length)for(var r,i=0,s=t.length;ii.bottom)&&(n.scrollTop=r.offsetTop-n.offsetTop)}}}}),[t,l]);var u=function(){var e=document.querySelector(".smart-linking-review-sidebar-tabs [data-active-item]"),t=null==e?void 0:e.nextElementSibling;t||(t=document.querySelector('.smart-linking-review-sidebar-tabs [role="tab"]')),t&&t.click()},d=(0,p.jsxs)("span",{className:"smart-linking-menu-label",children:[(0,_.__)("NEW","wp-parsely"),(0,p.jsx)(Ye,{})]}),h=[];n&&n.length>0&&h.push({name:"outbound",title:(0,_.__)("Outbound","wp-parsely")}),r&&r.length>0&&h.push({name:"inbound",title:(0,_.__)("Inbound","wp-parsely")});var v="outbound";return h=h.filter((function(e){return"outbound"===e.name&&r&&0===r.length&&(e.title=(0,_.__)("Outbound Smart Links","wp-parsely"),v="outbound"),"inbound"===e.name&&n&&0===n.length&&(e.title=(0,_.__)("Inbound Smart Links","wp-parsely"),v="inbound"),e})),(0,p.jsxs)("div",{className:"smart-linking-review-sidebar",ref:s,children:[(0,p.jsx)(f.KeyboardShortcuts,{shortcuts:{tab:function(){return u()},"shift+tab":function(){return u()}}}),(0,p.jsx)(f.TabPanel,{className:"smart-linking-review-sidebar-tabs",initialTabName:v,tabs:h,onSelect:function(e){var t,s;"outbound"===e&&n&&n.length>0&&i(n[0]),"inbound"===e&&r&&r.length>0&&i(r[0]),P.trackEvent("smart_linking_modal_tab_selected",{tab:e,total_inbound:null!==(t=null==r?void 0:r.length)&&void 0!==t?t:0,total_outbound:null!==(s=null==n?void 0:n.length)&&void 0!==s?s:0})},children:function(e){return(0,p.jsxs)(p.Fragment,{children:["outbound"===e.name&&(0,p.jsx)(p.Fragment,{children:n&&0!==n.length?n.map((function(e,n){return(0,p.jsxs)(f.MenuItem,{ref:function(e){o.current[n]=e},className:(null==t?void 0:t.uid)===e.uid?"is-selected":"",role:"menuitemradio",isSelected:(null==t?void 0:t.uid)===e.uid,onClick:function(){return i(e)},children:[(0,p.jsx)("span",{className:"smart-linking-menu-item",children:e.text}),!e.applied&&d]},e.uid)})):(0,p.jsxs)(p.Fragment,{children:[" ",(0,_.__)("No outbound links found.","wp-parsely")]})}),"inbound"===e.name&&(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)("div",{className:"review-sidebar-tip",children:(0,_.__)("This section shows external posts that link back to the current post.","wp-parsely")}),r&&0!==r.length?r.map((function(e,r){var s;return(0,p.jsx)(f.MenuItem,{ref:function(e){o.current[(n?n.length:0)+r]=e},className:(null==t?void 0:t.uid)===e.uid?"is-selected":"",role:"menuitemradio",isSelected:(null==t?void 0:t.uid)===e.uid,onClick:function(){return i(e)},children:(0,p.jsx)("span",{className:"smart-linking-menu-item",children:null===(s=e.post_data)||void 0===s?void 0:s.title})},e.uid)})):(0,p.jsxs)(p.Fragment,{children:[" ",(0,_.__)("No inbound links found.","wp-parsely")]})]})]})}})]})},Xe=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"M12 13.06l3.712 3.713 1.061-1.06L13.061 12l3.712-3.712-1.06-1.06L12 10.938 8.288 7.227l-1.061 1.06L10.939 12l-3.712 3.712 1.06 1.061L12 13.061z"})}),et=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"M16.7 7.1l-6.3 8.5-3.3-2.5-.9 1.2 4.5 3.4L17.9 8z"})}),tt=function(e){var t,n,r,i,s=null===(t=e.link.match)||void 0===t?void 0:t.blockId,o=(0,h.useSelect)((function(e){var t=e("core/block-editor"),n=t.getBlock,r=t.getBlockParents;return s?{block:n(s),parents:r(s).map((function(e){return n(e)})).filter((function(e){return void 0!==e}))}:{block:void 0,parents:[]}}),[s]),a=o.block,l=o.parents;return a?(0,p.jsxs)("div",{className:"review-suggestions-breadcrumbs",children:[l.map((function(e,t){var n;return(0,p.jsxs)("span",{children:[(0,p.jsx)("span",{className:"breadcrumbs-parent-block",children:null===(n=(0,Q.getBlockType)(e.name))||void 0===n?void 0:n.title}),(0,p.jsx)("span",{className:"breadcrumbs-parent-separator",children:" / "})]},t)})),(0,p.jsxs)("span",{className:"breadcrumbs-current-block",children:[(0,p.jsx)("span",{className:"breadcrumbs-current-block-type",children:null===(n=(0,Q.getBlockType)(a.name))||void 0===n?void 0:n.title}),(null===(i=null===(r=a.attributes)||void 0===r?void 0:r.metadata)||void 0===i?void 0:i.name)&&(0,p.jsx)("span",{className:"breadcrumbs-current-block-name",children:a.attributes.metadata.name})]})]}):(0,p.jsx)(p.Fragment,{})},nt=function(e){var t,n=e.link,r=(0,b.useState)(n.href),i=r[0],s=r[1],o=(0,b.useState)(null===(t=n.destination)||void 0===t?void 0:t.post_type),a=o[0],l=o[1],c=(0,b.useRef)(null),u=(0,h.useDispatch)(Te).updateSmartLink;return(0,b.useEffect)((function(){n.destination?l(n.destination.post_type):(l((0,_.__)("External","wp-parsely")),De.getInstance().getPostTypeByURL(n.href).then((function(e){e&&l(e.post_type),n.destination=e,u(n)})))}),[n,u]),(0,b.useEffect)((function(){var e=function(){if(c.current){var e=c.current.offsetWidth,t=Math.floor(e/8);s(function(e,t){var n=e.replace(/(^\w+:|^)\/\//,"").replace(/^www\./,"");if(!t||n.length<=t)return n;var r=n.split("/")[0],i=n.substring(r.length);t-=r.length;var s=Math.floor((t-3)/2),o=i.substring(0,s),a=i.substring(i.length-s);return"".concat(r).concat(o,"...").concat(a)}(n.href,t))}};return e(),window.addEventListener("resize",e),function(){window.removeEventListener("resize",e)}}),[n]),(0,p.jsx)(f.MenuItem,{ref:c,info:i,iconPosition:"left",icon:Ge,shortcut:a,className:"block-editor-link-control__search-item wp-parsely-link-suggestion-link-details",children:n.title})},rt=function(e){var t=e.link,n=e.onNext,r=e.onPrevious,i=e.onAccept,s=e.onReject,o=e.onRemove,a=e.onSelectInEditor,l=e.hasPrevious,c=e.hasNext;if(t&&void 0!==t.post_data)return(0,p.jsx)(Ke,{link:t,onNext:n,onPrevious:r,onAccept:i,onReject:s,onRemove:o,onSelectInEditor:a,hasPrevious:l,hasNext:c});if(!(null==t?void 0:t.match))return(0,p.jsx)(p.Fragment,{children:(0,_.__)("This Smart Link does not have any matches in the current content.","wp-parsely")});var u=t.match.blockId,d=(0,h.select)("core/block-editor").getBlock(u),v=t.applied;return d?(0,p.jsxs)("div",{className:"smart-linking-review-suggestion",children:[(0,p.jsx)(f.KeyboardShortcuts,{shortcuts:{left:r,right:n,up:r,down:n,a:function(){t&&!t.applied&&i()},r:function(){t&&(t.applied?o():s())}}}),(0,p.jsx)(tt,{link:t}),(0,p.jsx)("div",{className:"review-suggestion-preview",children:(0,p.jsx)(Ze,{block:d,link:t})}),(0,p.jsx)(f.__experimentalDivider,{}),(0,p.jsx)(nt,{link:t}),(0,p.jsxs)("div",{className:"review-controls",children:[(0,p.jsx)(f.Tooltip,{shortcut:"←",text:(0,_.__)("Previous","wp-parsely"),children:(0,p.jsx)(f.Button,{disabled:!l,className:"wp-parsely-review-suggestion-previous",onClick:r,icon:He,children:(0,_.__)("Previous","wp-parsely")})}),(0,p.jsxs)("div",{className:"reviews-controls-middle",children:[!v&&(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)(f.Tooltip,{shortcut:"R",text:(0,_.__)("Reject","wp-parsely"),children:(0,p.jsx)(f.Button,{className:"wp-parsely-review-suggestion-reject",icon:Xe,onClick:s,variant:"secondary",children:(0,_.__)("Reject","wp-parsely")})}),(0,p.jsx)(f.Tooltip,{shortcut:"A",text:(0,_.__)("Accept","wp-parsely"),children:(0,p.jsx)(f.Button,{className:"wp-parsely-review-suggestion-accept",icon:et,onClick:i,variant:"secondary",children:(0,_.__)("Accept","wp-parsely")})})]}),v&&(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)(f.Tooltip,{shortcut:"R",text:(0,_.__)("Remove","wp-parsely"),children:(0,p.jsx)(f.Button,{className:"wp-parsely-review-suggestion-reject",icon:Xe,onClick:o,variant:"secondary",children:(0,_.__)("Remove","wp-parsely")})}),(0,p.jsx)(f.Button,{className:"wp-parsely-review-suggestion-accept",onClick:a,variant:"secondary",children:(0,_.__)("Select in Editor","wp-parsely")})]})]}),(0,p.jsx)(f.Tooltip,{shortcut:"→",text:(0,_.__)("Next","wp-parsely"),children:(0,p.jsxs)(f.Button,{disabled:!c,onClick:n,className:"wp-parsely-review-suggestion-next",children:[(0,_.__)("Next","wp-parsely"),(0,p.jsx)(X,{icon:ze})]})})]})]}):(0,p.jsx)(p.Fragment,{children:(0,_.__)("No block is selected.","wp-parsely")})},it=function(e,t,n,r){return new(n||(n=Promise))((function(i,s){function o(e){try{l(r.next(e))}catch(e){s(e)}}function a(e){try{l(r.throw(e))}catch(e){s(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(o,a)}l((r=r.apply(e,t||[])).next())}))},st=function(e,t){var n,r,i,s,o={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return s={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function a(a){return function(l){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;s&&(s=0,a[0]&&(o=0)),o;)try{if(n=1,r&&(i=2&a[0]?r.return:a[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,a[1])).done)return i;switch(r=0,i&&(a=[2&a[0],i.value]),a[0]){case 0:case 1:i=a;break;case 4:return o.label++,{value:a[1],done:!1};case 5:o.label++,r=a[1],a=[0];continue;case 7:a=o.ops.pop(),o.trys.pop();continue;default:if(!((i=(i=o.trys).length>0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&(a=o[0],(l=a.parentNode)&&(c=document.createTextNode(null!==(u=a.textContent)&&void 0!==u?u:""),l.replaceChild(c,a),te.updateBlockAttributes(n,{content:s.innerHTML}))),[4,E(t.uid)]):[2]):[2];case 1:return d.sent(),[2]}}))}))},C=(0,b.useCallback)((function(){c(!1),w().filter((function(e){return!e.applied})).length>0?o(!0):(ne.unlockPostAutosaving("smart-linking-review-modal"),t())}),[w,t]),A=function(e){o(!1),e?(c(!1),T().then((function(){C()}))):c(!0)},O=function(){if(ue(k)){var e=g.indexOf(k);if(!g[t=e+1])return;S(g[t])}else{var t;if(e=v.indexOf(k),!v[t=e+1])return;S(v[t])}},R=function(){if(ue(k)){var e=g.indexOf(k);if(!g[t=e-1])return;S(g[t])}else{var t;if(e=v.indexOf(k),!v[t=e-1])return;S(v[t])}};return(0,b.useEffect)((function(){l?ne.lockPostAutosaving("smart-linking-review-modal"):l&&0===d.length&&C()}),[l,t,d,C]),(0,b.useEffect)((function(){c(n)}),[n]),(0,p.jsxs)(p.Fragment,{children:[l&&(0,p.jsx)(f.Modal,{title:(0,_.__)("Review Smart Links","wp-parsely"),className:"wp-parsely-smart-linking-review-modal",onRequestClose:C,shouldCloseOnClickOutside:!1,shouldCloseOnEsc:!1,children:(0,p.jsxs)("div",{className:"smart-linking-modal-body",children:[(0,p.jsx)(Qe,{outboundLinks:v,inboundLinks:g,activeLink:k,setSelectedLink:S}),k&&(ue(k)?(0,p.jsx)(Ke,{link:k,onNext:O,onPrevious:R,hasNext:g.indexOf(k)0}):(0,p.jsx)(rt,{link:k,hasNext:m().indexOf(k)0,onNext:O,onPrevious:R,onAccept:function(){return it(void 0,void 0,void 0,(function(){var e,t;return st(this,(function(n){switch(n.label){case 0:return k.match?(r(k),[4,(i=k.match.blockId,s=k,it(void 0,void 0,void 0,(function(){var e,t;return st(this,(function(n){switch(n.label){case 0:return(e=document.createElement("a")).href=s.href,e.title=s.title,e.setAttribute("data-smartlink",s.uid),(t=(0,h.select)("core/block-editor").getBlock(i))?(fe(t,s,e),s.applied=!0,[4,L(s)]):[2];case 1:return n.sent(),[2]}}))})))]):[2];case 1:return n.sent(),P.trackEvent("smart_linking_link_accepted",{link:k.href,title:k.title,text:k.text,uid:k.uid}),0===y().length?(C(),[2]):(e=v.indexOf(k),v[t=e+1]?S(v[t]):S(v[0]),[2])}var i,s}))}))},onReject:function(){return it(void 0,void 0,void 0,(function(){var e,t;return st(this,(function(n){switch(n.label){case 0:return e=v.indexOf(k),v[t=e+1]?S(v[t]):v[0]?S(v[0]):C(),[4,E(k.uid)];case 1:return n.sent(),P.trackEvent("smart_linking_link_rejected",{link:k.href,title:k.title,text:k.text,uid:k.uid}),[2]}}))}))},onRemove:function(){return it(void 0,void 0,void 0,(function(){var e,t,n,r;return st(this,(function(i){switch(i.label){case 0:return k.match?(e=(0,h.select)("core/block-editor").getBlock(k.match.blockId))?(t=m(),n=t.indexOf(k),r=n-1,[4,N(e,k)]):[3,2]:[2];case 1:if(i.sent(),P.trackEvent("smart_linking_link_removed",{link:k.href,title:k.title,text:k.text,uid:k.uid}),0===(t=m()).length&&g.length>0)return S(g[0]),[2];if(0===t.length&&0===g.length)return C(),[2];if(t[r])return S(t[r]),[2];S(t[0]),i.label=2;case 2:return[2]}}))}))},onSelectInEditor:function(){if(k.match){var e=(0,h.select)("core/block-editor").getBlock(k.match.blockId);if(e){te.selectBlock(e.clientId);var t=document.querySelector('[data-block="'.concat(e.clientId,'"]'));t&&ke(t,k.uid),P.trackEvent("smart_linking_select_in_editor_pressed",{type:"outbound",uid:k.uid}),C()}}}}))]})}),s&&(0,p.jsxs)(f.Modal,{title:(0,_.__)("Review Smart Links","wp-parsely"),onRequestClose:function(){return A(!1)},className:"wp-parsely-smart-linking-close-dialog",children:[(0,_.__)("Are you sure you want to close? All un-accepted smart links will not be added.","wp-parsely"),(0,p.jsxs)("div",{className:"smart-linking-close-dialog-actions",children:[(0,p.jsx)(f.Button,{variant:"secondary",onClick:function(){return A(!1)},children:(0,_.__)("Go Back","wp-parsely")}),(0,p.jsx)(f.Button,{variant:"primary",onClick:function(){return A(!0)},children:(0,_.__)("Close","wp-parsely")})]})]})]})})),at=function(){return at=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&k("success",/* translators: %d: number of smart links applied */ /* translators: %d: number of smart links applied */ +/* translators: %s: block name */n((0,_.sprintf)((0,_.__)("%s blocks are not supported for Smart Links.","wp-parsely"),s))}T(_e.All===C)}}),[d,S,C,r,i,y,E,T,c]),(0,b.useEffect)((function(){if(!r&&o.current&&C&&!k&&y){var e=o.current.querySelector('button[data-value="'.concat(C,'"]'));e&&"true"!==e.getAttribute("aria-checked")&&(E(C),L(!0))}}),[y,x,r,S]),(0,b.useEffect)((function(){c(null)}),[y]),(0,p.jsx)("div",{className:"parsely-panel-settings",children:(0,p.jsxs)("div",{className:"parsely-panel-settings-body",children:[(0,p.jsxs)("div",{className:"smart-linking-block-select",children:[(0,p.jsx)(f.Disabled,{isDisabled:r,children:(0,p.jsxs)(f.__experimentalToggleGroupControl,{ref:o,__nextHasNoMarginBottom:!0,__next40pxDefaultSize:!0,isBlock:!0,value:C,label:(0,_.__)("Apply Smart Links to","wp-parsely"),onChange:function(e){return Ee(void 0,void 0,void 0,(function(){return Ne(this,(function(t){switch(t.label){case 0:return r?[2]:(v(!0),[4,T(_e.All===e)]);case 1:return t.sent(),[4,E(e)];case 2:return t.sent(),setTimeout((function(){v(!1)}),500),[2]}}))}))},children:[(0,p.jsx)(f.__experimentalToggleGroupControlOption,{label:(0,_.__)("Selected Block","wp-parsely"),value:"selected"}),(0,p.jsx)(f.__experimentalToggleGroupControlOption,{label:(0,_.__)("All Blocks","wp-parsely"),value:"all"})]})}),l&&(0,p.jsxs)("div",{className:"wp-parsely-smart-linking-hint",children:[(0,p.jsx)("strong",{children:(0,_.__)("Hint:","wp-parsely")})," ",l]})]}),(0,p.jsx)("div",{className:"smart-linking-settings",children:(0,p.jsx)(oe,{value:w,onChange:function(e){j(null!=e?e:1),s("MaxLinks",null!=e?e:mt)},label:(0,_.__)("Target Number of Links","wp-parsely"),suffix:(0,_.__)("Links","wp-parsely"),min:1,max:20,initialPosition:w,disabled:r})})]})})},Ae=window.wp.editor,Oe=window.wp.url,Re=function(){function e(){this.abortControllers=new Map}return e.prototype.cancelRequest=function(e){if(e)(t=this.abortControllers.get(e))&&(t.abort(),this.abortControllers.delete(e));else{var t,n=Array.from(this.abortControllers.keys()).pop();n&&(t=this.abortControllers.get(n))&&(t.abort(),this.abortControllers.delete(n))}},e.prototype.cancelAll=function(){this.abortControllers.forEach((function(e){return e.abort()})),this.abortControllers.clear()},e.prototype.getOrCreateController=function(e){if(e&&this.abortControllers.has(e))return{abortController:this.abortControllers.get(e),abortId:e};var t=null!=e?e:"auto-"+Date.now(),n=new AbortController;return this.abortControllers.set(t,n),{abortController:n,abortId:t}},e.prototype.fetch=function(e,t){return n=this,r=void 0,s=function(){var n,r,i,s,o,a;return function(e,t){var n,r,i,s,o={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return s={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function a(a){return function(l){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;s&&(s=0,a[0]&&(o=0)),o;)try{if(n=1,r&&(i=2&a[0]?r.return:a[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,a[1])).done)return i;switch(r=0,i&&(a=[2&a[0],i.value]),a[0]){case 0:case 1:i=a;break;case 4:return o.label++,{value:a[1],done:!1};case 5:o.label++,r=a[1],a=[0];continue;case 7:a=o.ops.pop(),o.trys.pop();continue;default:if(!((i=(i=o.trys).length>0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]

","\n\x3c!-- /wp:paragraph --\x3e");t&&h((0,Q.parse)(n))}),[s]),(0,p.jsxs)("div",{className:"smart-linking-review-suggestion",children:[(0,p.jsx)(f.KeyboardShortcuts,{shortcuts:{left:o,right:a,up:o,down:a}}),(0,p.jsx)("div",{className:"review-suggestion-post-title",children:null===(t=s.post_data)||void 0===t?void 0:t.title}),(0,p.jsxs)("div",{className:"review-suggestion-preview",children:[!(null===(n=s.post_data)||void 0===n?void 0:n.is_first_paragraph)&&(0,p.jsx)($e,{topOrBottom:"top"}),(0,p.jsx)(Ze,{block:d[0],link:s,useOriginalBlock:!0}),!(null===(r=s.post_data)||void 0===r?void 0:r.is_last_paragraph)&&(0,p.jsx)($e,{topOrBottom:"bottom"})]}),(0,p.jsx)(f.__experimentalDivider,{}),(0,p.jsx)(We,{link:s}),(0,p.jsxs)("div",{className:"review-controls",children:[(0,p.jsx)(f.Tooltip,{shortcut:"←",text:(0,_.__)("Previous","wp-parsely"),children:(0,p.jsx)(f.Button,{disabled:!l,className:"wp-parsely-review-suggestion-previous",onClick:o,icon:He,children:(0,_.__)("Previous","wp-parsely")})}),(0,p.jsx)("div",{className:"reviews-controls-middle",children:(0,p.jsx)(f.Button,{target:"_blank",href:(null===(i=s.post_data)||void 0===i?void 0:i.edit_link)+"&smart-link="+s.uid,variant:"secondary",onClick:function(){P.trackEvent("smart_linking_open_in_editor_pressed",{type:"inbound",uid:s.uid})},children:(0,_.__)("Open in the Editor","wp-parsely")})}),(0,p.jsx)(f.Tooltip,{shortcut:"→",text:(0,_.__)("Next","wp-parsely"),children:(0,p.jsxs)(f.Button,{disabled:!c,onClick:a,className:"wp-parsely-review-suggestion-next",children:[(0,_.__)("Next","wp-parsely"),(0,p.jsx)(X,{icon:ze})]})})]})]})},Ye=function(e){var t=e.size,n=void 0===t?24:t,r=e.className,i=void 0===r?"wp-parsely-icon":r;return(0,p.jsxs)(f.SVG,{xmlns:"http://www.w3.org/2000/svg",className:i,width:n,height:n,viewBox:"0 0 24 24",fill:"none",children:[(0,p.jsx)(f.Path,{d:"M8.18983 5.90381L8.83642 7.54325L10.4758 8.18983L8.83642 8.8364L8.18983 10.4759L7.54324 8.8364L5.90381 8.18983L7.54324 7.54325L8.18983 5.90381Z"}),(0,p.jsx)(f.Path,{d:"M15.048 5.90381L15.9101 8.08972L18.0961 8.95186L15.9101 9.81397L15.048 11.9999L14.1859 9.81397L12 8.95186L14.1859 8.08972L15.048 5.90381Z"}),(0,p.jsx)(f.Path,{d:"M11.238 10.4761L12.3157 13.2085L15.048 14.2861L12.3157 15.3638L11.238 18.0962L10.1603 15.3638L7.42798 14.2861L10.1603 13.2085L11.238 10.4761Z"})]})},Je=function(e,t,n){if(n||2===arguments.length)for(var r,i=0,s=t.length;ii.bottom)&&(n.scrollTop=r.offsetTop-n.offsetTop)}}}}),[t,l]);var u=function(){var e=document.querySelector(".smart-linking-review-sidebar-tabs [data-active-item]"),t=null==e?void 0:e.nextElementSibling;t||(t=document.querySelector('.smart-linking-review-sidebar-tabs [role="tab"]')),t&&t.click()},d=(0,p.jsxs)("span",{className:"smart-linking-menu-label",children:[(0,_.__)("NEW","wp-parsely"),(0,p.jsx)(Ye,{})]}),h=[];n&&n.length>0&&h.push({name:"outbound",title:(0,_.__)("Outbound","wp-parsely")}),r&&r.length>0&&h.push({name:"inbound",title:(0,_.__)("Inbound","wp-parsely")});var v="outbound";return h=h.filter((function(e){return"outbound"===e.name&&r&&0===r.length&&(e.title=(0,_.__)("Outbound Smart Links","wp-parsely"),v="outbound"),"inbound"===e.name&&n&&0===n.length&&(e.title=(0,_.__)("Inbound Smart Links","wp-parsely"),v="inbound"),e})),(0,p.jsxs)("div",{className:"smart-linking-review-sidebar",ref:s,children:[(0,p.jsx)(f.KeyboardShortcuts,{shortcuts:{tab:function(){return u()},"shift+tab":function(){return u()}}}),(0,p.jsx)(f.TabPanel,{className:"smart-linking-review-sidebar-tabs",initialTabName:v,tabs:h,onSelect:function(e){var t,s;"outbound"===e&&n&&n.length>0&&i(n[0]),"inbound"===e&&r&&r.length>0&&i(r[0]),P.trackEvent("smart_linking_modal_tab_selected",{tab:e,total_inbound:null!==(t=null==r?void 0:r.length)&&void 0!==t?t:0,total_outbound:null!==(s=null==n?void 0:n.length)&&void 0!==s?s:0})},children:function(e){return(0,p.jsxs)(p.Fragment,{children:["outbound"===e.name&&(0,p.jsx)(p.Fragment,{children:n&&0!==n.length?n.map((function(e,n){return(0,p.jsxs)(f.MenuItem,{ref:function(e){o.current[n]=e},className:(null==t?void 0:t.uid)===e.uid?"is-selected":"",role:"menuitemradio",isSelected:(null==t?void 0:t.uid)===e.uid,onClick:function(){return i(e)},children:[(0,p.jsx)("span",{className:"smart-linking-menu-item",children:e.text}),!e.applied&&d]},e.uid)})):(0,p.jsxs)(p.Fragment,{children:[" ",(0,_.__)("No outbound links found.","wp-parsely")]})}),"inbound"===e.name&&(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)("div",{className:"review-sidebar-tip",children:(0,_.__)("This section shows external posts that link back to the current post.","wp-parsely")}),r&&0!==r.length?r.map((function(e,r){var s;return(0,p.jsx)(f.MenuItem,{ref:function(e){o.current[(n?n.length:0)+r]=e},className:(null==t?void 0:t.uid)===e.uid?"is-selected":"",role:"menuitemradio",isSelected:(null==t?void 0:t.uid)===e.uid,onClick:function(){return i(e)},children:(0,p.jsx)("span",{className:"smart-linking-menu-item",children:null===(s=e.post_data)||void 0===s?void 0:s.title})},e.uid)})):(0,p.jsxs)(p.Fragment,{children:[" ",(0,_.__)("No inbound links found.","wp-parsely")]})]})]})}})]})},Xe=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"M12 13.06l3.712 3.713 1.061-1.06L13.061 12l3.712-3.712-1.06-1.06L12 10.938 8.288 7.227l-1.061 1.06L10.939 12l-3.712 3.712 1.06 1.061L12 13.061z"})}),et=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"M16.7 7.1l-6.3 8.5-3.3-2.5-.9 1.2 4.5 3.4L17.9 8z"})}),tt=function(e){var t,n,r,i,s=null===(t=e.link.match)||void 0===t?void 0:t.blockId,o=(0,h.useSelect)((function(e){var t=e("core/block-editor"),n=t.getBlock,r=t.getBlockParents;return s?{block:n(s),parents:r(s).map((function(e){return n(e)})).filter((function(e){return void 0!==e}))}:{block:void 0,parents:[]}}),[s]),a=o.block,l=o.parents;return a?(0,p.jsxs)("div",{className:"review-suggestions-breadcrumbs",children:[l.map((function(e,t){var n;return(0,p.jsxs)("span",{children:[(0,p.jsx)("span",{className:"breadcrumbs-parent-block",children:null===(n=(0,Q.getBlockType)(e.name))||void 0===n?void 0:n.title}),(0,p.jsx)("span",{className:"breadcrumbs-parent-separator",children:" / "})]},t)})),(0,p.jsxs)("span",{className:"breadcrumbs-current-block",children:[(0,p.jsx)("span",{className:"breadcrumbs-current-block-type",children:null===(n=(0,Q.getBlockType)(a.name))||void 0===n?void 0:n.title}),(null===(i=null===(r=a.attributes)||void 0===r?void 0:r.metadata)||void 0===i?void 0:i.name)&&(0,p.jsx)("span",{className:"breadcrumbs-current-block-name",children:a.attributes.metadata.name})]})]}):(0,p.jsx)(p.Fragment,{})},nt=function(e){var t,n=e.link,r=(0,b.useState)(n.href),i=r[0],s=r[1],o=(0,b.useState)(null===(t=n.destination)||void 0===t?void 0:t.post_type),a=o[0],l=o[1],c=(0,b.useRef)(null),u=(0,h.useDispatch)(Te).updateSmartLink;return(0,b.useEffect)((function(){n.destination?l(n.destination.post_type):(l((0,_.__)("External","wp-parsely")),De.getInstance().getPostTypeByURL(n.href).then((function(e){e&&l(e.post_type),n.destination=e,u(n)})))}),[n,u]),(0,b.useEffect)((function(){var e=function(){if(c.current){var e=c.current.offsetWidth,t=Math.floor(e/8);s(function(e,t){var n=e.replace(/(^\w+:|^)\/\//,"").replace(/^www\./,"");if(!t||n.length<=t)return n;var r=n.split("/")[0],i=n.substring(r.length);t-=r.length;var s=Math.floor((t-3)/2),o=i.substring(0,s),a=i.substring(i.length-s);return"".concat(r).concat(o,"...").concat(a)}(n.href,t))}};return e(),window.addEventListener("resize",e),function(){window.removeEventListener("resize",e)}}),[n]),(0,p.jsx)(f.MenuItem,{ref:c,info:i,iconPosition:"left",icon:Ge,shortcut:a,className:"block-editor-link-control__search-item wp-parsely-link-suggestion-link-details",children:n.title})},rt=function(e){var t=e.link,n=e.onNext,r=e.onPrevious,i=e.onAccept,s=e.onReject,o=e.onRemove,a=e.onSelectInEditor,l=e.hasPrevious,c=e.hasNext;if(t&&void 0!==t.post_data)return(0,p.jsx)(Ke,{link:t,onNext:n,onPrevious:r,onAccept:i,onReject:s,onRemove:o,onSelectInEditor:a,hasPrevious:l,hasNext:c});if(!(null==t?void 0:t.match))return(0,p.jsx)(p.Fragment,{children:(0,_.__)("This Smart Link does not have any matches in the current content.","wp-parsely")});var u=t.match.blockId,d=(0,h.select)("core/block-editor").getBlock(u),v=t.applied;return d?(0,p.jsxs)("div",{className:"smart-linking-review-suggestion",children:[(0,p.jsx)(f.KeyboardShortcuts,{shortcuts:{left:r,right:n,up:r,down:n,a:function(){t&&!t.applied&&i()},r:function(){t&&(t.applied?o():s())}}}),(0,p.jsx)(tt,{link:t}),(0,p.jsx)("div",{className:"review-suggestion-preview",children:(0,p.jsx)(Ze,{block:d,link:t})}),(0,p.jsx)(f.__experimentalDivider,{}),(0,p.jsx)(nt,{link:t}),(0,p.jsxs)("div",{className:"review-controls",children:[(0,p.jsx)(f.Tooltip,{shortcut:"←",text:(0,_.__)("Previous","wp-parsely"),children:(0,p.jsx)(f.Button,{disabled:!l,className:"wp-parsely-review-suggestion-previous",onClick:r,icon:He,children:(0,_.__)("Previous","wp-parsely")})}),(0,p.jsxs)("div",{className:"reviews-controls-middle",children:[!v&&(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)(f.Tooltip,{shortcut:"R",text:(0,_.__)("Reject","wp-parsely"),children:(0,p.jsx)(f.Button,{className:"wp-parsely-review-suggestion-reject",icon:Xe,onClick:s,variant:"secondary",children:(0,_.__)("Reject","wp-parsely")})}),(0,p.jsx)(f.Tooltip,{shortcut:"A",text:(0,_.__)("Accept","wp-parsely"),children:(0,p.jsx)(f.Button,{className:"wp-parsely-review-suggestion-accept",icon:et,onClick:i,variant:"secondary",children:(0,_.__)("Accept","wp-parsely")})})]}),v&&(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)(f.Tooltip,{shortcut:"R",text:(0,_.__)("Remove","wp-parsely"),children:(0,p.jsx)(f.Button,{className:"wp-parsely-review-suggestion-reject",icon:Xe,onClick:o,variant:"secondary",children:(0,_.__)("Remove","wp-parsely")})}),(0,p.jsx)(f.Button,{className:"wp-parsely-review-suggestion-accept",onClick:a,variant:"secondary",children:(0,_.__)("Select in Editor","wp-parsely")})]})]}),(0,p.jsx)(f.Tooltip,{shortcut:"→",text:(0,_.__)("Next","wp-parsely"),children:(0,p.jsxs)(f.Button,{disabled:!c,onClick:n,className:"wp-parsely-review-suggestion-next",children:[(0,_.__)("Next","wp-parsely"),(0,p.jsx)(X,{icon:ze})]})})]})]}):(0,p.jsx)(p.Fragment,{children:(0,_.__)("No block is selected.","wp-parsely")})},it=function(e,t,n,r){return new(n||(n=Promise))((function(i,s){function o(e){try{l(r.next(e))}catch(e){s(e)}}function a(e){try{l(r.throw(e))}catch(e){s(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(o,a)}l((r=r.apply(e,t||[])).next())}))},st=function(e,t){var n,r,i,s,o={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return s={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function a(a){return function(l){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;s&&(s=0,a[0]&&(o=0)),o;)try{if(n=1,r&&(i=2&a[0]?r.return:a[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,a[1])).done)return i;switch(r=0,i&&(a=[2&a[0],i.value]),a[0]){case 0:case 1:i=a;break;case 4:return o.label++,{value:a[1],done:!1};case 5:o.label++,r=a[1],a=[0];continue;case 7:a=o.ops.pop(),o.trys.pop();continue;default:if(!((i=(i=o.trys).length>0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&(a=o[0],(l=a.parentNode)&&(c=document.createTextNode(null!==(u=a.textContent)&&void 0!==u?u:""),l.replaceChild(c,a),te.updateBlockAttributes(n,{content:s.innerHTML}))),[4,E(t.uid)]):[2]):[2];case 1:return d.sent(),[2]}}))}))},C=(0,b.useCallback)((function(){c(!1),w().filter((function(e){return!e.applied})).length>0?o(!0):(ne.unlockPostAutosaving("smart-linking-review-modal"),t())}),[w,t]),A=function(e){o(!1),e?(c(!1),T().then((function(){C()}))):c(!0)},O=function(){if(ue(k)){var e=g.indexOf(k);if(!g[t=e+1])return;S(g[t])}else{var t;if(e=v.indexOf(k),!v[t=e+1])return;S(v[t])}},R=function(){if(ue(k)){var e=g.indexOf(k);if(!g[t=e-1])return;S(g[t])}else{var t;if(e=v.indexOf(k),!v[t=e-1])return;S(v[t])}};return(0,b.useEffect)((function(){l?ne.lockPostAutosaving("smart-linking-review-modal"):l&&0===d.length&&C()}),[l,t,d,C]),(0,b.useEffect)((function(){c(n)}),[n]),(0,p.jsxs)(p.Fragment,{children:[l&&(0,p.jsx)(f.Modal,{title:(0,_.__)("Review Smart Links","wp-parsely"),className:"wp-parsely-smart-linking-review-modal",onRequestClose:C,shouldCloseOnClickOutside:!1,shouldCloseOnEsc:!1,children:(0,p.jsxs)("div",{className:"smart-linking-modal-body",children:[(0,p.jsx)(Qe,{outboundLinks:v,inboundLinks:g,activeLink:k,setSelectedLink:S}),k&&(ue(k)?(0,p.jsx)(Ke,{link:k,onNext:O,onPrevious:R,hasNext:g.indexOf(k)0}):(0,p.jsx)(rt,{link:k,hasNext:m().indexOf(k)0,onNext:O,onPrevious:R,onAccept:function(){return it(void 0,void 0,void 0,(function(){var e,t;return st(this,(function(n){switch(n.label){case 0:return k.match?(r(k),[4,(i=k.match.blockId,s=k,it(void 0,void 0,void 0,(function(){var e,t;return st(this,(function(n){switch(n.label){case 0:return(e=document.createElement("a")).href=s.href,e.title=s.title,e.setAttribute("data-smartlink",s.uid),(t=(0,h.select)("core/block-editor").getBlock(i))?(fe(t,s,e),s.applied=!0,[4,L(s)]):[2];case 1:return n.sent(),[2]}}))})))]):[2];case 1:return n.sent(),P.trackEvent("smart_linking_link_accepted",{link:k.href,title:k.title,text:k.text,uid:k.uid}),0===y().length?(C(),[2]):(e=v.indexOf(k),v[t=e+1]?S(v[t]):S(v[0]),[2])}var i,s}))}))},onReject:function(){return it(void 0,void 0,void 0,(function(){var e,t;return st(this,(function(n){switch(n.label){case 0:return e=v.indexOf(k),v[t=e+1]?S(v[t]):v[0]?S(v[0]):C(),[4,E(k.uid)];case 1:return n.sent(),P.trackEvent("smart_linking_link_rejected",{link:k.href,title:k.title,text:k.text,uid:k.uid}),[2]}}))}))},onRemove:function(){return it(void 0,void 0,void 0,(function(){var e,t,n,r;return st(this,(function(i){switch(i.label){case 0:return k.match?(e=(0,h.select)("core/block-editor").getBlock(k.match.blockId))?(t=m(),n=t.indexOf(k),r=n-1,[4,N(e,k)]):[3,2]:[2];case 1:if(i.sent(),P.trackEvent("smart_linking_link_removed",{link:k.href,title:k.title,text:k.text,uid:k.uid}),0===(t=m()).length&&g.length>0)return S(g[0]),[2];if(0===t.length&&0===g.length)return C(),[2];if(t[r])return S(t[r]),[2];S(t[0]),i.label=2;case 2:return[2]}}))}))},onSelectInEditor:function(){if(k.match){var e=(0,h.select)("core/block-editor").getBlock(k.match.blockId);if(e){te.selectBlock(e.clientId);var t=document.querySelector('[data-block="'.concat(e.clientId,'"]'));t&&ke(t,k.uid),P.trackEvent("smart_linking_select_in_editor_pressed",{type:"outbound",uid:k.uid}),C()}}}}))]})}),s&&(0,p.jsxs)(f.Modal,{title:(0,_.__)("Review Smart Links","wp-parsely"),onRequestClose:function(){return A(!1)},className:"wp-parsely-smart-linking-close-dialog",children:[(0,_.__)("Are you sure you want to close? All un-accepted smart links will not be added.","wp-parsely"),(0,p.jsxs)("div",{className:"smart-linking-close-dialog-actions",children:[(0,p.jsx)(f.Button,{variant:"secondary",onClick:function(){return A(!1)},children:(0,_.__)("Go Back","wp-parsely")}),(0,p.jsx)(f.Button,{variant:"primary",onClick:function(){return A(!0)},children:(0,_.__)("Close","wp-parsely")})]})]})]})})),at=function(){return at=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&k("success",/* translators: %d: number of smart links applied */ /* translators: %d: number of smart links applied */ (0,_.sprintf)((0,_.__)("%s smart links successfully applied.","wp-parsely"),g),{type:"snackbar"}):y(0)}),[w]),(0,b.useEffect)((function(){if(!(Object.keys(R).length>0)){var e={maxLinksPerPost:a.SmartLinking.MaxLinks};te(e)}}),[te,a]);var he=(0,h.useSelect)((function(e){var t=e("core/block-editor"),r=t.getSelectedBlock,i=t.getBlock,s=t.getBlocks,o=e("core/editor"),a=o.getEditedPostContent,l=o.getCurrentPostAttribute;return{allBlocks:s(),selectedBlock:n?i(n):r(),postContent:a(),postPermalink:l("link")}}),[n]),ve=he.allBlocks,me=he.selectedBlock,xe=he.postContent,ke=he.postPermalink,Se=function(e){return lt(void 0,void 0,void 0,(function(){var t,n,r,i,s;return ct(this,(function(o){switch(o.label){case 0:t=[],o.label=1;case 1:return o.trys.push([1,4,,9]),[4,re((n=E||!me)?_e.All:_e.Selected)];case 2:return o.sent(),a=ke.replace(/^https?:\/\//i,""),r=["http://"+a,"https://"+a],i=function(e){return e.map((function(e){return e.href}))}(F),r.push.apply(r,i),[4,De.getInstance().generateSmartLinks(me&&!n?(0,Q.getBlockContent)(me):xe,O,r)];case 3:return t=o.sent(),[3,9];case 4:if((s=o.sent()).code&&s.code===$.ParselyAborted)throw s.numRetries=3-e,s;return e>0&&s.retryFetch?(console.error(s),[4,ce(!0)]):[3,8];case 5:return o.sent(),[4,ue()];case 6:return o.sent(),[4,Se(e-1)];case 7:return[2,o.sent()];case 8:throw s;case 9:return[2,t]}var a}))}))},Pe=function(){for(var e=[],t=0;t[type="button"]').forEach((function(e){e.setAttribute("disabled","disabled")}))},Ne=function(){document.querySelectorAll('.edit-post-header__settings>[type="button"]').forEach((function(e){e.removeAttribute("disabled")})),ne.unlockPostSaving("wp-parsely-block-overlay")};return(0,p.jsxs)("div",{className:"wp-parsely-smart-linking",children:[(0,p.jsx)(se,{isDetectingEnabled:!L,onLinkRemove:function(e){!function(e){ae(this,void 0,void 0,(function(){var t,n,r;return le(this,(function(i){switch(i.label){case 0:return[4,we((0,Q.getBlockContent)(e),e.clientId)];case 1:return t=i.sent(),n=t.missingSmartLinks,r=t.didAnyFixes,n.forEach((function(e){(0,h.dispatch)(Te).removeSmartLink(e.uid)})),[2,r]}}))}))}(e.block)}}),(0,p.jsxs)(f.PanelRow,{className:t,children:[(0,p.jsxs)("div",{className:"smart-linking-text",children:[(0,_.__)("Automatically insert links to your most relevant, top performing content.","wp-parsely"),(0,p.jsxs)(f.Button,{href:"https://docs.parse.ly/plugin-content-helper/#h-smart-linking-beta",target:"_blank",variant:"link",children:[(0,_.__)("Learn more about Parse.ly AI","wp-parsely"),(0,p.jsx)(X,{icon:ee,size:18,className:"parsely-external-link-icon"})]})]}),C&&(0,p.jsx)(f.Notice,{status:"info",onRemove:function(){return Z(null)},className:"wp-parsely-content-helper-error",children:C.Message()}),w&&g>0&&(0,p.jsx)(f.Notice,{status:"success",onRemove:function(){return x(!1)},className:"wp-parsely-smart-linking-suggested-links",children:(0,_.sprintf)(/* translators: 1 - number of smart links generated */ /* translators: 1 - number of smart links generated */ (0,_.__)("Successfully added %s smart links.","wp-parsely"),g>0?g:A.length)}),(0,p.jsx)(Ce,{disabled:T,selectedBlock:me,onSettingChange:function(e,t){var n;d({SmartLinking:at(at({},a.SmartLinking),(n={},n[e]=t,n))}),"MaxLinks"===e&&oe(t)}}),(0,p.jsx)("div",{className:"smart-linking-generate",children:(0,p.jsx)(f.Button,{onClick:function(){return lt(void 0,void 0,void 0,(function(){var e,t,n,r,s,o,a,l;return ct(this,(function(c){switch(c.label){case 0:return[4,q(!0)];case 1:return c.sent(),[4,de()];case 2:return c.sent(),[4,Z(null)];case 3:return c.sent(),x(!1),P.trackEvent("smart_linking_generate_pressed",{is_full_content:E,selected_block:null!==(o=null==me?void 0:me.name)&&void 0!==o?o:"none",context:i}),[4,Pe(E?"all":null==me?void 0:me.clientId)];case 4:c.sent(),e=setTimeout((function(){var e;q(!1),P.trackEvent("smart_linking_generate_timeout",{is_full_content:E,selected_block:null!==(e=null==me?void 0:me.name)&&void 0!==e?e:"none",context:i}),je(E?"all":null==me?void 0:me.clientId)}),18e4),t=I,c.label=5;case 5:return c.trys.push([5,8,10,15]),[4,Se(3)];case 6:return n=c.sent(),[4,(u=n,lt(void 0,void 0,void 0,(function(){var e;return ct(this,(function(t){switch(t.label){case 0:return u=u.filter((function(e){return!F.some((function(t){return t.uid===e.uid&&t.applied}))})),e=ke.replace(/^https?:\/\//,"").replace(/\/+$/,""),u=(u=u.filter((function(t){return!t.href.includes(e)||(console.warn("PCH Smart Linking: Skipping self-reference link: ".concat(t.href)),!1)}))).filter((function(e){return!F.some((function(t){return t.href===e.href?(console.warn("PCH Smart Linking: Skipping duplicate link: ".concat(e.href)),!0):t.text===e.text&&t.offset!==e.offset&&(console.warn("PCH Smart Linking: Skipping duplicate link text: ".concat(e.text)),!0)}))})),u=(u=ge(E?ve:[me],u,{}).filter((function(e){return e.match}))).filter((function(e){if(!e.match)return!1;var t=e.match.blockLinkPosition,n=t+e.text.length;return!F.some((function(r){if(!r.match)return!1;if(e.match.blockId!==r.match.blockId)return!1;var i=r.match.blockLinkPosition,s=i+r.text.length;return t>=i&&n<=s}))})),[4,W(u)];case 1:return t.sent(),[2,u]}}))})))];case 7:if(0===c.sent().length)throw new ie((0,_.__)("No smart links were generated.","wp-parsely"),$.ParselySuggestionsApiNoData,"");return pe(!0),[3,15];case 8:return r=c.sent(),s=new ie(null!==(a=r.message)&&void 0!==a?a:"An unknown error has occurred.",null!==(l=r.code)&&void 0!==l?l:$.UnknownError),r.code&&r.code===$.ParselyAborted&&(s.message=(0,_.sprintf)(/* translators: %d: number of retry attempts, %s: attempt plural */ /* translators: %d: number of retry attempts, %s: attempt plural */ (0,_.__)("The Smart Linking process was cancelled after %1$d %2$s.","wp-parsely"),r.numRetries,(0,_._n)("attempt","attempts",r.numRetries,"wp-parsely"))),console.error(r),[4,Z(s)];case 9:return c.sent(),s.createErrorSnackbar(),[3,15];case 10:return[4,q(!1)];case 11:return c.sent(),[4,re(t)];case 12:return c.sent(),[4,ce(!1)];case 13:return c.sent(),[4,je(E?"all":null==me?void 0:me.clientId)];case 14:return c.sent(),clearTimeout(e),[7];case 15:return[2]}var u}))}))},variant:"primary",isBusy:T,disabled:T,children:M?(0,_.sprintf)(/* translators: %1$d: number of retry attempts, %2$d: maximum number of retries */ /* translators: %1$d: number of retry attempts, %2$d: maximum number of retries */ @@ -22,7 +22,7 @@ message:(0,_.sprintf)((0,_.__)('in section "%1$s"',"wp-parsely"),n.value)};if(w. message:(0,_.sprintf)((0,_.__)('by author "%1$s"',"wp-parsely"),n.value)};throw new ie((0,_.__)("No valid filter type has been specified.","wp-parsely"),$.CannotFormulateApiQuery)},t}(Re),xn=function(){return xn=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&f.every(Number.isInteger)?null!==(n=l("taxonomy","category",{include:f,context:"view"}))&&void 0!==n?n:void 0:null,tagRecords:o=Array.isArray(h)&&h.length>0&&h.every(Number.isInteger)?null!==(r=l("taxonomy","post_tag",{include:h,context:"view"}))&&void 0!==r?r:void 0:null,isLoading:u("getEntityRecords",["root","user",{include:[p],context:"view"}])||u("getEntityRecords",["taxonomy","category",{include:f,context:"view"}])||u("getEntityRecords",["taxonomy","post_tag",{include:h,context:"view"}]),hasResolved:(c("getEntityRecords",["root","user",{include:[p],context:"view"}])||null===i)&&(c("getEntityRecords",["taxonomy","category",{include:f,context:"view"}])||null===s)&&(c("getEntityRecords",["taxonomy","post_tag",{include:h,context:"view"}])||null===o)}}),[]);return(0,b.useEffect)((function(){var e=r.authorRecords,t=r.categoryRecords,i=r.tagRecords,s=r.isLoading;r.hasResolved&&!s&&n({authors:e,categories:t,tags:i,isReady:!0})}),[r]),t}(),c=l.authors,u=l.categories,d=l.tags,v=l.isReady;(0,b.useEffect)((function(){if(v){var e=function(e){return function(e){return!(!Array.isArray(e)||0===e.length)&&e.every((function(e){return"name"in e&&"id"in e&&"slug"in e&&"description"in e&&"link"in e}))}(e)?e.map((function(e){return e.name})):[]};a({authors:e(c),categories:e(u),tags:e(d)})}}),[c,u,d,v]);var g=(0,b.useState)(!0),x=g[0],k=g[1],S=(0,b.useState)(),j=S[0],T=S[1],L=(0,b.useState)(),E=L[0],N=L[1],C=(0,b.useState)([]),A=C[0],O=C[1],R=(0,b.useState)({type:t.RelatedPosts.FilterBy,value:t.RelatedPosts.FilterValue}),I=R[0],M=R[1],G=(0,b.useState)(void 0),H=G[0],U=G[1],q=(0,z.useDebounce)(U,1e3);(0,h.useSelect)((function(e){if("undefined"==typeof jest){var t=e("core/editor").getEditedPostContent;q(t())}else q("Jest test is running")}),[q]);var Z=function(e,r){n({RelatedPosts:xn(xn({},t.RelatedPosts),{FilterBy:e,FilterValue:r})})};return(0,b.useEffect)((function(){var e,t,n=function(e){return kn(void 0,void 0,void 0,(function(){return Sn(this,(function(t){return bn.getInstance().getRelatedPosts(r,i,I).then((function(e){O(e.posts),N(e.message),k(!1)})).catch((function(t){return kn(void 0,void 0,void 0,(function(){return Sn(this,(function(r){switch(r.label){case 0:return e>0&&t.retryFetch?[4,new Promise((function(e){return setTimeout(e,500)}))]:[3,3];case 1:return r.sent(),[4,n(e-1)];case 2:return r.sent(),[3,4];case 3:k(!1),T(t),r.label=4;case 4:return[2]}}))}))})),[2]}))}))},s=w.Author===I.type,a=w.Tag===I.type,l=w.Section===I.type,c=w.Unavailable===I.type,u=0===o.authors.length,d=0===o.tags.length,p=0===o.categories.length,f=s&&!o.authors.includes(I.value),h=a&&!o.tags.includes(I.value),v=l&&!o.categories.includes(I.value);return k(!0),c||a&&d||l&&p||s&&u?Object.values(o).every((function(e){return 0===e.length}))||M((e="",t=w.Unavailable,o.tags.length>=1?(t=w.Tag,e=o.tags[0]):o.categories.length>=1?(t=w.Section,e=o.categories[0]):o.authors.length>=1&&(t=w.Author,e=o.authors[0]),{type:t,value:e})):h?M({type:w.Tag,value:o.tags[0]}):v?M({type:w.Section,value:o.categories[0]}):f?M({type:w.Author,value:o.authors[0]}):n(1),function(){k(!1),O([]),N(""),T(void 0)}}),[r,i,I,o]),0===o.authors.length&&0===o.categories.length&&0===o.tags.length&&v?(0,p.jsx)("div",{className:"wp-parsely-related-posts",children:(0,p.jsx)("div",{className:"related-posts-body",children:(0,_.__)("Error: No author, section, or tags could be found for this post.","wp-parsely")})}):(0,p.jsxs)("div",{className:"wp-parsely-related-posts",children:[(0,p.jsx)("div",{className:"related-posts-description",children:(0,_.__)("Find top-performing related posts based on a key metric.","wp-parsely")}),(0,p.jsxs)("div",{className:"related-posts-body",children:[(0,p.jsxs)("div",{className:"related-posts-settings",children:[(0,p.jsx)(f.SelectControl,{size:"__unstable-large",onChange:function(e){var r;D(r=e,m)&&(n({RelatedPosts:xn(xn({},t.RelatedPosts),{Metric:r})}),P.trackEvent("related_posts_metric_changed",{metric:r}))},prefix:(0,p.jsx)(f.__experimentalInputControlPrefixWrapper,{children:(0,_.__)("Metric: ","wp-parsely")}),value:i,children:Object.values(m).map((function(e){return(0,p.jsx)("option",{value:e,children:V(e)},e)}))}),(0,p.jsx)(f.SelectControl,{size:"__unstable-large",value:r,prefix:(0,p.jsxs)(f.__experimentalInputControlPrefixWrapper,{children:[(0,_.__)("Period: ","wp-parsely")," "]}),onChange:function(e){return function(e){D(e,y)&&(n({RelatedPosts:xn(xn({},t.RelatedPosts),{Period:e})}),P.trackEvent("related_posts_period_changed",{period:e}))}(e)},children:Object.values(y).map((function(e){return(0,p.jsx)("option",{value:e,children:F(e)},e)}))})]}),(0,p.jsx)(ln,{label:(0,_.__)("Filter by","wp-parsely"),filter:I,onFilterTypeChange:function(e){if(D(e,w)){var t="",n=e;w.Tag===n&&(t=o.tags[0]),w.Section===n&&(t=o.categories[0]),w.Author===n&&(t=o.authors[0]),""!==t&&(Z(n,t),M({type:n,value:t}),P.trackEvent("related_posts_filter_type_changed",{filter_type:n}))}},onFilterValueChange:function(e){"string"==typeof e&&(Z(I.type,e),M(xn(xn({},I),{value:e})))},postData:o}),(0,p.jsxs)("div",{className:"related-posts-wrapper",children:[(0,p.jsx)("div",{children:(0,p.jsx)("p",{className:"related-posts-descr","data-testid":"parsely-related-posts-descr",children:w.Tag===I.type?(0,_.sprintf)(/* translators: 1: tag name, 2: period */ /* translators: 1: tag name, 2: period */ (0,_.__)("Top related posts with the “%1$s” tag in the %2$s.","wp-parsely"),I.value,F(r,!0)):w.Section===I.type?(0,_.sprintf)(/* translators: 1: section name, 2: period */ /* translators: 1: section name, 2: period */ (0,_.__)("Top related posts in the “%1$s” section in the %2$s.","wp-parsely"),I.value,F(r,!0)):w.Author===I.type?(0,_.sprintf)(/* translators: 1: author name, 2: period */ /* translators: 1: author name, 2: period */ -(0,_.__)("Top related posts by %1$s in the %2$s.","wp-parsely"),I.value,F(r,!0)):null!=E?E:""})}),j&&j.Message(),x&&(0,p.jsx)("div",{className:"related-posts-loading-message","data-testid":"parsely-related-posts-loading-message",children:(0,_.__)("Loading…","wp-parsely")}),!x&&!j&&0===A.length&&(0,p.jsx)("div",{className:"related-posts-empty","data-testid":"parsely-related-posts-empty",children:(0,_.__)("No related posts found.","wp-parsely")}),!x&&A.length>0&&(0,p.jsx)("div",{className:"related-posts-list",children:A.map((function(e){return(0,p.jsx)(hn,{metric:i,post:e,postContent:H},e.id)}))})]})]})]})},jn=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"m19 7-3-3-8.5 8.5-1 4 4-1L19 7Zm-7 11.5H5V20h7v-1.5Z"})}),Tn=function(){return(0,p.jsx)(f.SVG,{xmlns:"http://www.w3.org/2000/svg",width:"18",height:"18",viewBox:"0 0 18 18",fill:"none",children:(0,p.jsx)(f.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M13.5034 7.91642L9 12.0104L4.49662 7.91642L5.25337 7.08398L8.99999 10.49L12.7466 7.08398L13.5034 7.91642Z",fill:"#1E1E1E"})})},Ln={journalist:{label:(0,_.__)("Journalist","wp-parsely")},editorialWriter:{label:(0,_.__)("Editorial Writer","wp-parsely")},investigativeReporter:{label:(0,_.__)("Investigative Reporter","wp-parsely")},techAnalyst:{label:(0,_.__)("Tech Analyst","wp-parsely")},businessAnalyst:{label:(0,_.__)("Business Analyst","wp-parsely")},culturalCommentator:{label:(0,_.__)("Cultural Commentator","wp-parsely")},scienceCorrespondent:{label:(0,_.__)("Science Correspondent","wp-parsely")},politicalAnalyst:{label:(0,_.__)("Political Analyst","wp-parsely")},healthWellnessAdvocate:{label:(0,_.__)("Health and Wellness Advocate","wp-parsely")},environmentalJournalist:{label:(0,_.__)("Environmental Journalist","wp-parsely")},custom:{label:(0,_.__)("Custom Persona","wp-parsely"),icon:jn}},En=Object.keys(Ln),Nn=function(e){return"custom"===e||""===e?Ln.custom.label:Cn(e)?e:Ln[e].label},Cn=function(e){return!En.includes(e)||"custom"===e},An=function(e){var t=e.value,n=e.onChange,r=(0,b.useState)(""),i=r[0],s=r[1],o=(0,z.useDebounce)(n,500);return(0,p.jsx)("div",{className:"parsely-persona-selector-custom",children:(0,p.jsx)(f.TextControl,{value:i||t,placeholder:(0,_.__)("Enter a custom persona…","wp-parsely"),onChange:function(e){if(""===e)return n(""),void s("");e.length>32&&(e=e.slice(0,32)),o(e),s(e)}})})},On=function(e){var t=e.persona,n=e.value,r=void 0===n?(0,_.__)("Select a persona…","wp-parsely"):n,i=e.label,s=void 0===i?(0,_.__)("Persona","wp-parsely"):i,o=e.onChange,a=e.onDropdownChange,l=e.disabled,c=void 0!==l&&l,u=e.allowCustom,d=void 0!==u&&u;return(0,p.jsxs)(f.Disabled,{isDisabled:c,children:[s&&(0,p.jsx)("div",{className:"wp-parsely-dropdown-label",children:s}),(0,p.jsx)(f.DropdownMenu,{label:(0,_.__)("Persona","wp-parsely"),className:"parsely-persona-selector-dropdown"+(c?" is-disabled":""),popoverProps:{className:"wp-parsely-popover"},toggleProps:{children:(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)("div",{className:"parsely-persona-selector-label",children:Cn(t)?Ln.custom.label:r}),(0,p.jsx)(Tn,{})]})},children:function(e){var n=e.onClose;return(0,p.jsx)(f.MenuGroup,{label:(0,_.__)("Persona","wp-parsely"),children:(0,p.jsx)(p.Fragment,{children:En.map((function(e){if(!d&&"custom"===e)return null;var r=Ln[e],i=e===t||Cn(t)&&"custom"===e;return(0,p.jsxs)(f.MenuItem,{isSelected:i,className:i?"is-selected":"",role:"menuitemradio",onClick:function(){null==a||a(e),o(e),n(),"custom"===e&&setTimeout((function(){var e=document.querySelector(".parsely-persona-selector-custom input");e&&e.focus()}),0)},children:[r.icon&&(0,p.jsx)(X,{icon:r.icon}),r.label]},e)}))})})}}),d&&Cn(t)&&(0,p.jsx)(An,{onChange:function(e){o(""!==e?e:"custom")},value:"custom"===t?"":t})]})},Rn={neutral:{label:(0,_.__)("Neutral","wp-parsely")},formal:{label:(0,_.__)("Formal","wp-parsely")},humorous:{label:(0,_.__)("Humorous","wp-parsely")},confident:{label:(0,_.__)("Confident","wp-parsely")},provocative:{label:(0,_.__)("Provocative","wp-parsely")},serious:{label:(0,_.__)("Serious","wp-parsely")},inspirational:{label:(0,_.__)("Inspirational","wp-parsely")},skeptical:{label:(0,_.__)("Skeptical","wp-parsely")},conversational:{label:(0,_.__)("Conversational","wp-parsely")},analytical:{label:(0,_.__)("Analytical","wp-parsely")},custom:{label:(0,_.__)("Custom Tone","wp-parsely"),icon:jn}},In=Object.keys(Rn),Bn=function(e){return"custom"===e||""===e?Rn.custom.label:Mn(e)?e:Rn[e].label},Mn=function(e){return!In.includes(e)||"custom"===e},Dn=function(e){var t=e.value,n=e.onChange,r=(0,b.useState)(""),i=r[0],s=r[1],o=(0,z.useDebounce)(n,500);return(0,p.jsx)("div",{className:"parsely-tone-selector-custom",children:(0,p.jsx)(f.TextControl,{value:i||t,placeholder:(0,_.__)("Enter a custom tone","wp-parsely"),onChange:function(e){if(""===e)return n(""),void s("");e.length>32&&(e=e.slice(0,32)),o(e),s(e)}})})},Fn=function(e){var t=e.tone,n=e.value,r=void 0===n?(0,_.__)("Select a tone","wp-parsely"):n,i=e.label,s=void 0===i?(0,_.__)("Tone","wp-parsely"):i,o=e.onChange,a=e.onDropdownChange,l=e.disabled,c=void 0!==l&&l,u=e.allowCustom,d=void 0!==u&&u;return(0,p.jsxs)(f.Disabled,{isDisabled:c,children:[(0,p.jsx)("div",{className:"wp-parsely-dropdown-label",children:s}),(0,p.jsx)(f.DropdownMenu,{label:(0,_.__)("Tone","wp-parsely"),className:"parsely-tone-selector-dropdown"+(c?" is-disabled":""),popoverProps:{className:"wp-parsely-popover"},toggleProps:{children:(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)("div",{className:"parsely-tone-selector-label",children:Mn(t)?Rn.custom.label:r}),(0,p.jsx)(Tn,{})]})},children:function(e){var n=e.onClose;return(0,p.jsx)(f.MenuGroup,{label:(0,_.__)("Select a tone","wp-parsely"),children:(0,p.jsx)(p.Fragment,{children:In.map((function(e){if(!d&&"custom"===e)return null;var r=Rn[e],i=e===t||Mn(t)&&"custom"===e;return(0,p.jsxs)(f.MenuItem,{isSelected:i,className:i?"is-selected":"",role:"menuitemradio",onClick:function(){null==a||a(e),o(e),n(),"custom"===e&&setTimeout((function(){var e=document.querySelector(".parsely-tone-selector-custom input");e&&e.focus()}),0)},children:[r.icon&&(0,p.jsx)(X,{icon:r.icon}),r.label]},e)}))})})}}),d&&Mn(t)&&(0,p.jsx)(Dn,{onChange:function(e){o(""!==e?e:"custom")},value:"custom"===t?"":t})]})},Vn=(0,p.jsx)(x.SVG,{width:"24",height:"24",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:(0,p.jsx)(x.Path,{d:"M10.97 10.159a3.382 3.382 0 0 0-2.857.955l1.724 1.723-2.836 2.913L7 17h1.25l2.913-2.837 1.723 1.723a3.38 3.38 0 0 0 .606-.825c.33-.63.446-1.343.35-2.032L17 10.695 13.305 7l-2.334 3.159Z"})}),Gn=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"M18.3 11.7c-.6-.6-1.4-.9-2.3-.9H6.7l2.9-3.3-1.1-1-4.5 5L8.5 16l1-1-2.7-2.7H16c.5 0 .9.2 1.3.5 1 1 1 3.4 1 4.5v.3h1.5v-.2c0-1.5 0-4.3-1.5-5.7z"})}),Hn=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M12 5.5A2.25 2.25 0 0 0 9.878 7h4.244A2.251 2.251 0 0 0 12 5.5ZM12 4a3.751 3.751 0 0 0-3.675 3H5v1.5h1.27l.818 8.997a2.75 2.75 0 0 0 2.739 2.501h4.347a2.75 2.75 0 0 0 2.738-2.5L17.73 8.5H19V7h-3.325A3.751 3.751 0 0 0 12 4Zm4.224 4.5H7.776l.806 8.861a1.25 1.25 0 0 0 1.245 1.137h4.347a1.25 1.25 0 0 0 1.245-1.137l.805-8.861Z"})}),zn=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"m21.5 9.1-6.6-6.6-4.2 5.6c-1.2-.1-2.4.1-3.6.7-.1 0-.1.1-.2.1-.5.3-.9.6-1.2.9l3.7 3.7-5.7 5.7v1.1h1.1l5.7-5.7 3.7 3.7c.4-.4.7-.8.9-1.2.1-.1.1-.2.2-.3.6-1.1.8-2.4.6-3.6l5.6-4.1zm-7.3 3.5.1.9c.1.9 0 1.8-.4 2.6l-6-6c.8-.4 1.7-.5 2.6-.4l.9.1L15 4.9 19.1 9l-4.9 3.6z"})}),Un=function(){return Un=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0?(0,p.jsx)("span",{className:"parsely-write-titles-text",children:(0,b.createInterpolateElement)( +(0,_.__)("Top related posts by %1$s in the %2$s.","wp-parsely"),I.value,F(r,!0)):null!=E?E:""})}),j&&j.Message(),x&&(0,p.jsx)("div",{className:"related-posts-loading-message","data-testid":"parsely-related-posts-loading-message",children:(0,_.__)("Loading…","wp-parsely")}),!x&&!j&&0===A.length&&(0,p.jsx)("div",{className:"related-posts-empty","data-testid":"parsely-related-posts-empty",children:(0,_.__)("No related posts found.","wp-parsely")}),!x&&A.length>0&&(0,p.jsx)("div",{className:"related-posts-list",children:A.map((function(e){return(0,p.jsx)(hn,{metric:i,post:e,postContent:H},e.id)}))})]})]})]})},jn=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"m19 7-3-3-8.5 8.5-1 4 4-1L19 7Zm-7 11.5H5V20h7v-1.5Z"})}),Tn=function(){return(0,p.jsx)(f.SVG,{xmlns:"http://www.w3.org/2000/svg",width:"18",height:"18",viewBox:"0 0 18 18",fill:"none",children:(0,p.jsx)(f.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M13.5034 7.91642L9 12.0104L4.49662 7.91642L5.25337 7.08398L8.99999 10.49L12.7466 7.08398L13.5034 7.91642Z",fill:"#1E1E1E"})})},Ln={journalist:{label:(0,_.__)("Journalist","wp-parsely")},editorialWriter:{label:(0,_.__)("Editorial Writer","wp-parsely")},investigativeReporter:{label:(0,_.__)("Investigative Reporter","wp-parsely")},techAnalyst:{label:(0,_.__)("Tech Analyst","wp-parsely")},businessAnalyst:{label:(0,_.__)("Business Analyst","wp-parsely")},culturalCommentator:{label:(0,_.__)("Cultural Commentator","wp-parsely")},scienceCorrespondent:{label:(0,_.__)("Science Correspondent","wp-parsely")},politicalAnalyst:{label:(0,_.__)("Political Analyst","wp-parsely")},healthWellnessAdvocate:{label:(0,_.__)("Health and Wellness Advocate","wp-parsely")},environmentalJournalist:{label:(0,_.__)("Environmental Journalist","wp-parsely")},custom:{label:(0,_.__)("Custom Persona","wp-parsely"),icon:jn}},En=Object.keys(Ln),Nn=function(e){return"custom"===e||""===e?Ln.custom.label:Cn(e)?e:Ln[e].label},Cn=function(e){return!En.includes(e)||"custom"===e},An=function(e){var t=e.value,n=e.onChange,r=(0,b.useState)(""),i=r[0],s=r[1],o=(0,z.useDebounce)(n,500);return(0,p.jsx)("div",{className:"parsely-persona-selector-custom",children:(0,p.jsx)(f.TextControl,{value:i||t,placeholder:(0,_.__)("Enter a custom persona…","wp-parsely"),onChange:function(e){if(""===e)return n(""),void s("");e.length>32&&(e=e.slice(0,32)),o(e),s(e)}})})},On=function(e){var t=e.persona,n=e.value,r=void 0===n?(0,_.__)("Select a persona…","wp-parsely"):n,i=e.label,s=void 0===i?(0,_.__)("Persona","wp-parsely"):i,o=e.onChange,a=e.onDropdownChange,l=e.disabled,c=void 0!==l&&l,u=e.allowCustom,d=void 0!==u&&u;return(0,p.jsxs)(f.Disabled,{isDisabled:c,children:[s&&(0,p.jsx)("div",{className:"wp-parsely-dropdown-label",children:s}),(0,p.jsx)(f.DropdownMenu,{label:(0,_.__)("Persona","wp-parsely"),className:"parsely-persona-selector-dropdown"+(c?" is-disabled":""),popoverProps:{className:"wp-parsely-popover"},toggleProps:{children:(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)("div",{className:"parsely-persona-selector-label",children:Cn(t)?Ln.custom.label:r}),(0,p.jsx)(Tn,{})]})},children:function(e){var n=e.onClose;return(0,p.jsx)(f.MenuGroup,{label:(0,_.__)("Persona","wp-parsely"),children:(0,p.jsx)(p.Fragment,{children:En.map((function(e){if(!d&&"custom"===e)return null;var r=Ln[e],i=e===t||Cn(t)&&"custom"===e;return(0,p.jsxs)(f.MenuItem,{isSelected:i,className:i?"is-selected":"",role:"menuitemradio",onClick:function(){null==a||a(e),o(e),n(),"custom"===e&&setTimeout((function(){var e=document.querySelector(".parsely-persona-selector-custom input");e&&e.focus()}),0)},children:[r.icon&&(0,p.jsx)(X,{icon:r.icon}),r.label]},e)}))})})}}),d&&Cn(t)&&(0,p.jsx)(An,{onChange:function(e){o(""!==e?e:"custom")},value:"custom"===t?"":t})]})},Rn={neutral:{label:(0,_.__)("Neutral","wp-parsely")},formal:{label:(0,_.__)("Formal","wp-parsely")},humorous:{label:(0,_.__)("Humorous","wp-parsely")},confident:{label:(0,_.__)("Confident","wp-parsely")},provocative:{label:(0,_.__)("Provocative","wp-parsely")},serious:{label:(0,_.__)("Serious","wp-parsely")},inspirational:{label:(0,_.__)("Inspirational","wp-parsely")},skeptical:{label:(0,_.__)("Skeptical","wp-parsely")},conversational:{label:(0,_.__)("Conversational","wp-parsely")},analytical:{label:(0,_.__)("Analytical","wp-parsely")},custom:{label:(0,_.__)("Custom Tone","wp-parsely"),icon:jn}},In=Object.keys(Rn),Bn=function(e){return"custom"===e||""===e?Rn.custom.label:Mn(e)?e:Rn[e].label},Mn=function(e){return!In.includes(e)||"custom"===e},Dn=function(e){var t=e.value,n=e.onChange,r=(0,b.useState)(""),i=r[0],s=r[1],o=(0,z.useDebounce)(n,500);return(0,p.jsx)("div",{className:"parsely-tone-selector-custom",children:(0,p.jsx)(f.TextControl,{value:i||t,placeholder:(0,_.__)("Enter a custom tone","wp-parsely"),onChange:function(e){if(""===e)return n(""),void s("");e.length>32&&(e=e.slice(0,32)),o(e),s(e)}})})},Fn=function(e){var t=e.tone,n=e.value,r=void 0===n?(0,_.__)("Select a tone","wp-parsely"):n,i=e.label,s=void 0===i?(0,_.__)("Tone","wp-parsely"):i,o=e.onChange,a=e.onDropdownChange,l=e.disabled,c=void 0!==l&&l,u=e.allowCustom,d=void 0!==u&&u;return(0,p.jsxs)(f.Disabled,{isDisabled:c,children:[(0,p.jsx)("div",{className:"wp-parsely-dropdown-label",children:s}),(0,p.jsx)(f.DropdownMenu,{label:(0,_.__)("Tone","wp-parsely"),className:"parsely-tone-selector-dropdown"+(c?" is-disabled":""),popoverProps:{className:"wp-parsely-popover"},toggleProps:{children:(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)("div",{className:"parsely-tone-selector-label",children:Mn(t)?Rn.custom.label:r}),(0,p.jsx)(Tn,{})]})},children:function(e){var n=e.onClose;return(0,p.jsx)(f.MenuGroup,{label:(0,_.__)("Select a tone","wp-parsely"),children:(0,p.jsx)(p.Fragment,{children:In.map((function(e){if(!d&&"custom"===e)return null;var r=Rn[e],i=e===t||Mn(t)&&"custom"===e;return(0,p.jsxs)(f.MenuItem,{isSelected:i,className:i?"is-selected":"",role:"menuitemradio",onClick:function(){null==a||a(e),o(e),n(),"custom"===e&&setTimeout((function(){var e=document.querySelector(".parsely-tone-selector-custom input");e&&e.focus()}),0)},children:[r.icon&&(0,p.jsx)(X,{icon:r.icon}),r.label]},e)}))})})}}),d&&Mn(t)&&(0,p.jsx)(Dn,{onChange:function(e){o(""!==e?e:"custom")},value:"custom"===t?"":t})]})},Vn=(0,p.jsx)(x.SVG,{width:"24",height:"24",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:(0,p.jsx)(x.Path,{d:"M10.97 10.159a3.382 3.382 0 0 0-2.857.955l1.724 1.723-2.836 2.913L7 17h1.25l2.913-2.837 1.723 1.723a3.38 3.38 0 0 0 .606-.825c.33-.63.446-1.343.35-2.032L17 10.695 13.305 7l-2.334 3.159Z"})}),Gn=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"M18.3 11.7c-.6-.6-1.4-.9-2.3-.9H6.7l2.9-3.3-1.1-1-4.5 5L8.5 16l1-1-2.7-2.7H16c.5 0 .9.2 1.3.5 1 1 1 3.4 1 4.5v.3h1.5v-.2c0-1.5 0-4.3-1.5-5.7z"})}),Hn=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M12 5.5A2.25 2.25 0 0 0 9.878 7h4.244A2.251 2.251 0 0 0 12 5.5ZM12 4a3.751 3.751 0 0 0-3.675 3H5v1.5h1.27l.818 8.997a2.75 2.75 0 0 0 2.739 2.501h4.347a2.75 2.75 0 0 0 2.738-2.5L17.73 8.5H19V7h-3.325A3.751 3.751 0 0 0 12 4Zm4.224 4.5H7.776l.806 8.861a1.25 1.25 0 0 0 1.245 1.137h4.347a1.25 1.25 0 0 0 1.245-1.137l.805-8.861Z"})}),zn=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"m21.5 9.1-6.6-6.6-4.2 5.6c-1.2-.1-2.4.1-3.6.7-.1 0-.1.1-.2.1-.5.3-.9.6-1.2.9l3.7 3.7-5.7 5.7v1.1h1.1l5.7-5.7 3.7 3.7c.4-.4.7-.8.9-1.2.1-.1.1-.2.2-.3.6-1.1.8-2.4.6-3.6l5.6-4.1zm-7.3 3.5.1.9c.1.9 0 1.8-.4 2.6l-6-6c.8-.4 1.7-.5 2.6-.4l.9.1L15 4.9 19.1 9l-4.9 3.6z"})}),Un=function(){return Un=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0?(0,p.jsx)("span",{className:"parsely-write-titles-text",children:(0,b.createInterpolateElement)( // translators: %1$s is the tone, %2$s is the persona. // translators: %1$s is the tone, %2$s is the persona. (0,_.__)("We've generated a few titles based on the content of your post, written as a .","wp-parsely"),{tone:(0,p.jsx)("strong",{children:Bn(a)}),persona:(0,p.jsx)("strong",{children:Nn(u)})})}):(0,_.__)("Use Parse.ly AI to generate a title for your post.","wp-parsely"),(0,p.jsxs)(f.Button,{href:"https://docs.parse.ly/plugin-content-helper/#h-title-suggestions-beta",target:"_blank",variant:"link",children:[(0,_.__)("Learn more about Parse.ly AI","wp-parsely"),(0,p.jsx)(X,{icon:ee,size:18,className:"parsely-external-link-icon"})]})]}),i&&(0,p.jsx)(f.Notice,{className:"wp-parsely-content-helper-error",onRemove:function(){return s(void 0)},status:"info",children:i.Message()}),void 0!==k&&(0,p.jsx)(Jn,{title:k,type:fn.PostTitle,isOriginal:!0}),00&&(0,p.jsx)(Qn,{pinnedTitles:m,isOpen:!0}),y.length>0&&(0,p.jsx)(er,{suggestions:y,isOpen:!0,isLoading:g})]}),(0,p.jsx)(Xn,{isLoading:g,onPersonaChange:function(e){C("Persona",e),d(e)},onSettingChange:C,onToneChange:function(e){C("Tone",e),l(e)},persona:t.TitleSuggestions.Persona,tone:t.TitleSuggestions.Tone}),(0,p.jsx)("div",{className:"title-suggestions-generate",children:(0,p.jsxs)(f.Button,{variant:"primary",isBusy:g,disabled:g||"custom"===a||"custom"===u,onClick:function(){return ir(void 0,void 0,void 0,(function(){return sr(this,(function(e){switch(e.label){case 0:return s(void 0),!1!==g?[3,2]:(P.trackEvent("title_suggestions_generate_pressed",{request_more:y.length>0,total_titles:y.length,total_pinned:y.filter((function(e){return e.isPinned})).length,tone:a,persona:u}),[4,(t=fn.PostTitle,n=A,r=a,i=u,ir(void 0,void 0,void 0,(function(){var e,o,a;return sr(this,(function(l){switch(l.label){case 0:return[4,T(!0)];case 1:l.sent(),e=nr.getInstance(),l.label=2;case 2:return l.trys.push([2,5,,6]),[4,e.generateTitles(n,3,r,i)];case 3:return o=l.sent(),[4,j(t,o)];case 4:return l.sent(),[3,6];case 5:return a=l.sent(),s(a),j(t,[]),[3,6];case 6:return[4,T(!1)];case 7:return l.sent(),[2]}}))})))]);case 1:e.sent(),e.label=2;case 2:return[2]}var t,n,r,i}))}))},children:[g&&(0,_.__)("Generating Titles…","wp-parsely"),!g&&w.length>0&&(0,_.__)("Generate More","wp-parsely"),!g&&0===w.length&&(0,_.__)("Generate Titles","wp-parsely")]})})]})})},ar=function(){return ar=Object.assign||function(e){for(var t,n=1,r=arguments.length;n array('react', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-plugins', 'wp-primitives', 'wp-url', 'wp-wordcount'), 'version' => '654bab3f782c2b075d8f'); + array('react', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-plugins', 'wp-primitives', 'wp-url', 'wp-wordcount'), 'version' => '577d3025e0a7c2398780'); diff --git a/build/content-helper/excerpt-generator.js b/build/content-helper/excerpt-generator.js index dfc1398c0..82cb2f791 100644 --- a/build/content-helper/excerpt-generator.js +++ b/build/content-helper/excerpt-generator.js @@ -1,4 +1,4 @@ -!function(){"use strict";var e={20:function(e,t,r){var n=r(609),o=Symbol.for("react.element"),a=Symbol.for("react.fragment"),i=Object.prototype.hasOwnProperty,s=n.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function c(e,t,r){var n,a={},c=null,u=null;for(n in void 0!==r&&(c=""+r),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(u=t.ref),t)i.call(t,n)&&!l.hasOwnProperty(n)&&(a[n]=t[n]);if(e&&e.defaultProps)for(n in t=e.defaultProps)void 0===a[n]&&(a[n]=t[n]);return{$$typeof:o,type:e,key:c,ref:u,props:a,_owner:s.current}}t.Fragment=a,t.jsx=c,t.jsxs=c},848:function(e,t,r){e.exports=r(20)},609:function(e){e.exports=window.React}},t={};function r(n){var o=t[n];if(void 0!==o)return o.exports;var a=t[n]={exports:{}};return e[n](a,a.exports,r),a.exports}r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,{a:t}),t},r.d=function(e,t){for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},function(){var e,t,n,o,a,i,s,l,c,u,p,d=window.wp.data,y=window.wp.hooks,h=window.wp.plugins,f=((0,d.dispatch)("core/block-editor"),(0,d.dispatch)("core/editor"),(0,d.dispatch)("core/edit-post")),w=r(848),v=window.wp.components,g=window.wp.editor;void 0!==window.wp&&(p=null!==(t=null===(e=window.wp.editor)||void 0===e?void 0:e.PluginDocumentSettingPanel)&&void 0!==t?t:null!==(o=null===(n=window.wp.editPost)||void 0===n?void 0:n.PluginDocumentSettingPanel)&&void 0!==o?o:null===(a=window.wp.editSite)||void 0===a?void 0:a.PluginDocumentSettingPanel,null!==(s=null===(i=window.wp.editor)||void 0===i?void 0:i.PluginSidebar)&&void 0!==s||null!==(c=null===(l=window.wp.editPost)||void 0===l?void 0:l.PluginSidebar)&&void 0!==c||null===(u=window.wp.editSite)||void 0===u||u.PluginSidebar);var _,b,P=window.wp.element,m=window.wp.i18n,x=window.wp.wordcount,E=window.wp.primitives,A=(0,w.jsx)(E.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,w.jsx)(E.Path,{d:"M19.5 4.5h-7V6h4.44l-5.97 5.97 1.06 1.06L18 7.06v4.44h1.5v-7Zm-13 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-3H17v3a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h3V5.5h-3Z"})}),S=function(){function e(){this._tkq=[],this.isLoaded=!1,this.isEnabled=!1,"undefined"!=typeof wpParselyTracksTelemetry&&(this.isEnabled=!0,this.loadTrackingLibrary())}return e.getInstance=function(){return window.wpParselyTelemetryInstance||Object.defineProperty(window,"wpParselyTelemetryInstance",{value:new e,writable:!1,configurable:!1,enumerable:!1}),window.wpParselyTelemetryInstance},e.prototype.loadTrackingLibrary=function(){var e=this,t=document.createElement("script");t.async=!0,t.src="//stats.wp.com/w.js",t.onload=function(){e.isLoaded=!0,e._tkq=window._tkq||[]},document.head.appendChild(t)},e.trackEvent=function(t){return r=this,n=arguments,a=function(t,r){var n;return void 0===r&&(r={}),function(e,t){var r,n,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function s(s){return function(l){return function(s){if(r)throw new TypeError("Generator is already executing.");for(;a&&(a=0,s[0]&&(i=0)),i;)try{if(r=1,n&&(o=2&s[0]?n.return:s[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,s[1])).done)return o;switch(n=0,o&&(s=[2&s[0],o.value]),s[0]){case 0:case 1:o=s;break;case 4:return i.label++,{value:s[1],done:!1};case 5:i.label++,n=s[1],s=[0];continue;case 7:s=i.ops.pop(),i.trys.pop();continue;default:if(!((o=(o=i.trys).length>0&&o[o.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]=1e4&&(clearInterval(a),r("Telemetry library not loaded"))}),100);else r("Telemetry not enabled")}))},e.prototype.trackEvent=function(t,r){var n;this.isLoaded?(0!==t.indexOf(e.TRACKS_PREFIX)&&(t=e.TRACKS_PREFIX+t),this.isEventNameValid(t)?(r=this.prepareProperties(r),null===(n=this._tkq)||void 0===n||n.push(["recordEvent",t,r])):console.error("Error tracking event: Invalid event name")):console.error("Error tracking event: Telemetry not loaded")},e.prototype.isTelemetryEnabled=function(){return this.isEnabled},e.prototype.isProprietyValid=function(t){return e.PROPERTY_REGEX.test(t)},e.prototype.isEventNameValid=function(t){return e.EVENT_NAME_REGEX.test(t)},e.prototype.prepareProperties=function(e){return(e=this.sanitizeProperties(e)).parsely_version=wpParselyTracksTelemetry.version,wpParselyTracksTelemetry.user&&(e._ut=wpParselyTracksTelemetry.user.type,e._ui=wpParselyTracksTelemetry.user.id),wpParselyTracksTelemetry.vipgo_env&&(e.vipgo_env=wpParselyTracksTelemetry.vipgo_env),this.sanitizeProperties(e)},e.prototype.sanitizeProperties=function(e){var t=this,r={};return Object.keys(e).forEach((function(n){t.isProprietyValid(n)&&(r[n]=e[n])})),r},e.TRACKS_PREFIX="wpparsely_",e.EVENT_NAME_REGEX=/^(([a-z0-9]+)_){2}([a-z0-9_]+)$/,e.PROPERTY_REGEX=/^[a-z_][a-z0-9_]*$/,e}(),k=(S.trackEvent,function(e){void 0===e&&(e=null);var t="";(null==e?void 0:e.children)&&(t=e.children);var r="content-helper-error-message";return(null==e?void 0:e.className)&&(r+=" "+e.className),(0,w.jsx)("div",{className:r,"data-testid":null==e?void 0:e.testId,dangerouslySetInnerHTML:{__html:t}})}),T=(_=function(e,t){return _=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])},_(e,t)},function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function __(){this.constructor=e}_(e,t),e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)});!function(e){e.AccessToFeatureDisabled="ch_access_to_feature_disabled",e.CannotFormulateApiQuery="ch_cannot_formulate_api_query",e.FetchError="fetch_error",e.HttpRequestFailed="http_request_failed",e.ParselyAborted="ch_parsely_aborted",e[e.ParselyApiForbidden=403]="ParselyApiForbidden",e.ParselyApiResponseContainsError="ch_response_contains_error",e.ParselyApiReturnedNoData="ch_parsely_api_returned_no_data",e.ParselyApiReturnedTooManyResults="ch_parsely_api_returned_too_many_results",e.PluginCredentialsNotSetMessageDetected="parsely_credentials_not_set_message_detected",e.PluginSettingsApiSecretNotSet="parsely_api_secret_not_set",e.PluginSettingsSiteIdNotSet="parsely_site_id_not_set",e.PostIsNotPublished="ch_post_not_published",e.UnknownError="ch_unknown_error",e.ParselySuggestionsApiAuthUnavailable="AUTH_UNAVAILABLE",e.ParselySuggestionsApiNoAuthentication="NO_AUTHENTICATION",e.ParselySuggestionsApiNoAuthorization="NO_AUTHORIZATION",e.ParselySuggestionsApiNoData="NO_DATA",e.ParselySuggestionsApiOpenAiError="OPENAI_ERROR",e.ParselySuggestionsApiOpenAiSchema="OPENAI_SCHEMA",e.ParselySuggestionsApiOpenAiUnavailable="OPENAI_UNAVAILABLE",e.ParselySuggestionsApiSchemaError="SCHEMA_ERROR"}(b||(b={}));var N=function(e){function t(r,n,o){void 0===o&&(o=(0,m.__)("Error: ","wp-parsely"));var a=this;r.startsWith(o)&&(o=""),(a=e.call(this,o+r)||this).hint=null,a.name=a.constructor.name,a.code=n;var i=[b.AccessToFeatureDisabled,b.ParselyApiForbidden,b.ParselyApiResponseContainsError,b.ParselyApiReturnedNoData,b.ParselyApiReturnedTooManyResults,b.PluginCredentialsNotSetMessageDetected,b.PluginSettingsApiSecretNotSet,b.PluginSettingsSiteIdNotSet,b.PostIsNotPublished,b.UnknownError,b.ParselySuggestionsApiAuthUnavailable,b.ParselySuggestionsApiNoAuthentication,b.ParselySuggestionsApiNoAuthorization,b.ParselySuggestionsApiNoData,b.ParselySuggestionsApiSchemaError];return a.retryFetch=!i.includes(a.code),Object.setPrototypeOf(a,t.prototype),a.code===b.AccessToFeatureDisabled?a.message=(0,m.__)("Access to this feature is disabled by the site's administration.","wp-parsely"):a.code===b.ParselySuggestionsApiNoAuthorization?a.message=(0,m.__)('This AI-powered feature is opt-in. To gain access, please submit a request here.',"wp-parsely"):a.code===b.ParselySuggestionsApiOpenAiError||a.code===b.ParselySuggestionsApiOpenAiUnavailable?a.message=(0,m.__)("The Parse.ly API returned an internal server error. Please retry with a different input, or try again later.","wp-parsely"):a.code===b.HttpRequestFailed&&a.message.includes("cURL error 28")?a.message=(0,m.__)("The Parse.ly API did not respond in a timely manner. Please try again later.","wp-parsely"):a.code===b.ParselySuggestionsApiSchemaError?a.message=(0,m.__)("The Parse.ly API returned a validation error. Please try again with different parameters.","wp-parsely"):a.code===b.ParselySuggestionsApiNoData?a.message=(0,m.__)("The Parse.ly API couldn't find any relevant data to fulfill the request. Please retry with a different input.","wp-parsely"):a.code===b.ParselySuggestionsApiOpenAiSchema?a.message=(0,m.__)("The Parse.ly API returned an incorrect response. Please try again later.","wp-parsely"):a.code===b.ParselySuggestionsApiAuthUnavailable&&(a.message=(0,m.__)("The Parse.ly API is currently unavailable. Please try again later.","wp-parsely")),a}return T(t,e),t.prototype.Message=function(e){return void 0===e&&(e=null),[b.PluginCredentialsNotSetMessageDetected,b.PluginSettingsSiteIdNotSet,b.PluginSettingsApiSecretNotSet].includes(this.code)?function(e){var t;return void 0===e&&(e=null),(0,w.jsx)(k,{className:null==e?void 0:e.className,testId:"empty-credentials-message",children:null!==(t=window.wpParselyEmptyCredentialsMessage)&&void 0!==t?t:(0,m.__)("Please ensure that the Site ID and API Secret given in the plugin's settings are correct.","wp-parsely")})}(e):(this.code===b.FetchError&&(this.hint=this.Hint((0,m.__)("This error can sometimes be caused by ad-blockers or browser tracking protections. Please add this site to any applicable allow lists and try again.","wp-parsely"))),this.code!==b.ParselyApiForbidden&&this.code!==b.ParselySuggestionsApiNoAuthentication||(this.hint=this.Hint((0,m.__)("Please ensure that the Site ID and API Secret given in the plugin's settings are correct.","wp-parsely"))),this.code===b.HttpRequestFailed&&(this.hint=this.Hint((0,m.__)("The Parse.ly API cannot be reached. Please verify that you are online.","wp-parsely"))),(0,w.jsx)(k,{className:null==e?void 0:e.className,testId:"error",children:"

".concat(this.message,"

").concat(this.hint?this.hint:"")}))},t.prototype.Hint=function(e){return'

'.concat((0,m.__)("Hint:","wp-parsely")," ").concat(e,"

")},t.prototype.createErrorSnackbar=function(){//.test(this.message)||(0,d.dispatch)("core/notices").createNotice("error",this.message,{type:"snackbar"})},t}(Error),j=function(e){var t=e.size,r=void 0===t?24:t,n=e.className,o=void 0===n?"wp-parsely-icon":n;return(0,w.jsxs)(v.SVG,{className:o,height:r,viewBox:"0 0 60 65",width:r,xmlns:"http://www.w3.org/2000/svg",children:[(0,w.jsx)(v.Path,{fill:"#5ba745",d:"M23.72,51.53c0-.18,0-.34-.06-.52a13.11,13.11,0,0,0-2.1-5.53A14.74,14.74,0,0,0,19.12,43c-.27-.21-.5-.11-.51.22l-.24,3.42c0,.33-.38.35-.49,0l-1.5-4.8a1.4,1.4,0,0,0-.77-.78,23.91,23.91,0,0,0-3.1-.84c-1.38-.24-3.39-.39-3.39-.39-.34,0-.45.21-.25.49l2.06,3.76c.2.27,0,.54-.29.33l-4.51-3.6a3.68,3.68,0,0,0-2.86-.48c-1,.16-2.44.46-2.44.46a.68.68,0,0,0-.39.25.73.73,0,0,0-.14.45S.41,43,.54,44a3.63,3.63,0,0,0,1.25,2.62L6.48,50c.28.2.09.49-.23.37l-4.18-.94c-.32-.12-.5,0-.4.37,0,0,.69,1.89,1.31,3.16a24,24,0,0,0,1.66,2.74,1.34,1.34,0,0,0,1,.52l5,.13c.33,0,.41.38.1.48L7.51,58c-.31.1-.34.35-.07.55a14.29,14.29,0,0,0,3.05,1.66,13.09,13.09,0,0,0,5.9.5,25.13,25.13,0,0,0,4.34-1,9.55,9.55,0,0,1-.08-1.2,9.32,9.32,0,0,1,3.07-6.91"}),(0,w.jsx)(v.Path,{fill:"#5ba745",d:"M59.7,41.53a.73.73,0,0,0-.14-.45.68.68,0,0,0-.39-.25s-1.43-.3-2.44-.46a3.64,3.64,0,0,0-2.86.48l-4.51,3.6c-.26.21-.49-.06-.29-.33l2.06-3.76c.2-.28.09-.49-.25-.49,0,0-2,.15-3.39.39a23.91,23.91,0,0,0-3.1.84,1.4,1.4,0,0,0-.77.78l-1.5,4.8c-.11.32-.48.3-.49,0l-.24-3.42c0-.33-.24-.43-.51-.22a14.74,14.74,0,0,0-2.44,2.47A13.11,13.11,0,0,0,36.34,51c0,.18,0,.34-.06.52a9.26,9.26,0,0,1,3,8.1,24.1,24.1,0,0,0,4.34,1,13.09,13.09,0,0,0,5.9-.5,14.29,14.29,0,0,0,3.05-1.66c.27-.2.24-.45-.07-.55l-3.22-1.17c-.31-.1-.23-.47.1-.48l5-.13a1.38,1.38,0,0,0,1-.52A24.6,24.6,0,0,0,57,52.92c.61-1.27,1.31-3.16,1.31-3.16.1-.33-.08-.49-.4-.37l-4.18.94c-.32.12-.51-.17-.23-.37l4.69-3.34A3.63,3.63,0,0,0,59.46,44c.13-1,.24-2.47.24-2.47"}),(0,w.jsx)(v.Path,{fill:"#5ba745",d:"M46.5,25.61c0-.53-.35-.72-.8-.43l-4.86,2.66c-.45.28-.56-.27-.23-.69l4.66-6.23a2,2,0,0,0,.28-1.68,36.51,36.51,0,0,0-2.19-4.89,34,34,0,0,0-2.81-3.94c-.33-.41-.74-.35-.91.16l-2.28,5.68c-.16.5-.6.48-.59-.05l.28-8.93a2.54,2.54,0,0,0-.66-1.64S35,4.27,33.88,3.27,30.78.69,30.78.69a1.29,1.29,0,0,0-1.54,0s-1.88,1.49-3.12,2.59-2.48,2.35-2.48,2.35A2.5,2.5,0,0,0,23,7.27l.27,8.93c0,.53-.41.55-.58.05l-2.29-5.69c-.17-.5-.57-.56-.91-.14a35.77,35.77,0,0,0-3,4.2,35.55,35.55,0,0,0-2,4.62,2,2,0,0,0,.27,1.67l4.67,6.24c.33.42.23,1-.22.69l-4.87-2.66c-.45-.29-.82-.1-.82.43a18.6,18.6,0,0,0,.83,5.07,20.16,20.16,0,0,0,5.37,7.77c3.19,3,5.93,7.8,7.45,11.08A9.6,9.6,0,0,1,30,49.09a9.31,9.31,0,0,1,2.86.45c1.52-3.28,4.26-8.11,7.44-11.09a20.46,20.46,0,0,0,5.09-7,19,19,0,0,0,1.11-5.82"}),(0,w.jsx)(v.Path,{fill:"#5ba745",d:"M36.12,58.44A6.12,6.12,0,1,1,30,52.32a6.11,6.11,0,0,1,6.12,6.12"})]})},C=window.wp.url,I=window.wp.apiFetch,O=r.n(I),R=function(){function e(){this.abortControllers=new Map}return e.prototype.cancelRequest=function(e){if(e)(t=this.abortControllers.get(e))&&(t.abort(),this.abortControllers.delete(e));else{var t,r=Array.from(this.abortControllers.keys()).pop();r&&(t=this.abortControllers.get(r))&&(t.abort(),this.abortControllers.delete(r))}},e.prototype.cancelAll=function(){this.abortControllers.forEach((function(e){return e.abort()})),this.abortControllers.clear()},e.prototype.getOrCreateController=function(e){if(e&&this.abortControllers.has(e))return{abortController:this.abortControllers.get(e),abortId:e};var t=null!=e?e:"auto-"+Date.now(),r=new AbortController;return this.abortControllers.set(t,r),{abortController:r,abortId:t}},e.prototype.fetch=function(e,t){return r=this,n=void 0,a=function(){var r,n,o,a,i,s;return function(e,t){var r,n,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function s(s){return function(l){return function(s){if(r)throw new TypeError("Generator is already executing.");for(;a&&(a=0,s[0]&&(i=0)),i;)try{if(r=1,n&&(o=2&s[0]?n.return:s[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,s[1])).done)return o;switch(n=0,o&&(s=[2&s[0],o.value]),s[0]){case 0:case 1:o=s;break;case 4:return i.label++,{value:s[1],done:!1};case 5:i.label++,n=s[1],s=[0];continue;case 7:s=i.ops.pop(),i.trys.pop();continue;default:if(!((o=(o=i.trys).length>0&&o[o.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]0&&o[o.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]0&&o[o.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]0?(0,m.sprintf)( +!function(){"use strict";var e={20:function(e,t,r){var n=r(609),o=Symbol.for("react.element"),a=Symbol.for("react.fragment"),i=Object.prototype.hasOwnProperty,s=n.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function c(e,t,r){var n,a={},c=null,u=null;for(n in void 0!==r&&(c=""+r),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(u=t.ref),t)i.call(t,n)&&!l.hasOwnProperty(n)&&(a[n]=t[n]);if(e&&e.defaultProps)for(n in t=e.defaultProps)void 0===a[n]&&(a[n]=t[n]);return{$$typeof:o,type:e,key:c,ref:u,props:a,_owner:s.current}}t.Fragment=a,t.jsx=c,t.jsxs=c},848:function(e,t,r){e.exports=r(20)},609:function(e){e.exports=window.React}},t={};function r(n){var o=t[n];if(void 0!==o)return o.exports;var a=t[n]={exports:{}};return e[n](a,a.exports,r),a.exports}r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,{a:t}),t},r.d=function(e,t){for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},function(){var e,t,n,o,a,i,s,l,c,u,p,d=window.wp.data,y=window.wp.hooks,h=window.wp.plugins,f=((0,d.dispatch)("core/block-editor"),(0,d.dispatch)("core/editor"),(0,d.dispatch)("core/edit-post")),w=r(848),v=window.wp.components,g=window.wp.editor;void 0!==window.wp&&(p=null!==(t=null===(e=window.wp.editor)||void 0===e?void 0:e.PluginDocumentSettingPanel)&&void 0!==t?t:null!==(o=null===(n=window.wp.editPost)||void 0===n?void 0:n.PluginDocumentSettingPanel)&&void 0!==o?o:null===(a=window.wp.editSite)||void 0===a?void 0:a.PluginDocumentSettingPanel,null!==(s=null===(i=window.wp.editor)||void 0===i?void 0:i.PluginSidebar)&&void 0!==s||null!==(c=null===(l=window.wp.editPost)||void 0===l?void 0:l.PluginSidebar)&&void 0!==c||null===(u=window.wp.editSite)||void 0===u||u.PluginSidebar);var _,b,P=window.wp.element,m=window.wp.i18n,x=window.wp.wordcount,E=window.wp.primitives,A=(0,w.jsx)(E.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,w.jsx)(E.Path,{d:"M19.5 4.5h-7V6h4.44l-5.97 5.97 1.06 1.06L18 7.06v4.44h1.5v-7Zm-13 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-3H17v3a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h3V5.5h-3Z"})}),S=function(){function e(){this._tkq=[],this.isLoaded=!1,this.isEnabled=!1,"undefined"!=typeof wpParselyTracksTelemetry&&(this.isEnabled=!0,this.loadTrackingLibrary())}return e.getInstance=function(){return window.wpParselyTelemetryInstance||Object.defineProperty(window,"wpParselyTelemetryInstance",{value:new e,writable:!1,configurable:!1,enumerable:!1}),window.wpParselyTelemetryInstance},e.prototype.loadTrackingLibrary=function(){var e=this,t=document.createElement("script");t.async=!0,t.src="//stats.wp.com/w.js",t.onload=function(){e.isLoaded=!0,e._tkq=window._tkq||[]},document.head.appendChild(t)},e.trackEvent=function(t){return r=this,n=arguments,a=function(t,r){var n;return void 0===r&&(r={}),function(e,t){var r,n,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function s(s){return function(l){return function(s){if(r)throw new TypeError("Generator is already executing.");for(;a&&(a=0,s[0]&&(i=0)),i;)try{if(r=1,n&&(o=2&s[0]?n.return:s[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,s[1])).done)return o;switch(n=0,o&&(s=[2&s[0],o.value]),s[0]){case 0:case 1:o=s;break;case 4:return i.label++,{value:s[1],done:!1};case 5:i.label++,n=s[1],s=[0];continue;case 7:s=i.ops.pop(),i.trys.pop();continue;default:if(!((o=(o=i.trys).length>0&&o[o.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]=1e4&&(clearInterval(a),r("Telemetry library not loaded"))}),100);else r("Telemetry not enabled")}))},e.prototype.trackEvent=function(t,r){var n;this.isLoaded?(0!==t.indexOf(e.TRACKS_PREFIX)&&(t=e.TRACKS_PREFIX+t),this.isEventNameValid(t)?(r=this.prepareProperties(r),null===(n=this._tkq)||void 0===n||n.push(["recordEvent",t,r])):console.error("Error tracking event: Invalid event name")):console.error("Error tracking event: Telemetry not loaded")},e.prototype.isTelemetryEnabled=function(){return this.isEnabled},e.prototype.isProprietyValid=function(t){return e.PROPERTY_REGEX.test(t)},e.prototype.isEventNameValid=function(t){return e.EVENT_NAME_REGEX.test(t)},e.prototype.prepareProperties=function(e){return(e=this.sanitizeProperties(e)).parsely_version=wpParselyTracksTelemetry.version,wpParselyTracksTelemetry.user&&(e._ut=wpParselyTracksTelemetry.user.type,e._ui=wpParselyTracksTelemetry.user.id),wpParselyTracksTelemetry.vipgo_env&&(e.vipgo_env=wpParselyTracksTelemetry.vipgo_env),this.sanitizeProperties(e)},e.prototype.sanitizeProperties=function(e){var t=this,r={};return Object.keys(e).forEach((function(n){t.isProprietyValid(n)&&(r[n]=e[n])})),r},e.TRACKS_PREFIX="wpparsely_",e.EVENT_NAME_REGEX=/^(([a-z0-9]+)_){2}([a-z0-9_]+)$/,e.PROPERTY_REGEX=/^[a-z_][a-z0-9_]*$/,e}(),k=(S.trackEvent,function(e){void 0===e&&(e=null);var t="";(null==e?void 0:e.children)&&(t=e.children);var r="content-helper-error-message";return(null==e?void 0:e.className)&&(r+=" "+e.className),(0,w.jsx)("div",{className:r,"data-testid":null==e?void 0:e.testId,dangerouslySetInnerHTML:{__html:t}})}),T=(_=function(e,t){return _=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])},_(e,t)},function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function __(){this.constructor=e}_(e,t),e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)});!function(e){e.AccessToFeatureDisabled="ch_access_to_feature_disabled",e.CannotFormulateApiQuery="ch_cannot_formulate_api_query",e.FetchError="fetch_error",e.HttpRequestFailed="http_request_failed",e.ParselyAborted="ch_parsely_aborted",e[e.ParselyApiForbidden=403]="ParselyApiForbidden",e.ParselyApiResponseContainsError="ch_response_contains_error",e.ParselyApiReturnedNoData="ch_parsely_api_returned_no_data",e.ParselyApiReturnedTooManyResults="ch_parsely_api_returned_too_many_results",e.PluginCredentialsNotSetMessageDetected="parsely_credentials_not_set_message_detected",e.PluginSettingsApiSecretNotSet="parsely_api_secret_not_set",e.PluginSettingsSiteIdNotSet="parsely_site_id_not_set",e.PostIsNotPublished="ch_post_not_published",e.UnknownError="ch_unknown_error",e.ParselySuggestionsApiAuthUnavailable="AUTH_UNAVAILABLE",e.ParselySuggestionsApiNoAuthentication="NO_AUTHENTICATION",e.ParselySuggestionsApiNoAuthorization="NO_AUTHORIZATION",e.ParselySuggestionsApiNoData="NO_DATA",e.ParselySuggestionsApiOpenAiError="OPENAI_ERROR",e.ParselySuggestionsApiOpenAiSchema="OPENAI_SCHEMA",e.ParselySuggestionsApiOpenAiUnavailable="OPENAI_UNAVAILABLE",e.ParselySuggestionsApiSchemaError="SCHEMA_ERROR"}(b||(b={}));var N=function(e){function t(r,n,o){void 0===o&&(o=(0,m.__)("Error: ","wp-parsely"));var a=this;r.startsWith(o)&&(o=""),(a=e.call(this,o+r)||this).hint=null,a.name=a.constructor.name,a.code=n;var i=[b.AccessToFeatureDisabled,b.ParselyApiForbidden,b.ParselyApiResponseContainsError,b.ParselyApiReturnedNoData,b.ParselyApiReturnedTooManyResults,b.PluginCredentialsNotSetMessageDetected,b.PluginSettingsApiSecretNotSet,b.PluginSettingsSiteIdNotSet,b.PostIsNotPublished,b.UnknownError,b.ParselySuggestionsApiAuthUnavailable,b.ParselySuggestionsApiNoAuthentication,b.ParselySuggestionsApiNoAuthorization,b.ParselySuggestionsApiNoData,b.ParselySuggestionsApiSchemaError];return a.retryFetch=!i.includes(a.code),Object.setPrototypeOf(a,t.prototype),a.code===b.AccessToFeatureDisabled?a.message=(0,m.__)("Access to this feature is disabled by the site's administration.","wp-parsely"):a.code===b.ParselySuggestionsApiNoAuthorization?a.message=(0,m.__)('This AI-powered feature is opt-in. To gain access, please submit a request here.',"wp-parsely"):a.code===b.ParselySuggestionsApiOpenAiError||a.code===b.ParselySuggestionsApiOpenAiUnavailable?a.message=(0,m.__)("The Parse.ly API returned an internal server error. Please retry with a different input, or try again later.","wp-parsely"):a.code===b.HttpRequestFailed&&a.message.includes("cURL error 28")?a.message=(0,m.__)("The Parse.ly API did not respond in a timely manner. Please try again later.","wp-parsely"):a.code===b.ParselySuggestionsApiSchemaError?a.message=(0,m.__)("The Parse.ly API returned a validation error. Please try again with different parameters.","wp-parsely"):a.code===b.ParselySuggestionsApiNoData?a.message=(0,m.__)("The Parse.ly API couldn't find any relevant data to fulfill the request. Please retry with a different input.","wp-parsely"):a.code===b.ParselySuggestionsApiOpenAiSchema?a.message=(0,m.__)("The Parse.ly API returned an incorrect response. Please try again later.","wp-parsely"):a.code===b.ParselySuggestionsApiAuthUnavailable&&(a.message=(0,m.__)("The Parse.ly API is currently unavailable. Please try again later.","wp-parsely")),a}return T(t,e),t.prototype.Message=function(e){return void 0===e&&(e=null),[b.PluginCredentialsNotSetMessageDetected,b.PluginSettingsSiteIdNotSet,b.PluginSettingsApiSecretNotSet].includes(this.code)?function(e){var t;return void 0===e&&(e=null),(0,w.jsx)(k,{className:null==e?void 0:e.className,testId:"empty-credentials-message",children:null!==(t=window.wpParselyEmptyCredentialsMessage)&&void 0!==t?t:(0,m.__)("Please ensure that the Site ID and API Secret given in the plugin's settings are correct.","wp-parsely")})}(e):(this.code===b.FetchError&&(this.hint=this.Hint((0,m.__)("This error can sometimes be caused by ad-blockers or browser tracking protections. Please add this site to any applicable allow lists and try again.","wp-parsely"))),this.code!==b.ParselyApiForbidden&&this.code!==b.ParselySuggestionsApiNoAuthentication||(this.hint=this.Hint((0,m.__)("Please ensure that the Site ID and API Secret given in the plugin's settings are correct.","wp-parsely"))),this.code===b.HttpRequestFailed&&(this.hint=this.Hint((0,m.__)("The Parse.ly API cannot be reached. Please verify that you are online.","wp-parsely"))),(0,w.jsx)(k,{className:null==e?void 0:e.className,testId:"error",children:"

".concat(this.message,"

").concat(this.hint?this.hint:"")}))},t.prototype.Hint=function(e){return'

'.concat((0,m.__)("Hint:","wp-parsely")," ").concat(e,"

")},t.prototype.createErrorSnackbar=function(){//.test(this.message)||(0,d.dispatch)("core/notices").createNotice("error",this.message,{type:"snackbar"})},t}(Error),j=function(e){var t=e.size,r=void 0===t?24:t,n=e.className,o=void 0===n?"wp-parsely-icon":n;return(0,w.jsxs)(v.SVG,{className:o,height:r,viewBox:"0 0 60 65",width:r,xmlns:"http://www.w3.org/2000/svg",children:[(0,w.jsx)(v.Path,{fill:"#5ba745",d:"M23.72,51.53c0-.18,0-.34-.06-.52a13.11,13.11,0,0,0-2.1-5.53A14.74,14.74,0,0,0,19.12,43c-.27-.21-.5-.11-.51.22l-.24,3.42c0,.33-.38.35-.49,0l-1.5-4.8a1.4,1.4,0,0,0-.77-.78,23.91,23.91,0,0,0-3.1-.84c-1.38-.24-3.39-.39-3.39-.39-.34,0-.45.21-.25.49l2.06,3.76c.2.27,0,.54-.29.33l-4.51-3.6a3.68,3.68,0,0,0-2.86-.48c-1,.16-2.44.46-2.44.46a.68.68,0,0,0-.39.25.73.73,0,0,0-.14.45S.41,43,.54,44a3.63,3.63,0,0,0,1.25,2.62L6.48,50c.28.2.09.49-.23.37l-4.18-.94c-.32-.12-.5,0-.4.37,0,0,.69,1.89,1.31,3.16a24,24,0,0,0,1.66,2.74,1.34,1.34,0,0,0,1,.52l5,.13c.33,0,.41.38.1.48L7.51,58c-.31.1-.34.35-.07.55a14.29,14.29,0,0,0,3.05,1.66,13.09,13.09,0,0,0,5.9.5,25.13,25.13,0,0,0,4.34-1,9.55,9.55,0,0,1-.08-1.2,9.32,9.32,0,0,1,3.07-6.91"}),(0,w.jsx)(v.Path,{fill:"#5ba745",d:"M59.7,41.53a.73.73,0,0,0-.14-.45.68.68,0,0,0-.39-.25s-1.43-.3-2.44-.46a3.64,3.64,0,0,0-2.86.48l-4.51,3.6c-.26.21-.49-.06-.29-.33l2.06-3.76c.2-.28.09-.49-.25-.49,0,0-2,.15-3.39.39a23.91,23.91,0,0,0-3.1.84,1.4,1.4,0,0,0-.77.78l-1.5,4.8c-.11.32-.48.3-.49,0l-.24-3.42c0-.33-.24-.43-.51-.22a14.74,14.74,0,0,0-2.44,2.47A13.11,13.11,0,0,0,36.34,51c0,.18,0,.34-.06.52a9.26,9.26,0,0,1,3,8.1,24.1,24.1,0,0,0,4.34,1,13.09,13.09,0,0,0,5.9-.5,14.29,14.29,0,0,0,3.05-1.66c.27-.2.24-.45-.07-.55l-3.22-1.17c-.31-.1-.23-.47.1-.48l5-.13a1.38,1.38,0,0,0,1-.52A24.6,24.6,0,0,0,57,52.92c.61-1.27,1.31-3.16,1.31-3.16.1-.33-.08-.49-.4-.37l-4.18.94c-.32.12-.51-.17-.23-.37l4.69-3.34A3.63,3.63,0,0,0,59.46,44c.13-1,.24-2.47.24-2.47"}),(0,w.jsx)(v.Path,{fill:"#5ba745",d:"M46.5,25.61c0-.53-.35-.72-.8-.43l-4.86,2.66c-.45.28-.56-.27-.23-.69l4.66-6.23a2,2,0,0,0,.28-1.68,36.51,36.51,0,0,0-2.19-4.89,34,34,0,0,0-2.81-3.94c-.33-.41-.74-.35-.91.16l-2.28,5.68c-.16.5-.6.48-.59-.05l.28-8.93a2.54,2.54,0,0,0-.66-1.64S35,4.27,33.88,3.27,30.78.69,30.78.69a1.29,1.29,0,0,0-1.54,0s-1.88,1.49-3.12,2.59-2.48,2.35-2.48,2.35A2.5,2.5,0,0,0,23,7.27l.27,8.93c0,.53-.41.55-.58.05l-2.29-5.69c-.17-.5-.57-.56-.91-.14a35.77,35.77,0,0,0-3,4.2,35.55,35.55,0,0,0-2,4.62,2,2,0,0,0,.27,1.67l4.67,6.24c.33.42.23,1-.22.69l-4.87-2.66c-.45-.29-.82-.1-.82.43a18.6,18.6,0,0,0,.83,5.07,20.16,20.16,0,0,0,5.37,7.77c3.19,3,5.93,7.8,7.45,11.08A9.6,9.6,0,0,1,30,49.09a9.31,9.31,0,0,1,2.86.45c1.52-3.28,4.26-8.11,7.44-11.09a20.46,20.46,0,0,0,5.09-7,19,19,0,0,0,1.11-5.82"}),(0,w.jsx)(v.Path,{fill:"#5ba745",d:"M36.12,58.44A6.12,6.12,0,1,1,30,52.32a6.11,6.11,0,0,1,6.12,6.12"})]})},C=window.wp.url,I=window.wp.apiFetch,O=r.n(I),R=function(){function e(){this.abortControllers=new Map}return e.prototype.cancelRequest=function(e){if(e)(t=this.abortControllers.get(e))&&(t.abort(),this.abortControllers.delete(e));else{var t,r=Array.from(this.abortControllers.keys()).pop();r&&(t=this.abortControllers.get(r))&&(t.abort(),this.abortControllers.delete(r))}},e.prototype.cancelAll=function(){this.abortControllers.forEach((function(e){return e.abort()})),this.abortControllers.clear()},e.prototype.getOrCreateController=function(e){if(e&&this.abortControllers.has(e))return{abortController:this.abortControllers.get(e),abortId:e};var t=null!=e?e:"auto-"+Date.now(),r=new AbortController;return this.abortControllers.set(t,r),{abortController:r,abortId:t}},e.prototype.fetch=function(e,t){return r=this,n=void 0,a=function(){var r,n,o,a,i,s;return function(e,t){var r,n,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function s(s){return function(l){return function(s){if(r)throw new TypeError("Generator is already executing.");for(;a&&(a=0,s[0]&&(i=0)),i;)try{if(r=1,n&&(o=2&s[0]?n.return:s[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,s[1])).done)return o;switch(n=0,o&&(s=[2&s[0],o.value]),s[0]){case 0:case 1:o=s;break;case 4:return i.label++,{value:s[1],done:!1};case 5:i.label++,n=s[1],s=[0];continue;case 7:s=i.ops.pop(),i.trys.pop();continue;default:if(!((o=(o=i.trys).length>0&&o[o.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]0&&o[o.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]0&&o[o.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]0?(0,m.sprintf)( // Translators: %1$s the number of words in the excerpt. // Translators: %1$s the number of words in the excerpt. (0,m._n)("%1$s word","%1$s words",e,"wp-parsely"),e):"")}),[h.currentExcerpt,k]),(0,P.useEffect)((function(){var e=document.querySelector(".editor-post-excerpt textarea");e&&(e.scrollTop=0)}),[h.newExcerptGeneratedCount]),(0,w.jsxs)("div",{className:"editor-post-excerpt",children:[(0,w.jsxs)("div",{style:{position:"relative"},children:[t&&(0,w.jsx)("div",{className:"editor-post-excerpt__loading_animation",children:(0,w.jsx)(H,{})}),(0,w.jsx)(v.TextareaControl,{__nextHasNoMarginBottom:!0,label:(0,m.__)("Write an excerpt (optional)","wp-parsely"),className:"editor-post-excerpt__textarea",onChange:function(e){h.isUnderReview||_({excerpt:e}),f(F(F({},h),{currentExcerpt:e})),l(!0)},onKeyUp:function(){var e;if(s)l(!1);else{var t=document.querySelector(".editor-post-excerpt textarea"),r=null!==(e=null==t?void 0:t.textContent)&&void 0!==e?e:"";f(F(F({},h),{currentExcerpt:r}))}},value:t?"":h.isUnderReview?h.currentExcerpt:k,help:u||null})]}),(0,w.jsxs)(v.Button,{href:(0,m.__)("https://wordpress.org/documentation/article/page-post-settings-sidebar/#excerpt","wp-parsely"),target:"_blank",variant:"link",children:[(0,m.__)("Learn more about manual excerpts","wp-parsely"),(0,w.jsx)(v.Icon,{icon:A,size:18,className:"parsely-external-link-icon"})]}),(0,w.jsxs)("div",{className:"wp-parsely-excerpt-generator",children:[(0,w.jsxs)("div",{className:"wp-parsely-excerpt-generator-header",children:[(0,w.jsx)(j,{size:16}),(0,w.jsxs)("div",{className:"wp-parsely-excerpt-generator-header-label",children:[(0,m.__)("Generate With Parse.ly","wp-parsely"),(0,w.jsx)("span",{className:"beta-label",children:(0,m.__)("Beta","wp-parsely")})]})]}),o&&(0,w.jsx)(v.Notice,{className:"wp-parsely-excerpt-generator-error",onRemove:function(){return a(void 0)},status:"info",children:o.Message()}),(0,w.jsx)("div",{className:"wp-parsely-excerpt-generator-controls",children:h.isUnderReview?(0,w.jsxs)(w.Fragment,{children:[(0,w.jsx)(v.Button,{variant:"secondary",onClick:function(){return L(void 0,void 0,void 0,(function(){return M(this,(function(e){switch(e.label){case 0:return[4,_({excerpt:h.currentExcerpt})];case 1:return e.sent(),f(F(F({},h),{isUnderReview:!1})),S.trackEvent("excerpt_generator_accepted"),[2]}}))}))},children:(0,m.__)("Accept","wp-parsely")}),(0,w.jsx)(v.Button,{isDestructive:!0,variant:"secondary",onClick:function(){return L(void 0,void 0,void 0,(function(){return M(this,(function(e){return _({excerpt:h.oldExcerpt}),f(F(F({},h),{currentExcerpt:h.oldExcerpt,isUnderReview:!1})),S.trackEvent("excerpt_generator_discarded"),[2]}))}))},children:(0,m.__)("Discard","wp-parsely")})]}):(0,w.jsxs)(v.Button,{onClick:function(){return L(void 0,void 0,void 0,(function(){var e,t;return M(this,(function(n){switch(n.label){case 0:r(!0),a(void 0),n.label=1;case 1:return n.trys.push([1,3,4,5]),S.trackEvent("excerpt_generator_pressed"),[4,D.getInstance().generateExcerpt(C,T)];case 2:return e=n.sent(),f({currentExcerpt:e,isUnderReview:!0,newExcerptGeneratedCount:h.newExcerptGeneratedCount+1,oldExcerpt:k}),[3,5];case 3:return(t=n.sent())instanceof N?a(t):(a(new N((0,m.__)("An unknown error occurred.","wp-parsely"),b.UnknownError)),console.error(t)),[3,5];case 4:return r(!1),[7];case 5:return[2]}}))}))},variant:"primary",isBusy:t,disabled:t||!T,children:[t&&(0,m.__)("Generating Excerpt…","wp-parsely"),!t&&h.newExcerptGeneratedCount>0&&(0,m.__)("Regenerate Excerpt","wp-parsely"),!t&&0===h.newExcerptGeneratedCount&&(0,m.__)("Generate Excerpt","wp-parsely")]})}),(0,w.jsxs)(v.Button,{href:"https://docs.parse.ly/plugin-content-helper/#h-excerpt-generator-beta",target:"_blank",variant:"link",children:[(0,m.__)("Learn more about Parse.ly AI","wp-parsely"),(0,w.jsx)(v.Icon,{icon:A,size:18,className:"parsely-external-link-icon"})]})]})]})},H=function(){return(0,w.jsx)(v.Animate,{type:"loading",children:function(e){var t=e.className;return(0,w.jsx)("span",{className:t,children:(0,m.__)("Generating…","wp-parsely")})}})},q=function(){return(0,w.jsx)(g.PostTypeSupportCheck,{supportKeys:"excerpt",children:(0,w.jsx)(p,{name:"parsely-post-excerpt",title:(0,m.__)("Excerpt","wp-parsely"),children:(0,w.jsx)(G,{})})})};(0,y.addFilter)("plugins.registerPlugin","wp-parsely-excerpt-generator",(function(e,t){var r,n,o;return"wp-parsely-block-editor-sidebar"!==t||((null===(r=null===window||void 0===window?void 0:window.Jetpack_Editor_Initial_State)||void 0===r?void 0:r.available_blocks["ai-content-lens"])&&(console.log("Parse.ly: Jetpack AI is enabled and will be disabled."),(0,y.removeFilter)("blocks.registerBlockType","jetpack/ai-content-lens-features")),(0,h.registerPlugin)("wp-parsely-excerpt-generator",{render:q}),(null===(n=(0,d.dispatch)("core/editor"))||void 0===n?void 0:n.removeEditorPanel)?null===(o=(0,d.dispatch)("core/editor"))||void 0===o||o.removeEditorPanel("post-excerpt"):null==f||f.removeEditorPanel("post-excerpt")),e}),1e3)}()}(); \ No newline at end of file diff --git a/src/content-helper/editor-sidebar/smart-linking/provider.ts b/src/content-helper/editor-sidebar/smart-linking/provider.ts index ce30569f5..66b3215d4 100644 --- a/src/content-helper/editor-sidebar/smart-linking/provider.ts +++ b/src/content-helper/editor-sidebar/smart-linking/provider.ts @@ -140,12 +140,12 @@ export class SmartLinkingProvider extends BaseProvider { ): Promise { const response = await this.fetch( { method: 'POST', - path: addQueryArgs( '/wp-parsely/v1/content-suggestions/suggest-linked-reference', { + path: addQueryArgs( '/wp-parsely/v2/content-helper/smart-linking/generate', { max_links: maxLinksPerPost, } ), data: { url_exclusion_list: urlExclusionList, - text: content, + content, }, } ); @@ -165,7 +165,7 @@ export class SmartLinkingProvider extends BaseProvider { public async addSmartLink( postID: number, linkSuggestion: SmartLink ): Promise { return await this.fetch( { method: 'POST', - path: `/wp-parsely/v1/smart-linking/${ postID }/add`, + path: `/wp-parsely/v2/content-helper/smart-linking/${ postID }/add`, data: { link: linkSuggestion, }, @@ -195,7 +195,7 @@ export class SmartLinkingProvider extends BaseProvider { return await this.fetch( { method: 'POST', - path: `/wp-parsely/v1/smart-linking/${ postID }/add-multiple`, + path: `/wp-parsely/v2/content-helper/smart-linking/${ postID }/add-multiple`, data: { links: linkSuggestions, }, @@ -230,7 +230,7 @@ export class SmartLinkingProvider extends BaseProvider { return await this.fetch( { method: 'POST', - path: `/wp-parsely/v1/smart-linking/${ postID }/set`, + path: `/wp-parsely/v2/content-helper/smart-linking/${ postID }/set`, data: { links: appliedSmartLinks, }, @@ -249,7 +249,7 @@ export class SmartLinkingProvider extends BaseProvider { public async getSmartLinks( postID: number ): Promise { return await this.fetch( { method: 'GET', - path: `/wp-parsely/v1/smart-linking/${ postID }/get`, + path: `/wp-parsely/v2/content-helper/smart-linking/${ postID }/get`, } ); } @@ -265,7 +265,7 @@ export class SmartLinkingProvider extends BaseProvider { public async getPostTypeByURL( url: string ): Promise { return await this.fetch( { method: 'POST', - path: '/wp-parsely/v1/smart-linking/url-to-post-type', + path: '/wp-parsely/v2/content-helper/smart-linking/url-to-post-type', data: { url, }, diff --git a/src/content-helper/editor-sidebar/title-suggestions/provider.ts b/src/content-helper/editor-sidebar/title-suggestions/provider.ts index c6095bf5e..a5fb0d4a1 100644 --- a/src/content-helper/editor-sidebar/title-suggestions/provider.ts +++ b/src/content-helper/editor-sidebar/title-suggestions/provider.ts @@ -52,7 +52,7 @@ export class TitleSuggestionsProvider extends BaseProvider { public async generateTitles( content: string, limit: number = 3, tone: ToneProp, persona: PersonaProp ): Promise { const response = this.fetch( { method: 'POST', - path: addQueryArgs( '/wp-parsely/v1/content-suggestions/suggest-headline', { + path: addQueryArgs( '/wp-parsely/v2/content-helper/title-suggestions/generate', { limit, tone: getToneLabel( tone ), persona: getPersonaLabel( persona ), diff --git a/src/content-helper/excerpt-generator/provider.ts b/src/content-helper/excerpt-generator/provider.ts index 6fb4dcaf0..9716dcd87 100644 --- a/src/content-helper/excerpt-generator/provider.ts +++ b/src/content-helper/excerpt-generator/provider.ts @@ -51,7 +51,7 @@ export class ExcerptGeneratorProvider extends BaseProvider { return await this.fetch( { method: 'POST', - path: addQueryArgs( '/wp-parsely/v1/content-suggestions/suggest-brief', { + path: addQueryArgs( '/wp-parsely/v2/content-helper/excerpt-generator/generate', { title, } ), data: { From 04de75080752ee4818138baaa1cbb4a75f1fe72f Mon Sep 17 00:00:00 2001 From: Henrique Mouta Date: Thu, 22 Aug 2024 14:37:54 +0100 Subject: [PATCH 044/282] Remove unused code and initializations --- .../class-smart-linking-endpoint.php | 602 ------------------ .../class-suggest-brief-api-proxy.php | 152 ----- .../class-suggest-headline-api-proxy.php | 123 ---- ...ass-suggest-linked-reference-api-proxy.php | 162 ----- wp-parsely.php | 31 +- 5 files changed, 1 insertion(+), 1069 deletions(-) delete mode 100644 src/Endpoints/content-helper/class-smart-linking-endpoint.php delete mode 100644 src/Endpoints/content-suggestions/class-suggest-brief-api-proxy.php delete mode 100644 src/Endpoints/content-suggestions/class-suggest-headline-api-proxy.php delete mode 100644 src/Endpoints/content-suggestions/class-suggest-linked-reference-api-proxy.php diff --git a/src/Endpoints/content-helper/class-smart-linking-endpoint.php b/src/Endpoints/content-helper/class-smart-linking-endpoint.php deleted file mode 100644 index d52e7e2c0..000000000 --- a/src/Endpoints/content-helper/class-smart-linking-endpoint.php +++ /dev/null @@ -1,602 +0,0 @@ -get_param( 'post_id' ); - if ( is_numeric( $temp_post_id ) ) { - $post_id = intval( $temp_post_id ); - } - } - - $can_access_pch = Permissions::current_user_can_use_pch_feature( - 'smart_linking', - $this->parsely->get_options()['content_helper'], - $post_id - ); - - // Check if the current user has the smart linking capability. - $has_capability = current_user_can( - // phpcs:ignore WordPress.WP.Capabilities.Undetermined - $this->apply_capability_filters( - Base_Endpoint::DEFAULT_ACCESS_CAPABILITY - ) - ); - - return $can_access_pch && $has_capability; - } - - /** - * Registers the endpoints. - * - * @since 3.16.0 - */ - public function run(): void { - /** - * POST /smart-linking/url-to-post-type - * Converts a URL to a post type. - */ - $this->register_endpoint( - static::ENDPOINT . '/url-to-post-type', - 'url_to_post_type', - array( 'POST' ) - ); - - /** - * GET /smart-linking/{post_id}/get - * Gets the smart links for a post. - */ - $this->register_endpoint_with_args( - static::ENDPOINT . '/(?P\d+)/get', - 'get_smart_links', - array( 'GET' ), - array( - 'post_id' => array( - 'required' => true, - 'description' => __( 'The post ID.', 'wp-parsely' ), - 'validate_callback' => array( $this, 'private_api_request_validate_post_id' ), - ), - ) - ); - - /** - * POST /smart-linking/{post_id}/add - * Adds a smart link to a post. - */ - $this->register_endpoint_with_args( - static::ENDPOINT . '/(?P\d+)/add', - 'add_smart_link', - array( 'POST' ), - array( - 'post_id' => array( - 'required' => true, - 'description' => __( 'The post ID.', 'wp-parsely' ), - 'validate_callback' => array( $this, 'private_api_request_validate_post_id' ), - ), - 'link' => array( - 'required' => true, - 'type' => 'array', - 'description' => __( 'The smart link data to add.', 'wp-parsely' ), - 'validate_callback' => array( $this, 'private_api_request_validate_smart_link_params' ), - ), - 'update' => array( - 'type' => 'boolean', - 'description' => __( 'Whether to update the existing smart link.', 'wp-parsely' ), - 'default' => false, - ), - ) - ); - - /** - * POST /smart-linking/{post_id}/add-multiple - * Adds multiple smart links to a post. - */ - $this->register_endpoint_with_args( - static::ENDPOINT . '/(?P\d+)/add-multiple', - 'add_multiple_smart_links', - array( 'POST' ), - array( - 'post_id' => array( - 'required' => true, - 'description' => __( 'The post ID.', 'wp-parsely' ), - 'validate_callback' => array( $this, 'private_api_request_validate_post_id' ), - ), - 'links' => array( - 'required' => true, - 'type' => 'array', - 'description' => __( 'The multiple smart links data to add.', 'wp-parsely' ), - 'validate_callback' => array( $this, 'private_api_request_validate_multiple_smart_links' ), - ), - 'update' => array( - 'type' => 'boolean', - 'description' => __( 'Whether to update the existing smart links.', 'wp-parsely' ), - 'default' => false, - ), - ) - ); - - /** - * POST /smart-linking/{post_id}/set - * Updates the smart links of a given post and removes the ones that are not in the request. - */ - $this->register_endpoint_with_args( - static::ENDPOINT . '/(?P\d+)/set', - 'set_smart_links', - array( 'POST' ), - array( - 'post_id' => array( - 'required' => true, - 'description' => __( 'The post ID.', 'wp-parsely' ), - 'validate_callback' => array( $this, 'private_api_request_validate_post_id' ), - ), - 'links' => array( - 'required' => true, - 'type' => 'array', - 'description' => __( 'The smart links data to set.', 'wp-parsely' ), - 'validate_callback' => array( $this, 'private_api_request_validate_multiple_smart_links' ), - ), - ) - ); - } - - /** - * API Endpoint: POST /smart-linking/url-to-post-type. - * - * Converts a URL to a post type. - * - * @since 3.16.0 - * - * @param WP_REST_Request $request The request object. - * @return WP_REST_Response The response object. - */ - public function url_to_post_type( WP_REST_Request $request ): WP_REST_Response { - $url = $request->get_param( 'url' ); - - if ( ! is_string( $url ) ) { - return new WP_REST_Response( - array( - 'error' => array( - 'name' => 'invalid_request', - 'message' => __( 'Invalid request body.', 'wp-parsely' ), - ), - ), - 400 - ); - } - - $post_id = 0; - $cache = wp_cache_get( $url, 'wp_parsely_smart_link_url_to_postid' ); - - if ( is_integer( $cache ) ) { - $post_id = $cache; - } elseif ( function_exists( 'wpcom_vip_url_to_postid' ) ) { - $post_id = wpcom_vip_url_to_postid( $url ); - } else { - // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.url_to_postid_url_to_postid - $post_id = url_to_postid( $url ); - wp_cache_set( $url, $post_id, 'wp_parsely_smart_link_url_to_postid' ); - } - - $response = array( - 'data' => array( - 'post_id' => false, - 'post_type' => false, - ), - ); - - if ( 0 !== $post_id ) { - $response['data']['post_id'] = $post_id; - $response['data']['post_type'] = get_post_type( $post_id ); - } - - return new WP_REST_Response( $response, 200 ); - } - - - /** - * API Endpoint: GET /smart-linking/{post_id}/get. - * - * Gets the smart links for a post. - * - * @since 3.16.0 - * - * @param WP_REST_Request $request The request object. - * @return WP_REST_Response The response object. - */ - public function get_smart_links( WP_REST_Request $request ): WP_REST_Response { - /** - * The post object. - * - * @var WP_Post $post - */ - $post = $request->get_param( 'post' ); - - $outbound_links = Smart_Link::get_outbound_smart_links( $post->ID ); - $inbound_links = Smart_Link::get_inbound_smart_links( $post->ID ); - - $response = array( - 'outbound' => $this->serialize_smart_links( $outbound_links ), - 'inbound' => $this->serialize_smart_links( $inbound_links ), - ); - - return new WP_REST_Response( array( 'data' => $response ), 200 ); - } - - - /** - * API Endpoint: POST /smart-linking/{post_id}/add. - * - * Adds a smart link to a post. - * If the update parameter is set to true, the existing smart link will be updated. - * - * @since 3.16.0 - * - * @param WP_REST_Request $request The request object. - * @return WP_REST_Response The response object. - */ - public function add_smart_link( WP_REST_Request $request ): WP_REST_Response { - /** - * The Smart Link model. - * - * @var Smart_Link $smart_link - */ - $smart_link = $request->get_param( 'smart_link' ); - $should_update = $request->get_param( 'update' ) === true; - - if ( $smart_link->exists() && ! $should_update ) { - return new WP_REST_Response( - array( - 'error' => array( - 'name' => 'smart_link_exists', - 'message' => __( 'Smart link already exists.', 'wp-parsely' ), - ), - ), - 409 // HTTP Conflict. - ); - } - - // The smart link properties are set in the validate callback. - $saved = $smart_link->save(); - if ( ! $saved ) { - return new WP_REST_Response( - array( - 'error' => array( - 'name' => 'add_smart_link_failed', - 'message' => __( 'Failed to add the smart link.', 'wp-parsely' ), - ), - ), - 500 - ); - } - - return new WP_REST_Response( - array( - 'data' => json_decode( $smart_link->serialize() ), - ), - 200 - ); - } - - /** - * API Endpoint: POST /smart-linking/{post_id}/add_multiple. - * - * Adds multiple smart links to a post. - * - * @since 3.16.0 - * - * @param WP_REST_Request $request The request object. - * @return WP_REST_Response The response object. - */ - public function add_multiple_smart_links( WP_REST_Request $request ): WP_REST_Response { - /** - * Array of Smart Link models. - * - * @var Smart_Link[] $smart_links - */ - $smart_links = $request->get_param( 'smart_links' ); - $should_update = $request->get_param( 'update' ) === true; - - $added_links = array(); - $updated_links = array(); - $failed_links = array(); - - foreach ( $smart_links as $smart_link ) { - if ( $smart_link->exists() && ! $should_update ) { - $failed_links[] = $smart_link; - continue; - } - - $updated_link = $smart_link->exists() && $should_update; - - // The smart link properties are set in the validate callback. - $saved = $smart_link->save(); - - if ( ! $saved ) { - $failed_links[] = $smart_link; - continue; - } - - if ( $updated_link ) { - $updated_links[] = $smart_link; - } else { - $added_links[] = $smart_link; - } - } - - // If no link was added, return an error response. - if ( count( $added_links ) === 0 && count( $updated_links ) === 0 ) { - return new WP_REST_Response( - array( - 'error' => array( - 'name' => 'add_smart_link_failed', - 'message' => __( 'Failed to add all the smart links.', 'wp-parsely' ), - ), - ), - 500 - ); - } - - $response = array(); - if ( count( $added_links ) > 0 ) { - $response['added'] = $this->serialize_smart_links( $added_links ); - } - if ( count( $failed_links ) > 0 ) { - $response['failed'] = $this->serialize_smart_links( $failed_links ); - } - if ( count( $updated_links ) > 0 ) { - $response['updated'] = $this->serialize_smart_links( $updated_links ); - } - - return new WP_REST_Response( array( 'data' => $response ), 200 ); - } - - /** - * API Endpoint: POST /smart-linking/{post_id}/set. - * - * Updates the smart links of a given post and removes the ones that are not in the request. - * - * @since 3.16.0 - * - * @param WP_REST_Request $request The request object. - * @return WP_REST_Response The response object. - */ - public function set_smart_links( WP_REST_Request $request ): WP_REST_Response { - /** - * The post object. - * - * @var WP_Post $post - */ - $post = $request->get_param( 'post' ); - - /** - * Array of Smart Link models provided in the request. - * - * @var Smart_Link[] $smart_links - */ - $smart_links = $request->get_param( 'smart_links' ); - - // Get the current stored smart links. - $existing_links = Smart_Link::get_outbound_smart_links( $post->ID ); - $removed_links = array(); - - foreach ( $existing_links as $existing_link ) { - $found = false; - foreach ( $smart_links as $smart_link ) { - if ( $smart_link->get_uid() === $existing_link->get_uid() ) { - $found = true; - break; - } - } - - if ( ! $found ) { - $removed_links[] = $existing_link; - $existing_link->delete(); - } - } - - $saved_links = array(); - $failed_links = array(); - - foreach ( $smart_links as $smart_link ) { - // The smart link properties are set in the validate callback. - $saved = $smart_link->save(); - - if ( ! $saved ) { - $failed_links[] = $smart_link; - continue; - } - - $saved_links[] = $smart_link; - } - - $response = array( - 'saved' => $this->serialize_smart_links( $saved_links ), - 'removed' => $this->serialize_smart_links( $removed_links ), - ); - - if ( count( $failed_links ) > 0 ) { - $response['failed'] = $this->serialize_smart_links( $failed_links ); - } - - return new WP_REST_Response( array( 'data' => $response ), 200 ); - } - - /** - * Validates the post ID parameter. - * - * The callback sets the post object in the request object if the parameter is valid. - * - * @since 3.16.0 - * @access private - * - * @param string $param The parameter value. - * @param WP_REST_Request $request The request object. - * @return bool Whether the parameter is valid. - */ - public function private_api_request_validate_post_id( string $param, WP_REST_Request $request ): bool { - if ( ! is_numeric( $param ) ) { - return false; - } - - $param = filter_var( $param, FILTER_VALIDATE_INT ); - - if ( false === $param ) { - return false; - } - - // Validate if the post ID exists. - $post = get_post( $param ); - // Set the post attribute in the request. - $request->set_param( 'post', $post ); - - return null !== $post; - } - - /** - * Validates the smart link parameters. - * - * The callback sets the smart link object in the request object if the parameters are valid. - * - * @since 3.16.0 - * @access private - * - * @param array $params The parameters. - * @param WP_REST_Request $request The request object. - * @return bool Whether the parameters are valid. - */ - public function private_api_request_validate_smart_link_params( array $params, WP_REST_Request $request ): bool { - $required_params = array( 'uid', 'href', 'title', 'text', 'offset' ); - - foreach ( $required_params as $param ) { - if ( ! isset( $params[ $param ] ) ) { - return false; - } - } - - $encoded_data = wp_json_encode( $params ); - if ( false === $encoded_data ) { - return false; - } - - $post_id = $request->get_param( 'post_id' ); - if ( ! is_numeric( $post_id ) ) { - return false; - } - - if ( ! is_string( $params['uid'] ) ) { - return false; - } - - // Try to get the smart link from the UID. - $smart_link = Smart_Link::get_smart_link( $params['uid'], intval( $post_id ) ); - if ( $smart_link->exists() ) { - // Update the smart link with the new data. - $smart_link->set_href( $params['href'] ); - $smart_link->title = $params['title']; - $smart_link->text = $params['text']; - $smart_link->offset = $params['offset']; - } else { - /** - * The Smart Link model. - * - * @var Smart_Link $smart_link - */ - $smart_link = Smart_Link::deserialize( $encoded_data ); - $smart_link->set_source_post_id( intval( $post_id ) ); - } - - // Set the smart link attribute in the request. - $request->set_param( 'smart_link', $smart_link ); - - return true; - } - - /** - * Validates the multiple smart link parameters. - * - * The callback sets the smart links object in the request object if the parameters are valid. - * - * @since 3.16.0 - * @access private - * - * @param array> $param The parameter value. - * @param WP_REST_Request $request The request object. - * @return bool Whether the parameter is valid. - */ - public function private_api_request_validate_multiple_smart_links( array $param, WP_REST_Request $request ): bool { - $smart_links = array(); - - foreach ( $param as $link ) { - if ( $this->private_api_request_validate_smart_link_params( $link, $request ) ) { - $smart_link = $request->get_param( 'smart_link' ); - $smart_links[] = $smart_link; - } else { - return false; - } - } - $request->set_param( 'smart_link', null ); - $request->set_param( 'smart_links', $smart_links ); - - return true; - } - - /** - * Serializes an array of Smart Links. - * - * @since 3.16.0 - * - * @param Smart_Link[] $links The Smart Links to serialize. - * @return array The serialized Smart Links. - */ - private function serialize_smart_links( array $links ): array { - return array_map( - function ( Smart_Link $link ) { - return json_decode( $link->serialize(), true ); - }, - $links - ); - } -} diff --git a/src/Endpoints/content-suggestions/class-suggest-brief-api-proxy.php b/src/Endpoints/content-suggestions/class-suggest-brief-api-proxy.php deleted file mode 100644 index 78bb9c327..000000000 --- a/src/Endpoints/content-suggestions/class-suggest-brief-api-proxy.php +++ /dev/null @@ -1,152 +0,0 @@ -suggest_brief_api = new Suggest_Brief_API( $parsely ); - parent::__construct( $parsely, $this->suggest_brief_api ); - } - - /** - * Registers the endpoint's WP REST route. - * - * @since 3.13.0 - */ - public function run(): void { - $this->register_endpoint( '/content-suggestions/suggest-brief', array( 'POST' ) ); - } - - /** - * Generates the final data from the passed response. - * - * @since 3.13.0 - * - * @param array $response The response received by the proxy. - * @return array The generated data. - */ - protected function generate_data( $response ): array { - // Unused function. - return $response; - } - - /** - * Cached "proxy" to the Parse.ly API endpoint. - * - * @since 3.13.0 - * - * @param WP_REST_Request $request The request object. - * @return stdClass|WP_Error stdClass containing the data or a WP_Error object on failure. - */ - public function get_items( WP_REST_Request $request ) { - $validation = $this->validate_apikey_and_secret(); - if ( is_wp_error( $validation ) ) { - return $validation; - } - - $pch_options = $this->parsely->get_options()['content_helper']; - if ( ! Permissions::current_user_can_use_pch_feature( 'excerpt_suggestions', $pch_options ) ) { - return new WP_Error( 'ch_access_to_feature_disabled', '', array( 'status' => 403 ) ); - } - - /** - * The post content to be sent to the API. - * - * @var string|null $post_content - */ - $post_content = $request->get_param( 'content' ); - - /** - * The post title to be sent to the API. - * - * @var string|null $post_title - */ - $post_title = $request->get_param( 'title' ); - - /** - * The persona to be sent to the API. - * - * @var string|null $persona - */ - $persona = $request->get_param( 'persona' ); - - /** - * The style to be sent to the API. - * - * @var string|null $style - */ - $style = $request->get_param( 'style' ); - - if ( null === $post_content ) { - return new WP_Error( - 'parsely_content_not_set', - __( 'A post content must be set to use this endpoint', 'wp-parsely' ), - array( 'status' => 403 ) - ); - } - - if ( null === $post_title ) { - return new WP_Error( - 'parsely_title_not_set', - __( 'A post title must be set to use this endpoint', 'wp-parsely' ), - array( 'status' => 403 ) - ); - } - - if ( null === $persona ) { - $persona = 'journalist'; - } - - if ( null === $style ) { - $style = 'neutral'; - } - - $response = $this->suggest_brief_api->get_suggestion( $post_title, $post_content, $persona, $style ); - - if ( is_wp_error( $response ) ) { - return $response; - } - - return (object) array( - 'data' => $response, - ); - } -} diff --git a/src/Endpoints/content-suggestions/class-suggest-headline-api-proxy.php b/src/Endpoints/content-suggestions/class-suggest-headline-api-proxy.php deleted file mode 100644 index 49e02a77a..000000000 --- a/src/Endpoints/content-suggestions/class-suggest-headline-api-proxy.php +++ /dev/null @@ -1,123 +0,0 @@ -suggest_headline_api = new Suggest_Headline_API( $parsely ); - parent::__construct( $parsely, $this->suggest_headline_api ); - } - - /** - * Registers the endpoint's WP REST route. - * - * @since 3.12.0 - */ - public function run(): void { - $this->register_endpoint( '/content-suggestions/suggest-headline', array( 'POST' ) ); - } - - /** - * Generates the final data from the passed response. - * - * @since 3.12.0 - * - * @param array $response The response received by the proxy. - * @return array The generated data. - */ - protected function generate_data( $response ): array { - // Unused function. - return $response; - } - - /** - * Cached "proxy" to the Parse.ly API endpoint. - * - * @since 3.12.0 - * - * @param WP_REST_Request $request The request object. - * @return stdClass|WP_Error stdClass containing the data or a WP_Error object on failure. - */ - public function get_items( WP_REST_Request $request ) { - $validation = $this->validate_apikey_and_secret(); - if ( is_wp_error( $validation ) ) { - return $validation; - } - - $pch_options = $this->parsely->get_options()['content_helper']; - if ( ! Permissions::current_user_can_use_pch_feature( 'title_suggestions', $pch_options ) ) { - return new WP_Error( 'ch_access_to_feature_disabled', '', array( 'status' => 403 ) ); - } - - /** - * The post content to be sent to the API. - * - * @var string|null $post_content - */ - $post_content = $request->get_param( 'content' ); - - if ( null === $post_content ) { - return new WP_Error( - 'parsely_content_not_set', - __( 'A post content must be set to use this endpoint', 'wp-parsely' ), - array( 'status' => 403 ) - ); - } - - $limit = is_numeric( $request->get_param( 'limit' ) ) ? intval( $request->get_param( 'limit' ) ) : 3; - $tone = is_string( $request->get_param( 'tone' ) ) ? $request->get_param( 'tone' ) : 'neutral'; - $persona = is_string( $request->get_param( 'persona' ) ) ? $request->get_param( 'persona' ) : 'journalist'; - - if ( 0 === $limit ) { - $limit = 3; - } - - $response = $this->suggest_headline_api->get_titles( $post_content, $limit, $persona, $tone ); - - if ( is_wp_error( $response ) ) { - return $response; - } - - return (object) array( - 'data' => $response, - ); - } -} diff --git a/src/Endpoints/content-suggestions/class-suggest-linked-reference-api-proxy.php b/src/Endpoints/content-suggestions/class-suggest-linked-reference-api-proxy.php deleted file mode 100644 index c224155ed..000000000 --- a/src/Endpoints/content-suggestions/class-suggest-linked-reference-api-proxy.php +++ /dev/null @@ -1,162 +0,0 @@ -suggest_linked_reference_api = new Suggest_Linked_Reference_API( $parsely ); - parent::__construct( $parsely, $this->suggest_linked_reference_api ); - } - - /** - * Registers the endpoint's WP REST route. - * - * @since 3.14.0 - */ - public function run(): void { - $this->register_endpoint( '/content-suggestions/suggest-linked-reference', array( 'POST' ) ); - } - - /** - * Generates the final data from the passed response. - * - * @since 3.14.0 - * - * @param array $response The response received by the proxy. - * @return array The generated data. - */ - protected function generate_data( $response ): array { - // Unused function. - return $response; - } - - /** - * Cached "proxy" to the Parse.ly API endpoint. - * - * @since 3.14.0 - * - * @param WP_REST_Request $request The request object. - * @return stdClass|WP_Error stdClass containing the data or a WP_Error - * object on failure. - */ - public function get_items( WP_REST_Request $request ) { - $validation = $this->validate_apikey_and_secret(); - if ( is_wp_error( $validation ) ) { - return $validation; - } - - $pch_options = $this->parsely->get_options()['content_helper']; - if ( ! Permissions::current_user_can_use_pch_feature( 'smart_linking', $pch_options ) ) { - return new WP_Error( 'ch_access_to_feature_disabled', '', array( 'status' => 403 ) ); - } - - /** - * The post content to be sent to the API. - * - * @var string|null $post_content - */ - $post_content = $request->get_param( 'text' ); - - /** - * The maximum amount of words of the link text. - * - * @var string|null $max_link_words - */ - $max_link_words = $request->get_param( 'max_link_words' ); - - /** - * The maximum number of links to return. - * - * @var string|null $max_links - */ - $max_links = $request->get_param( 'max_links' ); - - /** - * The URL exclusion list. - * - * @var mixed $url_exclusion_list - */ - $url_exclusion_list = $request->get_param( 'url_exclusion_list' ) ?? array(); - - if ( null === $post_content ) { - return new WP_Error( - 'parsely_content_not_set', - __( 'A post content must be set to use this endpoint', 'wp-parsely' ), - array( 'status' => 403 ) - ); - } - - if ( is_numeric( $max_link_words ) ) { - $max_link_words = (int) $max_link_words; - } else { - $max_link_words = 4; - } - - if ( is_numeric( $max_links ) ) { - $max_links = (int) $max_links; - } else { - $max_links = 10; - } - - if ( ! is_array( $url_exclusion_list ) ) { - $url_exclusion_list = array(); - } - - $response = $this->suggest_linked_reference_api->get_links( - $post_content, - $max_link_words, - $max_links, - $url_exclusion_list - ); - - if ( is_wp_error( $response ) ) { - return $response; - } - - // Convert the smart links to an array of objects. - $smart_links = array(); - foreach ( $response as $link ) { - $smart_links[] = $link->to_array(); - } - - return (object) array( - 'data' => $smart_links, - ); - } -} diff --git a/wp-parsely.php b/wp-parsely.php index bff6aad66..ebe9c85c0 100644 --- a/wp-parsely.php +++ b/wp-parsely.php @@ -32,10 +32,6 @@ use Parsely\Content_Helper\Post_List_Stats; use Parsely\Endpoints\Analytics_Post_Detail_API_Proxy; use Parsely\Endpoints\Analytics_Posts_API_Proxy; -use Parsely\Endpoints\Content_Helper\Smart_Linking_Endpoint; -use Parsely\Endpoints\ContentSuggestions\Suggest_Brief_API_Proxy; -use Parsely\Endpoints\ContentSuggestions\Suggest_Headline_API_Proxy; -use Parsely\Endpoints\ContentSuggestions\Suggest_Linked_Reference_API_Proxy; use Parsely\Endpoints\GraphQL_Metadata; use Parsely\Endpoints\Referrers_Post_Detail_API_Proxy; use Parsely\Endpoints\Related_API_Proxy; @@ -47,9 +43,6 @@ use Parsely\Integrations\Integrations; use Parsely\RemoteAPI\Analytics_Post_Detail_API; use Parsely\RemoteAPI\Analytics_Posts_API; -use Parsely\RemoteAPI\ContentSuggestions\Suggest_Brief_API; -use Parsely\RemoteAPI\ContentSuggestions\Suggest_Headline_API; -use Parsely\RemoteAPI\ContentSuggestions\Suggest_Linked_Reference_API; use Parsely\RemoteAPI\Referrers_Post_Detail_API; use Parsely\RemoteAPI\Related_API; use Parsely\RemoteAPI\Remote_API_Cache; @@ -126,10 +119,9 @@ function parsely_wp_admin_early_register(): void { $network_admin_sites_list = new Network_Admin_Sites_List( $GLOBALS['parsely'] ); $network_admin_sites_list->run(); - // START OF PARSE.LY REST API REFACTOR (TODO: make the rest of the plugin use this). + // Initialize the REST API Controller. $rest_api_controller = new REST_API_Controller( $GLOBALS['parsely'] ); $rest_api_controller->init(); - // END OF PARSE.LY REST API REFACTOR. } add_action( 'rest_api_init', __NAMESPACE__ . '\\parsely_rest_api_init' ); @@ -148,9 +140,6 @@ function parsely_rest_api_init(): void { ( new Dashboard_Widget_Settings_Endpoint( $GLOBALS['parsely'] ) )->run(); ( new Editor_Sidebar_Settings_Endpoint( $GLOBALS['parsely'] ) )->run(); - // Internal Content Helper endpoints. - ( new Smart_Linking_Endpoint( $GLOBALS['parsely'] ) )->run(); - parsely_run_rest_api_endpoint( Related_API::class, Related_API_Proxy::class, @@ -174,24 +163,6 @@ function parsely_rest_api_init(): void { Referrers_Post_Detail_API_Proxy::class, $wp_cache ); - - parsely_run_rest_api_endpoint( - Suggest_Headline_API::class, - Suggest_Headline_API_Proxy::class, - $wp_cache - ); - - parsely_run_rest_api_endpoint( - Suggest_Brief_API::class, - Suggest_Brief_API_Proxy::class, - $wp_cache - ); - - parsely_run_rest_api_endpoint( - Suggest_Linked_Reference_API::class, - Suggest_Linked_Reference_API_Proxy::class, - $wp_cache - ); } add_action( 'init', __NAMESPACE__ . '\\init_recommendations_block' ); From 1b45964b9d60352a722b15b556e097b6b1e51352 Mon Sep 17 00:00:00 2001 From: Henrique Mouta Date: Thu, 22 Aug 2024 14:57:03 +0100 Subject: [PATCH 045/282] Fix sonarcloud issues --- tests/Integration/RestAPI/BaseAPIControllerTest.php | 1 - tests/Integration/RestAPI/BaseEndpointTest.php | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/Integration/RestAPI/BaseAPIControllerTest.php b/tests/Integration/RestAPI/BaseAPIControllerTest.php index cc9835bce..a584d1c51 100644 --- a/tests/Integration/RestAPI/BaseAPIControllerTest.php +++ b/tests/Integration/RestAPI/BaseAPIControllerTest.php @@ -146,7 +146,6 @@ protected function init(): void {} * @uses \Parsely\REST_API\Base_API_Controller::register_endpoint */ public function test_register_endpoint(): void { - $parsely = self::createMock( Parsely::class ); $endpoint = self::createMock( Base_Endpoint::class ); $endpoint->expects( self::once() )->method( 'init' ); diff --git a/tests/Integration/RestAPI/BaseEndpointTest.php b/tests/Integration/RestAPI/BaseEndpointTest.php index e9b1e6f85..a8b15e377 100644 --- a/tests/Integration/RestAPI/BaseEndpointTest.php +++ b/tests/Integration/RestAPI/BaseEndpointTest.php @@ -129,10 +129,9 @@ public function register_routes(): void { * * @since 3.17.0 * - * @param WP_REST_Request $request The request object. * @return array */ - public function get_test_data( WP_REST_Request $request ): array { + public function get_test_data(): array { return array( 'data' => 'test' ); } }; From bab0616b8a551c5f94a435b068f2c1cdaf269dad Mon Sep 17 00:00:00 2001 From: Alex Cicovic <23142906+acicovic@users.noreply.github.com> Date: Fri, 23 Aug 2024 09:03:22 +0300 Subject: [PATCH 046/282] Remove unneeded spacing Co-authored-by: Henrique Mouta --- tests/Integration/PermissionsTest.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/Integration/PermissionsTest.php b/tests/Integration/PermissionsTest.php index 2f24d8e53..1c5ac1601 100644 --- a/tests/Integration/PermissionsTest.php +++ b/tests/Integration/PermissionsTest.php @@ -348,12 +348,12 @@ public function assert_current_user_access_to_pch_feature_with_unset_options( // Filter set to true. add_filter( 'wp_parsely_current_user_can_use_pch_feature', '__return_true' ); - self::assertFalse( - Permissions::current_user_can_use_pch_feature( - $feature, - $pch_options // @phpstan-ignore-line - ) - ); + self::assertFalse( + Permissions::current_user_can_use_pch_feature( + $feature, + $pch_options // @phpstan-ignore-line + ) + ); remove_filter( 'wp_parsely_current_user_can_use_pch_feature', '__return_true' ); // Filter set to false. From fe193159586bf8a34ad406e40f2f3f08b7b477c7 Mon Sep 17 00:00:00 2001 From: Henrique Mouta Date: Fri, 23 Aug 2024 11:24:09 +0100 Subject: [PATCH 047/282] Refactor to avoid consts and use getters instead --- src/rest-api/class-base-api-controller.php | 144 +++++++++++------- src/rest-api/class-base-endpoint.php | 98 +++++------- src/rest-api/class-rest-api-controller.php | 24 +-- .../class-content-helper-controller.php | 9 +- .../class-endpoint-excerpt-generator.php | 20 +-- .../class-endpoint-smart-linking.php | 20 +-- .../class-endpoint-title-suggestions.php | 11 ++ .../RestAPI/BaseAPIControllerTest.php | 90 ++++++----- .../Integration/RestAPI/BaseEndpointTest.php | 58 ++----- .../ContentHelperControllerTest.php | 15 +- .../EndpointExcerptGeneratorTest.php | 4 +- .../EndpointSmartLinkingTest.php | 12 +- .../EndpointTitleSuggestionsTest.php | 4 +- .../RestAPI/RestAPIControllerTest.php | 4 +- 14 files changed, 272 insertions(+), 241 deletions(-) diff --git a/src/rest-api/class-base-api-controller.php b/src/rest-api/class-base-api-controller.php index 8e6693ea5..a9f29f2ef 100644 --- a/src/rest-api/class-base-api-controller.php +++ b/src/rest-api/class-base-api-controller.php @@ -23,116 +23,150 @@ abstract class Base_API_Controller { /** - * The API namespace. - * - * @var string|false - */ - public const NAMESPACE = false; - - /** - * The API version. - * - * @var string - */ - public const VERSION = ''; - - /** - * The route prefix, which acts as a namespace for the endpoints. + * The endpoints. * * @since 3.17.0 * - * @var string - */ - public const ROUTE_PREFIX = ''; - - /** - * The endpoints. - * * @var Base_Endpoint[] */ - public $endpoints; + private $endpoints; /** * The Parsely instance. * + * @since 3.17.0 + * * @var Parsely */ - public $parsely; + private $parsely; /** * Constructor. * + * @since 3.17.0 + * * @param Parsely $parsely The Parsely instance. - * @throws \UnexpectedValueException If the namespace is not defined. */ public function __construct( Parsely $parsely ) { $this->parsely = $parsely; $this->endpoints = array(); - - if ( static::NAMESPACE === false ) { - throw new \UnexpectedValueException( 'The API controller must define a namespace.' ); - } } /** - * Initialize the API controller. + * Initializes the API controller. * * This method should be overridden by child classes and used to register * endpoints. * + * @since 3.17.0 + * * @return void */ abstract protected function init(): void; /** - * Register a single endpoint. + * Gets the namespace for the API. + * + * This method should be overridden by child classes to define the namespace. * * @since 3.17.0 * - * @param Base_Endpoint $endpoint The endpoint to register. + * @return string The namespace. */ - protected function register_endpoint( Base_Endpoint $endpoint ): void { - $this->endpoints[] = $endpoint; - $endpoint->init(); - } + abstract protected function get_namespace(): string; /** - * Register multiple endpoints. + * Gets the version for the API. + * + * This method can be overridden by child classes to define the version. * * @since 3.17.0 * - * @param Base_Endpoint[] $endpoints The endpoints to register. + * @return string The version. */ - protected function register_endpoints( array $endpoints ): void { - foreach ( $endpoints as $endpoint ) { - $this->register_endpoint( $endpoint ); - } + protected function get_version(): string { + return ''; } /** - * Returns the namespace for the API. + * Gets the route prefix, which acts as a namespace for the endpoints. * - * If a version is defined, it will be appended to the namespace. + * This method can be overridden by child classes to define the route prefix. * * @since 3.17.0 - * @return string + * + * @return string The route prefix. */ - public function get_namespace(): string { - $namespace = static::NAMESPACE; + public function get_route_prefix(): string { + return ''; + } - if ( false === $namespace ) { - return ''; - } + /** + * Returns the full namespace for the API, including the version if defined. + * + * @since 3.17.0 + * + * @return string + */ + public function get_full_namespace(): string { + $namespace = $this->get_namespace(); - if ( '' !== static::VERSION ) { - $namespace .= '/' . static::VERSION; + if ( '' !== $this->get_version() ) { + $namespace .= '/' . $this->get_version(); } return $namespace; } /** - * Prefix a route with the route prefix. + * Gets the Parsely instance. + * + * @since 3.17.0 + * + * @return Parsely The Parsely instance. + */ + public function get_parsely(): Parsely { + return $this->parsely; + } + + /** + * Gets the registered endpoints. + * + * @since 3.17.0 + * + * @return Base_Endpoint[] The registered endpoints. + */ + public function get_endpoints(): array { + return $this->endpoints; + } + + /** + * Registers a single endpoint. + * + * @since 3.17.0 + * + * @param Base_Endpoint $endpoint The endpoint to register. + */ + protected function register_endpoint( Base_Endpoint $endpoint ): void { + $this->endpoints[] = $endpoint; + $endpoint->init(); + } + + /** + * Registers multiple endpoints. + * + * @since 3.17.0 + * + * @param Base_Endpoint[] $endpoints The endpoints to register. + */ + protected function register_endpoints( array $endpoints ): void { + foreach ( $endpoints as $endpoint ) { + $this->register_endpoint( $endpoint ); + } + } + + /** + * Prefixes a route with the route prefix. * * @since 3.17.0 * @@ -140,10 +174,10 @@ public function get_namespace(): string { * @return string The prefixed route. */ public function prefix_route( string $route ): string { - if ( '' === static::ROUTE_PREFIX ) { + if ( '' === $this->get_route_prefix() ) { return $route; } - return static::ROUTE_PREFIX . '/' . $route; + return $this->get_route_prefix() . '/' . $route; } } diff --git a/src/rest-api/class-base-endpoint.php b/src/rest-api/class-base-endpoint.php index e5cacc96f..6c8568134 100644 --- a/src/rest-api/class-base-endpoint.php +++ b/src/rest-api/class-base-endpoint.php @@ -12,7 +12,6 @@ use Parsely\Parsely; use Parsely\Utils\Utils; -use UnexpectedValueException; use WP_Error; use WP_REST_Request; @@ -25,24 +24,6 @@ * @since 3.17.0 */ abstract class Base_Endpoint { - /** - * The endpoint. - * - * @since 3.17.0 - * - * @var string|false - */ - protected const ENDPOINT = false; - - /** - * The default user capability needed to access endpoints. - * - * @since 3.17.0 - * - * @var string - */ - public const DEFAULT_ACCESS_CAPABILITY = 'publish_posts'; - /** * The Parsely instance. * @@ -59,7 +40,7 @@ abstract class Base_Endpoint { * * @var Base_API_Controller $api_controller */ - public $api_controller; + protected $api_controller; /** * The registered routes. @@ -79,31 +60,25 @@ abstract class Base_Endpoint { */ public function __construct( Base_API_Controller $controller ) { $this->api_controller = $controller; - $this->parsely = $controller->parsely; + $this->parsely = $controller->get_parsely(); } /** - * Initialize the API endpoint, by registering the routes. + * Initializes the API endpoint, by registering the routes. * * Allows for the endpoint to be disabled via the * `wp_parsely_api_{endpoint}_endpoint_enabled` filter. * * @since 3.17.0 - * - * @throws UnexpectedValueException If the ENDPOINT constant is not defined. */ public function init(): void { - if ( false === static::ENDPOINT ) { - throw new UnexpectedValueException( 'ENDPOINT constant must be defined in child class.' ); - } - /** * Filter to enable/disable the endpoint. * * @return bool */ $filter_name = 'wp_parsely_api_' . - Utils::convert_endpoint_to_filter_key( static::ENDPOINT ) . + Utils::convert_endpoint_to_filter_key( $this->get_endpoint_name() ) . '_endpoint_enabled'; if ( ! apply_filters( $filter_name, true ) ) { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound return; @@ -113,6 +88,33 @@ public function init(): void { add_action( 'rest_api_init', array( $this, 'register_routes' ) ); } + + /** + * Returns the endpoint name. + * + * This method should be overridden by child classes and used to return the + * endpoint name. + * + * @since 3.17.0 + * + * @return string + */ + abstract public function get_endpoint_name(): string; + + /** + * Returns the default access capability for the endpoint. + * + * This method can be overridden by child classes to return a different + * default access capability. + * + * @since 3.17.0 + * + * @return string + */ + protected function get_default_access_capability(): string { + return 'publish_posts'; + } + /** * Registers the routes for the endpoint. * @@ -135,18 +137,17 @@ abstract public function register_routes(): void; * @since 3.17.0 */ public function register_rest_route( string $route, array $methods, callable $callback, array $args = array() ): void { - // Trim any possible slashes from the route - // . + // Trim any possible slashes from the route. $route = trim( $route, '/' ); // Store the route for later reference. $this->registered_routes[] = $route; // Create the full route for the endpoint. - $route = $this->get_endpoint() . '/' . $route; + $route = $this->get_endpoint_name() . '/' . $route; // Register the route. register_rest_route( - $this->api_controller->get_namespace(), + $this->api_controller->get_full_namespace(), $this->api_controller->prefix_route( $route ), array( array( @@ -160,20 +161,6 @@ public function register_rest_route( string $route, array $methods, callable $ca ); } - /** - * Returns the endpoint name. - * - * @since 3.17.0 - * - * @return string - */ - public function get_endpoint(): string { - if ( false === static::ENDPOINT ) { - return ''; - } - return static::ENDPOINT; - } - /** * Returns the full endpoint path for a given route. @@ -184,10 +171,10 @@ public function get_endpoint(): string { * @return string */ public function get_full_endpoint( string $route = '' ): string { - $route = $this->get_endpoint() . '/' . $route; + $route = $this->get_endpoint_name() . '/' . $route; return '/' . - $this->api_controller->get_namespace() . + $this->api_controller->get_full_namespace() . '/' . $this->api_controller->prefix_route( $route ); } @@ -223,7 +210,7 @@ public function is_available_to_current_user( ?WP_REST_Request $request = null ) } // Validate the user capability. - $capability = static::DEFAULT_ACCESS_CAPABILITY; + $capability = $this->get_default_access_capability(); return current_user_can( // phpcs:ignore WordPress.WP.Capabilities.Undetermined $this->apply_capability_filters( $capability ) @@ -234,7 +221,7 @@ public function is_available_to_current_user( ?WP_REST_Request $request = null ) * Returns the user capability allowing access to the endpoint, after having * applied capability filters. * - * `DEFAULT_ACCESS_CAPABILITY` is not passed here by default, to allow for + * The default access capability is not passed here by default, to allow for * a more explicit declaration in child classes. * * @since 3.14.0 @@ -242,7 +229,6 @@ public function is_available_to_current_user( ?WP_REST_Request $request = null ) * * @param string $capability The original capability allowing access. * @return string The capability allowing access after applying the filters. - * @throws UnexpectedValueException If the ENDPOINT constant is not defined. */ public function apply_capability_filters( string $capability ): string { /** @@ -255,10 +241,6 @@ public function apply_capability_filters( string $capability ): string { $capability ); - if ( false === static::ENDPOINT ) { - throw new UnexpectedValueException( 'ENDPOINT constant must be defined in child class.' ); - } - /** * Filter to change the user capability for the specific endpoint. * @@ -266,8 +248,8 @@ public function apply_capability_filters( string $capability ): string { */ $endpoint_specific_user_capability = apply_filters( 'wp_parsely_user_capability_for_' . - Utils::convert_endpoint_to_filter_key( static::ENDPOINT ) . - '_api', + Utils::convert_endpoint_to_filter_key( $this->get_endpoint_name() ) . + '_api', $default_user_capability ); diff --git a/src/rest-api/class-rest-api-controller.php b/src/rest-api/class-rest-api-controller.php index b47850f42..e864e59fa 100644 --- a/src/rest-api/class-rest-api-controller.php +++ b/src/rest-api/class-rest-api-controller.php @@ -21,31 +21,35 @@ */ class REST_API_Controller extends Base_API_Controller { /** - * The API namespace. + * The controllers for each namespace. * * @since 3.17.0 * - * @var string + * @var Base_API_Controller[] */ - public const NAMESPACE = 'wp-parsely'; + public $controllers = array(); /** - * The API version. + * Gets the namespace for the API. * * @since 3.17.0 * - * @var string + * @return string The namespace. */ - public const VERSION = 'v2'; + protected function get_namespace(): string { + return 'wp-parsely'; + } /** - * The controllers for each namespace. + * Gets the version for the API. * * @since 3.17.0 * - * @var Base_API_Controller[] + * @return string The version. */ - public $controllers = array(); + protected function get_version(): string { + return 'v2'; + } /** * Initializes the REST API controller. @@ -55,7 +59,7 @@ class REST_API_Controller extends Base_API_Controller { public function init(): void { // Register the controllers for each namespace. $controllers = array( - new Content_Helper_Controller( $this->parsely ), + new Content_Helper_Controller( $this->get_parsely() ), ); // Initialize the controllers. diff --git a/src/rest-api/content-helper/class-content-helper-controller.php b/src/rest-api/content-helper/class-content-helper-controller.php index 5e58f9a0e..0093a5576 100644 --- a/src/rest-api/content-helper/class-content-helper-controller.php +++ b/src/rest-api/content-helper/class-content-helper-controller.php @@ -22,13 +22,15 @@ class Content_Helper_Controller extends REST_API_Controller { /** - * The route prefix, which acts as a namespace for the endpoints. + * Gets the prefix for this API route. * * @since 3.17.0 * - * @var string + * @return string The namespace. */ - public const ROUTE_PREFIX = 'content-helper'; + public function get_route_prefix(): string { + return 'content-helper'; + } /** * Initializes the Content Helper API endpoints. @@ -36,6 +38,7 @@ class Content_Helper_Controller extends REST_API_Controller { * @since 3.17.0 */ public function init(): void { + $endpoints = array( new Endpoint_Smart_Linking( $this ), new Endpoint_Excerpt_Generator( $this ), diff --git a/src/rest-api/content-helper/class-endpoint-excerpt-generator.php b/src/rest-api/content-helper/class-endpoint-excerpt-generator.php index f2fbaeb2a..409631a59 100644 --- a/src/rest-api/content-helper/class-endpoint-excerpt-generator.php +++ b/src/rest-api/content-helper/class-endpoint-excerpt-generator.php @@ -27,15 +27,6 @@ class Endpoint_Excerpt_Generator extends Base_Endpoint { use Content_Helper_Feature; - /** - * The endpoint. - * - * @since 3.17.0 - * - * @var string - */ - protected const ENDPOINT = 'excerpt-generator'; - /** * The Suggest Brief API instance. * @@ -57,6 +48,17 @@ public function __construct( Content_Helper_Controller $controller ) { $this->suggest_brief_api = new Suggest_Brief_API( $this->parsely ); } + /** + * Returns the name of the endpoint. + * + * @since 3.17.0 + * + * @return string The endpoint name. + */ + public function get_endpoint_name(): string { + return 'excerpt-generator'; + } + /** * Returns the name of the feature associated with the current endpoint. * diff --git a/src/rest-api/content-helper/class-endpoint-smart-linking.php b/src/rest-api/content-helper/class-endpoint-smart-linking.php index 902bc8d47..12822b6e7 100644 --- a/src/rest-api/content-helper/class-endpoint-smart-linking.php +++ b/src/rest-api/content-helper/class-endpoint-smart-linking.php @@ -29,15 +29,6 @@ class Endpoint_Smart_Linking extends Base_Endpoint { use Content_Helper_Feature; - /** - * The endpoint. - * - * @since 3.17.0 - * - * @var string - */ - protected const ENDPOINT = 'smart-linking'; - /** * The Suggest Linked Reference API instance. * @@ -59,6 +50,17 @@ public function __construct( Content_Helper_Controller $controller ) { $this->suggest_linked_reference_api = new Suggest_Linked_Reference_API( $this->parsely ); } + /** + * Returns the name of the endpoint. + * + * @since 3.17.0 + * + * @return string The endpoint name. + */ + public function get_endpoint_name(): string { + return 'smart-linking'; + } + /** * Returns the name of the feature associated with the current endpoint. * diff --git a/src/rest-api/content-helper/class-endpoint-title-suggestions.php b/src/rest-api/content-helper/class-endpoint-title-suggestions.php index 1f05f4411..cf80953b0 100644 --- a/src/rest-api/content-helper/class-endpoint-title-suggestions.php +++ b/src/rest-api/content-helper/class-endpoint-title-suggestions.php @@ -50,6 +50,17 @@ public function __construct( Content_Helper_Controller $controller ) { $this->suggest_headline_api = new Suggest_Headline_API( $this->parsely ); } + /** + * Returns the name of the endpoint. + * + * @since 3.17.0 + * + * @return string The endpoint name. + */ + public function get_endpoint_name(): string { + return 'title-suggestions'; + } + /** * Returns the name of the feature associated with the current endpoint. * diff --git a/tests/Integration/RestAPI/BaseAPIControllerTest.php b/tests/Integration/RestAPI/BaseAPIControllerTest.php index a584d1c51..3b5b03731 100644 --- a/tests/Integration/RestAPI/BaseAPIControllerTest.php +++ b/tests/Integration/RestAPI/BaseAPIControllerTest.php @@ -43,8 +43,28 @@ public function setUp(): void { TestCase::set_options(); $parsely = self::createMock( Parsely::class ); $this->test_controller = new class($parsely) extends Base_API_Controller { - public const NAMESPACE = 'test'; - public const VERSION = 'v1'; + + /** + * Get the namespace for the API. + * + * @since 3.17.0 + * + * @return string The namespace. + */ + protected function get_namespace(): string { + return 'test'; + } + + /** + * Get the version for the API. + * + * @since 3.17.0 + * + * @return string The version. + */ + protected function get_version(): string { + return 'v1'; + } /** * Initialize the test controller. @@ -73,40 +93,16 @@ public function testable_register_endpoint( Base_Endpoint $endpoint ): void { }; } - /** - * Test that the constructor throws an exception if the NAMESPACE is not defined. - * - * @since 3.17.0 - * - * @covers \Parsely\REST_API\Base_API_Controller::__construct - */ - public function test_constructor_throws_exception_without_namespace(): void { - self::expectException( \UnexpectedValueException::class ); - self::expectExceptionMessage( 'The API controller must define a namespace.' ); - - $parsely = self::createMock( Parsely::class ); - - // Use an anonymous class to avoid implementing abstract methods. - new class($parsely) extends Base_API_Controller { - /** - * Initialize the test controller. - * - * @since 3.17.0 - */ - protected function init(): void {} - }; - } - /** * Test the get_namespace method. * * @since 3.17.0 * - * @covers \Parsely\REST_API\Base_API_Controller::get_namespace + * @covers \Parsely\REST_API\Base_API_Controller::get_full_namespace * @uses \Parsely\REST_API\Base_API_Controller::__construct */ public function test_get_namespace(): void { - self::assertEquals( 'test/v1', $this->test_controller->get_namespace() ); + self::assertEquals( 'test/v1', $this->test_controller->get_full_namespace() ); } /** @@ -122,15 +118,34 @@ public function test_prefix_route(): void { $parsely = self::createMock( Parsely::class ); $controller_with_prefix = new class($parsely) extends Base_API_Controller { - public const NAMESPACE = 'test'; - public const ROUTE_PREFIX = 'prefix'; - /** * Initialize the test controller. * * @since 3.17.0 */ protected function init(): void {} + + /** + * Get the namespace for the API. + * + * @since 3.17.0 + * + * @return string The namespace. + */ + protected function get_namespace(): string { + return 'test'; + } + + /** + * Get the version for the API. + * + * @since 3.17.0 + * + * @return string The version. + */ + public function get_route_prefix(): string { + return 'prefix'; + } }; self::assertEquals( 'prefix/my-route', $controller_with_prefix->prefix_route( 'my-route' ) ); @@ -151,8 +166,9 @@ public function test_register_endpoint(): void { $this->test_controller->testable_register_endpoint( $endpoint ); // @phpstan-ignore-line - self::assertCount( 1, $this->test_controller->endpoints ); - self::assertSame( $endpoint, $this->test_controller->endpoints[0] ); + $endpoints = $this->test_controller->get_endpoints(); + self::assertCount( 1, $endpoints ); + self::assertSame( $endpoint, $endpoints[0] ); } /** @@ -174,8 +190,10 @@ public function test_register_multiple_endpoints(): void { $this->test_controller->testable_register_endpoints( array( $endpoint1, $endpoint2 ) ); // @phpstan-ignore-line - self::assertCount( 2, $this->test_controller->endpoints ); - self::assertSame( $endpoint1, $this->test_controller->endpoints[0] ); - self::assertSame( $endpoint2, $this->test_controller->endpoints[1] ); + $endpoints = $this->test_controller->get_endpoints(); + + self::assertCount( 2, $endpoints ); + self::assertSame( $endpoint1, $endpoints[0] ); + self::assertSame( $endpoint2, $endpoints[1] ); } } diff --git a/tests/Integration/RestAPI/BaseEndpointTest.php b/tests/Integration/RestAPI/BaseEndpointTest.php index a8b15e377..62b57b51f 100644 --- a/tests/Integration/RestAPI/BaseEndpointTest.php +++ b/tests/Integration/RestAPI/BaseEndpointTest.php @@ -16,9 +16,7 @@ use Parsely\REST_API\REST_API_Controller; use Parsely\Tests\Integration\TestCase; use ReflectionException; -use UnexpectedValueException; use WP_Error; -use WP_REST_Request; /** * Integration tests for the Base_Endpoint class. @@ -109,7 +107,17 @@ public function set_up(): void { // Create a concrete class for testing purposes. $this->test_endpoint = new class($this->api_controller) extends Base_Endpoint { - protected const ENDPOINT = 'test-endpoint'; + + /** + * Get the endpoint name. + * + * @since 3.17.0 + * + * @return string + */ + public function get_endpoint_name(): string { + return 'test'; + } /** * Register the test route. @@ -163,40 +171,6 @@ public function get_endpoint(): Base_Endpoint { return $this->test_endpoint; } - /** - * Test the init method throws an exception if ENDPOINT is not defined. - * - * @since 3.17.0 - * - * @covers \Parsely\REST_API\Base_Endpoint::init - * @uses \Parsely\REST_API\Base_Endpoint::__construct - * @uses \Parsely\REST_API\Base_API_Controller::__construct - * @uses \Parsely\Parsely::__construct - * @uses \Parsely\Parsely::allow_parsely_remote_requests - * @uses \Parsely\Parsely::are_credentials_managed - * @uses \Parsely\Parsely::set_managed_options - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key - */ - public function test_init_throws_exception_without_endpoint(): void { - self::expectException( UnexpectedValueException::class ); - self::expectExceptionMessage( 'ENDPOINT constant must be defined in child class.' ); - - // Create an endpoint with no ENDPOINT constant defined. - $endpoint_without_endpoint = new class($this->api_controller) extends Base_Endpoint { - /** - * Register the routes. - * - * @since 3.17.0 - */ - public function register_routes(): void { - // Mock method for testing. - } - }; - - $endpoint_without_endpoint->init(); - } - /** * Test that the route is correctly registered in WordPress. * @@ -206,7 +180,7 @@ public function register_routes(): void { * @covers \Parsely\REST_API\Base_Endpoint::register_routes * @covers \Parsely\REST_API\Base_Endpoint::get_full_endpoint * @uses \Parsely\REST_API\Base_API_Controller::__construct - * @uses \Parsely\REST_API\Base_API_Controller::get_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace * @uses \Parsely\REST_API\Base_API_Controller::prefix_route * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key * @uses \Parsely\Parsely::__construct @@ -226,7 +200,7 @@ public function test_route_is_registered(): void { $routes = rest_get_server()->get_routes(); // Check that the namespace route is registered. - $expected_namespace = '/' . $this->api_controller->get_namespace(); + $expected_namespace = '/' . $this->api_controller->get_full_namespace(); self::assertArrayHasKey( $expected_namespace, $routes ); // Check that the test route is registered. @@ -262,10 +236,10 @@ public function test_route_is_registered(): void { * @uses \Parsely\Permissions::current_user_can_use_pch_feature * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap * @uses \Parsely\REST_API\Base_API_Controller::__construct - * @uses \Parsely\REST_API\Base_API_Controller::get_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace * @uses \Parsely\REST_API\Base_API_Controller::prefix_route * @uses \Parsely\REST_API\Base_Endpoint::__construct - * @uses \Parsely\REST_API\Base_Endpoint::get_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::get_endpoint_name * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route * @uses \Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret @@ -273,7 +247,7 @@ public function test_route_is_registered(): void { */ public function test_endpoint_is_registered_based_on_filter(): void { $filter_name = 'wp_parsely_api_' . - \Parsely\Utils\Utils::convert_endpoint_to_filter_key( $this->get_endpoint()->get_endpoint() ) . + \Parsely\Utils\Utils::convert_endpoint_to_filter_key( $this->get_endpoint()->get_endpoint_name() ) . '_endpoint_enabled'; // Test when the filter allows the endpoint to be enabled. diff --git a/tests/Integration/RestAPI/ContentHelper/ContentHelperControllerTest.php b/tests/Integration/RestAPI/ContentHelper/ContentHelperControllerTest.php index 87380d31d..fcc563d07 100644 --- a/tests/Integration/RestAPI/ContentHelper/ContentHelperControllerTest.php +++ b/tests/Integration/RestAPI/ContentHelper/ContentHelperControllerTest.php @@ -54,10 +54,10 @@ public function setUp(): void { * @since 3.17.0 * * @covers \Parsely\REST_API\Content_Helper\Content_Helper_Controller::__construct - * @uses \Parsely\REST_API\Content_Helper\Content_Helper_Controller::get_namespace + * @uses \Parsely\REST_API\Content_Helper\Content_Helper_Controller::get_full_namespace */ public function test_constructor_sets_up_namespace_and_version(): void { - self::assertEquals( 'wp-parsely/v2', $this->content_helper_controller->get_namespace() ); + self::assertEquals( 'wp-parsely/v2', $this->content_helper_controller->get_full_namespace() ); } /** @@ -68,7 +68,7 @@ public function test_constructor_sets_up_namespace_and_version(): void { * @covers \Parsely\REST_API\Content_Helper\Content_Helper_Controller::ROUTE_PREFIX */ public function test_route_prefix(): void { - self::assertEquals( 'content-helper', Content_Helper_Controller::ROUTE_PREFIX ); + self::assertEquals( 'content-helper', $this->content_helper_controller->get_route_prefix() ); } /** @@ -90,10 +90,11 @@ public function test_route_prefix(): void { */ public function test_init_registers_endpoints(): void { $this->content_helper_controller->init(); + $endpoints = $this->content_helper_controller->get_endpoints(); - self::assertCount( 3, $this->content_helper_controller->endpoints ); - self::assertInstanceOf( Endpoint_Smart_Linking::class, $this->content_helper_controller->endpoints[0] ); - self::assertInstanceOf( Endpoint_Excerpt_Generator::class, $this->content_helper_controller->endpoints[1] ); - self::assertInstanceOf( Endpoint_Title_Suggestions::class, $this->content_helper_controller->endpoints[2] ); + self::assertCount( 3, $endpoints ); + self::assertInstanceOf( Endpoint_Smart_Linking::class, $endpoints[0] ); + self::assertInstanceOf( Endpoint_Excerpt_Generator::class, $endpoints[1] ); + self::assertInstanceOf( Endpoint_Title_Suggestions::class, $endpoints[2] ); } } diff --git a/tests/Integration/RestAPI/ContentHelper/EndpointExcerptGeneratorTest.php b/tests/Integration/RestAPI/ContentHelper/EndpointExcerptGeneratorTest.php index 2fe8e904c..a489f194a 100644 --- a/tests/Integration/RestAPI/ContentHelper/EndpointExcerptGeneratorTest.php +++ b/tests/Integration/RestAPI/ContentHelper/EndpointExcerptGeneratorTest.php @@ -82,10 +82,10 @@ public function get_endpoint(): \Parsely\REST_API\Base_Endpoint { * @uses \Parsely\Permissions::current_user_can_use_pch_feature * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap * @uses \Parsely\REST_API\Base_API_Controller::__construct - * @uses \Parsely\REST_API\Base_API_Controller::get_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace * @uses \Parsely\REST_API\Base_API_Controller::prefix_route * @uses \Parsely\REST_API\Base_Endpoint::__construct - * @uses \Parsely\REST_API\Base_Endpoint::get_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::get_endpoint_name * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint * @uses \Parsely\REST_API\Base_Endpoint::init * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user diff --git a/tests/Integration/RestAPI/ContentHelper/EndpointSmartLinkingTest.php b/tests/Integration/RestAPI/ContentHelper/EndpointSmartLinkingTest.php index 476f3a8c7..15a228d3b 100644 --- a/tests/Integration/RestAPI/ContentHelper/EndpointSmartLinkingTest.php +++ b/tests/Integration/RestAPI/ContentHelper/EndpointSmartLinkingTest.php @@ -93,10 +93,10 @@ public function get_endpoint(): \Parsely\REST_API\Base_Endpoint { * @uses \Parsely\Permissions::current_user_can_use_pch_feature * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap * @uses \Parsely\REST_API\Base_API_Controller::__construct - * @uses \Parsely\REST_API\Base_API_Controller::get_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace * @uses \Parsely\REST_API\Base_API_Controller::prefix_route * @uses \Parsely\REST_API\Base_Endpoint::__construct - * @uses \Parsely\REST_API\Base_Endpoint::get_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::get_endpoint_name * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint * @uses \Parsely\REST_API\Base_Endpoint::init * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user @@ -237,11 +237,11 @@ public function test_generate_smart_links_returns_error_on_failure(): void { * @uses \Parsely\Permissions::current_user_can_use_pch_feature * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap * @uses \Parsely\REST_API\Base_API_Controller::__construct - * @uses \Parsely\REST_API\Base_API_Controller::get_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace * @uses \Parsely\REST_API\Base_API_Controller::prefix_route * @uses \Parsely\REST_API\Base_Endpoint::__construct * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters - * @uses \Parsely\REST_API\Base_Endpoint::get_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::get_endpoint_name * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint * @uses \Parsely\REST_API\Base_Endpoint::init * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user @@ -334,11 +334,11 @@ public function test_add_smart_link_returns_valid_response(): void { * @uses \Parsely\Permissions::current_user_can_use_pch_feature * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap * @uses \Parsely\REST_API\Base_API_Controller::__construct - * @uses \Parsely\REST_API\Base_API_Controller::get_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace * @uses \Parsely\REST_API\Base_API_Controller::prefix_route * @uses \Parsely\REST_API\Base_Endpoint::__construct * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters - * @uses \Parsely\REST_API\Base_Endpoint::get_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::get_endpoint_name * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint * @uses \Parsely\REST_API\Base_Endpoint::init * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user diff --git a/tests/Integration/RestAPI/ContentHelper/EndpointTitleSuggestionsTest.php b/tests/Integration/RestAPI/ContentHelper/EndpointTitleSuggestionsTest.php index 9e94182cf..ec93d2404 100644 --- a/tests/Integration/RestAPI/ContentHelper/EndpointTitleSuggestionsTest.php +++ b/tests/Integration/RestAPI/ContentHelper/EndpointTitleSuggestionsTest.php @@ -81,10 +81,10 @@ public function get_endpoint(): \Parsely\REST_API\Base_Endpoint { * @uses \Parsely\Permissions::current_user_can_use_pch_feature * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap * @uses \Parsely\REST_API\Base_API_Controller::__construct - * @uses \Parsely\REST_API\Base_API_Controller::get_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace * @uses \Parsely\REST_API\Base_API_Controller::prefix_route * @uses \Parsely\REST_API\Base_Endpoint::__construct - * @uses \Parsely\REST_API\Base_Endpoint::get_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::get_endpoint_name * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint * @uses \Parsely\REST_API\Base_Endpoint::init * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user diff --git a/tests/Integration/RestAPI/RestAPIControllerTest.php b/tests/Integration/RestAPI/RestAPIControllerTest.php index 0a8968691..0261c5ec4 100644 --- a/tests/Integration/RestAPI/RestAPIControllerTest.php +++ b/tests/Integration/RestAPI/RestAPIControllerTest.php @@ -50,9 +50,9 @@ public function setUp(): void { * @since 3.17.0 * * @covers \Parsely\REST_API\REST_API_Controller::__construct - * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_full_namespace */ public function test_constructor_sets_up_namespace_and_version(): void { - self::assertEquals( 'wp-parsely/v2', $this->test_controller->get_namespace() ); + self::assertEquals( 'wp-parsely/v2', $this->test_controller->get_full_namespace() ); } } From 90c9808ac91fa4a1735315889f2851d60cb845c2 Mon Sep 17 00:00:00 2001 From: Henrique Mouta Date: Fri, 23 Aug 2024 11:26:45 +0100 Subject: [PATCH 048/282] Fix minor docblock issues per code review --- .../content-helper/class-content-helper-controller.php | 1 - src/rest-api/content-helper/trait-content-helper-feature.php | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/rest-api/content-helper/class-content-helper-controller.php b/src/rest-api/content-helper/class-content-helper-controller.php index 0093a5576..b93f65fef 100644 --- a/src/rest-api/content-helper/class-content-helper-controller.php +++ b/src/rest-api/content-helper/class-content-helper-controller.php @@ -20,7 +20,6 @@ * @since 3.17.0 */ class Content_Helper_Controller extends REST_API_Controller { - /** * Gets the prefix for this API route. * diff --git a/src/rest-api/content-helper/trait-content-helper-feature.php b/src/rest-api/content-helper/trait-content-helper-feature.php index b30338365..02e45c760 100644 --- a/src/rest-api/content-helper/trait-content-helper-feature.php +++ b/src/rest-api/content-helper/trait-content-helper-feature.php @@ -3,8 +3,8 @@ * API Content Helper Feature Trait * To be used with content helper endpoints that require a feature to be enabled. * - * @since 3.17.0 * @package Parsely + * @since 3.17.0 */ declare(strict_types=1); @@ -12,7 +12,6 @@ namespace Parsely\REST_API\Content_Helper; use Parsely\Permissions; -use Parsely\REST_API\Base_Endpoint; use WP_Error; use WP_REST_Request; From 77dbd2b13eb446e38877dec8aefb93d1bdb087ea Mon Sep 17 00:00:00 2001 From: Henrique Mouta Date: Mon, 26 Aug 2024 11:35:26 +0100 Subject: [PATCH 049/282] Apply code review suggestions by @acicovic --- src/rest-api/class-base-api-controller.php | 1 - src/rest-api/class-base-endpoint.php | 16 +++++++--------- .../class-endpoint-excerpt-generator.php | 3 --- .../class-endpoint-smart-linking.php | 4 ++-- .../class-endpoint-title-suggestions.php | 5 ----- .../trait-content-helper-feature.php | 8 ++++---- tests/Integration/RestAPI/BaseEndpointTest.php | 12 ++++++------ .../EndpointExcerptGeneratorTest.php | 2 +- .../ContentHelper/EndpointSmartLinkingTest.php | 6 +++--- .../EndpointTitleSuggestionsTest.php | 2 +- 10 files changed, 24 insertions(+), 35 deletions(-) diff --git a/src/rest-api/class-base-api-controller.php b/src/rest-api/class-base-api-controller.php index a9f29f2ef..7f06c98d4 100644 --- a/src/rest-api/class-base-api-controller.php +++ b/src/rest-api/class-base-api-controller.php @@ -21,7 +21,6 @@ * @since 3.17.0 */ abstract class Base_API_Controller { - /** * The endpoints. * diff --git a/src/rest-api/class-base-endpoint.php b/src/rest-api/class-base-endpoint.php index 6c8568134..3229b4bb8 100644 --- a/src/rest-api/class-base-endpoint.php +++ b/src/rest-api/class-base-endpoint.php @@ -18,8 +18,8 @@ /** * Base class for API endpoints. * - * Most endpoint classes should derive from this class. Child classes must add a - * protected `ENDPOINT` constant. + * Most endpoint classes should derive from this class. Child classes should + * implement the `get_endpoint_name` and `register_routes` methods. * * @since 3.17.0 */ @@ -88,7 +88,6 @@ public function init(): void { add_action( 'rest_api_init', array( $this, 'register_routes' ) ); } - /** * Returns the endpoint name. * @@ -128,13 +127,13 @@ abstract public function register_routes(): void; /** * Registers a REST route. * + * @since 3.17.0 + * * @param string $route The route to register. * @param string[] $methods Array with the allowed methods. * @param callable $callback Callback function to call when the endpoint is hit. * @param array $args The endpoint arguments definition. - * * @return void - * @since 3.17.0 */ public function register_rest_route( string $route, array $methods, callable $callback, array $args = array() ): void { // Trim any possible slashes from the route. @@ -161,7 +160,6 @@ public function register_rest_route( string $route, array $methods, callable $ca ); } - /** * Returns the full endpoint path for a given route. * @@ -202,9 +200,8 @@ public function get_registered_routes(): array { * @return WP_Error|bool True if the endpoint is available. */ public function is_available_to_current_user( ?WP_REST_Request $request = null ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found - // Validate the API key and secret. - $api_key_validation = $this->validate_apikey_and_secret(); + $api_key_validation = $this->validate_site_id_and_secret(); if ( is_wp_error( $api_key_validation ) ) { return $api_key_validation; } @@ -261,11 +258,12 @@ public function apply_capability_filters( string $capability ): string { * If the API secret is not required, it will not be validated. * * @since 3.13.0 + * @since 3.17.0 Moved to the new API structure and renamed from `validate_apikey_and_secret`. * * @param bool $require_api_secret Specifies if the API Secret is required. * @return WP_Error|bool */ - public function validate_apikey_and_secret( bool $require_api_secret = true ) { + public function validate_site_id_and_secret( bool $require_api_secret = true ) { if ( false === $this->parsely->site_id_is_set() ) { return new WP_Error( 'parsely_site_id_not_set', diff --git a/src/rest-api/content-helper/class-endpoint-excerpt-generator.php b/src/rest-api/content-helper/class-endpoint-excerpt-generator.php index 409631a59..d2ee59424 100644 --- a/src/rest-api/content-helper/class-endpoint-excerpt-generator.php +++ b/src/rest-api/content-helper/class-endpoint-excerpt-generator.php @@ -73,9 +73,6 @@ public function get_pch_feature_name(): string { /** * Registers the routes for the endpoint. * - * This method should be overridden by child classes and used to register - * the routes for the endpoint. - * * @since 3.17.0 */ public function register_routes(): void { diff --git a/src/rest-api/content-helper/class-endpoint-smart-linking.php b/src/rest-api/content-helper/class-endpoint-smart-linking.php index 12822b6e7..ab1a2f14b 100644 --- a/src/rest-api/content-helper/class-endpoint-smart-linking.php +++ b/src/rest-api/content-helper/class-endpoint-smart-linking.php @@ -101,11 +101,11 @@ public function register_routes(): void { 'type' => 'array', 'description' => __( 'The list of URLs to exclude from the smart links.', 'wp-parsely' ), 'validate_callback' => array( $this, 'validate_url_exclusion_list' ), + 'default' => array(), ), ) ); - /** * GET /smart-linking/{post_id}/get * Gets the smart links for a post. @@ -584,7 +584,7 @@ public function validate_post_id( string $param, WP_REST_Request $request ): boo * * The callback sets the URL exclusion list in the request object if the parameter is valid. * - * @since 3.16.0 + * @since 3.17.0 * @access private * * @param mixed $param The parameter value. diff --git a/src/rest-api/content-helper/class-endpoint-title-suggestions.php b/src/rest-api/content-helper/class-endpoint-title-suggestions.php index cf80953b0..8b81fc958 100644 --- a/src/rest-api/content-helper/class-endpoint-title-suggestions.php +++ b/src/rest-api/content-helper/class-endpoint-title-suggestions.php @@ -27,8 +27,6 @@ class Endpoint_Title_Suggestions extends Base_Endpoint { use Content_Helper_Feature; - protected const ENDPOINT = 'title-suggestions'; - /** * The Suggest Headline API. * @@ -75,9 +73,6 @@ public function get_pch_feature_name(): string { /** * Registers the routes for the endpoint. * - * This method should be overridden by child classes and used to register - * the routes for the endpoint. - * * @since 3.17.0 */ public function register_routes(): void { diff --git a/src/rest-api/content-helper/trait-content-helper-feature.php b/src/rest-api/content-helper/trait-content-helper-feature.php index 02e45c760..383e7c2ce 100644 --- a/src/rest-api/content-helper/trait-content-helper-feature.php +++ b/src/rest-api/content-helper/trait-content-helper-feature.php @@ -1,7 +1,8 @@ is_pch_feature_enabled_for_user(); diff --git a/tests/Integration/RestAPI/BaseEndpointTest.php b/tests/Integration/RestAPI/BaseEndpointTest.php index 62b57b51f..4b0b01505 100644 --- a/tests/Integration/RestAPI/BaseEndpointTest.php +++ b/tests/Integration/RestAPI/BaseEndpointTest.php @@ -242,7 +242,7 @@ public function test_route_is_registered(): void { * @uses \Parsely\REST_API\Base_Endpoint::get_endpoint_name * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route - * @uses \Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret + * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_endpoint_is_registered_based_on_filter(): void { @@ -283,7 +283,7 @@ public function test_endpoint_is_registered_based_on_filter(): void { * @since 3.17.0 * * @covers \Parsely\REST_API\Base_Endpoint::is_available_to_current_user - * @covers \Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret + * @covers \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret * @uses \Parsely\REST_API\Base_API_Controller::__construct * @uses \Parsely\Parsely::__construct * @uses \Parsely\Parsely::allow_parsely_remote_requests @@ -322,7 +322,7 @@ public function test_is_available_to_current_user_returns_error_site_id_not_set( * @since 3.17.0 * * @covers \Parsely\REST_API\Base_Endpoint::is_available_to_current_user - * @covers \Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret + * @covers \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret * @uses \Parsely\REST_API\Base_API_Controller::__construct * @uses \Parsely\Parsely::__construct * @uses \Parsely\Parsely::allow_parsely_remote_requests @@ -385,7 +385,7 @@ function () { /** * Test validate_apikey_and_secret returns true when API key and secret are set. * - * @covers \Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret + * @covers \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret * @uses \Parsely\REST_API\Base_API_Controller::__construct * @uses \Parsely\Parsely::__construct * @uses \Parsely\Parsely::allow_parsely_remote_requests @@ -404,7 +404,7 @@ function () { * @uses \Parsely\REST_API\Base_Endpoint::init * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ - public function test_validate_api_key_and_secret_returns_true(): void { + public function test_validate_site_id_and_secret_returns_true(): void { TestCase::set_options( array( 'apikey' => 'test-apikey', @@ -412,7 +412,7 @@ public function test_validate_api_key_and_secret_returns_true(): void { ) ); - $result = $this->get_endpoint()->validate_apikey_and_secret(); + $result = $this->get_endpoint()->validate_site_id_and_secret(); self::assertTrue( $result ); } diff --git a/tests/Integration/RestAPI/ContentHelper/EndpointExcerptGeneratorTest.php b/tests/Integration/RestAPI/ContentHelper/EndpointExcerptGeneratorTest.php index a489f194a..7d38eedc1 100644 --- a/tests/Integration/RestAPI/ContentHelper/EndpointExcerptGeneratorTest.php +++ b/tests/Integration/RestAPI/ContentHelper/EndpointExcerptGeneratorTest.php @@ -90,7 +90,7 @@ public function get_endpoint(): \Parsely\REST_API\Base_Endpoint { * @uses \Parsely\REST_API\Base_Endpoint::init * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route - * @uses \Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret + * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_route_is_registered(): void { diff --git a/tests/Integration/RestAPI/ContentHelper/EndpointSmartLinkingTest.php b/tests/Integration/RestAPI/ContentHelper/EndpointSmartLinkingTest.php index 15a228d3b..3c52d72ed 100644 --- a/tests/Integration/RestAPI/ContentHelper/EndpointSmartLinkingTest.php +++ b/tests/Integration/RestAPI/ContentHelper/EndpointSmartLinkingTest.php @@ -101,7 +101,7 @@ public function get_endpoint(): \Parsely\REST_API\Base_Endpoint { * @uses \Parsely\REST_API\Base_Endpoint::init * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route - * @uses \Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret + * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_route_is_registered(): void { @@ -246,7 +246,7 @@ public function test_generate_smart_links_returns_error_on_failure(): void { * @uses \Parsely\REST_API\Base_Endpoint::init * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route - * @uses \Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret + * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_add_smart_link_returns_valid_response(): void { @@ -343,7 +343,7 @@ public function test_add_smart_link_returns_valid_response(): void { * @uses \Parsely\REST_API\Base_Endpoint::init * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route - * @uses \Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret + * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_add_multiple_smart_links_returns_valid_response(): void { diff --git a/tests/Integration/RestAPI/ContentHelper/EndpointTitleSuggestionsTest.php b/tests/Integration/RestAPI/ContentHelper/EndpointTitleSuggestionsTest.php index ec93d2404..a9c96e8fa 100644 --- a/tests/Integration/RestAPI/ContentHelper/EndpointTitleSuggestionsTest.php +++ b/tests/Integration/RestAPI/ContentHelper/EndpointTitleSuggestionsTest.php @@ -89,7 +89,7 @@ public function get_endpoint(): \Parsely\REST_API\Base_Endpoint { * @uses \Parsely\REST_API\Base_Endpoint::init * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route - * @uses \Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret + * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_route_is_registered(): void { From 78395a701d491d69b6f0d58a9034b765bed50dcd Mon Sep 17 00:00:00 2001 From: Henrique Mouta Date: Mon, 26 Aug 2024 11:42:39 +0100 Subject: [PATCH 050/282] Rename API parameter `content` to `text` --- build/content-helper/editor-sidebar.asset.php | 2 +- build/content-helper/editor-sidebar.js | 4 ++-- build/content-helper/excerpt-generator.asset.php | 2 +- build/content-helper/excerpt-generator.js | 2 +- src/content-helper/editor-sidebar/smart-linking/provider.ts | 2 +- .../editor-sidebar/title-suggestions/provider.ts | 2 +- src/content-helper/excerpt-generator/provider.ts | 2 +- .../content-helper/class-endpoint-excerpt-generator.php | 4 ++-- src/rest-api/content-helper/class-endpoint-smart-linking.php | 4 ++-- .../content-helper/class-endpoint-title-suggestions.php | 4 ++-- .../RestAPI/ContentHelper/EndpointExcerptGeneratorTest.php | 4 ++-- .../RestAPI/ContentHelper/EndpointSmartLinkingTest.php | 4 ++-- .../RestAPI/ContentHelper/EndpointTitleSuggestionsTest.php | 4 ++-- 13 files changed, 20 insertions(+), 20 deletions(-) diff --git a/build/content-helper/editor-sidebar.asset.php b/build/content-helper/editor-sidebar.asset.php index 9aedc4547..0a96a2013 100644 --- a/build/content-helper/editor-sidebar.asset.php +++ b/build/content-helper/editor-sidebar.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-dom-ready', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-plugins', 'wp-primitives', 'wp-url'), 'version' => '6a5829c6e4ff7bf83951'); + array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-dom-ready', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-plugins', 'wp-primitives', 'wp-url'), 'version' => 'ceb704108c34274732ed'); diff --git a/build/content-helper/editor-sidebar.js b/build/content-helper/editor-sidebar.js index c44b4e693..303604252 100644 --- a/build/content-helper/editor-sidebar.js +++ b/build/content-helper/editor-sidebar.js @@ -1,5 +1,5 @@ !function(){"use strict";var e={20:function(e,t,n){var r=n(609),i=Symbol.for("react.element"),s=Symbol.for("react.fragment"),o=Object.prototype.hasOwnProperty,a=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function c(e,t,n){var r,s={},c=null,u=null;for(r in void 0!==n&&(c=""+n),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(u=t.ref),t)o.call(t,r)&&!l.hasOwnProperty(r)&&(s[r]=t[r]);if(e&&e.defaultProps)for(r in t=e.defaultProps)void 0===s[r]&&(s[r]=t[r]);return{$$typeof:i,type:e,key:c,ref:u,props:s,_owner:a.current}}t.Fragment=s,t.jsx=c,t.jsxs=c},848:function(e,t,n){e.exports=n(20)},609:function(e){e.exports=window.React}},t={};function n(r){var i=t[r];if(void 0!==i)return i.exports;var s=t[r]={exports:{}};return e[r](s,s.exports,n),s.exports}n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,{a:t}),t},n.d=function(e,t){for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},function(){n.d({},{_:function(){return ur}});var e,t,r,i,s,o,a,l,c,u,d,p=n(848),f=window.wp.components,h=window.wp.data,v=window.wp.domReady,g=n.n(v);void 0!==window.wp&&(null!==(t=null===(e=window.wp.editor)||void 0===e?void 0:e.PluginDocumentSettingPanel)&&void 0!==t||(null!==(i=null===(r=window.wp.editPost)||void 0===r?void 0:r.PluginDocumentSettingPanel)&&void 0!==i||(null===(s=window.wp.editSite)||void 0===s||s.PluginDocumentSettingPanel)),d=null!==(a=null===(o=window.wp.editor)||void 0===o?void 0:o.PluginSidebar)&&void 0!==a?a:null!==(c=null===(l=window.wp.editPost)||void 0===l?void 0:l.PluginSidebar)&&void 0!==c?c:null===(u=window.wp.editSite)||void 0===u?void 0:u.PluginSidebar);var y,m,w,b=window.wp.element,_=window.wp.i18n,x=window.wp.primitives,k=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{fillRule:"evenodd",d:"M11.25 5h1.5v15h-1.5V5zM6 10h1.5v10H6V10zm12 4h-1.5v6H18v-6z",clipRule:"evenodd"})}),S=window.wp.plugins,P=function(){function e(){this._tkq=[],this.isLoaded=!1,this.isEnabled=!1,"undefined"!=typeof wpParselyTracksTelemetry&&(this.isEnabled=!0,this.loadTrackingLibrary())}return e.getInstance=function(){return window.wpParselyTelemetryInstance||Object.defineProperty(window,"wpParselyTelemetryInstance",{value:new e,writable:!1,configurable:!1,enumerable:!1}),window.wpParselyTelemetryInstance},e.prototype.loadTrackingLibrary=function(){var e=this,t=document.createElement("script");t.async=!0,t.src="//stats.wp.com/w.js",t.onload=function(){e.isLoaded=!0,e._tkq=window._tkq||[]},document.head.appendChild(t)},e.trackEvent=function(t){return n=this,r=arguments,s=function(t,n){var r;return void 0===n&&(n={}),function(e,t){var n,r,i,s,o={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return s={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function a(a){return function(l){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;s&&(s=0,a[0]&&(o=0)),o;)try{if(n=1,r&&(i=2&a[0]?r.return:a[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,a[1])).done)return i;switch(r=0,i&&(a=[2&a[0],i.value]),a[0]){case 0:case 1:i=a;break;case 4:return o.label++,{value:a[1],done:!1};case 5:o.label++,r=a[1],a=[0];continue;case 7:a=o.ops.pop(),o.trys.pop();continue;default:if(!((i=(i=o.trys).length>0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]=1e4&&(clearInterval(s),n("Telemetry library not loaded"))}),100);else n("Telemetry not enabled")}))},e.prototype.trackEvent=function(t,n){var r;this.isLoaded?(0!==t.indexOf(e.TRACKS_PREFIX)&&(t=e.TRACKS_PREFIX+t),this.isEventNameValid(t)?(n=this.prepareProperties(n),null===(r=this._tkq)||void 0===r||r.push(["recordEvent",t,n])):console.error("Error tracking event: Invalid event name")):console.error("Error tracking event: Telemetry not loaded")},e.prototype.isTelemetryEnabled=function(){return this.isEnabled},e.prototype.isProprietyValid=function(t){return e.PROPERTY_REGEX.test(t)},e.prototype.isEventNameValid=function(t){return e.EVENT_NAME_REGEX.test(t)},e.prototype.prepareProperties=function(e){return(e=this.sanitizeProperties(e)).parsely_version=wpParselyTracksTelemetry.version,wpParselyTracksTelemetry.user&&(e._ut=wpParselyTracksTelemetry.user.type,e._ui=wpParselyTracksTelemetry.user.id),wpParselyTracksTelemetry.vipgo_env&&(e.vipgo_env=wpParselyTracksTelemetry.vipgo_env),this.sanitizeProperties(e)},e.prototype.sanitizeProperties=function(e){var t=this,n={};return Object.keys(e).forEach((function(r){t.isProprietyValid(r)&&(n[r]=e[r])})),n},e.TRACKS_PREFIX="wpparsely_",e.EVENT_NAME_REGEX=/^(([a-z0-9]+)_){2}([a-z0-9_]+)$/,e.PROPERTY_REGEX=/^[a-z_][a-z0-9_]*$/,e}(),j=(P.trackEvent,function(){return(0,p.jsx)(f.SVG,{"aria-hidden":"true",version:"1.1",viewBox:"0 0 15 15",width:"15",height:"15",xmlns:"http://www.w3.org/2000/svg",children:(0,p.jsx)(f.Path,{d:"M0 14.0025V11.0025L7.5 3.5025L10.5 6.5025L3 14.0025H0ZM12 5.0025L13.56 3.4425C14.15 2.8525 14.15 1.9025 13.56 1.3225L12.68 0.4425C12.09 -0.1475 11.14 -0.1475 10.56 0.4425L9 2.0025L12 5.0025Z"})})}),T=function(e){var t=e.size,n=void 0===t?24:t,r=e.className,i=void 0===r?"wp-parsely-icon":r;return(0,p.jsxs)(f.SVG,{className:i,height:n,viewBox:"0 0 60 65",width:n,xmlns:"http://www.w3.org/2000/svg",children:[(0,p.jsx)(f.Path,{fill:"#5ba745",d:"M23.72,51.53c0-.18,0-.34-.06-.52a13.11,13.11,0,0,0-2.1-5.53A14.74,14.74,0,0,0,19.12,43c-.27-.21-.5-.11-.51.22l-.24,3.42c0,.33-.38.35-.49,0l-1.5-4.8a1.4,1.4,0,0,0-.77-.78,23.91,23.91,0,0,0-3.1-.84c-1.38-.24-3.39-.39-3.39-.39-.34,0-.45.21-.25.49l2.06,3.76c.2.27,0,.54-.29.33l-4.51-3.6a3.68,3.68,0,0,0-2.86-.48c-1,.16-2.44.46-2.44.46a.68.68,0,0,0-.39.25.73.73,0,0,0-.14.45S.41,43,.54,44a3.63,3.63,0,0,0,1.25,2.62L6.48,50c.28.2.09.49-.23.37l-4.18-.94c-.32-.12-.5,0-.4.37,0,0,.69,1.89,1.31,3.16a24,24,0,0,0,1.66,2.74,1.34,1.34,0,0,0,1,.52l5,.13c.33,0,.41.38.1.48L7.51,58c-.31.1-.34.35-.07.55a14.29,14.29,0,0,0,3.05,1.66,13.09,13.09,0,0,0,5.9.5,25.13,25.13,0,0,0,4.34-1,9.55,9.55,0,0,1-.08-1.2,9.32,9.32,0,0,1,3.07-6.91"}),(0,p.jsx)(f.Path,{fill:"#5ba745",d:"M59.7,41.53a.73.73,0,0,0-.14-.45.68.68,0,0,0-.39-.25s-1.43-.3-2.44-.46a3.64,3.64,0,0,0-2.86.48l-4.51,3.6c-.26.21-.49-.06-.29-.33l2.06-3.76c.2-.28.09-.49-.25-.49,0,0-2,.15-3.39.39a23.91,23.91,0,0,0-3.1.84,1.4,1.4,0,0,0-.77.78l-1.5,4.8c-.11.32-.48.3-.49,0l-.24-3.42c0-.33-.24-.43-.51-.22a14.74,14.74,0,0,0-2.44,2.47A13.11,13.11,0,0,0,36.34,51c0,.18,0,.34-.06.52a9.26,9.26,0,0,1,3,8.1,24.1,24.1,0,0,0,4.34,1,13.09,13.09,0,0,0,5.9-.5,14.29,14.29,0,0,0,3.05-1.66c.27-.2.24-.45-.07-.55l-3.22-1.17c-.31-.1-.23-.47.1-.48l5-.13a1.38,1.38,0,0,0,1-.52A24.6,24.6,0,0,0,57,52.92c.61-1.27,1.31-3.16,1.31-3.16.1-.33-.08-.49-.4-.37l-4.18.94c-.32.12-.51-.17-.23-.37l4.69-3.34A3.63,3.63,0,0,0,59.46,44c.13-1,.24-2.47.24-2.47"}),(0,p.jsx)(f.Path,{fill:"#5ba745",d:"M46.5,25.61c0-.53-.35-.72-.8-.43l-4.86,2.66c-.45.28-.56-.27-.23-.69l4.66-6.23a2,2,0,0,0,.28-1.68,36.51,36.51,0,0,0-2.19-4.89,34,34,0,0,0-2.81-3.94c-.33-.41-.74-.35-.91.16l-2.28,5.68c-.16.5-.6.48-.59-.05l.28-8.93a2.54,2.54,0,0,0-.66-1.64S35,4.27,33.88,3.27,30.78.69,30.78.69a1.29,1.29,0,0,0-1.54,0s-1.88,1.49-3.12,2.59-2.48,2.35-2.48,2.35A2.5,2.5,0,0,0,23,7.27l.27,8.93c0,.53-.41.55-.58.05l-2.29-5.69c-.17-.5-.57-.56-.91-.14a35.77,35.77,0,0,0-3,4.2,35.55,35.55,0,0,0-2,4.62,2,2,0,0,0,.27,1.67l4.67,6.24c.33.42.23,1-.22.69l-4.87-2.66c-.45-.29-.82-.1-.82.43a18.6,18.6,0,0,0,.83,5.07,20.16,20.16,0,0,0,5.37,7.77c3.19,3,5.93,7.8,7.45,11.08A9.6,9.6,0,0,1,30,49.09a9.31,9.31,0,0,1,2.86.45c1.52-3.28,4.26-8.11,7.44-11.09a20.46,20.46,0,0,0,5.09-7,19,19,0,0,0,1.11-5.82"}),(0,p.jsx)(f.Path,{fill:"#5ba745",d:"M36.12,58.44A6.12,6.12,0,1,1,30,52.32a6.11,6.11,0,0,1,6.12,6.12"})]})},L=function(){return L=Object.assign||function(e){for(var t,n=1,r=arguments.length;nhere.',"wp-parsely"):s.code===$.ParselySuggestionsApiOpenAiError||s.code===$.ParselySuggestionsApiOpenAiUnavailable?s.message=(0,_.__)("The Parse.ly API returned an internal server error. Please retry with a different input, or try again later.","wp-parsely"):s.code===$.HttpRequestFailed&&s.message.includes("cURL error 28")?s.message=(0,_.__)("The Parse.ly API did not respond in a timely manner. Please try again later.","wp-parsely"):s.code===$.ParselySuggestionsApiSchemaError?s.message=(0,_.__)("The Parse.ly API returned a validation error. Please try again with different parameters.","wp-parsely"):s.code===$.ParselySuggestionsApiNoData?s.message=(0,_.__)("The Parse.ly API couldn't find any relevant data to fulfill the request. Please retry with a different input.","wp-parsely"):s.code===$.ParselySuggestionsApiOpenAiSchema?s.message=(0,_.__)("The Parse.ly API returned an incorrect response. Please try again later.","wp-parsely"):s.code===$.ParselySuggestionsApiAuthUnavailable&&(s.message=(0,_.__)("The Parse.ly API is currently unavailable. Please try again later.","wp-parsely")),s}return re(t,e),t.prototype.Message=function(e){return void 0===e&&(e=null),[$.PluginCredentialsNotSetMessageDetected,$.PluginSettingsSiteIdNotSet,$.PluginSettingsApiSecretNotSet].includes(this.code)?K(e):(this.code===$.FetchError&&(this.hint=this.Hint((0,_.__)("This error can sometimes be caused by ad-blockers or browser tracking protections. Please add this site to any applicable allow lists and try again.","wp-parsely"))),this.code!==$.ParselyApiForbidden&&this.code!==$.ParselySuggestionsApiNoAuthentication||(this.hint=this.Hint((0,_.__)("Please ensure that the Site ID and API Secret given in the plugin's settings are correct.","wp-parsely"))),this.code===$.HttpRequestFailed&&(this.hint=this.Hint((0,_.__)("The Parse.ly API cannot be reached. Please verify that you are online.","wp-parsely"))),(0,p.jsx)(W,{className:null==e?void 0:e.className,testId:"error",children:"

".concat(this.message,"

").concat(this.hint?this.hint:"")}))},t.prototype.Hint=function(e){return'

'.concat((0,_.__)("Hint:","wp-parsely")," ").concat(e,"

")},t.prototype.createErrorSnackbar=function(){//.test(this.message)||(0,h.dispatch)("core/notices").createNotice("error",this.message,{type:"snackbar"})},t}(Error),se=function(e){var t=e.isDetectingEnabled,n=e.onLinkChange,r=e.onLinkRemove,i=e.onLinkAdd,s=e.debounceValue,o=void 0===s?500:s,a=(0,h.useSelect)((function(e){return{blocks:(0,e("core/block-editor").getBlocks)()}}),[]).blocks,l=(0,b.useRef)(a),c=(0,b.useRef)(t);return(0,b.useEffect)((function(){var e=(0,z.debounce)((function(){for(var t=[],s=0;s0)return r(e.innerBlocks,t[s].innerBlocks);if(JSON.stringify(e)!==JSON.stringify(t[s])){var o=t[s],a=i.parseFromString(e.attributes.content||"","text/html"),l=i.parseFromString((null==o?void 0:o.attributes.content)||"","text/html"),c=Array.from(a.querySelectorAll("a[data-smartlink]")),u=Array.from(l.querySelectorAll("a[data-smartlink]")),d=c.filter((function(e){return!u.some((function(t){return t.dataset.smartlink===e.dataset.smartlink}))})),p=u.filter((function(e){return!c.some((function(t){return t.dataset.smartlink===e.dataset.smartlink}))})),f=c.filter((function(e){var t=u.find((function(t){return t.dataset.smartlink===e.dataset.smartlink}));return t&&t.outerHTML!==e.outerHTML}));(d.length>0||p.length>0||f.length>0)&&n.push({block:e,prevBlock:o,addedLinks:d,removedLinks:p,changedLinks:f})}}}))};return r(e,t),n}(a,l.current);o.length>0&&(o.forEach((function(e){e.changedLinks.length>0&&n&&n(e),e.addedLinks.length>0&&i&&i(e),e.removedLinks.length>0&&r&&r(e)})),l.current=a)}),o);return e(t),function(){e.cancel()}}),[a,o,t,i,n,r]),null},oe=function(e){var t=e.value,n=e.onChange,r=e.max,i=e.min,s=e.suffix,o=e.size,a=e.label,l=e.initialPosition,c=e.disabled,u=e.className;return(0,p.jsxs)("div",{className:"parsely-inputrange-control ".concat(u||""),children:[(0,p.jsx)(f.__experimentalHeading,{className:"parsely-inputrange-control__label",level:3,children:a}),(0,p.jsxs)("div",{className:"parsely-inputrange-control__controls",children:[(0,p.jsx)(f.__experimentalNumberControl,{disabled:c,value:t,suffix:(0,p.jsx)(f.__experimentalInputControlSuffixWrapper,{children:s}),size:null!=o?o:"__unstable-large",min:i,max:r,onChange:function(e){var t=parseInt(e,10);isNaN(t)||n(t)}}),(0,p.jsx)(f.RangeControl,{disabled:c,value:t,showTooltip:!1,initialPosition:l,onChange:function(e){n(e)},withInputField:!1,min:i,max:r})]})]})},ae=function(e,t,n,r){return new(n||(n=Promise))((function(i,s){function o(e){try{l(r.next(e))}catch(e){s(e)}}function a(e){try{l(r.throw(e))}catch(e){s(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(o,a)}l((r=r.apply(e,t||[])).next())}))},le=function(e,t){var n,r,i,s,o={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return s={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function a(a){return function(l){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;s&&(s=0,a[0]&&(o=0)),o;)try{if(n=1,r&&(i=2&a[0]?r.return:a[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,a[1])).done)return i;switch(r=0,i&&(a=[2&a[0],i.value]),a[0]){case 0:case 1:i=a;break;case 4:return o.label++,{value:a[1],done:!1};case 5:o.label++,r=a[1],a=[0];continue;case 7:a=o.ops.pop(),o.trys.pop();continue;default:if(!((i=(i=o.trys).length>0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]

","\n\x3c!-- /wp:paragraph --\x3e");t&&h((0,Q.parse)(n))}),[s]),(0,p.jsxs)("div",{className:"smart-linking-review-suggestion",children:[(0,p.jsx)(f.KeyboardShortcuts,{shortcuts:{left:o,right:a,up:o,down:a}}),(0,p.jsx)("div",{className:"review-suggestion-post-title",children:null===(t=s.post_data)||void 0===t?void 0:t.title}),(0,p.jsxs)("div",{className:"review-suggestion-preview",children:[!(null===(n=s.post_data)||void 0===n?void 0:n.is_first_paragraph)&&(0,p.jsx)($e,{topOrBottom:"top"}),(0,p.jsx)(Ze,{block:d[0],link:s,useOriginalBlock:!0}),!(null===(r=s.post_data)||void 0===r?void 0:r.is_last_paragraph)&&(0,p.jsx)($e,{topOrBottom:"bottom"})]}),(0,p.jsx)(f.__experimentalDivider,{}),(0,p.jsx)(We,{link:s}),(0,p.jsxs)("div",{className:"review-controls",children:[(0,p.jsx)(f.Tooltip,{shortcut:"←",text:(0,_.__)("Previous","wp-parsely"),children:(0,p.jsx)(f.Button,{disabled:!l,className:"wp-parsely-review-suggestion-previous",onClick:o,icon:He,children:(0,_.__)("Previous","wp-parsely")})}),(0,p.jsx)("div",{className:"reviews-controls-middle",children:(0,p.jsx)(f.Button,{target:"_blank",href:(null===(i=s.post_data)||void 0===i?void 0:i.edit_link)+"&smart-link="+s.uid,variant:"secondary",onClick:function(){P.trackEvent("smart_linking_open_in_editor_pressed",{type:"inbound",uid:s.uid})},children:(0,_.__)("Open in the Editor","wp-parsely")})}),(0,p.jsx)(f.Tooltip,{shortcut:"→",text:(0,_.__)("Next","wp-parsely"),children:(0,p.jsxs)(f.Button,{disabled:!c,onClick:a,className:"wp-parsely-review-suggestion-next",children:[(0,_.__)("Next","wp-parsely"),(0,p.jsx)(X,{icon:ze})]})})]})]})},Ye=function(e){var t=e.size,n=void 0===t?24:t,r=e.className,i=void 0===r?"wp-parsely-icon":r;return(0,p.jsxs)(f.SVG,{xmlns:"http://www.w3.org/2000/svg",className:i,width:n,height:n,viewBox:"0 0 24 24",fill:"none",children:[(0,p.jsx)(f.Path,{d:"M8.18983 5.90381L8.83642 7.54325L10.4758 8.18983L8.83642 8.8364L8.18983 10.4759L7.54324 8.8364L5.90381 8.18983L7.54324 7.54325L8.18983 5.90381Z"}),(0,p.jsx)(f.Path,{d:"M15.048 5.90381L15.9101 8.08972L18.0961 8.95186L15.9101 9.81397L15.048 11.9999L14.1859 9.81397L12 8.95186L14.1859 8.08972L15.048 5.90381Z"}),(0,p.jsx)(f.Path,{d:"M11.238 10.4761L12.3157 13.2085L15.048 14.2861L12.3157 15.3638L11.238 18.0962L10.1603 15.3638L7.42798 14.2861L10.1603 13.2085L11.238 10.4761Z"})]})},Je=function(e,t,n){if(n||2===arguments.length)for(var r,i=0,s=t.length;ii.bottom)&&(n.scrollTop=r.offsetTop-n.offsetTop)}}}}),[t,l]);var u=function(){var e=document.querySelector(".smart-linking-review-sidebar-tabs [data-active-item]"),t=null==e?void 0:e.nextElementSibling;t||(t=document.querySelector('.smart-linking-review-sidebar-tabs [role="tab"]')),t&&t.click()},d=(0,p.jsxs)("span",{className:"smart-linking-menu-label",children:[(0,_.__)("NEW","wp-parsely"),(0,p.jsx)(Ye,{})]}),h=[];n&&n.length>0&&h.push({name:"outbound",title:(0,_.__)("Outbound","wp-parsely")}),r&&r.length>0&&h.push({name:"inbound",title:(0,_.__)("Inbound","wp-parsely")});var v="outbound";return h=h.filter((function(e){return"outbound"===e.name&&r&&0===r.length&&(e.title=(0,_.__)("Outbound Smart Links","wp-parsely"),v="outbound"),"inbound"===e.name&&n&&0===n.length&&(e.title=(0,_.__)("Inbound Smart Links","wp-parsely"),v="inbound"),e})),(0,p.jsxs)("div",{className:"smart-linking-review-sidebar",ref:s,children:[(0,p.jsx)(f.KeyboardShortcuts,{shortcuts:{tab:function(){return u()},"shift+tab":function(){return u()}}}),(0,p.jsx)(f.TabPanel,{className:"smart-linking-review-sidebar-tabs",initialTabName:v,tabs:h,onSelect:function(e){var t,s;"outbound"===e&&n&&n.length>0&&i(n[0]),"inbound"===e&&r&&r.length>0&&i(r[0]),P.trackEvent("smart_linking_modal_tab_selected",{tab:e,total_inbound:null!==(t=null==r?void 0:r.length)&&void 0!==t?t:0,total_outbound:null!==(s=null==n?void 0:n.length)&&void 0!==s?s:0})},children:function(e){return(0,p.jsxs)(p.Fragment,{children:["outbound"===e.name&&(0,p.jsx)(p.Fragment,{children:n&&0!==n.length?n.map((function(e,n){return(0,p.jsxs)(f.MenuItem,{ref:function(e){o.current[n]=e},className:(null==t?void 0:t.uid)===e.uid?"is-selected":"",role:"menuitemradio",isSelected:(null==t?void 0:t.uid)===e.uid,onClick:function(){return i(e)},children:[(0,p.jsx)("span",{className:"smart-linking-menu-item",children:e.text}),!e.applied&&d]},e.uid)})):(0,p.jsxs)(p.Fragment,{children:[" ",(0,_.__)("No outbound links found.","wp-parsely")]})}),"inbound"===e.name&&(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)("div",{className:"review-sidebar-tip",children:(0,_.__)("This section shows external posts that link back to the current post.","wp-parsely")}),r&&0!==r.length?r.map((function(e,r){var s;return(0,p.jsx)(f.MenuItem,{ref:function(e){o.current[(n?n.length:0)+r]=e},className:(null==t?void 0:t.uid)===e.uid?"is-selected":"",role:"menuitemradio",isSelected:(null==t?void 0:t.uid)===e.uid,onClick:function(){return i(e)},children:(0,p.jsx)("span",{className:"smart-linking-menu-item",children:null===(s=e.post_data)||void 0===s?void 0:s.title})},e.uid)})):(0,p.jsxs)(p.Fragment,{children:[" ",(0,_.__)("No inbound links found.","wp-parsely")]})]})]})}})]})},Xe=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"M12 13.06l3.712 3.713 1.061-1.06L13.061 12l3.712-3.712-1.06-1.06L12 10.938 8.288 7.227l-1.061 1.06L10.939 12l-3.712 3.712 1.06 1.061L12 13.061z"})}),et=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"M16.7 7.1l-6.3 8.5-3.3-2.5-.9 1.2 4.5 3.4L17.9 8z"})}),tt=function(e){var t,n,r,i,s=null===(t=e.link.match)||void 0===t?void 0:t.blockId,o=(0,h.useSelect)((function(e){var t=e("core/block-editor"),n=t.getBlock,r=t.getBlockParents;return s?{block:n(s),parents:r(s).map((function(e){return n(e)})).filter((function(e){return void 0!==e}))}:{block:void 0,parents:[]}}),[s]),a=o.block,l=o.parents;return a?(0,p.jsxs)("div",{className:"review-suggestions-breadcrumbs",children:[l.map((function(e,t){var n;return(0,p.jsxs)("span",{children:[(0,p.jsx)("span",{className:"breadcrumbs-parent-block",children:null===(n=(0,Q.getBlockType)(e.name))||void 0===n?void 0:n.title}),(0,p.jsx)("span",{className:"breadcrumbs-parent-separator",children:" / "})]},t)})),(0,p.jsxs)("span",{className:"breadcrumbs-current-block",children:[(0,p.jsx)("span",{className:"breadcrumbs-current-block-type",children:null===(n=(0,Q.getBlockType)(a.name))||void 0===n?void 0:n.title}),(null===(i=null===(r=a.attributes)||void 0===r?void 0:r.metadata)||void 0===i?void 0:i.name)&&(0,p.jsx)("span",{className:"breadcrumbs-current-block-name",children:a.attributes.metadata.name})]})]}):(0,p.jsx)(p.Fragment,{})},nt=function(e){var t,n=e.link,r=(0,b.useState)(n.href),i=r[0],s=r[1],o=(0,b.useState)(null===(t=n.destination)||void 0===t?void 0:t.post_type),a=o[0],l=o[1],c=(0,b.useRef)(null),u=(0,h.useDispatch)(Te).updateSmartLink;return(0,b.useEffect)((function(){n.destination?l(n.destination.post_type):(l((0,_.__)("External","wp-parsely")),De.getInstance().getPostTypeByURL(n.href).then((function(e){e&&l(e.post_type),n.destination=e,u(n)})))}),[n,u]),(0,b.useEffect)((function(){var e=function(){if(c.current){var e=c.current.offsetWidth,t=Math.floor(e/8);s(function(e,t){var n=e.replace(/(^\w+:|^)\/\//,"").replace(/^www\./,"");if(!t||n.length<=t)return n;var r=n.split("/")[0],i=n.substring(r.length);t-=r.length;var s=Math.floor((t-3)/2),o=i.substring(0,s),a=i.substring(i.length-s);return"".concat(r).concat(o,"...").concat(a)}(n.href,t))}};return e(),window.addEventListener("resize",e),function(){window.removeEventListener("resize",e)}}),[n]),(0,p.jsx)(f.MenuItem,{ref:c,info:i,iconPosition:"left",icon:Ge,shortcut:a,className:"block-editor-link-control__search-item wp-parsely-link-suggestion-link-details",children:n.title})},rt=function(e){var t=e.link,n=e.onNext,r=e.onPrevious,i=e.onAccept,s=e.onReject,o=e.onRemove,a=e.onSelectInEditor,l=e.hasPrevious,c=e.hasNext;if(t&&void 0!==t.post_data)return(0,p.jsx)(Ke,{link:t,onNext:n,onPrevious:r,onAccept:i,onReject:s,onRemove:o,onSelectInEditor:a,hasPrevious:l,hasNext:c});if(!(null==t?void 0:t.match))return(0,p.jsx)(p.Fragment,{children:(0,_.__)("This Smart Link does not have any matches in the current content.","wp-parsely")});var u=t.match.blockId,d=(0,h.select)("core/block-editor").getBlock(u),v=t.applied;return d?(0,p.jsxs)("div",{className:"smart-linking-review-suggestion",children:[(0,p.jsx)(f.KeyboardShortcuts,{shortcuts:{left:r,right:n,up:r,down:n,a:function(){t&&!t.applied&&i()},r:function(){t&&(t.applied?o():s())}}}),(0,p.jsx)(tt,{link:t}),(0,p.jsx)("div",{className:"review-suggestion-preview",children:(0,p.jsx)(Ze,{block:d,link:t})}),(0,p.jsx)(f.__experimentalDivider,{}),(0,p.jsx)(nt,{link:t}),(0,p.jsxs)("div",{className:"review-controls",children:[(0,p.jsx)(f.Tooltip,{shortcut:"←",text:(0,_.__)("Previous","wp-parsely"),children:(0,p.jsx)(f.Button,{disabled:!l,className:"wp-parsely-review-suggestion-previous",onClick:r,icon:He,children:(0,_.__)("Previous","wp-parsely")})}),(0,p.jsxs)("div",{className:"reviews-controls-middle",children:[!v&&(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)(f.Tooltip,{shortcut:"R",text:(0,_.__)("Reject","wp-parsely"),children:(0,p.jsx)(f.Button,{className:"wp-parsely-review-suggestion-reject",icon:Xe,onClick:s,variant:"secondary",children:(0,_.__)("Reject","wp-parsely")})}),(0,p.jsx)(f.Tooltip,{shortcut:"A",text:(0,_.__)("Accept","wp-parsely"),children:(0,p.jsx)(f.Button,{className:"wp-parsely-review-suggestion-accept",icon:et,onClick:i,variant:"secondary",children:(0,_.__)("Accept","wp-parsely")})})]}),v&&(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)(f.Tooltip,{shortcut:"R",text:(0,_.__)("Remove","wp-parsely"),children:(0,p.jsx)(f.Button,{className:"wp-parsely-review-suggestion-reject",icon:Xe,onClick:o,variant:"secondary",children:(0,_.__)("Remove","wp-parsely")})}),(0,p.jsx)(f.Button,{className:"wp-parsely-review-suggestion-accept",onClick:a,variant:"secondary",children:(0,_.__)("Select in Editor","wp-parsely")})]})]}),(0,p.jsx)(f.Tooltip,{shortcut:"→",text:(0,_.__)("Next","wp-parsely"),children:(0,p.jsxs)(f.Button,{disabled:!c,onClick:n,className:"wp-parsely-review-suggestion-next",children:[(0,_.__)("Next","wp-parsely"),(0,p.jsx)(X,{icon:ze})]})})]})]}):(0,p.jsx)(p.Fragment,{children:(0,_.__)("No block is selected.","wp-parsely")})},it=function(e,t,n,r){return new(n||(n=Promise))((function(i,s){function o(e){try{l(r.next(e))}catch(e){s(e)}}function a(e){try{l(r.throw(e))}catch(e){s(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(o,a)}l((r=r.apply(e,t||[])).next())}))},st=function(e,t){var n,r,i,s,o={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return s={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function a(a){return function(l){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;s&&(s=0,a[0]&&(o=0)),o;)try{if(n=1,r&&(i=2&a[0]?r.return:a[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,a[1])).done)return i;switch(r=0,i&&(a=[2&a[0],i.value]),a[0]){case 0:case 1:i=a;break;case 4:return o.label++,{value:a[1],done:!1};case 5:o.label++,r=a[1],a=[0];continue;case 7:a=o.ops.pop(),o.trys.pop();continue;default:if(!((i=(i=o.trys).length>0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&(a=o[0],(l=a.parentNode)&&(c=document.createTextNode(null!==(u=a.textContent)&&void 0!==u?u:""),l.replaceChild(c,a),te.updateBlockAttributes(n,{content:s.innerHTML}))),[4,E(t.uid)]):[2]):[2];case 1:return d.sent(),[2]}}))}))},C=(0,b.useCallback)((function(){c(!1),w().filter((function(e){return!e.applied})).length>0?o(!0):(ne.unlockPostAutosaving("smart-linking-review-modal"),t())}),[w,t]),A=function(e){o(!1),e?(c(!1),T().then((function(){C()}))):c(!0)},O=function(){if(ue(k)){var e=g.indexOf(k);if(!g[t=e+1])return;S(g[t])}else{var t;if(e=v.indexOf(k),!v[t=e+1])return;S(v[t])}},R=function(){if(ue(k)){var e=g.indexOf(k);if(!g[t=e-1])return;S(g[t])}else{var t;if(e=v.indexOf(k),!v[t=e-1])return;S(v[t])}};return(0,b.useEffect)((function(){l?ne.lockPostAutosaving("smart-linking-review-modal"):l&&0===d.length&&C()}),[l,t,d,C]),(0,b.useEffect)((function(){c(n)}),[n]),(0,p.jsxs)(p.Fragment,{children:[l&&(0,p.jsx)(f.Modal,{title:(0,_.__)("Review Smart Links","wp-parsely"),className:"wp-parsely-smart-linking-review-modal",onRequestClose:C,shouldCloseOnClickOutside:!1,shouldCloseOnEsc:!1,children:(0,p.jsxs)("div",{className:"smart-linking-modal-body",children:[(0,p.jsx)(Qe,{outboundLinks:v,inboundLinks:g,activeLink:k,setSelectedLink:S}),k&&(ue(k)?(0,p.jsx)(Ke,{link:k,onNext:O,onPrevious:R,hasNext:g.indexOf(k)0}):(0,p.jsx)(rt,{link:k,hasNext:m().indexOf(k)0,onNext:O,onPrevious:R,onAccept:function(){return it(void 0,void 0,void 0,(function(){var e,t;return st(this,(function(n){switch(n.label){case 0:return k.match?(r(k),[4,(i=k.match.blockId,s=k,it(void 0,void 0,void 0,(function(){var e,t;return st(this,(function(n){switch(n.label){case 0:return(e=document.createElement("a")).href=s.href,e.title=s.title,e.setAttribute("data-smartlink",s.uid),(t=(0,h.select)("core/block-editor").getBlock(i))?(fe(t,s,e),s.applied=!0,[4,L(s)]):[2];case 1:return n.sent(),[2]}}))})))]):[2];case 1:return n.sent(),P.trackEvent("smart_linking_link_accepted",{link:k.href,title:k.title,text:k.text,uid:k.uid}),0===y().length?(C(),[2]):(e=v.indexOf(k),v[t=e+1]?S(v[t]):S(v[0]),[2])}var i,s}))}))},onReject:function(){return it(void 0,void 0,void 0,(function(){var e,t;return st(this,(function(n){switch(n.label){case 0:return e=v.indexOf(k),v[t=e+1]?S(v[t]):v[0]?S(v[0]):C(),[4,E(k.uid)];case 1:return n.sent(),P.trackEvent("smart_linking_link_rejected",{link:k.href,title:k.title,text:k.text,uid:k.uid}),[2]}}))}))},onRemove:function(){return it(void 0,void 0,void 0,(function(){var e,t,n,r;return st(this,(function(i){switch(i.label){case 0:return k.match?(e=(0,h.select)("core/block-editor").getBlock(k.match.blockId))?(t=m(),n=t.indexOf(k),r=n-1,[4,N(e,k)]):[3,2]:[2];case 1:if(i.sent(),P.trackEvent("smart_linking_link_removed",{link:k.href,title:k.title,text:k.text,uid:k.uid}),0===(t=m()).length&&g.length>0)return S(g[0]),[2];if(0===t.length&&0===g.length)return C(),[2];if(t[r])return S(t[r]),[2];S(t[0]),i.label=2;case 2:return[2]}}))}))},onSelectInEditor:function(){if(k.match){var e=(0,h.select)("core/block-editor").getBlock(k.match.blockId);if(e){te.selectBlock(e.clientId);var t=document.querySelector('[data-block="'.concat(e.clientId,'"]'));t&&ke(t,k.uid),P.trackEvent("smart_linking_select_in_editor_pressed",{type:"outbound",uid:k.uid}),C()}}}}))]})}),s&&(0,p.jsxs)(f.Modal,{title:(0,_.__)("Review Smart Links","wp-parsely"),onRequestClose:function(){return A(!1)},className:"wp-parsely-smart-linking-close-dialog",children:[(0,_.__)("Are you sure you want to close? All un-accepted smart links will not be added.","wp-parsely"),(0,p.jsxs)("div",{className:"smart-linking-close-dialog-actions",children:[(0,p.jsx)(f.Button,{variant:"secondary",onClick:function(){return A(!1)},children:(0,_.__)("Go Back","wp-parsely")}),(0,p.jsx)(f.Button,{variant:"primary",onClick:function(){return A(!0)},children:(0,_.__)("Close","wp-parsely")})]})]})]})})),at=function(){return at=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&k("success",/* translators: %d: number of smart links applied */ /* translators: %d: number of smart links applied */ +/* translators: %s: block name */n((0,_.sprintf)((0,_.__)("%s blocks are not supported for Smart Links.","wp-parsely"),s))}T(_e.All===C)}}),[d,S,C,r,i,y,E,T,c]),(0,b.useEffect)((function(){if(!r&&o.current&&C&&!k&&y){var e=o.current.querySelector('button[data-value="'.concat(C,'"]'));e&&"true"!==e.getAttribute("aria-checked")&&(E(C),L(!0))}}),[y,x,r,S]),(0,b.useEffect)((function(){c(null)}),[y]),(0,p.jsx)("div",{className:"parsely-panel-settings",children:(0,p.jsxs)("div",{className:"parsely-panel-settings-body",children:[(0,p.jsxs)("div",{className:"smart-linking-block-select",children:[(0,p.jsx)(f.Disabled,{isDisabled:r,children:(0,p.jsxs)(f.__experimentalToggleGroupControl,{ref:o,__nextHasNoMarginBottom:!0,__next40pxDefaultSize:!0,isBlock:!0,value:C,label:(0,_.__)("Apply Smart Links to","wp-parsely"),onChange:function(e){return Ee(void 0,void 0,void 0,(function(){return Ne(this,(function(t){switch(t.label){case 0:return r?[2]:(v(!0),[4,T(_e.All===e)]);case 1:return t.sent(),[4,E(e)];case 2:return t.sent(),setTimeout((function(){v(!1)}),500),[2]}}))}))},children:[(0,p.jsx)(f.__experimentalToggleGroupControlOption,{label:(0,_.__)("Selected Block","wp-parsely"),value:"selected"}),(0,p.jsx)(f.__experimentalToggleGroupControlOption,{label:(0,_.__)("All Blocks","wp-parsely"),value:"all"})]})}),l&&(0,p.jsxs)("div",{className:"wp-parsely-smart-linking-hint",children:[(0,p.jsx)("strong",{children:(0,_.__)("Hint:","wp-parsely")})," ",l]})]}),(0,p.jsx)("div",{className:"smart-linking-settings",children:(0,p.jsx)(oe,{value:w,onChange:function(e){j(null!=e?e:1),s("MaxLinks",null!=e?e:mt)},label:(0,_.__)("Target Number of Links","wp-parsely"),suffix:(0,_.__)("Links","wp-parsely"),min:1,max:20,initialPosition:w,disabled:r})})]})})},Ae=window.wp.editor,Oe=window.wp.url,Re=function(){function e(){this.abortControllers=new Map}return e.prototype.cancelRequest=function(e){if(e)(t=this.abortControllers.get(e))&&(t.abort(),this.abortControllers.delete(e));else{var t,n=Array.from(this.abortControllers.keys()).pop();n&&(t=this.abortControllers.get(n))&&(t.abort(),this.abortControllers.delete(n))}},e.prototype.cancelAll=function(){this.abortControllers.forEach((function(e){return e.abort()})),this.abortControllers.clear()},e.prototype.getOrCreateController=function(e){if(e&&this.abortControllers.has(e))return{abortController:this.abortControllers.get(e),abortId:e};var t=null!=e?e:"auto-"+Date.now(),n=new AbortController;return this.abortControllers.set(t,n),{abortController:n,abortId:t}},e.prototype.fetch=function(e,t){return n=this,r=void 0,s=function(){var n,r,i,s,o,a;return function(e,t){var n,r,i,s,o={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return s={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function a(a){return function(l){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;s&&(s=0,a[0]&&(o=0)),o;)try{if(n=1,r&&(i=2&a[0]?r.return:a[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,a[1])).done)return i;switch(r=0,i&&(a=[2&a[0],i.value]),a[0]){case 0:case 1:i=a;break;case 4:return o.label++,{value:a[1],done:!1};case 5:o.label++,r=a[1],a=[0];continue;case 7:a=o.ops.pop(),o.trys.pop();continue;default:if(!((i=(i=o.trys).length>0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]

","\n\x3c!-- /wp:paragraph --\x3e");t&&h((0,Q.parse)(n))}),[s]),(0,p.jsxs)("div",{className:"smart-linking-review-suggestion",children:[(0,p.jsx)(f.KeyboardShortcuts,{shortcuts:{left:o,right:a,up:o,down:a}}),(0,p.jsx)("div",{className:"review-suggestion-post-title",children:null===(t=s.post_data)||void 0===t?void 0:t.title}),(0,p.jsxs)("div",{className:"review-suggestion-preview",children:[!(null===(n=s.post_data)||void 0===n?void 0:n.is_first_paragraph)&&(0,p.jsx)($e,{topOrBottom:"top"}),(0,p.jsx)(Ze,{block:d[0],link:s,useOriginalBlock:!0}),!(null===(r=s.post_data)||void 0===r?void 0:r.is_last_paragraph)&&(0,p.jsx)($e,{topOrBottom:"bottom"})]}),(0,p.jsx)(f.__experimentalDivider,{}),(0,p.jsx)(We,{link:s}),(0,p.jsxs)("div",{className:"review-controls",children:[(0,p.jsx)(f.Tooltip,{shortcut:"←",text:(0,_.__)("Previous","wp-parsely"),children:(0,p.jsx)(f.Button,{disabled:!l,className:"wp-parsely-review-suggestion-previous",onClick:o,icon:He,children:(0,_.__)("Previous","wp-parsely")})}),(0,p.jsx)("div",{className:"reviews-controls-middle",children:(0,p.jsx)(f.Button,{target:"_blank",href:(null===(i=s.post_data)||void 0===i?void 0:i.edit_link)+"&smart-link="+s.uid,variant:"secondary",onClick:function(){P.trackEvent("smart_linking_open_in_editor_pressed",{type:"inbound",uid:s.uid})},children:(0,_.__)("Open in the Editor","wp-parsely")})}),(0,p.jsx)(f.Tooltip,{shortcut:"→",text:(0,_.__)("Next","wp-parsely"),children:(0,p.jsxs)(f.Button,{disabled:!c,onClick:a,className:"wp-parsely-review-suggestion-next",children:[(0,_.__)("Next","wp-parsely"),(0,p.jsx)(X,{icon:ze})]})})]})]})},Ye=function(e){var t=e.size,n=void 0===t?24:t,r=e.className,i=void 0===r?"wp-parsely-icon":r;return(0,p.jsxs)(f.SVG,{xmlns:"http://www.w3.org/2000/svg",className:i,width:n,height:n,viewBox:"0 0 24 24",fill:"none",children:[(0,p.jsx)(f.Path,{d:"M8.18983 5.90381L8.83642 7.54325L10.4758 8.18983L8.83642 8.8364L8.18983 10.4759L7.54324 8.8364L5.90381 8.18983L7.54324 7.54325L8.18983 5.90381Z"}),(0,p.jsx)(f.Path,{d:"M15.048 5.90381L15.9101 8.08972L18.0961 8.95186L15.9101 9.81397L15.048 11.9999L14.1859 9.81397L12 8.95186L14.1859 8.08972L15.048 5.90381Z"}),(0,p.jsx)(f.Path,{d:"M11.238 10.4761L12.3157 13.2085L15.048 14.2861L12.3157 15.3638L11.238 18.0962L10.1603 15.3638L7.42798 14.2861L10.1603 13.2085L11.238 10.4761Z"})]})},Je=function(e,t,n){if(n||2===arguments.length)for(var r,i=0,s=t.length;ii.bottom)&&(n.scrollTop=r.offsetTop-n.offsetTop)}}}}),[t,l]);var u=function(){var e=document.querySelector(".smart-linking-review-sidebar-tabs [data-active-item]"),t=null==e?void 0:e.nextElementSibling;t||(t=document.querySelector('.smart-linking-review-sidebar-tabs [role="tab"]')),t&&t.click()},d=(0,p.jsxs)("span",{className:"smart-linking-menu-label",children:[(0,_.__)("NEW","wp-parsely"),(0,p.jsx)(Ye,{})]}),h=[];n&&n.length>0&&h.push({name:"outbound",title:(0,_.__)("Outbound","wp-parsely")}),r&&r.length>0&&h.push({name:"inbound",title:(0,_.__)("Inbound","wp-parsely")});var v="outbound";return h=h.filter((function(e){return"outbound"===e.name&&r&&0===r.length&&(e.title=(0,_.__)("Outbound Smart Links","wp-parsely"),v="outbound"),"inbound"===e.name&&n&&0===n.length&&(e.title=(0,_.__)("Inbound Smart Links","wp-parsely"),v="inbound"),e})),(0,p.jsxs)("div",{className:"smart-linking-review-sidebar",ref:s,children:[(0,p.jsx)(f.KeyboardShortcuts,{shortcuts:{tab:function(){return u()},"shift+tab":function(){return u()}}}),(0,p.jsx)(f.TabPanel,{className:"smart-linking-review-sidebar-tabs",initialTabName:v,tabs:h,onSelect:function(e){var t,s;"outbound"===e&&n&&n.length>0&&i(n[0]),"inbound"===e&&r&&r.length>0&&i(r[0]),P.trackEvent("smart_linking_modal_tab_selected",{tab:e,total_inbound:null!==(t=null==r?void 0:r.length)&&void 0!==t?t:0,total_outbound:null!==(s=null==n?void 0:n.length)&&void 0!==s?s:0})},children:function(e){return(0,p.jsxs)(p.Fragment,{children:["outbound"===e.name&&(0,p.jsx)(p.Fragment,{children:n&&0!==n.length?n.map((function(e,n){return(0,p.jsxs)(f.MenuItem,{ref:function(e){o.current[n]=e},className:(null==t?void 0:t.uid)===e.uid?"is-selected":"",role:"menuitemradio",isSelected:(null==t?void 0:t.uid)===e.uid,onClick:function(){return i(e)},children:[(0,p.jsx)("span",{className:"smart-linking-menu-item",children:e.text}),!e.applied&&d]},e.uid)})):(0,p.jsxs)(p.Fragment,{children:[" ",(0,_.__)("No outbound links found.","wp-parsely")]})}),"inbound"===e.name&&(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)("div",{className:"review-sidebar-tip",children:(0,_.__)("This section shows external posts that link back to the current post.","wp-parsely")}),r&&0!==r.length?r.map((function(e,r){var s;return(0,p.jsx)(f.MenuItem,{ref:function(e){o.current[(n?n.length:0)+r]=e},className:(null==t?void 0:t.uid)===e.uid?"is-selected":"",role:"menuitemradio",isSelected:(null==t?void 0:t.uid)===e.uid,onClick:function(){return i(e)},children:(0,p.jsx)("span",{className:"smart-linking-menu-item",children:null===(s=e.post_data)||void 0===s?void 0:s.title})},e.uid)})):(0,p.jsxs)(p.Fragment,{children:[" ",(0,_.__)("No inbound links found.","wp-parsely")]})]})]})}})]})},Xe=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"M12 13.06l3.712 3.713 1.061-1.06L13.061 12l3.712-3.712-1.06-1.06L12 10.938 8.288 7.227l-1.061 1.06L10.939 12l-3.712 3.712 1.06 1.061L12 13.061z"})}),et=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"M16.7 7.1l-6.3 8.5-3.3-2.5-.9 1.2 4.5 3.4L17.9 8z"})}),tt=function(e){var t,n,r,i,s=null===(t=e.link.match)||void 0===t?void 0:t.blockId,o=(0,h.useSelect)((function(e){var t=e("core/block-editor"),n=t.getBlock,r=t.getBlockParents;return s?{block:n(s),parents:r(s).map((function(e){return n(e)})).filter((function(e){return void 0!==e}))}:{block:void 0,parents:[]}}),[s]),a=o.block,l=o.parents;return a?(0,p.jsxs)("div",{className:"review-suggestions-breadcrumbs",children:[l.map((function(e,t){var n;return(0,p.jsxs)("span",{children:[(0,p.jsx)("span",{className:"breadcrumbs-parent-block",children:null===(n=(0,Q.getBlockType)(e.name))||void 0===n?void 0:n.title}),(0,p.jsx)("span",{className:"breadcrumbs-parent-separator",children:" / "})]},t)})),(0,p.jsxs)("span",{className:"breadcrumbs-current-block",children:[(0,p.jsx)("span",{className:"breadcrumbs-current-block-type",children:null===(n=(0,Q.getBlockType)(a.name))||void 0===n?void 0:n.title}),(null===(i=null===(r=a.attributes)||void 0===r?void 0:r.metadata)||void 0===i?void 0:i.name)&&(0,p.jsx)("span",{className:"breadcrumbs-current-block-name",children:a.attributes.metadata.name})]})]}):(0,p.jsx)(p.Fragment,{})},nt=function(e){var t,n=e.link,r=(0,b.useState)(n.href),i=r[0],s=r[1],o=(0,b.useState)(null===(t=n.destination)||void 0===t?void 0:t.post_type),a=o[0],l=o[1],c=(0,b.useRef)(null),u=(0,h.useDispatch)(Te).updateSmartLink;return(0,b.useEffect)((function(){n.destination?l(n.destination.post_type):(l((0,_.__)("External","wp-parsely")),De.getInstance().getPostTypeByURL(n.href).then((function(e){e&&l(e.post_type),n.destination=e,u(n)})))}),[n,u]),(0,b.useEffect)((function(){var e=function(){if(c.current){var e=c.current.offsetWidth,t=Math.floor(e/8);s(function(e,t){var n=e.replace(/(^\w+:|^)\/\//,"").replace(/^www\./,"");if(!t||n.length<=t)return n;var r=n.split("/")[0],i=n.substring(r.length);t-=r.length;var s=Math.floor((t-3)/2),o=i.substring(0,s),a=i.substring(i.length-s);return"".concat(r).concat(o,"...").concat(a)}(n.href,t))}};return e(),window.addEventListener("resize",e),function(){window.removeEventListener("resize",e)}}),[n]),(0,p.jsx)(f.MenuItem,{ref:c,info:i,iconPosition:"left",icon:Ge,shortcut:a,className:"block-editor-link-control__search-item wp-parsely-link-suggestion-link-details",children:n.title})},rt=function(e){var t=e.link,n=e.onNext,r=e.onPrevious,i=e.onAccept,s=e.onReject,o=e.onRemove,a=e.onSelectInEditor,l=e.hasPrevious,c=e.hasNext;if(t&&void 0!==t.post_data)return(0,p.jsx)(Ke,{link:t,onNext:n,onPrevious:r,onAccept:i,onReject:s,onRemove:o,onSelectInEditor:a,hasPrevious:l,hasNext:c});if(!(null==t?void 0:t.match))return(0,p.jsx)(p.Fragment,{children:(0,_.__)("This Smart Link does not have any matches in the current content.","wp-parsely")});var u=t.match.blockId,d=(0,h.select)("core/block-editor").getBlock(u),v=t.applied;return d?(0,p.jsxs)("div",{className:"smart-linking-review-suggestion",children:[(0,p.jsx)(f.KeyboardShortcuts,{shortcuts:{left:r,right:n,up:r,down:n,a:function(){t&&!t.applied&&i()},r:function(){t&&(t.applied?o():s())}}}),(0,p.jsx)(tt,{link:t}),(0,p.jsx)("div",{className:"review-suggestion-preview",children:(0,p.jsx)(Ze,{block:d,link:t})}),(0,p.jsx)(f.__experimentalDivider,{}),(0,p.jsx)(nt,{link:t}),(0,p.jsxs)("div",{className:"review-controls",children:[(0,p.jsx)(f.Tooltip,{shortcut:"←",text:(0,_.__)("Previous","wp-parsely"),children:(0,p.jsx)(f.Button,{disabled:!l,className:"wp-parsely-review-suggestion-previous",onClick:r,icon:He,children:(0,_.__)("Previous","wp-parsely")})}),(0,p.jsxs)("div",{className:"reviews-controls-middle",children:[!v&&(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)(f.Tooltip,{shortcut:"R",text:(0,_.__)("Reject","wp-parsely"),children:(0,p.jsx)(f.Button,{className:"wp-parsely-review-suggestion-reject",icon:Xe,onClick:s,variant:"secondary",children:(0,_.__)("Reject","wp-parsely")})}),(0,p.jsx)(f.Tooltip,{shortcut:"A",text:(0,_.__)("Accept","wp-parsely"),children:(0,p.jsx)(f.Button,{className:"wp-parsely-review-suggestion-accept",icon:et,onClick:i,variant:"secondary",children:(0,_.__)("Accept","wp-parsely")})})]}),v&&(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)(f.Tooltip,{shortcut:"R",text:(0,_.__)("Remove","wp-parsely"),children:(0,p.jsx)(f.Button,{className:"wp-parsely-review-suggestion-reject",icon:Xe,onClick:o,variant:"secondary",children:(0,_.__)("Remove","wp-parsely")})}),(0,p.jsx)(f.Button,{className:"wp-parsely-review-suggestion-accept",onClick:a,variant:"secondary",children:(0,_.__)("Select in Editor","wp-parsely")})]})]}),(0,p.jsx)(f.Tooltip,{shortcut:"→",text:(0,_.__)("Next","wp-parsely"),children:(0,p.jsxs)(f.Button,{disabled:!c,onClick:n,className:"wp-parsely-review-suggestion-next",children:[(0,_.__)("Next","wp-parsely"),(0,p.jsx)(X,{icon:ze})]})})]})]}):(0,p.jsx)(p.Fragment,{children:(0,_.__)("No block is selected.","wp-parsely")})},it=function(e,t,n,r){return new(n||(n=Promise))((function(i,s){function o(e){try{l(r.next(e))}catch(e){s(e)}}function a(e){try{l(r.throw(e))}catch(e){s(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(o,a)}l((r=r.apply(e,t||[])).next())}))},st=function(e,t){var n,r,i,s,o={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return s={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function a(a){return function(l){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;s&&(s=0,a[0]&&(o=0)),o;)try{if(n=1,r&&(i=2&a[0]?r.return:a[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,a[1])).done)return i;switch(r=0,i&&(a=[2&a[0],i.value]),a[0]){case 0:case 1:i=a;break;case 4:return o.label++,{value:a[1],done:!1};case 5:o.label++,r=a[1],a=[0];continue;case 7:a=o.ops.pop(),o.trys.pop();continue;default:if(!((i=(i=o.trys).length>0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&(a=o[0],(l=a.parentNode)&&(c=document.createTextNode(null!==(u=a.textContent)&&void 0!==u?u:""),l.replaceChild(c,a),te.updateBlockAttributes(n,{content:s.innerHTML}))),[4,E(t.uid)]):[2]):[2];case 1:return d.sent(),[2]}}))}))},C=(0,b.useCallback)((function(){c(!1),w().filter((function(e){return!e.applied})).length>0?o(!0):(ne.unlockPostAutosaving("smart-linking-review-modal"),t())}),[w,t]),A=function(e){o(!1),e?(c(!1),T().then((function(){C()}))):c(!0)},O=function(){if(ue(k)){var e=g.indexOf(k);if(!g[t=e+1])return;S(g[t])}else{var t;if(e=v.indexOf(k),!v[t=e+1])return;S(v[t])}},R=function(){if(ue(k)){var e=g.indexOf(k);if(!g[t=e-1])return;S(g[t])}else{var t;if(e=v.indexOf(k),!v[t=e-1])return;S(v[t])}};return(0,b.useEffect)((function(){l?ne.lockPostAutosaving("smart-linking-review-modal"):l&&0===d.length&&C()}),[l,t,d,C]),(0,b.useEffect)((function(){c(n)}),[n]),(0,p.jsxs)(p.Fragment,{children:[l&&(0,p.jsx)(f.Modal,{title:(0,_.__)("Review Smart Links","wp-parsely"),className:"wp-parsely-smart-linking-review-modal",onRequestClose:C,shouldCloseOnClickOutside:!1,shouldCloseOnEsc:!1,children:(0,p.jsxs)("div",{className:"smart-linking-modal-body",children:[(0,p.jsx)(Qe,{outboundLinks:v,inboundLinks:g,activeLink:k,setSelectedLink:S}),k&&(ue(k)?(0,p.jsx)(Ke,{link:k,onNext:O,onPrevious:R,hasNext:g.indexOf(k)0}):(0,p.jsx)(rt,{link:k,hasNext:m().indexOf(k)0,onNext:O,onPrevious:R,onAccept:function(){return it(void 0,void 0,void 0,(function(){var e,t;return st(this,(function(n){switch(n.label){case 0:return k.match?(r(k),[4,(i=k.match.blockId,s=k,it(void 0,void 0,void 0,(function(){var e,t;return st(this,(function(n){switch(n.label){case 0:return(e=document.createElement("a")).href=s.href,e.title=s.title,e.setAttribute("data-smartlink",s.uid),(t=(0,h.select)("core/block-editor").getBlock(i))?(fe(t,s,e),s.applied=!0,[4,L(s)]):[2];case 1:return n.sent(),[2]}}))})))]):[2];case 1:return n.sent(),P.trackEvent("smart_linking_link_accepted",{link:k.href,title:k.title,text:k.text,uid:k.uid}),0===y().length?(C(),[2]):(e=v.indexOf(k),v[t=e+1]?S(v[t]):S(v[0]),[2])}var i,s}))}))},onReject:function(){return it(void 0,void 0,void 0,(function(){var e,t;return st(this,(function(n){switch(n.label){case 0:return e=v.indexOf(k),v[t=e+1]?S(v[t]):v[0]?S(v[0]):C(),[4,E(k.uid)];case 1:return n.sent(),P.trackEvent("smart_linking_link_rejected",{link:k.href,title:k.title,text:k.text,uid:k.uid}),[2]}}))}))},onRemove:function(){return it(void 0,void 0,void 0,(function(){var e,t,n,r;return st(this,(function(i){switch(i.label){case 0:return k.match?(e=(0,h.select)("core/block-editor").getBlock(k.match.blockId))?(t=m(),n=t.indexOf(k),r=n-1,[4,N(e,k)]):[3,2]:[2];case 1:if(i.sent(),P.trackEvent("smart_linking_link_removed",{link:k.href,title:k.title,text:k.text,uid:k.uid}),0===(t=m()).length&&g.length>0)return S(g[0]),[2];if(0===t.length&&0===g.length)return C(),[2];if(t[r])return S(t[r]),[2];S(t[0]),i.label=2;case 2:return[2]}}))}))},onSelectInEditor:function(){if(k.match){var e=(0,h.select)("core/block-editor").getBlock(k.match.blockId);if(e){te.selectBlock(e.clientId);var t=document.querySelector('[data-block="'.concat(e.clientId,'"]'));t&&ke(t,k.uid),P.trackEvent("smart_linking_select_in_editor_pressed",{type:"outbound",uid:k.uid}),C()}}}}))]})}),s&&(0,p.jsxs)(f.Modal,{title:(0,_.__)("Review Smart Links","wp-parsely"),onRequestClose:function(){return A(!1)},className:"wp-parsely-smart-linking-close-dialog",children:[(0,_.__)("Are you sure you want to close? All un-accepted smart links will not be added.","wp-parsely"),(0,p.jsxs)("div",{className:"smart-linking-close-dialog-actions",children:[(0,p.jsx)(f.Button,{variant:"secondary",onClick:function(){return A(!1)},children:(0,_.__)("Go Back","wp-parsely")}),(0,p.jsx)(f.Button,{variant:"primary",onClick:function(){return A(!0)},children:(0,_.__)("Close","wp-parsely")})]})]})]})})),at=function(){return at=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&k("success",/* translators: %d: number of smart links applied */ /* translators: %d: number of smart links applied */ (0,_.sprintf)((0,_.__)("%s smart links successfully applied.","wp-parsely"),g),{type:"snackbar"}):y(0)}),[w]),(0,b.useEffect)((function(){if(!(Object.keys(R).length>0)){var e={maxLinksPerPost:a.SmartLinking.MaxLinks};te(e)}}),[te,a]);var he=(0,h.useSelect)((function(e){var t=e("core/block-editor"),r=t.getSelectedBlock,i=t.getBlock,s=t.getBlocks,o=e("core/editor"),a=o.getEditedPostContent,l=o.getCurrentPostAttribute;return{allBlocks:s(),selectedBlock:n?i(n):r(),postContent:a(),postPermalink:l("link")}}),[n]),ve=he.allBlocks,me=he.selectedBlock,xe=he.postContent,ke=he.postPermalink,Se=function(e){return lt(void 0,void 0,void 0,(function(){var t,n,r,i,s;return ct(this,(function(o){switch(o.label){case 0:t=[],o.label=1;case 1:return o.trys.push([1,4,,9]),[4,re((n=E||!me)?_e.All:_e.Selected)];case 2:return o.sent(),a=ke.replace(/^https?:\/\//i,""),r=["http://"+a,"https://"+a],i=function(e){return e.map((function(e){return e.href}))}(F),r.push.apply(r,i),[4,De.getInstance().generateSmartLinks(me&&!n?(0,Q.getBlockContent)(me):xe,O,r)];case 3:return t=o.sent(),[3,9];case 4:if((s=o.sent()).code&&s.code===$.ParselyAborted)throw s.numRetries=3-e,s;return e>0&&s.retryFetch?(console.error(s),[4,ce(!0)]):[3,8];case 5:return o.sent(),[4,ue()];case 6:return o.sent(),[4,Se(e-1)];case 7:return[2,o.sent()];case 8:throw s;case 9:return[2,t]}var a}))}))},Pe=function(){for(var e=[],t=0;t[type="button"]').forEach((function(e){e.setAttribute("disabled","disabled")}))},Ne=function(){document.querySelectorAll('.edit-post-header__settings>[type="button"]').forEach((function(e){e.removeAttribute("disabled")})),ne.unlockPostSaving("wp-parsely-block-overlay")};return(0,p.jsxs)("div",{className:"wp-parsely-smart-linking",children:[(0,p.jsx)(se,{isDetectingEnabled:!L,onLinkRemove:function(e){!function(e){ae(this,void 0,void 0,(function(){var t,n,r;return le(this,(function(i){switch(i.label){case 0:return[4,we((0,Q.getBlockContent)(e),e.clientId)];case 1:return t=i.sent(),n=t.missingSmartLinks,r=t.didAnyFixes,n.forEach((function(e){(0,h.dispatch)(Te).removeSmartLink(e.uid)})),[2,r]}}))}))}(e.block)}}),(0,p.jsxs)(f.PanelRow,{className:t,children:[(0,p.jsxs)("div",{className:"smart-linking-text",children:[(0,_.__)("Automatically insert links to your most relevant, top performing content.","wp-parsely"),(0,p.jsxs)(f.Button,{href:"https://docs.parse.ly/plugin-content-helper/#h-smart-linking-beta",target:"_blank",variant:"link",children:[(0,_.__)("Learn more about Parse.ly AI","wp-parsely"),(0,p.jsx)(X,{icon:ee,size:18,className:"parsely-external-link-icon"})]})]}),C&&(0,p.jsx)(f.Notice,{status:"info",onRemove:function(){return Z(null)},className:"wp-parsely-content-helper-error",children:C.Message()}),w&&g>0&&(0,p.jsx)(f.Notice,{status:"success",onRemove:function(){return x(!1)},className:"wp-parsely-smart-linking-suggested-links",children:(0,_.sprintf)(/* translators: 1 - number of smart links generated */ /* translators: 1 - number of smart links generated */ (0,_.__)("Successfully added %s smart links.","wp-parsely"),g>0?g:A.length)}),(0,p.jsx)(Ce,{disabled:T,selectedBlock:me,onSettingChange:function(e,t){var n;d({SmartLinking:at(at({},a.SmartLinking),(n={},n[e]=t,n))}),"MaxLinks"===e&&oe(t)}}),(0,p.jsx)("div",{className:"smart-linking-generate",children:(0,p.jsx)(f.Button,{onClick:function(){return lt(void 0,void 0,void 0,(function(){var e,t,n,r,s,o,a,l;return ct(this,(function(c){switch(c.label){case 0:return[4,q(!0)];case 1:return c.sent(),[4,de()];case 2:return c.sent(),[4,Z(null)];case 3:return c.sent(),x(!1),P.trackEvent("smart_linking_generate_pressed",{is_full_content:E,selected_block:null!==(o=null==me?void 0:me.name)&&void 0!==o?o:"none",context:i}),[4,Pe(E?"all":null==me?void 0:me.clientId)];case 4:c.sent(),e=setTimeout((function(){var e;q(!1),P.trackEvent("smart_linking_generate_timeout",{is_full_content:E,selected_block:null!==(e=null==me?void 0:me.name)&&void 0!==e?e:"none",context:i}),je(E?"all":null==me?void 0:me.clientId)}),18e4),t=I,c.label=5;case 5:return c.trys.push([5,8,10,15]),[4,Se(3)];case 6:return n=c.sent(),[4,(u=n,lt(void 0,void 0,void 0,(function(){var e;return ct(this,(function(t){switch(t.label){case 0:return u=u.filter((function(e){return!F.some((function(t){return t.uid===e.uid&&t.applied}))})),e=ke.replace(/^https?:\/\//,"").replace(/\/+$/,""),u=(u=u.filter((function(t){return!t.href.includes(e)||(console.warn("PCH Smart Linking: Skipping self-reference link: ".concat(t.href)),!1)}))).filter((function(e){return!F.some((function(t){return t.href===e.href?(console.warn("PCH Smart Linking: Skipping duplicate link: ".concat(e.href)),!0):t.text===e.text&&t.offset!==e.offset&&(console.warn("PCH Smart Linking: Skipping duplicate link text: ".concat(e.text)),!0)}))})),u=(u=ge(E?ve:[me],u,{}).filter((function(e){return e.match}))).filter((function(e){if(!e.match)return!1;var t=e.match.blockLinkPosition,n=t+e.text.length;return!F.some((function(r){if(!r.match)return!1;if(e.match.blockId!==r.match.blockId)return!1;var i=r.match.blockLinkPosition,s=i+r.text.length;return t>=i&&n<=s}))})),[4,W(u)];case 1:return t.sent(),[2,u]}}))})))];case 7:if(0===c.sent().length)throw new ie((0,_.__)("No smart links were generated.","wp-parsely"),$.ParselySuggestionsApiNoData,"");return pe(!0),[3,15];case 8:return r=c.sent(),s=new ie(null!==(a=r.message)&&void 0!==a?a:"An unknown error has occurred.",null!==(l=r.code)&&void 0!==l?l:$.UnknownError),r.code&&r.code===$.ParselyAborted&&(s.message=(0,_.sprintf)(/* translators: %d: number of retry attempts, %s: attempt plural */ /* translators: %d: number of retry attempts, %s: attempt plural */ (0,_.__)("The Smart Linking process was cancelled after %1$d %2$s.","wp-parsely"),r.numRetries,(0,_._n)("attempt","attempts",r.numRetries,"wp-parsely"))),console.error(r),[4,Z(s)];case 9:return c.sent(),s.createErrorSnackbar(),[3,15];case 10:return[4,q(!1)];case 11:return c.sent(),[4,re(t)];case 12:return c.sent(),[4,ce(!1)];case 13:return c.sent(),[4,je(E?"all":null==me?void 0:me.clientId)];case 14:return c.sent(),clearTimeout(e),[7];case 15:return[2]}var u}))}))},variant:"primary",isBusy:T,disabled:T,children:M?(0,_.sprintf)(/* translators: %1$d: number of retry attempts, %2$d: maximum number of retries */ /* translators: %1$d: number of retry attempts, %2$d: maximum number of retries */ @@ -22,7 +22,7 @@ message:(0,_.sprintf)((0,_.__)('in section "%1$s"',"wp-parsely"),n.value)};if(w. message:(0,_.sprintf)((0,_.__)('by author "%1$s"',"wp-parsely"),n.value)};throw new ie((0,_.__)("No valid filter type has been specified.","wp-parsely"),$.CannotFormulateApiQuery)},t}(Re),xn=function(){return xn=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&f.every(Number.isInteger)?null!==(n=l("taxonomy","category",{include:f,context:"view"}))&&void 0!==n?n:void 0:null,tagRecords:o=Array.isArray(h)&&h.length>0&&h.every(Number.isInteger)?null!==(r=l("taxonomy","post_tag",{include:h,context:"view"}))&&void 0!==r?r:void 0:null,isLoading:u("getEntityRecords",["root","user",{include:[p],context:"view"}])||u("getEntityRecords",["taxonomy","category",{include:f,context:"view"}])||u("getEntityRecords",["taxonomy","post_tag",{include:h,context:"view"}]),hasResolved:(c("getEntityRecords",["root","user",{include:[p],context:"view"}])||null===i)&&(c("getEntityRecords",["taxonomy","category",{include:f,context:"view"}])||null===s)&&(c("getEntityRecords",["taxonomy","post_tag",{include:h,context:"view"}])||null===o)}}),[]);return(0,b.useEffect)((function(){var e=r.authorRecords,t=r.categoryRecords,i=r.tagRecords,s=r.isLoading;r.hasResolved&&!s&&n({authors:e,categories:t,tags:i,isReady:!0})}),[r]),t}(),c=l.authors,u=l.categories,d=l.tags,v=l.isReady;(0,b.useEffect)((function(){if(v){var e=function(e){return function(e){return!(!Array.isArray(e)||0===e.length)&&e.every((function(e){return"name"in e&&"id"in e&&"slug"in e&&"description"in e&&"link"in e}))}(e)?e.map((function(e){return e.name})):[]};a({authors:e(c),categories:e(u),tags:e(d)})}}),[c,u,d,v]);var g=(0,b.useState)(!0),x=g[0],k=g[1],S=(0,b.useState)(),j=S[0],T=S[1],L=(0,b.useState)(),E=L[0],N=L[1],C=(0,b.useState)([]),A=C[0],O=C[1],R=(0,b.useState)({type:t.RelatedPosts.FilterBy,value:t.RelatedPosts.FilterValue}),I=R[0],M=R[1],G=(0,b.useState)(void 0),H=G[0],U=G[1],q=(0,z.useDebounce)(U,1e3);(0,h.useSelect)((function(e){if("undefined"==typeof jest){var t=e("core/editor").getEditedPostContent;q(t())}else q("Jest test is running")}),[q]);var Z=function(e,r){n({RelatedPosts:xn(xn({},t.RelatedPosts),{FilterBy:e,FilterValue:r})})};return(0,b.useEffect)((function(){var e,t,n=function(e){return kn(void 0,void 0,void 0,(function(){return Sn(this,(function(t){return bn.getInstance().getRelatedPosts(r,i,I).then((function(e){O(e.posts),N(e.message),k(!1)})).catch((function(t){return kn(void 0,void 0,void 0,(function(){return Sn(this,(function(r){switch(r.label){case 0:return e>0&&t.retryFetch?[4,new Promise((function(e){return setTimeout(e,500)}))]:[3,3];case 1:return r.sent(),[4,n(e-1)];case 2:return r.sent(),[3,4];case 3:k(!1),T(t),r.label=4;case 4:return[2]}}))}))})),[2]}))}))},s=w.Author===I.type,a=w.Tag===I.type,l=w.Section===I.type,c=w.Unavailable===I.type,u=0===o.authors.length,d=0===o.tags.length,p=0===o.categories.length,f=s&&!o.authors.includes(I.value),h=a&&!o.tags.includes(I.value),v=l&&!o.categories.includes(I.value);return k(!0),c||a&&d||l&&p||s&&u?Object.values(o).every((function(e){return 0===e.length}))||M((e="",t=w.Unavailable,o.tags.length>=1?(t=w.Tag,e=o.tags[0]):o.categories.length>=1?(t=w.Section,e=o.categories[0]):o.authors.length>=1&&(t=w.Author,e=o.authors[0]),{type:t,value:e})):h?M({type:w.Tag,value:o.tags[0]}):v?M({type:w.Section,value:o.categories[0]}):f?M({type:w.Author,value:o.authors[0]}):n(1),function(){k(!1),O([]),N(""),T(void 0)}}),[r,i,I,o]),0===o.authors.length&&0===o.categories.length&&0===o.tags.length&&v?(0,p.jsx)("div",{className:"wp-parsely-related-posts",children:(0,p.jsx)("div",{className:"related-posts-body",children:(0,_.__)("Error: No author, section, or tags could be found for this post.","wp-parsely")})}):(0,p.jsxs)("div",{className:"wp-parsely-related-posts",children:[(0,p.jsx)("div",{className:"related-posts-description",children:(0,_.__)("Find top-performing related posts based on a key metric.","wp-parsely")}),(0,p.jsxs)("div",{className:"related-posts-body",children:[(0,p.jsxs)("div",{className:"related-posts-settings",children:[(0,p.jsx)(f.SelectControl,{size:"__unstable-large",onChange:function(e){var r;D(r=e,m)&&(n({RelatedPosts:xn(xn({},t.RelatedPosts),{Metric:r})}),P.trackEvent("related_posts_metric_changed",{metric:r}))},prefix:(0,p.jsx)(f.__experimentalInputControlPrefixWrapper,{children:(0,_.__)("Metric: ","wp-parsely")}),value:i,children:Object.values(m).map((function(e){return(0,p.jsx)("option",{value:e,children:V(e)},e)}))}),(0,p.jsx)(f.SelectControl,{size:"__unstable-large",value:r,prefix:(0,p.jsxs)(f.__experimentalInputControlPrefixWrapper,{children:[(0,_.__)("Period: ","wp-parsely")," "]}),onChange:function(e){return function(e){D(e,y)&&(n({RelatedPosts:xn(xn({},t.RelatedPosts),{Period:e})}),P.trackEvent("related_posts_period_changed",{period:e}))}(e)},children:Object.values(y).map((function(e){return(0,p.jsx)("option",{value:e,children:F(e)},e)}))})]}),(0,p.jsx)(ln,{label:(0,_.__)("Filter by","wp-parsely"),filter:I,onFilterTypeChange:function(e){if(D(e,w)){var t="",n=e;w.Tag===n&&(t=o.tags[0]),w.Section===n&&(t=o.categories[0]),w.Author===n&&(t=o.authors[0]),""!==t&&(Z(n,t),M({type:n,value:t}),P.trackEvent("related_posts_filter_type_changed",{filter_type:n}))}},onFilterValueChange:function(e){"string"==typeof e&&(Z(I.type,e),M(xn(xn({},I),{value:e})))},postData:o}),(0,p.jsxs)("div",{className:"related-posts-wrapper",children:[(0,p.jsx)("div",{children:(0,p.jsx)("p",{className:"related-posts-descr","data-testid":"parsely-related-posts-descr",children:w.Tag===I.type?(0,_.sprintf)(/* translators: 1: tag name, 2: period */ /* translators: 1: tag name, 2: period */ (0,_.__)("Top related posts with the “%1$s” tag in the %2$s.","wp-parsely"),I.value,F(r,!0)):w.Section===I.type?(0,_.sprintf)(/* translators: 1: section name, 2: period */ /* translators: 1: section name, 2: period */ (0,_.__)("Top related posts in the “%1$s” section in the %2$s.","wp-parsely"),I.value,F(r,!0)):w.Author===I.type?(0,_.sprintf)(/* translators: 1: author name, 2: period */ /* translators: 1: author name, 2: period */ -(0,_.__)("Top related posts by %1$s in the %2$s.","wp-parsely"),I.value,F(r,!0)):null!=E?E:""})}),j&&j.Message(),x&&(0,p.jsx)("div",{className:"related-posts-loading-message","data-testid":"parsely-related-posts-loading-message",children:(0,_.__)("Loading…","wp-parsely")}),!x&&!j&&0===A.length&&(0,p.jsx)("div",{className:"related-posts-empty","data-testid":"parsely-related-posts-empty",children:(0,_.__)("No related posts found.","wp-parsely")}),!x&&A.length>0&&(0,p.jsx)("div",{className:"related-posts-list",children:A.map((function(e){return(0,p.jsx)(hn,{metric:i,post:e,postContent:H},e.id)}))})]})]})]})},jn=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"m19 7-3-3-8.5 8.5-1 4 4-1L19 7Zm-7 11.5H5V20h7v-1.5Z"})}),Tn=function(){return(0,p.jsx)(f.SVG,{xmlns:"http://www.w3.org/2000/svg",width:"18",height:"18",viewBox:"0 0 18 18",fill:"none",children:(0,p.jsx)(f.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M13.5034 7.91642L9 12.0104L4.49662 7.91642L5.25337 7.08398L8.99999 10.49L12.7466 7.08398L13.5034 7.91642Z",fill:"#1E1E1E"})})},Ln={journalist:{label:(0,_.__)("Journalist","wp-parsely")},editorialWriter:{label:(0,_.__)("Editorial Writer","wp-parsely")},investigativeReporter:{label:(0,_.__)("Investigative Reporter","wp-parsely")},techAnalyst:{label:(0,_.__)("Tech Analyst","wp-parsely")},businessAnalyst:{label:(0,_.__)("Business Analyst","wp-parsely")},culturalCommentator:{label:(0,_.__)("Cultural Commentator","wp-parsely")},scienceCorrespondent:{label:(0,_.__)("Science Correspondent","wp-parsely")},politicalAnalyst:{label:(0,_.__)("Political Analyst","wp-parsely")},healthWellnessAdvocate:{label:(0,_.__)("Health and Wellness Advocate","wp-parsely")},environmentalJournalist:{label:(0,_.__)("Environmental Journalist","wp-parsely")},custom:{label:(0,_.__)("Custom Persona","wp-parsely"),icon:jn}},En=Object.keys(Ln),Nn=function(e){return"custom"===e||""===e?Ln.custom.label:Cn(e)?e:Ln[e].label},Cn=function(e){return!En.includes(e)||"custom"===e},An=function(e){var t=e.value,n=e.onChange,r=(0,b.useState)(""),i=r[0],s=r[1],o=(0,z.useDebounce)(n,500);return(0,p.jsx)("div",{className:"parsely-persona-selector-custom",children:(0,p.jsx)(f.TextControl,{value:i||t,placeholder:(0,_.__)("Enter a custom persona…","wp-parsely"),onChange:function(e){if(""===e)return n(""),void s("");e.length>32&&(e=e.slice(0,32)),o(e),s(e)}})})},On=function(e){var t=e.persona,n=e.value,r=void 0===n?(0,_.__)("Select a persona…","wp-parsely"):n,i=e.label,s=void 0===i?(0,_.__)("Persona","wp-parsely"):i,o=e.onChange,a=e.onDropdownChange,l=e.disabled,c=void 0!==l&&l,u=e.allowCustom,d=void 0!==u&&u;return(0,p.jsxs)(f.Disabled,{isDisabled:c,children:[s&&(0,p.jsx)("div",{className:"wp-parsely-dropdown-label",children:s}),(0,p.jsx)(f.DropdownMenu,{label:(0,_.__)("Persona","wp-parsely"),className:"parsely-persona-selector-dropdown"+(c?" is-disabled":""),popoverProps:{className:"wp-parsely-popover"},toggleProps:{children:(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)("div",{className:"parsely-persona-selector-label",children:Cn(t)?Ln.custom.label:r}),(0,p.jsx)(Tn,{})]})},children:function(e){var n=e.onClose;return(0,p.jsx)(f.MenuGroup,{label:(0,_.__)("Persona","wp-parsely"),children:(0,p.jsx)(p.Fragment,{children:En.map((function(e){if(!d&&"custom"===e)return null;var r=Ln[e],i=e===t||Cn(t)&&"custom"===e;return(0,p.jsxs)(f.MenuItem,{isSelected:i,className:i?"is-selected":"",role:"menuitemradio",onClick:function(){null==a||a(e),o(e),n(),"custom"===e&&setTimeout((function(){var e=document.querySelector(".parsely-persona-selector-custom input");e&&e.focus()}),0)},children:[r.icon&&(0,p.jsx)(X,{icon:r.icon}),r.label]},e)}))})})}}),d&&Cn(t)&&(0,p.jsx)(An,{onChange:function(e){o(""!==e?e:"custom")},value:"custom"===t?"":t})]})},Rn={neutral:{label:(0,_.__)("Neutral","wp-parsely")},formal:{label:(0,_.__)("Formal","wp-parsely")},humorous:{label:(0,_.__)("Humorous","wp-parsely")},confident:{label:(0,_.__)("Confident","wp-parsely")},provocative:{label:(0,_.__)("Provocative","wp-parsely")},serious:{label:(0,_.__)("Serious","wp-parsely")},inspirational:{label:(0,_.__)("Inspirational","wp-parsely")},skeptical:{label:(0,_.__)("Skeptical","wp-parsely")},conversational:{label:(0,_.__)("Conversational","wp-parsely")},analytical:{label:(0,_.__)("Analytical","wp-parsely")},custom:{label:(0,_.__)("Custom Tone","wp-parsely"),icon:jn}},In=Object.keys(Rn),Bn=function(e){return"custom"===e||""===e?Rn.custom.label:Mn(e)?e:Rn[e].label},Mn=function(e){return!In.includes(e)||"custom"===e},Dn=function(e){var t=e.value,n=e.onChange,r=(0,b.useState)(""),i=r[0],s=r[1],o=(0,z.useDebounce)(n,500);return(0,p.jsx)("div",{className:"parsely-tone-selector-custom",children:(0,p.jsx)(f.TextControl,{value:i||t,placeholder:(0,_.__)("Enter a custom tone","wp-parsely"),onChange:function(e){if(""===e)return n(""),void s("");e.length>32&&(e=e.slice(0,32)),o(e),s(e)}})})},Fn=function(e){var t=e.tone,n=e.value,r=void 0===n?(0,_.__)("Select a tone","wp-parsely"):n,i=e.label,s=void 0===i?(0,_.__)("Tone","wp-parsely"):i,o=e.onChange,a=e.onDropdownChange,l=e.disabled,c=void 0!==l&&l,u=e.allowCustom,d=void 0!==u&&u;return(0,p.jsxs)(f.Disabled,{isDisabled:c,children:[(0,p.jsx)("div",{className:"wp-parsely-dropdown-label",children:s}),(0,p.jsx)(f.DropdownMenu,{label:(0,_.__)("Tone","wp-parsely"),className:"parsely-tone-selector-dropdown"+(c?" is-disabled":""),popoverProps:{className:"wp-parsely-popover"},toggleProps:{children:(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)("div",{className:"parsely-tone-selector-label",children:Mn(t)?Rn.custom.label:r}),(0,p.jsx)(Tn,{})]})},children:function(e){var n=e.onClose;return(0,p.jsx)(f.MenuGroup,{label:(0,_.__)("Select a tone","wp-parsely"),children:(0,p.jsx)(p.Fragment,{children:In.map((function(e){if(!d&&"custom"===e)return null;var r=Rn[e],i=e===t||Mn(t)&&"custom"===e;return(0,p.jsxs)(f.MenuItem,{isSelected:i,className:i?"is-selected":"",role:"menuitemradio",onClick:function(){null==a||a(e),o(e),n(),"custom"===e&&setTimeout((function(){var e=document.querySelector(".parsely-tone-selector-custom input");e&&e.focus()}),0)},children:[r.icon&&(0,p.jsx)(X,{icon:r.icon}),r.label]},e)}))})})}}),d&&Mn(t)&&(0,p.jsx)(Dn,{onChange:function(e){o(""!==e?e:"custom")},value:"custom"===t?"":t})]})},Vn=(0,p.jsx)(x.SVG,{width:"24",height:"24",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:(0,p.jsx)(x.Path,{d:"M10.97 10.159a3.382 3.382 0 0 0-2.857.955l1.724 1.723-2.836 2.913L7 17h1.25l2.913-2.837 1.723 1.723a3.38 3.38 0 0 0 .606-.825c.33-.63.446-1.343.35-2.032L17 10.695 13.305 7l-2.334 3.159Z"})}),Gn=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"M18.3 11.7c-.6-.6-1.4-.9-2.3-.9H6.7l2.9-3.3-1.1-1-4.5 5L8.5 16l1-1-2.7-2.7H16c.5 0 .9.2 1.3.5 1 1 1 3.4 1 4.5v.3h1.5v-.2c0-1.5 0-4.3-1.5-5.7z"})}),Hn=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M12 5.5A2.25 2.25 0 0 0 9.878 7h4.244A2.251 2.251 0 0 0 12 5.5ZM12 4a3.751 3.751 0 0 0-3.675 3H5v1.5h1.27l.818 8.997a2.75 2.75 0 0 0 2.739 2.501h4.347a2.75 2.75 0 0 0 2.738-2.5L17.73 8.5H19V7h-3.325A3.751 3.751 0 0 0 12 4Zm4.224 4.5H7.776l.806 8.861a1.25 1.25 0 0 0 1.245 1.137h4.347a1.25 1.25 0 0 0 1.245-1.137l.805-8.861Z"})}),zn=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"m21.5 9.1-6.6-6.6-4.2 5.6c-1.2-.1-2.4.1-3.6.7-.1 0-.1.1-.2.1-.5.3-.9.6-1.2.9l3.7 3.7-5.7 5.7v1.1h1.1l5.7-5.7 3.7 3.7c.4-.4.7-.8.9-1.2.1-.1.1-.2.2-.3.6-1.1.8-2.4.6-3.6l5.6-4.1zm-7.3 3.5.1.9c.1.9 0 1.8-.4 2.6l-6-6c.8-.4 1.7-.5 2.6-.4l.9.1L15 4.9 19.1 9l-4.9 3.6z"})}),Un=function(){return Un=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0?(0,p.jsx)("span",{className:"parsely-write-titles-text",children:(0,b.createInterpolateElement)( +(0,_.__)("Top related posts by %1$s in the %2$s.","wp-parsely"),I.value,F(r,!0)):null!=E?E:""})}),j&&j.Message(),x&&(0,p.jsx)("div",{className:"related-posts-loading-message","data-testid":"parsely-related-posts-loading-message",children:(0,_.__)("Loading…","wp-parsely")}),!x&&!j&&0===A.length&&(0,p.jsx)("div",{className:"related-posts-empty","data-testid":"parsely-related-posts-empty",children:(0,_.__)("No related posts found.","wp-parsely")}),!x&&A.length>0&&(0,p.jsx)("div",{className:"related-posts-list",children:A.map((function(e){return(0,p.jsx)(hn,{metric:i,post:e,postContent:H},e.id)}))})]})]})]})},jn=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"m19 7-3-3-8.5 8.5-1 4 4-1L19 7Zm-7 11.5H5V20h7v-1.5Z"})}),Tn=function(){return(0,p.jsx)(f.SVG,{xmlns:"http://www.w3.org/2000/svg",width:"18",height:"18",viewBox:"0 0 18 18",fill:"none",children:(0,p.jsx)(f.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M13.5034 7.91642L9 12.0104L4.49662 7.91642L5.25337 7.08398L8.99999 10.49L12.7466 7.08398L13.5034 7.91642Z",fill:"#1E1E1E"})})},Ln={journalist:{label:(0,_.__)("Journalist","wp-parsely")},editorialWriter:{label:(0,_.__)("Editorial Writer","wp-parsely")},investigativeReporter:{label:(0,_.__)("Investigative Reporter","wp-parsely")},techAnalyst:{label:(0,_.__)("Tech Analyst","wp-parsely")},businessAnalyst:{label:(0,_.__)("Business Analyst","wp-parsely")},culturalCommentator:{label:(0,_.__)("Cultural Commentator","wp-parsely")},scienceCorrespondent:{label:(0,_.__)("Science Correspondent","wp-parsely")},politicalAnalyst:{label:(0,_.__)("Political Analyst","wp-parsely")},healthWellnessAdvocate:{label:(0,_.__)("Health and Wellness Advocate","wp-parsely")},environmentalJournalist:{label:(0,_.__)("Environmental Journalist","wp-parsely")},custom:{label:(0,_.__)("Custom Persona","wp-parsely"),icon:jn}},En=Object.keys(Ln),Nn=function(e){return"custom"===e||""===e?Ln.custom.label:Cn(e)?e:Ln[e].label},Cn=function(e){return!En.includes(e)||"custom"===e},An=function(e){var t=e.value,n=e.onChange,r=(0,b.useState)(""),i=r[0],s=r[1],o=(0,z.useDebounce)(n,500);return(0,p.jsx)("div",{className:"parsely-persona-selector-custom",children:(0,p.jsx)(f.TextControl,{value:i||t,placeholder:(0,_.__)("Enter a custom persona…","wp-parsely"),onChange:function(e){if(""===e)return n(""),void s("");e.length>32&&(e=e.slice(0,32)),o(e),s(e)}})})},On=function(e){var t=e.persona,n=e.value,r=void 0===n?(0,_.__)("Select a persona…","wp-parsely"):n,i=e.label,s=void 0===i?(0,_.__)("Persona","wp-parsely"):i,o=e.onChange,a=e.onDropdownChange,l=e.disabled,c=void 0!==l&&l,u=e.allowCustom,d=void 0!==u&&u;return(0,p.jsxs)(f.Disabled,{isDisabled:c,children:[s&&(0,p.jsx)("div",{className:"wp-parsely-dropdown-label",children:s}),(0,p.jsx)(f.DropdownMenu,{label:(0,_.__)("Persona","wp-parsely"),className:"parsely-persona-selector-dropdown"+(c?" is-disabled":""),popoverProps:{className:"wp-parsely-popover"},toggleProps:{children:(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)("div",{className:"parsely-persona-selector-label",children:Cn(t)?Ln.custom.label:r}),(0,p.jsx)(Tn,{})]})},children:function(e){var n=e.onClose;return(0,p.jsx)(f.MenuGroup,{label:(0,_.__)("Persona","wp-parsely"),children:(0,p.jsx)(p.Fragment,{children:En.map((function(e){if(!d&&"custom"===e)return null;var r=Ln[e],i=e===t||Cn(t)&&"custom"===e;return(0,p.jsxs)(f.MenuItem,{isSelected:i,className:i?"is-selected":"",role:"menuitemradio",onClick:function(){null==a||a(e),o(e),n(),"custom"===e&&setTimeout((function(){var e=document.querySelector(".parsely-persona-selector-custom input");e&&e.focus()}),0)},children:[r.icon&&(0,p.jsx)(X,{icon:r.icon}),r.label]},e)}))})})}}),d&&Cn(t)&&(0,p.jsx)(An,{onChange:function(e){o(""!==e?e:"custom")},value:"custom"===t?"":t})]})},Rn={neutral:{label:(0,_.__)("Neutral","wp-parsely")},formal:{label:(0,_.__)("Formal","wp-parsely")},humorous:{label:(0,_.__)("Humorous","wp-parsely")},confident:{label:(0,_.__)("Confident","wp-parsely")},provocative:{label:(0,_.__)("Provocative","wp-parsely")},serious:{label:(0,_.__)("Serious","wp-parsely")},inspirational:{label:(0,_.__)("Inspirational","wp-parsely")},skeptical:{label:(0,_.__)("Skeptical","wp-parsely")},conversational:{label:(0,_.__)("Conversational","wp-parsely")},analytical:{label:(0,_.__)("Analytical","wp-parsely")},custom:{label:(0,_.__)("Custom Tone","wp-parsely"),icon:jn}},In=Object.keys(Rn),Bn=function(e){return"custom"===e||""===e?Rn.custom.label:Mn(e)?e:Rn[e].label},Mn=function(e){return!In.includes(e)||"custom"===e},Dn=function(e){var t=e.value,n=e.onChange,r=(0,b.useState)(""),i=r[0],s=r[1],o=(0,z.useDebounce)(n,500);return(0,p.jsx)("div",{className:"parsely-tone-selector-custom",children:(0,p.jsx)(f.TextControl,{value:i||t,placeholder:(0,_.__)("Enter a custom tone","wp-parsely"),onChange:function(e){if(""===e)return n(""),void s("");e.length>32&&(e=e.slice(0,32)),o(e),s(e)}})})},Fn=function(e){var t=e.tone,n=e.value,r=void 0===n?(0,_.__)("Select a tone","wp-parsely"):n,i=e.label,s=void 0===i?(0,_.__)("Tone","wp-parsely"):i,o=e.onChange,a=e.onDropdownChange,l=e.disabled,c=void 0!==l&&l,u=e.allowCustom,d=void 0!==u&&u;return(0,p.jsxs)(f.Disabled,{isDisabled:c,children:[(0,p.jsx)("div",{className:"wp-parsely-dropdown-label",children:s}),(0,p.jsx)(f.DropdownMenu,{label:(0,_.__)("Tone","wp-parsely"),className:"parsely-tone-selector-dropdown"+(c?" is-disabled":""),popoverProps:{className:"wp-parsely-popover"},toggleProps:{children:(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)("div",{className:"parsely-tone-selector-label",children:Mn(t)?Rn.custom.label:r}),(0,p.jsx)(Tn,{})]})},children:function(e){var n=e.onClose;return(0,p.jsx)(f.MenuGroup,{label:(0,_.__)("Select a tone","wp-parsely"),children:(0,p.jsx)(p.Fragment,{children:In.map((function(e){if(!d&&"custom"===e)return null;var r=Rn[e],i=e===t||Mn(t)&&"custom"===e;return(0,p.jsxs)(f.MenuItem,{isSelected:i,className:i?"is-selected":"",role:"menuitemradio",onClick:function(){null==a||a(e),o(e),n(),"custom"===e&&setTimeout((function(){var e=document.querySelector(".parsely-tone-selector-custom input");e&&e.focus()}),0)},children:[r.icon&&(0,p.jsx)(X,{icon:r.icon}),r.label]},e)}))})})}}),d&&Mn(t)&&(0,p.jsx)(Dn,{onChange:function(e){o(""!==e?e:"custom")},value:"custom"===t?"":t})]})},Vn=(0,p.jsx)(x.SVG,{width:"24",height:"24",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:(0,p.jsx)(x.Path,{d:"M10.97 10.159a3.382 3.382 0 0 0-2.857.955l1.724 1.723-2.836 2.913L7 17h1.25l2.913-2.837 1.723 1.723a3.38 3.38 0 0 0 .606-.825c.33-.63.446-1.343.35-2.032L17 10.695 13.305 7l-2.334 3.159Z"})}),Gn=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"M18.3 11.7c-.6-.6-1.4-.9-2.3-.9H6.7l2.9-3.3-1.1-1-4.5 5L8.5 16l1-1-2.7-2.7H16c.5 0 .9.2 1.3.5 1 1 1 3.4 1 4.5v.3h1.5v-.2c0-1.5 0-4.3-1.5-5.7z"})}),Hn=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M12 5.5A2.25 2.25 0 0 0 9.878 7h4.244A2.251 2.251 0 0 0 12 5.5ZM12 4a3.751 3.751 0 0 0-3.675 3H5v1.5h1.27l.818 8.997a2.75 2.75 0 0 0 2.739 2.501h4.347a2.75 2.75 0 0 0 2.738-2.5L17.73 8.5H19V7h-3.325A3.751 3.751 0 0 0 12 4Zm4.224 4.5H7.776l.806 8.861a1.25 1.25 0 0 0 1.245 1.137h4.347a1.25 1.25 0 0 0 1.245-1.137l.805-8.861Z"})}),zn=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"m21.5 9.1-6.6-6.6-4.2 5.6c-1.2-.1-2.4.1-3.6.7-.1 0-.1.1-.2.1-.5.3-.9.6-1.2.9l3.7 3.7-5.7 5.7v1.1h1.1l5.7-5.7 3.7 3.7c.4-.4.7-.8.9-1.2.1-.1.1-.2.2-.3.6-1.1.8-2.4.6-3.6l5.6-4.1zm-7.3 3.5.1.9c.1.9 0 1.8-.4 2.6l-6-6c.8-.4 1.7-.5 2.6-.4l.9.1L15 4.9 19.1 9l-4.9 3.6z"})}),Un=function(){return Un=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0?(0,p.jsx)("span",{className:"parsely-write-titles-text",children:(0,b.createInterpolateElement)( // translators: %1$s is the tone, %2$s is the persona. // translators: %1$s is the tone, %2$s is the persona. (0,_.__)("We've generated a few titles based on the content of your post, written as a .","wp-parsely"),{tone:(0,p.jsx)("strong",{children:Bn(a)}),persona:(0,p.jsx)("strong",{children:Nn(u)})})}):(0,_.__)("Use Parse.ly AI to generate a title for your post.","wp-parsely"),(0,p.jsxs)(f.Button,{href:"https://docs.parse.ly/plugin-content-helper/#h-title-suggestions-beta",target:"_blank",variant:"link",children:[(0,_.__)("Learn more about Parse.ly AI","wp-parsely"),(0,p.jsx)(X,{icon:ee,size:18,className:"parsely-external-link-icon"})]})]}),i&&(0,p.jsx)(f.Notice,{className:"wp-parsely-content-helper-error",onRemove:function(){return s(void 0)},status:"info",children:i.Message()}),void 0!==k&&(0,p.jsx)(Jn,{title:k,type:fn.PostTitle,isOriginal:!0}),00&&(0,p.jsx)(Qn,{pinnedTitles:m,isOpen:!0}),y.length>0&&(0,p.jsx)(er,{suggestions:y,isOpen:!0,isLoading:g})]}),(0,p.jsx)(Xn,{isLoading:g,onPersonaChange:function(e){C("Persona",e),d(e)},onSettingChange:C,onToneChange:function(e){C("Tone",e),l(e)},persona:t.TitleSuggestions.Persona,tone:t.TitleSuggestions.Tone}),(0,p.jsx)("div",{className:"title-suggestions-generate",children:(0,p.jsxs)(f.Button,{variant:"primary",isBusy:g,disabled:g||"custom"===a||"custom"===u,onClick:function(){return ir(void 0,void 0,void 0,(function(){return sr(this,(function(e){switch(e.label){case 0:return s(void 0),!1!==g?[3,2]:(P.trackEvent("title_suggestions_generate_pressed",{request_more:y.length>0,total_titles:y.length,total_pinned:y.filter((function(e){return e.isPinned})).length,tone:a,persona:u}),[4,(t=fn.PostTitle,n=A,r=a,i=u,ir(void 0,void 0,void 0,(function(){var e,o,a;return sr(this,(function(l){switch(l.label){case 0:return[4,T(!0)];case 1:l.sent(),e=nr.getInstance(),l.label=2;case 2:return l.trys.push([2,5,,6]),[4,e.generateTitles(n,3,r,i)];case 3:return o=l.sent(),[4,j(t,o)];case 4:return l.sent(),[3,6];case 5:return a=l.sent(),s(a),j(t,[]),[3,6];case 6:return[4,T(!1)];case 7:return l.sent(),[2]}}))})))]);case 1:e.sent(),e.label=2;case 2:return[2]}var t,n,r,i}))}))},children:[g&&(0,_.__)("Generating Titles…","wp-parsely"),!g&&w.length>0&&(0,_.__)("Generate More","wp-parsely"),!g&&0===w.length&&(0,_.__)("Generate Titles","wp-parsely")]})})]})})},ar=function(){return ar=Object.assign||function(e){for(var t,n=1,r=arguments.length;n array('react', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-plugins', 'wp-primitives', 'wp-url', 'wp-wordcount'), 'version' => '577d3025e0a7c2398780'); + array('react', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-plugins', 'wp-primitives', 'wp-url', 'wp-wordcount'), 'version' => 'c02551fe09a73f993b6f'); diff --git a/build/content-helper/excerpt-generator.js b/build/content-helper/excerpt-generator.js index 82cb2f791..26c6f9ac7 100644 --- a/build/content-helper/excerpt-generator.js +++ b/build/content-helper/excerpt-generator.js @@ -1,4 +1,4 @@ -!function(){"use strict";var e={20:function(e,t,r){var n=r(609),o=Symbol.for("react.element"),a=Symbol.for("react.fragment"),i=Object.prototype.hasOwnProperty,s=n.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function c(e,t,r){var n,a={},c=null,u=null;for(n in void 0!==r&&(c=""+r),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(u=t.ref),t)i.call(t,n)&&!l.hasOwnProperty(n)&&(a[n]=t[n]);if(e&&e.defaultProps)for(n in t=e.defaultProps)void 0===a[n]&&(a[n]=t[n]);return{$$typeof:o,type:e,key:c,ref:u,props:a,_owner:s.current}}t.Fragment=a,t.jsx=c,t.jsxs=c},848:function(e,t,r){e.exports=r(20)},609:function(e){e.exports=window.React}},t={};function r(n){var o=t[n];if(void 0!==o)return o.exports;var a=t[n]={exports:{}};return e[n](a,a.exports,r),a.exports}r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,{a:t}),t},r.d=function(e,t){for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},function(){var e,t,n,o,a,i,s,l,c,u,p,d=window.wp.data,y=window.wp.hooks,h=window.wp.plugins,f=((0,d.dispatch)("core/block-editor"),(0,d.dispatch)("core/editor"),(0,d.dispatch)("core/edit-post")),w=r(848),v=window.wp.components,g=window.wp.editor;void 0!==window.wp&&(p=null!==(t=null===(e=window.wp.editor)||void 0===e?void 0:e.PluginDocumentSettingPanel)&&void 0!==t?t:null!==(o=null===(n=window.wp.editPost)||void 0===n?void 0:n.PluginDocumentSettingPanel)&&void 0!==o?o:null===(a=window.wp.editSite)||void 0===a?void 0:a.PluginDocumentSettingPanel,null!==(s=null===(i=window.wp.editor)||void 0===i?void 0:i.PluginSidebar)&&void 0!==s||null!==(c=null===(l=window.wp.editPost)||void 0===l?void 0:l.PluginSidebar)&&void 0!==c||null===(u=window.wp.editSite)||void 0===u||u.PluginSidebar);var _,b,P=window.wp.element,m=window.wp.i18n,x=window.wp.wordcount,E=window.wp.primitives,A=(0,w.jsx)(E.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,w.jsx)(E.Path,{d:"M19.5 4.5h-7V6h4.44l-5.97 5.97 1.06 1.06L18 7.06v4.44h1.5v-7Zm-13 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-3H17v3a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h3V5.5h-3Z"})}),S=function(){function e(){this._tkq=[],this.isLoaded=!1,this.isEnabled=!1,"undefined"!=typeof wpParselyTracksTelemetry&&(this.isEnabled=!0,this.loadTrackingLibrary())}return e.getInstance=function(){return window.wpParselyTelemetryInstance||Object.defineProperty(window,"wpParselyTelemetryInstance",{value:new e,writable:!1,configurable:!1,enumerable:!1}),window.wpParselyTelemetryInstance},e.prototype.loadTrackingLibrary=function(){var e=this,t=document.createElement("script");t.async=!0,t.src="//stats.wp.com/w.js",t.onload=function(){e.isLoaded=!0,e._tkq=window._tkq||[]},document.head.appendChild(t)},e.trackEvent=function(t){return r=this,n=arguments,a=function(t,r){var n;return void 0===r&&(r={}),function(e,t){var r,n,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function s(s){return function(l){return function(s){if(r)throw new TypeError("Generator is already executing.");for(;a&&(a=0,s[0]&&(i=0)),i;)try{if(r=1,n&&(o=2&s[0]?n.return:s[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,s[1])).done)return o;switch(n=0,o&&(s=[2&s[0],o.value]),s[0]){case 0:case 1:o=s;break;case 4:return i.label++,{value:s[1],done:!1};case 5:i.label++,n=s[1],s=[0];continue;case 7:s=i.ops.pop(),i.trys.pop();continue;default:if(!((o=(o=i.trys).length>0&&o[o.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]=1e4&&(clearInterval(a),r("Telemetry library not loaded"))}),100);else r("Telemetry not enabled")}))},e.prototype.trackEvent=function(t,r){var n;this.isLoaded?(0!==t.indexOf(e.TRACKS_PREFIX)&&(t=e.TRACKS_PREFIX+t),this.isEventNameValid(t)?(r=this.prepareProperties(r),null===(n=this._tkq)||void 0===n||n.push(["recordEvent",t,r])):console.error("Error tracking event: Invalid event name")):console.error("Error tracking event: Telemetry not loaded")},e.prototype.isTelemetryEnabled=function(){return this.isEnabled},e.prototype.isProprietyValid=function(t){return e.PROPERTY_REGEX.test(t)},e.prototype.isEventNameValid=function(t){return e.EVENT_NAME_REGEX.test(t)},e.prototype.prepareProperties=function(e){return(e=this.sanitizeProperties(e)).parsely_version=wpParselyTracksTelemetry.version,wpParselyTracksTelemetry.user&&(e._ut=wpParselyTracksTelemetry.user.type,e._ui=wpParselyTracksTelemetry.user.id),wpParselyTracksTelemetry.vipgo_env&&(e.vipgo_env=wpParselyTracksTelemetry.vipgo_env),this.sanitizeProperties(e)},e.prototype.sanitizeProperties=function(e){var t=this,r={};return Object.keys(e).forEach((function(n){t.isProprietyValid(n)&&(r[n]=e[n])})),r},e.TRACKS_PREFIX="wpparsely_",e.EVENT_NAME_REGEX=/^(([a-z0-9]+)_){2}([a-z0-9_]+)$/,e.PROPERTY_REGEX=/^[a-z_][a-z0-9_]*$/,e}(),k=(S.trackEvent,function(e){void 0===e&&(e=null);var t="";(null==e?void 0:e.children)&&(t=e.children);var r="content-helper-error-message";return(null==e?void 0:e.className)&&(r+=" "+e.className),(0,w.jsx)("div",{className:r,"data-testid":null==e?void 0:e.testId,dangerouslySetInnerHTML:{__html:t}})}),T=(_=function(e,t){return _=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])},_(e,t)},function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function __(){this.constructor=e}_(e,t),e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)});!function(e){e.AccessToFeatureDisabled="ch_access_to_feature_disabled",e.CannotFormulateApiQuery="ch_cannot_formulate_api_query",e.FetchError="fetch_error",e.HttpRequestFailed="http_request_failed",e.ParselyAborted="ch_parsely_aborted",e[e.ParselyApiForbidden=403]="ParselyApiForbidden",e.ParselyApiResponseContainsError="ch_response_contains_error",e.ParselyApiReturnedNoData="ch_parsely_api_returned_no_data",e.ParselyApiReturnedTooManyResults="ch_parsely_api_returned_too_many_results",e.PluginCredentialsNotSetMessageDetected="parsely_credentials_not_set_message_detected",e.PluginSettingsApiSecretNotSet="parsely_api_secret_not_set",e.PluginSettingsSiteIdNotSet="parsely_site_id_not_set",e.PostIsNotPublished="ch_post_not_published",e.UnknownError="ch_unknown_error",e.ParselySuggestionsApiAuthUnavailable="AUTH_UNAVAILABLE",e.ParselySuggestionsApiNoAuthentication="NO_AUTHENTICATION",e.ParselySuggestionsApiNoAuthorization="NO_AUTHORIZATION",e.ParselySuggestionsApiNoData="NO_DATA",e.ParselySuggestionsApiOpenAiError="OPENAI_ERROR",e.ParselySuggestionsApiOpenAiSchema="OPENAI_SCHEMA",e.ParselySuggestionsApiOpenAiUnavailable="OPENAI_UNAVAILABLE",e.ParselySuggestionsApiSchemaError="SCHEMA_ERROR"}(b||(b={}));var N=function(e){function t(r,n,o){void 0===o&&(o=(0,m.__)("Error: ","wp-parsely"));var a=this;r.startsWith(o)&&(o=""),(a=e.call(this,o+r)||this).hint=null,a.name=a.constructor.name,a.code=n;var i=[b.AccessToFeatureDisabled,b.ParselyApiForbidden,b.ParselyApiResponseContainsError,b.ParselyApiReturnedNoData,b.ParselyApiReturnedTooManyResults,b.PluginCredentialsNotSetMessageDetected,b.PluginSettingsApiSecretNotSet,b.PluginSettingsSiteIdNotSet,b.PostIsNotPublished,b.UnknownError,b.ParselySuggestionsApiAuthUnavailable,b.ParselySuggestionsApiNoAuthentication,b.ParselySuggestionsApiNoAuthorization,b.ParselySuggestionsApiNoData,b.ParselySuggestionsApiSchemaError];return a.retryFetch=!i.includes(a.code),Object.setPrototypeOf(a,t.prototype),a.code===b.AccessToFeatureDisabled?a.message=(0,m.__)("Access to this feature is disabled by the site's administration.","wp-parsely"):a.code===b.ParselySuggestionsApiNoAuthorization?a.message=(0,m.__)('This AI-powered feature is opt-in. To gain access, please submit a request here.',"wp-parsely"):a.code===b.ParselySuggestionsApiOpenAiError||a.code===b.ParselySuggestionsApiOpenAiUnavailable?a.message=(0,m.__)("The Parse.ly API returned an internal server error. Please retry with a different input, or try again later.","wp-parsely"):a.code===b.HttpRequestFailed&&a.message.includes("cURL error 28")?a.message=(0,m.__)("The Parse.ly API did not respond in a timely manner. Please try again later.","wp-parsely"):a.code===b.ParselySuggestionsApiSchemaError?a.message=(0,m.__)("The Parse.ly API returned a validation error. Please try again with different parameters.","wp-parsely"):a.code===b.ParselySuggestionsApiNoData?a.message=(0,m.__)("The Parse.ly API couldn't find any relevant data to fulfill the request. Please retry with a different input.","wp-parsely"):a.code===b.ParselySuggestionsApiOpenAiSchema?a.message=(0,m.__)("The Parse.ly API returned an incorrect response. Please try again later.","wp-parsely"):a.code===b.ParselySuggestionsApiAuthUnavailable&&(a.message=(0,m.__)("The Parse.ly API is currently unavailable. Please try again later.","wp-parsely")),a}return T(t,e),t.prototype.Message=function(e){return void 0===e&&(e=null),[b.PluginCredentialsNotSetMessageDetected,b.PluginSettingsSiteIdNotSet,b.PluginSettingsApiSecretNotSet].includes(this.code)?function(e){var t;return void 0===e&&(e=null),(0,w.jsx)(k,{className:null==e?void 0:e.className,testId:"empty-credentials-message",children:null!==(t=window.wpParselyEmptyCredentialsMessage)&&void 0!==t?t:(0,m.__)("Please ensure that the Site ID and API Secret given in the plugin's settings are correct.","wp-parsely")})}(e):(this.code===b.FetchError&&(this.hint=this.Hint((0,m.__)("This error can sometimes be caused by ad-blockers or browser tracking protections. Please add this site to any applicable allow lists and try again.","wp-parsely"))),this.code!==b.ParselyApiForbidden&&this.code!==b.ParselySuggestionsApiNoAuthentication||(this.hint=this.Hint((0,m.__)("Please ensure that the Site ID and API Secret given in the plugin's settings are correct.","wp-parsely"))),this.code===b.HttpRequestFailed&&(this.hint=this.Hint((0,m.__)("The Parse.ly API cannot be reached. Please verify that you are online.","wp-parsely"))),(0,w.jsx)(k,{className:null==e?void 0:e.className,testId:"error",children:"

".concat(this.message,"

").concat(this.hint?this.hint:"")}))},t.prototype.Hint=function(e){return'

'.concat((0,m.__)("Hint:","wp-parsely")," ").concat(e,"

")},t.prototype.createErrorSnackbar=function(){//.test(this.message)||(0,d.dispatch)("core/notices").createNotice("error",this.message,{type:"snackbar"})},t}(Error),j=function(e){var t=e.size,r=void 0===t?24:t,n=e.className,o=void 0===n?"wp-parsely-icon":n;return(0,w.jsxs)(v.SVG,{className:o,height:r,viewBox:"0 0 60 65",width:r,xmlns:"http://www.w3.org/2000/svg",children:[(0,w.jsx)(v.Path,{fill:"#5ba745",d:"M23.72,51.53c0-.18,0-.34-.06-.52a13.11,13.11,0,0,0-2.1-5.53A14.74,14.74,0,0,0,19.12,43c-.27-.21-.5-.11-.51.22l-.24,3.42c0,.33-.38.35-.49,0l-1.5-4.8a1.4,1.4,0,0,0-.77-.78,23.91,23.91,0,0,0-3.1-.84c-1.38-.24-3.39-.39-3.39-.39-.34,0-.45.21-.25.49l2.06,3.76c.2.27,0,.54-.29.33l-4.51-3.6a3.68,3.68,0,0,0-2.86-.48c-1,.16-2.44.46-2.44.46a.68.68,0,0,0-.39.25.73.73,0,0,0-.14.45S.41,43,.54,44a3.63,3.63,0,0,0,1.25,2.62L6.48,50c.28.2.09.49-.23.37l-4.18-.94c-.32-.12-.5,0-.4.37,0,0,.69,1.89,1.31,3.16a24,24,0,0,0,1.66,2.74,1.34,1.34,0,0,0,1,.52l5,.13c.33,0,.41.38.1.48L7.51,58c-.31.1-.34.35-.07.55a14.29,14.29,0,0,0,3.05,1.66,13.09,13.09,0,0,0,5.9.5,25.13,25.13,0,0,0,4.34-1,9.55,9.55,0,0,1-.08-1.2,9.32,9.32,0,0,1,3.07-6.91"}),(0,w.jsx)(v.Path,{fill:"#5ba745",d:"M59.7,41.53a.73.73,0,0,0-.14-.45.68.68,0,0,0-.39-.25s-1.43-.3-2.44-.46a3.64,3.64,0,0,0-2.86.48l-4.51,3.6c-.26.21-.49-.06-.29-.33l2.06-3.76c.2-.28.09-.49-.25-.49,0,0-2,.15-3.39.39a23.91,23.91,0,0,0-3.1.84,1.4,1.4,0,0,0-.77.78l-1.5,4.8c-.11.32-.48.3-.49,0l-.24-3.42c0-.33-.24-.43-.51-.22a14.74,14.74,0,0,0-2.44,2.47A13.11,13.11,0,0,0,36.34,51c0,.18,0,.34-.06.52a9.26,9.26,0,0,1,3,8.1,24.1,24.1,0,0,0,4.34,1,13.09,13.09,0,0,0,5.9-.5,14.29,14.29,0,0,0,3.05-1.66c.27-.2.24-.45-.07-.55l-3.22-1.17c-.31-.1-.23-.47.1-.48l5-.13a1.38,1.38,0,0,0,1-.52A24.6,24.6,0,0,0,57,52.92c.61-1.27,1.31-3.16,1.31-3.16.1-.33-.08-.49-.4-.37l-4.18.94c-.32.12-.51-.17-.23-.37l4.69-3.34A3.63,3.63,0,0,0,59.46,44c.13-1,.24-2.47.24-2.47"}),(0,w.jsx)(v.Path,{fill:"#5ba745",d:"M46.5,25.61c0-.53-.35-.72-.8-.43l-4.86,2.66c-.45.28-.56-.27-.23-.69l4.66-6.23a2,2,0,0,0,.28-1.68,36.51,36.51,0,0,0-2.19-4.89,34,34,0,0,0-2.81-3.94c-.33-.41-.74-.35-.91.16l-2.28,5.68c-.16.5-.6.48-.59-.05l.28-8.93a2.54,2.54,0,0,0-.66-1.64S35,4.27,33.88,3.27,30.78.69,30.78.69a1.29,1.29,0,0,0-1.54,0s-1.88,1.49-3.12,2.59-2.48,2.35-2.48,2.35A2.5,2.5,0,0,0,23,7.27l.27,8.93c0,.53-.41.55-.58.05l-2.29-5.69c-.17-.5-.57-.56-.91-.14a35.77,35.77,0,0,0-3,4.2,35.55,35.55,0,0,0-2,4.62,2,2,0,0,0,.27,1.67l4.67,6.24c.33.42.23,1-.22.69l-4.87-2.66c-.45-.29-.82-.1-.82.43a18.6,18.6,0,0,0,.83,5.07,20.16,20.16,0,0,0,5.37,7.77c3.19,3,5.93,7.8,7.45,11.08A9.6,9.6,0,0,1,30,49.09a9.31,9.31,0,0,1,2.86.45c1.52-3.28,4.26-8.11,7.44-11.09a20.46,20.46,0,0,0,5.09-7,19,19,0,0,0,1.11-5.82"}),(0,w.jsx)(v.Path,{fill:"#5ba745",d:"M36.12,58.44A6.12,6.12,0,1,1,30,52.32a6.11,6.11,0,0,1,6.12,6.12"})]})},C=window.wp.url,I=window.wp.apiFetch,O=r.n(I),R=function(){function e(){this.abortControllers=new Map}return e.prototype.cancelRequest=function(e){if(e)(t=this.abortControllers.get(e))&&(t.abort(),this.abortControllers.delete(e));else{var t,r=Array.from(this.abortControllers.keys()).pop();r&&(t=this.abortControllers.get(r))&&(t.abort(),this.abortControllers.delete(r))}},e.prototype.cancelAll=function(){this.abortControllers.forEach((function(e){return e.abort()})),this.abortControllers.clear()},e.prototype.getOrCreateController=function(e){if(e&&this.abortControllers.has(e))return{abortController:this.abortControllers.get(e),abortId:e};var t=null!=e?e:"auto-"+Date.now(),r=new AbortController;return this.abortControllers.set(t,r),{abortController:r,abortId:t}},e.prototype.fetch=function(e,t){return r=this,n=void 0,a=function(){var r,n,o,a,i,s;return function(e,t){var r,n,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function s(s){return function(l){return function(s){if(r)throw new TypeError("Generator is already executing.");for(;a&&(a=0,s[0]&&(i=0)),i;)try{if(r=1,n&&(o=2&s[0]?n.return:s[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,s[1])).done)return o;switch(n=0,o&&(s=[2&s[0],o.value]),s[0]){case 0:case 1:o=s;break;case 4:return i.label++,{value:s[1],done:!1};case 5:i.label++,n=s[1],s=[0];continue;case 7:s=i.ops.pop(),i.trys.pop();continue;default:if(!((o=(o=i.trys).length>0&&o[o.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]0&&o[o.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]0&&o[o.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]0?(0,m.sprintf)( +!function(){"use strict";var e={20:function(e,t,r){var n=r(609),o=Symbol.for("react.element"),a=Symbol.for("react.fragment"),i=Object.prototype.hasOwnProperty,s=n.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function c(e,t,r){var n,a={},c=null,u=null;for(n in void 0!==r&&(c=""+r),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(u=t.ref),t)i.call(t,n)&&!l.hasOwnProperty(n)&&(a[n]=t[n]);if(e&&e.defaultProps)for(n in t=e.defaultProps)void 0===a[n]&&(a[n]=t[n]);return{$$typeof:o,type:e,key:c,ref:u,props:a,_owner:s.current}}t.Fragment=a,t.jsx=c,t.jsxs=c},848:function(e,t,r){e.exports=r(20)},609:function(e){e.exports=window.React}},t={};function r(n){var o=t[n];if(void 0!==o)return o.exports;var a=t[n]={exports:{}};return e[n](a,a.exports,r),a.exports}r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,{a:t}),t},r.d=function(e,t){for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},function(){var e,t,n,o,a,i,s,l,c,u,p,d=window.wp.data,y=window.wp.hooks,h=window.wp.plugins,f=((0,d.dispatch)("core/block-editor"),(0,d.dispatch)("core/editor"),(0,d.dispatch)("core/edit-post")),w=r(848),v=window.wp.components,g=window.wp.editor;void 0!==window.wp&&(p=null!==(t=null===(e=window.wp.editor)||void 0===e?void 0:e.PluginDocumentSettingPanel)&&void 0!==t?t:null!==(o=null===(n=window.wp.editPost)||void 0===n?void 0:n.PluginDocumentSettingPanel)&&void 0!==o?o:null===(a=window.wp.editSite)||void 0===a?void 0:a.PluginDocumentSettingPanel,null!==(s=null===(i=window.wp.editor)||void 0===i?void 0:i.PluginSidebar)&&void 0!==s||null!==(c=null===(l=window.wp.editPost)||void 0===l?void 0:l.PluginSidebar)&&void 0!==c||null===(u=window.wp.editSite)||void 0===u||u.PluginSidebar);var _,b,P=window.wp.element,m=window.wp.i18n,x=window.wp.wordcount,E=window.wp.primitives,A=(0,w.jsx)(E.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,w.jsx)(E.Path,{d:"M19.5 4.5h-7V6h4.44l-5.97 5.97 1.06 1.06L18 7.06v4.44h1.5v-7Zm-13 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-3H17v3a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h3V5.5h-3Z"})}),S=function(){function e(){this._tkq=[],this.isLoaded=!1,this.isEnabled=!1,"undefined"!=typeof wpParselyTracksTelemetry&&(this.isEnabled=!0,this.loadTrackingLibrary())}return e.getInstance=function(){return window.wpParselyTelemetryInstance||Object.defineProperty(window,"wpParselyTelemetryInstance",{value:new e,writable:!1,configurable:!1,enumerable:!1}),window.wpParselyTelemetryInstance},e.prototype.loadTrackingLibrary=function(){var e=this,t=document.createElement("script");t.async=!0,t.src="//stats.wp.com/w.js",t.onload=function(){e.isLoaded=!0,e._tkq=window._tkq||[]},document.head.appendChild(t)},e.trackEvent=function(t){return r=this,n=arguments,a=function(t,r){var n;return void 0===r&&(r={}),function(e,t){var r,n,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function s(s){return function(l){return function(s){if(r)throw new TypeError("Generator is already executing.");for(;a&&(a=0,s[0]&&(i=0)),i;)try{if(r=1,n&&(o=2&s[0]?n.return:s[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,s[1])).done)return o;switch(n=0,o&&(s=[2&s[0],o.value]),s[0]){case 0:case 1:o=s;break;case 4:return i.label++,{value:s[1],done:!1};case 5:i.label++,n=s[1],s=[0];continue;case 7:s=i.ops.pop(),i.trys.pop();continue;default:if(!((o=(o=i.trys).length>0&&o[o.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]=1e4&&(clearInterval(a),r("Telemetry library not loaded"))}),100);else r("Telemetry not enabled")}))},e.prototype.trackEvent=function(t,r){var n;this.isLoaded?(0!==t.indexOf(e.TRACKS_PREFIX)&&(t=e.TRACKS_PREFIX+t),this.isEventNameValid(t)?(r=this.prepareProperties(r),null===(n=this._tkq)||void 0===n||n.push(["recordEvent",t,r])):console.error("Error tracking event: Invalid event name")):console.error("Error tracking event: Telemetry not loaded")},e.prototype.isTelemetryEnabled=function(){return this.isEnabled},e.prototype.isProprietyValid=function(t){return e.PROPERTY_REGEX.test(t)},e.prototype.isEventNameValid=function(t){return e.EVENT_NAME_REGEX.test(t)},e.prototype.prepareProperties=function(e){return(e=this.sanitizeProperties(e)).parsely_version=wpParselyTracksTelemetry.version,wpParselyTracksTelemetry.user&&(e._ut=wpParselyTracksTelemetry.user.type,e._ui=wpParselyTracksTelemetry.user.id),wpParselyTracksTelemetry.vipgo_env&&(e.vipgo_env=wpParselyTracksTelemetry.vipgo_env),this.sanitizeProperties(e)},e.prototype.sanitizeProperties=function(e){var t=this,r={};return Object.keys(e).forEach((function(n){t.isProprietyValid(n)&&(r[n]=e[n])})),r},e.TRACKS_PREFIX="wpparsely_",e.EVENT_NAME_REGEX=/^(([a-z0-9]+)_){2}([a-z0-9_]+)$/,e.PROPERTY_REGEX=/^[a-z_][a-z0-9_]*$/,e}(),k=(S.trackEvent,function(e){void 0===e&&(e=null);var t="";(null==e?void 0:e.children)&&(t=e.children);var r="content-helper-error-message";return(null==e?void 0:e.className)&&(r+=" "+e.className),(0,w.jsx)("div",{className:r,"data-testid":null==e?void 0:e.testId,dangerouslySetInnerHTML:{__html:t}})}),T=(_=function(e,t){return _=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])},_(e,t)},function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function __(){this.constructor=e}_(e,t),e.prototype=null===t?Object.create(t):(__.prototype=t.prototype,new __)});!function(e){e.AccessToFeatureDisabled="ch_access_to_feature_disabled",e.CannotFormulateApiQuery="ch_cannot_formulate_api_query",e.FetchError="fetch_error",e.HttpRequestFailed="http_request_failed",e.ParselyAborted="ch_parsely_aborted",e[e.ParselyApiForbidden=403]="ParselyApiForbidden",e.ParselyApiResponseContainsError="ch_response_contains_error",e.ParselyApiReturnedNoData="ch_parsely_api_returned_no_data",e.ParselyApiReturnedTooManyResults="ch_parsely_api_returned_too_many_results",e.PluginCredentialsNotSetMessageDetected="parsely_credentials_not_set_message_detected",e.PluginSettingsApiSecretNotSet="parsely_api_secret_not_set",e.PluginSettingsSiteIdNotSet="parsely_site_id_not_set",e.PostIsNotPublished="ch_post_not_published",e.UnknownError="ch_unknown_error",e.ParselySuggestionsApiAuthUnavailable="AUTH_UNAVAILABLE",e.ParselySuggestionsApiNoAuthentication="NO_AUTHENTICATION",e.ParselySuggestionsApiNoAuthorization="NO_AUTHORIZATION",e.ParselySuggestionsApiNoData="NO_DATA",e.ParselySuggestionsApiOpenAiError="OPENAI_ERROR",e.ParselySuggestionsApiOpenAiSchema="OPENAI_SCHEMA",e.ParselySuggestionsApiOpenAiUnavailable="OPENAI_UNAVAILABLE",e.ParselySuggestionsApiSchemaError="SCHEMA_ERROR"}(b||(b={}));var N=function(e){function t(r,n,o){void 0===o&&(o=(0,m.__)("Error: ","wp-parsely"));var a=this;r.startsWith(o)&&(o=""),(a=e.call(this,o+r)||this).hint=null,a.name=a.constructor.name,a.code=n;var i=[b.AccessToFeatureDisabled,b.ParselyApiForbidden,b.ParselyApiResponseContainsError,b.ParselyApiReturnedNoData,b.ParselyApiReturnedTooManyResults,b.PluginCredentialsNotSetMessageDetected,b.PluginSettingsApiSecretNotSet,b.PluginSettingsSiteIdNotSet,b.PostIsNotPublished,b.UnknownError,b.ParselySuggestionsApiAuthUnavailable,b.ParselySuggestionsApiNoAuthentication,b.ParselySuggestionsApiNoAuthorization,b.ParselySuggestionsApiNoData,b.ParselySuggestionsApiSchemaError];return a.retryFetch=!i.includes(a.code),Object.setPrototypeOf(a,t.prototype),a.code===b.AccessToFeatureDisabled?a.message=(0,m.__)("Access to this feature is disabled by the site's administration.","wp-parsely"):a.code===b.ParselySuggestionsApiNoAuthorization?a.message=(0,m.__)('This AI-powered feature is opt-in. To gain access, please submit a request here.',"wp-parsely"):a.code===b.ParselySuggestionsApiOpenAiError||a.code===b.ParselySuggestionsApiOpenAiUnavailable?a.message=(0,m.__)("The Parse.ly API returned an internal server error. Please retry with a different input, or try again later.","wp-parsely"):a.code===b.HttpRequestFailed&&a.message.includes("cURL error 28")?a.message=(0,m.__)("The Parse.ly API did not respond in a timely manner. Please try again later.","wp-parsely"):a.code===b.ParselySuggestionsApiSchemaError?a.message=(0,m.__)("The Parse.ly API returned a validation error. Please try again with different parameters.","wp-parsely"):a.code===b.ParselySuggestionsApiNoData?a.message=(0,m.__)("The Parse.ly API couldn't find any relevant data to fulfill the request. Please retry with a different input.","wp-parsely"):a.code===b.ParselySuggestionsApiOpenAiSchema?a.message=(0,m.__)("The Parse.ly API returned an incorrect response. Please try again later.","wp-parsely"):a.code===b.ParselySuggestionsApiAuthUnavailable&&(a.message=(0,m.__)("The Parse.ly API is currently unavailable. Please try again later.","wp-parsely")),a}return T(t,e),t.prototype.Message=function(e){return void 0===e&&(e=null),[b.PluginCredentialsNotSetMessageDetected,b.PluginSettingsSiteIdNotSet,b.PluginSettingsApiSecretNotSet].includes(this.code)?function(e){var t;return void 0===e&&(e=null),(0,w.jsx)(k,{className:null==e?void 0:e.className,testId:"empty-credentials-message",children:null!==(t=window.wpParselyEmptyCredentialsMessage)&&void 0!==t?t:(0,m.__)("Please ensure that the Site ID and API Secret given in the plugin's settings are correct.","wp-parsely")})}(e):(this.code===b.FetchError&&(this.hint=this.Hint((0,m.__)("This error can sometimes be caused by ad-blockers or browser tracking protections. Please add this site to any applicable allow lists and try again.","wp-parsely"))),this.code!==b.ParselyApiForbidden&&this.code!==b.ParselySuggestionsApiNoAuthentication||(this.hint=this.Hint((0,m.__)("Please ensure that the Site ID and API Secret given in the plugin's settings are correct.","wp-parsely"))),this.code===b.HttpRequestFailed&&(this.hint=this.Hint((0,m.__)("The Parse.ly API cannot be reached. Please verify that you are online.","wp-parsely"))),(0,w.jsx)(k,{className:null==e?void 0:e.className,testId:"error",children:"

".concat(this.message,"

").concat(this.hint?this.hint:"")}))},t.prototype.Hint=function(e){return'

'.concat((0,m.__)("Hint:","wp-parsely")," ").concat(e,"

")},t.prototype.createErrorSnackbar=function(){//.test(this.message)||(0,d.dispatch)("core/notices").createNotice("error",this.message,{type:"snackbar"})},t}(Error),j=function(e){var t=e.size,r=void 0===t?24:t,n=e.className,o=void 0===n?"wp-parsely-icon":n;return(0,w.jsxs)(v.SVG,{className:o,height:r,viewBox:"0 0 60 65",width:r,xmlns:"http://www.w3.org/2000/svg",children:[(0,w.jsx)(v.Path,{fill:"#5ba745",d:"M23.72,51.53c0-.18,0-.34-.06-.52a13.11,13.11,0,0,0-2.1-5.53A14.74,14.74,0,0,0,19.12,43c-.27-.21-.5-.11-.51.22l-.24,3.42c0,.33-.38.35-.49,0l-1.5-4.8a1.4,1.4,0,0,0-.77-.78,23.91,23.91,0,0,0-3.1-.84c-1.38-.24-3.39-.39-3.39-.39-.34,0-.45.21-.25.49l2.06,3.76c.2.27,0,.54-.29.33l-4.51-3.6a3.68,3.68,0,0,0-2.86-.48c-1,.16-2.44.46-2.44.46a.68.68,0,0,0-.39.25.73.73,0,0,0-.14.45S.41,43,.54,44a3.63,3.63,0,0,0,1.25,2.62L6.48,50c.28.2.09.49-.23.37l-4.18-.94c-.32-.12-.5,0-.4.37,0,0,.69,1.89,1.31,3.16a24,24,0,0,0,1.66,2.74,1.34,1.34,0,0,0,1,.52l5,.13c.33,0,.41.38.1.48L7.51,58c-.31.1-.34.35-.07.55a14.29,14.29,0,0,0,3.05,1.66,13.09,13.09,0,0,0,5.9.5,25.13,25.13,0,0,0,4.34-1,9.55,9.55,0,0,1-.08-1.2,9.32,9.32,0,0,1,3.07-6.91"}),(0,w.jsx)(v.Path,{fill:"#5ba745",d:"M59.7,41.53a.73.73,0,0,0-.14-.45.68.68,0,0,0-.39-.25s-1.43-.3-2.44-.46a3.64,3.64,0,0,0-2.86.48l-4.51,3.6c-.26.21-.49-.06-.29-.33l2.06-3.76c.2-.28.09-.49-.25-.49,0,0-2,.15-3.39.39a23.91,23.91,0,0,0-3.1.84,1.4,1.4,0,0,0-.77.78l-1.5,4.8c-.11.32-.48.3-.49,0l-.24-3.42c0-.33-.24-.43-.51-.22a14.74,14.74,0,0,0-2.44,2.47A13.11,13.11,0,0,0,36.34,51c0,.18,0,.34-.06.52a9.26,9.26,0,0,1,3,8.1,24.1,24.1,0,0,0,4.34,1,13.09,13.09,0,0,0,5.9-.5,14.29,14.29,0,0,0,3.05-1.66c.27-.2.24-.45-.07-.55l-3.22-1.17c-.31-.1-.23-.47.1-.48l5-.13a1.38,1.38,0,0,0,1-.52A24.6,24.6,0,0,0,57,52.92c.61-1.27,1.31-3.16,1.31-3.16.1-.33-.08-.49-.4-.37l-4.18.94c-.32.12-.51-.17-.23-.37l4.69-3.34A3.63,3.63,0,0,0,59.46,44c.13-1,.24-2.47.24-2.47"}),(0,w.jsx)(v.Path,{fill:"#5ba745",d:"M46.5,25.61c0-.53-.35-.72-.8-.43l-4.86,2.66c-.45.28-.56-.27-.23-.69l4.66-6.23a2,2,0,0,0,.28-1.68,36.51,36.51,0,0,0-2.19-4.89,34,34,0,0,0-2.81-3.94c-.33-.41-.74-.35-.91.16l-2.28,5.68c-.16.5-.6.48-.59-.05l.28-8.93a2.54,2.54,0,0,0-.66-1.64S35,4.27,33.88,3.27,30.78.69,30.78.69a1.29,1.29,0,0,0-1.54,0s-1.88,1.49-3.12,2.59-2.48,2.35-2.48,2.35A2.5,2.5,0,0,0,23,7.27l.27,8.93c0,.53-.41.55-.58.05l-2.29-5.69c-.17-.5-.57-.56-.91-.14a35.77,35.77,0,0,0-3,4.2,35.55,35.55,0,0,0-2,4.62,2,2,0,0,0,.27,1.67l4.67,6.24c.33.42.23,1-.22.69l-4.87-2.66c-.45-.29-.82-.1-.82.43a18.6,18.6,0,0,0,.83,5.07,20.16,20.16,0,0,0,5.37,7.77c3.19,3,5.93,7.8,7.45,11.08A9.6,9.6,0,0,1,30,49.09a9.31,9.31,0,0,1,2.86.45c1.52-3.28,4.26-8.11,7.44-11.09a20.46,20.46,0,0,0,5.09-7,19,19,0,0,0,1.11-5.82"}),(0,w.jsx)(v.Path,{fill:"#5ba745",d:"M36.12,58.44A6.12,6.12,0,1,1,30,52.32a6.11,6.11,0,0,1,6.12,6.12"})]})},C=window.wp.url,I=window.wp.apiFetch,O=r.n(I),R=function(){function e(){this.abortControllers=new Map}return e.prototype.cancelRequest=function(e){if(e)(t=this.abortControllers.get(e))&&(t.abort(),this.abortControllers.delete(e));else{var t,r=Array.from(this.abortControllers.keys()).pop();r&&(t=this.abortControllers.get(r))&&(t.abort(),this.abortControllers.delete(r))}},e.prototype.cancelAll=function(){this.abortControllers.forEach((function(e){return e.abort()})),this.abortControllers.clear()},e.prototype.getOrCreateController=function(e){if(e&&this.abortControllers.has(e))return{abortController:this.abortControllers.get(e),abortId:e};var t=null!=e?e:"auto-"+Date.now(),r=new AbortController;return this.abortControllers.set(t,r),{abortController:r,abortId:t}},e.prototype.fetch=function(e,t){return r=this,n=void 0,a=function(){var r,n,o,a,i,s;return function(e,t){var r,n,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function s(s){return function(l){return function(s){if(r)throw new TypeError("Generator is already executing.");for(;a&&(a=0,s[0]&&(i=0)),i;)try{if(r=1,n&&(o=2&s[0]?n.return:s[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,s[1])).done)return o;switch(n=0,o&&(s=[2&s[0],o.value]),s[0]){case 0:case 1:o=s;break;case 4:return i.label++,{value:s[1],done:!1};case 5:i.label++,n=s[1],s=[0];continue;case 7:s=i.ops.pop(),i.trys.pop();continue;default:if(!((o=(o=i.trys).length>0&&o[o.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]0&&o[o.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]0&&o[o.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]0?(0,m.sprintf)( // Translators: %1$s the number of words in the excerpt. // Translators: %1$s the number of words in the excerpt. (0,m._n)("%1$s word","%1$s words",e,"wp-parsely"),e):"")}),[h.currentExcerpt,k]),(0,P.useEffect)((function(){var e=document.querySelector(".editor-post-excerpt textarea");e&&(e.scrollTop=0)}),[h.newExcerptGeneratedCount]),(0,w.jsxs)("div",{className:"editor-post-excerpt",children:[(0,w.jsxs)("div",{style:{position:"relative"},children:[t&&(0,w.jsx)("div",{className:"editor-post-excerpt__loading_animation",children:(0,w.jsx)(H,{})}),(0,w.jsx)(v.TextareaControl,{__nextHasNoMarginBottom:!0,label:(0,m.__)("Write an excerpt (optional)","wp-parsely"),className:"editor-post-excerpt__textarea",onChange:function(e){h.isUnderReview||_({excerpt:e}),f(F(F({},h),{currentExcerpt:e})),l(!0)},onKeyUp:function(){var e;if(s)l(!1);else{var t=document.querySelector(".editor-post-excerpt textarea"),r=null!==(e=null==t?void 0:t.textContent)&&void 0!==e?e:"";f(F(F({},h),{currentExcerpt:r}))}},value:t?"":h.isUnderReview?h.currentExcerpt:k,help:u||null})]}),(0,w.jsxs)(v.Button,{href:(0,m.__)("https://wordpress.org/documentation/article/page-post-settings-sidebar/#excerpt","wp-parsely"),target:"_blank",variant:"link",children:[(0,m.__)("Learn more about manual excerpts","wp-parsely"),(0,w.jsx)(v.Icon,{icon:A,size:18,className:"parsely-external-link-icon"})]}),(0,w.jsxs)("div",{className:"wp-parsely-excerpt-generator",children:[(0,w.jsxs)("div",{className:"wp-parsely-excerpt-generator-header",children:[(0,w.jsx)(j,{size:16}),(0,w.jsxs)("div",{className:"wp-parsely-excerpt-generator-header-label",children:[(0,m.__)("Generate With Parse.ly","wp-parsely"),(0,w.jsx)("span",{className:"beta-label",children:(0,m.__)("Beta","wp-parsely")})]})]}),o&&(0,w.jsx)(v.Notice,{className:"wp-parsely-excerpt-generator-error",onRemove:function(){return a(void 0)},status:"info",children:o.Message()}),(0,w.jsx)("div",{className:"wp-parsely-excerpt-generator-controls",children:h.isUnderReview?(0,w.jsxs)(w.Fragment,{children:[(0,w.jsx)(v.Button,{variant:"secondary",onClick:function(){return L(void 0,void 0,void 0,(function(){return M(this,(function(e){switch(e.label){case 0:return[4,_({excerpt:h.currentExcerpt})];case 1:return e.sent(),f(F(F({},h),{isUnderReview:!1})),S.trackEvent("excerpt_generator_accepted"),[2]}}))}))},children:(0,m.__)("Accept","wp-parsely")}),(0,w.jsx)(v.Button,{isDestructive:!0,variant:"secondary",onClick:function(){return L(void 0,void 0,void 0,(function(){return M(this,(function(e){return _({excerpt:h.oldExcerpt}),f(F(F({},h),{currentExcerpt:h.oldExcerpt,isUnderReview:!1})),S.trackEvent("excerpt_generator_discarded"),[2]}))}))},children:(0,m.__)("Discard","wp-parsely")})]}):(0,w.jsxs)(v.Button,{onClick:function(){return L(void 0,void 0,void 0,(function(){var e,t;return M(this,(function(n){switch(n.label){case 0:r(!0),a(void 0),n.label=1;case 1:return n.trys.push([1,3,4,5]),S.trackEvent("excerpt_generator_pressed"),[4,D.getInstance().generateExcerpt(C,T)];case 2:return e=n.sent(),f({currentExcerpt:e,isUnderReview:!0,newExcerptGeneratedCount:h.newExcerptGeneratedCount+1,oldExcerpt:k}),[3,5];case 3:return(t=n.sent())instanceof N?a(t):(a(new N((0,m.__)("An unknown error occurred.","wp-parsely"),b.UnknownError)),console.error(t)),[3,5];case 4:return r(!1),[7];case 5:return[2]}}))}))},variant:"primary",isBusy:t,disabled:t||!T,children:[t&&(0,m.__)("Generating Excerpt…","wp-parsely"),!t&&h.newExcerptGeneratedCount>0&&(0,m.__)("Regenerate Excerpt","wp-parsely"),!t&&0===h.newExcerptGeneratedCount&&(0,m.__)("Generate Excerpt","wp-parsely")]})}),(0,w.jsxs)(v.Button,{href:"https://docs.parse.ly/plugin-content-helper/#h-excerpt-generator-beta",target:"_blank",variant:"link",children:[(0,m.__)("Learn more about Parse.ly AI","wp-parsely"),(0,w.jsx)(v.Icon,{icon:A,size:18,className:"parsely-external-link-icon"})]})]})]})},H=function(){return(0,w.jsx)(v.Animate,{type:"loading",children:function(e){var t=e.className;return(0,w.jsx)("span",{className:t,children:(0,m.__)("Generating…","wp-parsely")})}})},q=function(){return(0,w.jsx)(g.PostTypeSupportCheck,{supportKeys:"excerpt",children:(0,w.jsx)(p,{name:"parsely-post-excerpt",title:(0,m.__)("Excerpt","wp-parsely"),children:(0,w.jsx)(G,{})})})};(0,y.addFilter)("plugins.registerPlugin","wp-parsely-excerpt-generator",(function(e,t){var r,n,o;return"wp-parsely-block-editor-sidebar"!==t||((null===(r=null===window||void 0===window?void 0:window.Jetpack_Editor_Initial_State)||void 0===r?void 0:r.available_blocks["ai-content-lens"])&&(console.log("Parse.ly: Jetpack AI is enabled and will be disabled."),(0,y.removeFilter)("blocks.registerBlockType","jetpack/ai-content-lens-features")),(0,h.registerPlugin)("wp-parsely-excerpt-generator",{render:q}),(null===(n=(0,d.dispatch)("core/editor"))||void 0===n?void 0:n.removeEditorPanel)?null===(o=(0,d.dispatch)("core/editor"))||void 0===o||o.removeEditorPanel("post-excerpt"):null==f||f.removeEditorPanel("post-excerpt")),e}),1e3)}()}(); \ No newline at end of file diff --git a/src/content-helper/editor-sidebar/smart-linking/provider.ts b/src/content-helper/editor-sidebar/smart-linking/provider.ts index 66b3215d4..4e60e8edf 100644 --- a/src/content-helper/editor-sidebar/smart-linking/provider.ts +++ b/src/content-helper/editor-sidebar/smart-linking/provider.ts @@ -145,7 +145,7 @@ export class SmartLinkingProvider extends BaseProvider { } ), data: { url_exclusion_list: urlExclusionList, - content, + text: content, }, } ); diff --git a/src/content-helper/editor-sidebar/title-suggestions/provider.ts b/src/content-helper/editor-sidebar/title-suggestions/provider.ts index a5fb0d4a1..9b85f4767 100644 --- a/src/content-helper/editor-sidebar/title-suggestions/provider.ts +++ b/src/content-helper/editor-sidebar/title-suggestions/provider.ts @@ -58,7 +58,7 @@ export class TitleSuggestionsProvider extends BaseProvider { persona: getPersonaLabel( persona ), } ), data: { - content, + text: content, }, } ); diff --git a/src/content-helper/excerpt-generator/provider.ts b/src/content-helper/excerpt-generator/provider.ts index 9716dcd87..2a5ebaf83 100644 --- a/src/content-helper/excerpt-generator/provider.ts +++ b/src/content-helper/excerpt-generator/provider.ts @@ -55,7 +55,7 @@ export class ExcerptGeneratorProvider extends BaseProvider { title, } ), data: { - content, + text: content, }, } ); } diff --git a/src/rest-api/content-helper/class-endpoint-excerpt-generator.php b/src/rest-api/content-helper/class-endpoint-excerpt-generator.php index d2ee59424..1adb8d544 100644 --- a/src/rest-api/content-helper/class-endpoint-excerpt-generator.php +++ b/src/rest-api/content-helper/class-endpoint-excerpt-generator.php @@ -85,7 +85,7 @@ public function register_routes(): void { array( 'POST' ), array( $this, 'generate_excerpt' ), array( - 'content' => array( + 'text' => array( 'description' => __( 'The text to generate the excerpt from.', 'wp-parsely' ), 'type' => 'string', 'required' => true, @@ -127,7 +127,7 @@ public function generate_excerpt( WP_REST_Request $request ) { * * @var string $post_content */ - $post_content = $request->get_param( 'content' ); + $post_content = $request->get_param( 'text' ); /** * The post title to be sent to the API. diff --git a/src/rest-api/content-helper/class-endpoint-smart-linking.php b/src/rest-api/content-helper/class-endpoint-smart-linking.php index ab1a2f14b..fe37e324f 100644 --- a/src/rest-api/content-helper/class-endpoint-smart-linking.php +++ b/src/rest-api/content-helper/class-endpoint-smart-linking.php @@ -87,7 +87,7 @@ public function register_routes(): void { array( 'POST' ), array( $this, 'generate_smart_links' ), array( - 'content' => array( + 'text' => array( 'required' => true, 'type' => 'string', 'description' => __( 'The text to generate smart links for.', 'wp-parsely' ), @@ -229,7 +229,7 @@ public function generate_smart_links( WP_REST_Request $request ) { * * @var string $post_content */ - $post_content = $request->get_param( 'content' ); + $post_content = $request->get_param( 'text' ); /** * The maximum number of smart links to generate. diff --git a/src/rest-api/content-helper/class-endpoint-title-suggestions.php b/src/rest-api/content-helper/class-endpoint-title-suggestions.php index 8b81fc958..df5717bba 100644 --- a/src/rest-api/content-helper/class-endpoint-title-suggestions.php +++ b/src/rest-api/content-helper/class-endpoint-title-suggestions.php @@ -85,7 +85,7 @@ public function register_routes(): void { array( 'POST' ), array( $this, 'generate_titles' ), array( - 'content' => array( + 'text' => array( 'description' => __( 'The content for which to generate titles.', 'wp-parsely' ), 'required' => true, 'type' => 'string', @@ -128,7 +128,7 @@ public function generate_titles( WP_REST_Request $request ) { * * @var string $post_content */ - $post_content = $request->get_param( 'content' ); + $post_content = $request->get_param( 'text' ); /** * The maximum number of titles to generate. diff --git a/tests/Integration/RestAPI/ContentHelper/EndpointExcerptGeneratorTest.php b/tests/Integration/RestAPI/ContentHelper/EndpointExcerptGeneratorTest.php index 7d38eedc1..c959a8e2d 100644 --- a/tests/Integration/RestAPI/ContentHelper/EndpointExcerptGeneratorTest.php +++ b/tests/Integration/RestAPI/ContentHelper/EndpointExcerptGeneratorTest.php @@ -132,7 +132,7 @@ public function test_generate_excerpt_returns_valid_response(): void { // Create a mock request. $request = new WP_REST_Request( 'POST', '/excerpt-generator/generate' ); - $request->set_param( 'content', 'Test content' ); + $request->set_param( 'text', 'Test content' ); $request->set_param( 'title', 'Test title' ); $request->set_param( 'persona', 'journalist' ); $request->set_param( 'style', 'neutral' ); @@ -178,7 +178,7 @@ public function test_generate_excerpt_returns_error_on_failure(): void { // Create a mock request. $request = new WP_REST_Request( 'POST', '/excerpt-generator/generate' ); - $request->set_param( 'content', 'Test content' ); + $request->set_param( 'text', 'Test content' ); $request->set_param( 'title', 'Test title' ); $request->set_param( 'persona', 'journalist' ); $request->set_param( 'style', 'neutral' ); diff --git a/tests/Integration/RestAPI/ContentHelper/EndpointSmartLinkingTest.php b/tests/Integration/RestAPI/ContentHelper/EndpointSmartLinkingTest.php index 3c52d72ed..8389bd7c0 100644 --- a/tests/Integration/RestAPI/ContentHelper/EndpointSmartLinkingTest.php +++ b/tests/Integration/RestAPI/ContentHelper/EndpointSmartLinkingTest.php @@ -148,7 +148,7 @@ public function test_generate_smart_links_returns_valid_response(): void { // Create a mock request. $request = new WP_REST_Request( 'POST', '/smart-linking/generate' ); - $request->set_param( 'content', 'Test content' ); + $request->set_param( 'text', 'Test content' ); $request->set_param( 'max_links', 2 ); $request->set_param( 'url_exclusion_list', array( 'http://excluded.com' ) ); @@ -193,7 +193,7 @@ public function test_generate_smart_links_returns_error_on_failure(): void { // Create a mock request. $request = new WP_REST_Request( 'POST', '/smart-linking/generate' ); - $request->set_param( 'content', 'Test content' ); + $request->set_param( 'text', 'Test content' ); $request->set_param( 'max_links', 2 ); $request->set_param( 'url_exclusion_list', array( 'http://excluded.com' ) ); diff --git a/tests/Integration/RestAPI/ContentHelper/EndpointTitleSuggestionsTest.php b/tests/Integration/RestAPI/ContentHelper/EndpointTitleSuggestionsTest.php index a9c96e8fa..a54e9391b 100644 --- a/tests/Integration/RestAPI/ContentHelper/EndpointTitleSuggestionsTest.php +++ b/tests/Integration/RestAPI/ContentHelper/EndpointTitleSuggestionsTest.php @@ -131,7 +131,7 @@ public function test_generate_titles_returns_valid_response(): void { // Create a mock request. $request = new WP_REST_Request( 'POST', '/title-suggestions/generate' ); - $request->set_param( 'content', 'Test content' ); + $request->set_param( 'text', 'Test content' ); $request->set_param( 'limit', 3 ); $request->set_param( 'style', 'neutral' ); $request->set_param( 'persona', 'journalist' ); @@ -179,7 +179,7 @@ public function test_generate_titles_returns_error_on_failure(): void { // Create a mock request. $request = new WP_REST_Request( 'POST', '/title-suggestions/generate' ); - $request->set_param( 'content', 'Test content' ); + $request->set_param( 'text', 'Test content' ); $request->set_param( 'limit', 3 ); $request->set_param( 'style', 'neutral' ); $request->set_param( 'persona', 'journalist' ); From cafdfed5a1107fd779d991106cad5c2cec4ce655 Mon Sep 17 00:00:00 2001 From: Alex Cicovic <23142906+acicovic@users.noreply.github.com> Date: Wed, 21 Aug 2024 12:46:15 +0300 Subject: [PATCH 051/282] Add Playwright packages and base config --- package-lock.json | 211 +++++++++++++++++++--------------- package.json | 4 + test/e2e/playwright.config.ts | 16 +++ 3 files changed, 139 insertions(+), 92 deletions(-) create mode 100644 test/e2e/playwright.config.ts diff --git a/package-lock.json b/package-lock.json index 5ce12a36e..8c302d45c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "lodash.debounce": "^4.0.8" }, "devDependencies": { + "@playwright/test": "^1.46.1", "@testing-library/jest-dom": "^6.4.8", "@testing-library/react": "^16.0.0", "@types/jest": "^29.5.12", @@ -35,6 +36,7 @@ "@wordpress/core-data": "^7.5.0", "@wordpress/data": "^10.5.0", "@wordpress/e2e-test-utils": "^11.5.0", + "@wordpress/e2e-test-utils-playwright": "^1.5.0", "@wordpress/edit-post": "^8.5.0", "@wordpress/editor": "^14.5.0", "@wordpress/element": "^6.5.0", @@ -4072,20 +4074,19 @@ } }, "node_modules/@playwright/test": { - "version": "1.44.1", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.44.1.tgz", - "integrity": "sha512-1hZ4TNvD5z9VuhNJ/walIjvMVvYkZKf71axoF/uiAqpntQJXpG64dlXhoDXE3OczPuTuvjf/M5KWFg5VAVUS3Q==", + "version": "1.46.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.46.1.tgz", + "integrity": "sha512-Fq6SwLujA/DOIvNC2EL/SojJnkKf/rAwJ//APpJJHRyMi1PdKrY3Az+4XNQ51N4RTbItbIByQ0jgd1tayq1aeA==", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { - "playwright": "1.44.1" + "playwright": "1.46.1" }, "bin": { "playwright": "cli.js" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/@pmmmwh/react-refresh-webpack-plugin": { @@ -10554,92 +10555,27 @@ } }, "node_modules/@wordpress/e2e-test-utils-playwright": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/@wordpress/e2e-test-utils-playwright/-/e2e-test-utils-playwright-0.26.0.tgz", - "integrity": "sha512-4KFyQ3IsYIJaIvOQ1qhAHhRISs9abNToF/bktfMNxQiEJsmbNn7lq/IbaY+shqwdBWVg8TQtLcL4MpSl0ISaxQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@wordpress/e2e-test-utils-playwright/-/e2e-test-utils-playwright-1.5.0.tgz", + "integrity": "sha512-gQuhdDMejum7a4hWW4ejIWSBv1xeeCFda5o7eq766evarU+HwcN+4GPiSYKj2iEHJ4dge1On2VXeg1RFLY3w5Q==", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { - "@wordpress/api-fetch": "^6.55.0", - "@wordpress/keycodes": "^3.58.0", - "@wordpress/url": "^3.59.0", "change-case": "^4.1.2", "form-data": "^4.0.0", "get-port": "^5.1.1", "lighthouse": "^10.4.0", "mime": "^3.0.0", - "web-vitals": "^3.5.0" + "web-vitals": "^4.2.1" }, "engines": { - "node": ">=12" + "node": ">=18.12.0", + "npm": ">=8.19.2" }, "peerDependencies": { "@playwright/test": ">=1" } }, - "node_modules/@wordpress/e2e-test-utils-playwright/node_modules/@wordpress/api-fetch": { - "version": "6.55.0", - "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-6.55.0.tgz", - "integrity": "sha512-1HrCUsJdeRY5Y0IjplotINwqMRO81e7O7VhBScuKk7iOuDm/E1ioKv2uLGnPNWziYu+Zf025byxOqVzXDyM2gw==", - "dev": true, - "license": "GPL-2.0-or-later", - "dependencies": { - "@babel/runtime": "^7.16.0", - "@wordpress/i18n": "^4.58.0", - "@wordpress/url": "^3.59.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@wordpress/e2e-test-utils-playwright/node_modules/@wordpress/hooks": { - "version": "3.58.0", - "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-3.58.0.tgz", - "integrity": "sha512-9LB0ZHnZRQlORttux9t/xbAskF+dk2ujqzPGsVzc92mSKpQP3K2a5Wy74fUnInguB1vLUNHT6nrNdkVom5qX1Q==", - "dev": true, - "license": "GPL-2.0-or-later", - "dependencies": { - "@babel/runtime": "^7.16.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@wordpress/e2e-test-utils-playwright/node_modules/@wordpress/i18n": { - "version": "4.58.0", - "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-4.58.0.tgz", - "integrity": "sha512-VfvS3BWv/RDjRKD6PscIcvYfWKnGJcI/DEqyDgUMhxCM6NRwoL478CsUKTiGJIymeyRodNRfprdcF086DpGKYw==", - "dev": true, - "license": "GPL-2.0-or-later", - "dependencies": { - "@babel/runtime": "^7.16.0", - "@wordpress/hooks": "^3.58.0", - "gettext-parser": "^1.3.1", - "memize": "^2.1.0", - "sprintf-js": "^1.1.1", - "tannin": "^1.2.0" - }, - "bin": { - "pot-to-php": "tools/pot-to-php.js" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@wordpress/e2e-test-utils-playwright/node_modules/@wordpress/url": { - "version": "3.59.0", - "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-3.59.0.tgz", - "integrity": "sha512-GxvoMjYCav0w4CiX0i0h3qflrE/9rhLIZg5aPCQjbrBdwTxYR3Exfw0IJYcmVaTKXQOUU8fOxlDxULsbLmKe9w==", - "dev": true, - "license": "GPL-2.0-or-later", - "dependencies": { - "@babel/runtime": "^7.16.0", - "remove-accents": "^0.5.0" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/@wordpress/e2e-test-utils/node_modules/@wordpress/keycodes": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/@wordpress/keycodes/-/keycodes-4.5.0.tgz", @@ -11984,6 +11920,45 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@wordpress/scripts/node_modules/@wordpress/api-fetch": { + "version": "6.55.0", + "resolved": "https://registry.npmjs.org/@wordpress/api-fetch/-/api-fetch-6.55.0.tgz", + "integrity": "sha512-1HrCUsJdeRY5Y0IjplotINwqMRO81e7O7VhBScuKk7iOuDm/E1ioKv2uLGnPNWziYu+Zf025byxOqVzXDyM2gw==", + "dev": true, + "license": "GPL-2.0-or-later", + "dependencies": { + "@babel/runtime": "^7.16.0", + "@wordpress/i18n": "^4.58.0", + "@wordpress/url": "^3.59.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@wordpress/scripts/node_modules/@wordpress/e2e-test-utils-playwright": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/@wordpress/e2e-test-utils-playwright/-/e2e-test-utils-playwright-0.26.0.tgz", + "integrity": "sha512-4KFyQ3IsYIJaIvOQ1qhAHhRISs9abNToF/bktfMNxQiEJsmbNn7lq/IbaY+shqwdBWVg8TQtLcL4MpSl0ISaxQ==", + "dev": true, + "license": "GPL-2.0-or-later", + "dependencies": { + "@wordpress/api-fetch": "^6.55.0", + "@wordpress/keycodes": "^3.58.0", + "@wordpress/url": "^3.59.0", + "change-case": "^4.1.2", + "form-data": "^4.0.0", + "get-port": "^5.1.1", + "lighthouse": "^10.4.0", + "mime": "^3.0.0", + "web-vitals": "^3.5.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "@playwright/test": ">=1" + } + }, "node_modules/@wordpress/scripts/node_modules/@wordpress/eslint-plugin": { "version": "18.1.0", "resolved": "https://registry.npmjs.org/@wordpress/eslint-plugin/-/eslint-plugin-18.1.0.tgz", @@ -12028,6 +12003,40 @@ } } }, + "node_modules/@wordpress/scripts/node_modules/@wordpress/hooks": { + "version": "3.58.0", + "resolved": "https://registry.npmjs.org/@wordpress/hooks/-/hooks-3.58.0.tgz", + "integrity": "sha512-9LB0ZHnZRQlORttux9t/xbAskF+dk2ujqzPGsVzc92mSKpQP3K2a5Wy74fUnInguB1vLUNHT6nrNdkVom5qX1Q==", + "dev": true, + "license": "GPL-2.0-or-later", + "dependencies": { + "@babel/runtime": "^7.16.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@wordpress/scripts/node_modules/@wordpress/i18n": { + "version": "4.58.0", + "resolved": "https://registry.npmjs.org/@wordpress/i18n/-/i18n-4.58.0.tgz", + "integrity": "sha512-VfvS3BWv/RDjRKD6PscIcvYfWKnGJcI/DEqyDgUMhxCM6NRwoL478CsUKTiGJIymeyRodNRfprdcF086DpGKYw==", + "dev": true, + "license": "GPL-2.0-or-later", + "dependencies": { + "@babel/runtime": "^7.16.0", + "@wordpress/hooks": "^3.58.0", + "gettext-parser": "^1.3.1", + "memize": "^2.1.0", + "sprintf-js": "^1.1.1", + "tannin": "^1.2.0" + }, + "bin": { + "pot-to-php": "tools/pot-to-php.js" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@wordpress/scripts/node_modules/@wordpress/prettier-config": { "version": "3.15.0", "resolved": "https://registry.npmjs.org/@wordpress/prettier-config/-/prettier-config-3.15.0.tgz", @@ -12041,6 +12050,20 @@ "prettier": ">=3" } }, + "node_modules/@wordpress/scripts/node_modules/@wordpress/url": { + "version": "3.59.0", + "resolved": "https://registry.npmjs.org/@wordpress/url/-/url-3.59.0.tgz", + "integrity": "sha512-GxvoMjYCav0w4CiX0i0h3qflrE/9rhLIZg5aPCQjbrBdwTxYR3Exfw0IJYcmVaTKXQOUU8fOxlDxULsbLmKe9w==", + "dev": true, + "license": "GPL-2.0-or-later", + "dependencies": { + "@babel/runtime": "^7.16.0", + "remove-accents": "^0.5.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@wordpress/scripts/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -12335,6 +12358,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@wordpress/scripts/node_modules/web-vitals": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-3.5.2.tgz", + "integrity": "sha512-c0rhqNcHXRkY/ogGDJQxZ9Im9D19hDihbzSQJrsioex+KnFgmMzBiy57Z1EjkhX/+OjyBpclDCzz2ITtjokFmg==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/@wordpress/scripts/node_modules/ws": { "version": "8.5.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", @@ -26540,37 +26570,35 @@ } }, "node_modules/playwright": { - "version": "1.44.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.44.1.tgz", - "integrity": "sha512-qr/0UJ5CFAtloI3avF95Y0L1xQo6r3LQArLIg/z/PoGJ6xa+EwzrwO5lpNr/09STxdHuUoP2mvuELJS+hLdtgg==", + "version": "1.46.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.46.1.tgz", + "integrity": "sha512-oPcr1yqoXLCkgKtD5eNUPLiN40rYEM39odNpIb6VE6S7/15gJmA1NzVv6zJYusV0e7tzvkU/utBFNa/Kpxmwng==", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { - "playwright-core": "1.44.1" + "playwright-core": "1.46.1" }, "bin": { "playwright": "cli.js" }, "engines": { - "node": ">=16" + "node": ">=18" }, "optionalDependencies": { "fsevents": "2.3.2" } }, "node_modules/playwright-core": { - "version": "1.44.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.44.1.tgz", - "integrity": "sha512-wh0JWtYTrhv1+OSsLPgFzGzt67Y7BE/ZS3jEqgGBlp2ppp1ZDj8c+9IARNW4dwf1poq5MgHreEM2KV/GuR4cFA==", + "version": "1.46.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.46.1.tgz", + "integrity": "sha512-h9LqIQaAv+CYvWzsZ+h3RsrqCStkBHlgo6/TJlFst3cOTlLghBQlJwPOZKQJTKNaD3QIB7aAVQ+gfWbN3NXB7A==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "playwright-core": "cli.js" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/playwright/node_modules/fsevents": { @@ -26584,7 +26612,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } @@ -31752,9 +31779,9 @@ } }, "node_modules/web-vitals": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-3.5.2.tgz", - "integrity": "sha512-c0rhqNcHXRkY/ogGDJQxZ9Im9D19hDihbzSQJrsioex+KnFgmMzBiy57Z1EjkhX/+OjyBpclDCzz2ITtjokFmg==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-4.2.3.tgz", + "integrity": "sha512-/CFAm1mNxSmOj6i0Co+iGFJ58OS4NRGVP+AWS/l509uIK5a1bSoIVaHz/ZumpHTfHSZBpgrJ+wjfpAOrTHok5Q==", "dev": true, "license": "Apache-2.0" }, diff --git a/package.json b/package.json index 231ce40b1..947648607 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "lodash.debounce": "^4.0.8" }, "devDependencies": { + "@playwright/test": "^1.46.1", "@testing-library/jest-dom": "^6.4.8", "@testing-library/react": "^16.0.0", "@types/jest": "^29.5.12", @@ -63,6 +64,7 @@ "@wordpress/core-data": "^7.5.0", "@wordpress/data": "^10.5.0", "@wordpress/e2e-test-utils": "^11.5.0", + "@wordpress/e2e-test-utils-playwright": "^1.5.0", "@wordpress/edit-post": "^8.5.0", "@wordpress/editor": "^14.5.0", "@wordpress/element": "^6.5.0", @@ -101,7 +103,9 @@ "start": "wp-scripts start", "test": "npm run test:unit", "test:e2e": "wp-scripts test-e2e", + "test:e2e:playwright": "wp-scripts test-playwright --config test/e2e/playwright.config.ts", "test:e2e:debug": "wp-scripts --inspect-brk test-e2e --puppeteer-devtools", + "test:e2e:playwright:debug": "wp-scripts test-playwright --config test/e2e/playwright.config.ts --ui", "test:e2e:help": "wp-scripts test-e2e --help", "test:e2e:interactive": "npm run test:e2e -- --puppeteer-interactive", "test:e2e:watch": "npm run test:e2e -- --watch", diff --git a/test/e2e/playwright.config.ts b/test/e2e/playwright.config.ts new file mode 100644 index 000000000..764839a00 --- /dev/null +++ b/test/e2e/playwright.config.ts @@ -0,0 +1,16 @@ +/** + * External dependencies + */ +import { defineConfig } from '@playwright/test'; + +/** + * WordPress dependencies + */ +// eslint-disable-next-line @typescript-eslint/no-var-requires +const baseConfig = require( '@wordpress/scripts/config/playwright.config' ); + +const config = defineConfig( { + ...baseConfig, +} ); + +export default config; From 8c8ef36fad5395322ec0fdb11fd12638e6c4997d Mon Sep 17 00:00:00 2001 From: Alex Cicovic <23142906+acicovic@users.noreply.github.com> Date: Mon, 26 Aug 2024 16:05:38 +0300 Subject: [PATCH 052/282] Add untested Playwright GitHub workflow --- .github/workflows/e2e-tests-playwright.yml | 62 ++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 .github/workflows/e2e-tests-playwright.yml diff --git a/.github/workflows/e2e-tests-playwright.yml b/.github/workflows/e2e-tests-playwright.yml new file mode 100644 index 000000000..e5165578a --- /dev/null +++ b/.github/workflows/e2e-tests-playwright.yml @@ -0,0 +1,62 @@ +name: End-to-end (e2e) Tests - Playwright + +on: + # Run on all pull requests. + pull_request: + push: + branches: + - trunk + +# Cancels all previous workflow runs for pull requests that have not completed. +concurrency: + # The concurrency group contains the workflow name and the branch name for pull requests + # or the commit hash for any other events. + group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }} + cancel-in-progress: true + +jobs: + test: + name: e2e against WordPress latest + runs-on: ubuntu-20.04 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Refresh Composer autoload files + run: composer dump-autoload --classmap-authoritative + + - name: Use desired version of NodeJS + uses: actions/setup-node@v4.0.3 + with: + node-version: 16 + cache: npm + + - name: Npm install + run: | + npm ci + + - name: Install Playwright dependencies + run: | + npx playwright install chromium --with-deps + + - name: Start up WordPress environment + run: | + npm run dev:start + + - name: Running the tests + env: + PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 + run: | + npm run test:e2e:playwright + + - name: Stop WordPress environment + run: | + npm run dev:stop + + - name: Archive e2e results + uses: actions/upload-artifact@v4 + if: failure() + with: + name: test-results + path: artifacts From 332a15b42fc10fcbc862f981855a8f103ddcffd1 Mon Sep 17 00:00:00 2001 From: Alex Cicovic <23142906+acicovic@users.noreply.github.com> Date: Mon, 26 Aug 2024 16:09:34 +0300 Subject: [PATCH 053/282] Migrate plugin-action-link E2E test to Playwright --- test/e2e/specs/plugin-action-link.spec.ts | 15 ++++++++++++++ tests/e2e/specs/plugin-action-link.spec.ts | 23 ---------------------- 2 files changed, 15 insertions(+), 23 deletions(-) create mode 100644 test/e2e/specs/plugin-action-link.spec.ts delete mode 100644 tests/e2e/specs/plugin-action-link.spec.ts diff --git a/test/e2e/specs/plugin-action-link.spec.ts b/test/e2e/specs/plugin-action-link.spec.ts new file mode 100644 index 000000000..78d45d4aa --- /dev/null +++ b/test/e2e/specs/plugin-action-link.spec.ts @@ -0,0 +1,15 @@ +/** + * WordPress dependencies + */ +import { expect, test } from '@wordpress/e2e-test-utils-playwright'; + +test.describe( 'Plugin action link', () => { + test( 'Should link to the plugin\'s settings page', async ( { admin, page } ) => { + await admin.visitAdminPage( '/plugins.php' ); + await page.locator( '#the-list' ).getByRole( 'link', { name: 'Settings' } ).click(); + + // Check loaded page's URL and heading. + await page.waitForURL( '**/wp-admin/options-general.php?page=parsely' ); + await expect( page.getByText( 'Parse.ly Settings version' ) ).toBeVisible(); + } ); +} ); diff --git a/tests/e2e/specs/plugin-action-link.spec.ts b/tests/e2e/specs/plugin-action-link.spec.ts deleted file mode 100644 index 38dcacaa4..000000000 --- a/tests/e2e/specs/plugin-action-link.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -/** - * WordPress dependencies - */ -import { visitAdminPage } from '@wordpress/e2e-test-utils'; - -/** - * Internal dependencies - */ -import { - waitForWpAdmin, -} from '../utils'; - -describe( 'Plugin action link', () => { - it( 'Should link to plugin settings page', async () => { - await visitAdminPage( '/plugins.php', '' ); - - await page.click( '[data-slug=wp-parsely] .settings>a' ); - await waitForWpAdmin(); - - const versionText = await page.$eval( '#wp-parsely_version', ( el: Element ) => el.textContent ); - expect( versionText ).toMatch( /^Version \d+.\d+/ ); - } ); -} ); From 945a362b8978d08613db739fbc24875b8f7e6b0f Mon Sep 17 00:00:00 2001 From: Alex Cicovic <23142906+acicovic@users.noreply.github.com> Date: Mon, 26 Aug 2024 18:42:58 +0300 Subject: [PATCH 054/282] Prevent Jest from running Playwright tests --- jest-e2e.config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/jest-e2e.config.js b/jest-e2e.config.js index a429b3fa8..1bf75b508 100644 --- a/jest-e2e.config.js +++ b/jest-e2e.config.js @@ -3,5 +3,6 @@ const baseConfig = require( '@wordpress/scripts/config/jest-e2e.config' ); module.exports = { ...baseConfig, + testMatch: [ '**/tests/e2e/specs/**/*.[jt]s?(x)' ], // Prevent running Playwright tests. testTimeout: 35000, // Increased timeout for E2E tests. }; From 8e5420fbf6810385610f137ec932b45dae0271dd Mon Sep 17 00:00:00 2001 From: Alex Cicovic <23142906+acicovic@users.noreply.github.com> Date: Mon, 26 Aug 2024 18:52:08 +0300 Subject: [PATCH 055/282] Attempt to fix failing E2E test --- test/e2e/specs/plugin-action-link.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/specs/plugin-action-link.spec.ts b/test/e2e/specs/plugin-action-link.spec.ts index 78d45d4aa..63abf3ccb 100644 --- a/test/e2e/specs/plugin-action-link.spec.ts +++ b/test/e2e/specs/plugin-action-link.spec.ts @@ -10,6 +10,6 @@ test.describe( 'Plugin action link', () => { // Check loaded page's URL and heading. await page.waitForURL( '**/wp-admin/options-general.php?page=parsely' ); - await expect( page.getByText( 'Parse.ly Settings version' ) ).toBeVisible(); + await expect( page.getByText( 'Parse.ly Settings' ) ).toBeVisible(); } ); } ); From a35e6966b71b0952ba6095948e2f48047274b0ba Mon Sep 17 00:00:00 2001 From: Alex Cicovic <23142906+acicovic@users.noreply.github.com> Date: Mon, 26 Aug 2024 22:36:11 +0300 Subject: [PATCH 056/282] Merge E2E GitHub workflows and update tooling --- .github/workflows/e2e-tests-playwright.yml | 62 ---------------------- .github/workflows/e2e-tests.yml | 20 +++++-- 2 files changed, 15 insertions(+), 67 deletions(-) delete mode 100644 .github/workflows/e2e-tests-playwright.yml diff --git a/.github/workflows/e2e-tests-playwright.yml b/.github/workflows/e2e-tests-playwright.yml deleted file mode 100644 index e5165578a..000000000 --- a/.github/workflows/e2e-tests-playwright.yml +++ /dev/null @@ -1,62 +0,0 @@ -name: End-to-end (e2e) Tests - Playwright - -on: - # Run on all pull requests. - pull_request: - push: - branches: - - trunk - -# Cancels all previous workflow runs for pull requests that have not completed. -concurrency: - # The concurrency group contains the workflow name and the branch name for pull requests - # or the commit hash for any other events. - group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }} - cancel-in-progress: true - -jobs: - test: - name: e2e against WordPress latest - runs-on: ubuntu-20.04 - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Refresh Composer autoload files - run: composer dump-autoload --classmap-authoritative - - - name: Use desired version of NodeJS - uses: actions/setup-node@v4.0.3 - with: - node-version: 16 - cache: npm - - - name: Npm install - run: | - npm ci - - - name: Install Playwright dependencies - run: | - npx playwright install chromium --with-deps - - - name: Start up WordPress environment - run: | - npm run dev:start - - - name: Running the tests - env: - PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 - run: | - npm run test:e2e:playwright - - - name: Stop WordPress environment - run: | - npm run dev:stop - - - name: Archive e2e results - uses: actions/upload-artifact@v4 - if: failure() - with: - name: test-results - path: artifacts diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 099f295ff..032b91639 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -1,4 +1,4 @@ -name: End-to-end (e2e) Tests +name: End-to-end Tests on: # Run on all pull requests. @@ -16,8 +16,8 @@ concurrency: jobs: test: - name: e2e against WordPress latest - runs-on: ubuntu-20.04 + name: E2E against WordPress latest + runs-on: ubuntu-24.04 steps: - name: Checkout code @@ -29,22 +29,32 @@ jobs: - name: Use desired version of NodeJS uses: actions/setup-node@v4.0.3 with: - node-version: 16 + node-version: 18 cache: npm - name: Npm install run: | npm ci + - name: Install Playwright dependencies + run: | + npx playwright install chromium --with-deps + - name: Start up WordPress environment run: | npm run dev:start - - name: Running the tests + - name: Running E2E tests run: | npm run test:e2e -- --listTests > ~/.jest-e2e-tests npm run test:e2e + - name: Running Playwright E2E tests + env: + PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 + run: | + npm run test:e2e:playwright + - name: Stop WordPress environment run: | npm run dev:stop From a2cefb5bf5f9da08ed21b1f5039766d13d9345da Mon Sep 17 00:00:00 2001 From: Henrique Mouta Date: Thu, 29 Aug 2024 11:54:54 +0100 Subject: [PATCH 057/282] Add `stats` endpoint --- src/RemoteAPI/class-base-endpoint-remote.php | 6 +- src/rest-api/class-base-endpoint.php | 8 +- src/rest-api/class-rest-api-controller.php | 2 + .../class-endpoint-smart-linking.php | 83 +-- src/rest-api/stats/class-endpoint-post.php | 495 ++++++++++++++++++ src/rest-api/stats/class-endpoint-posts.php | 249 +++++++++ src/rest-api/stats/class-endpoint-related.php | 112 ++++ src/rest-api/stats/class-stats-controller.php | 48 ++ src/rest-api/stats/trait-post-data.php | 145 +++++ src/rest-api/stats/trait-related-posts.php | 165 ++++++ src/rest-api/trait-use-post-id-parameter.php | 88 ++++ 11 files changed, 1332 insertions(+), 69 deletions(-) create mode 100644 src/rest-api/stats/class-endpoint-post.php create mode 100644 src/rest-api/stats/class-endpoint-posts.php create mode 100644 src/rest-api/stats/class-endpoint-related.php create mode 100644 src/rest-api/stats/class-stats-controller.php create mode 100644 src/rest-api/stats/trait-post-data.php create mode 100644 src/rest-api/stats/trait-related-posts.php create mode 100644 src/rest-api/trait-use-post-id-parameter.php diff --git a/src/RemoteAPI/class-base-endpoint-remote.php b/src/RemoteAPI/class-base-endpoint-remote.php index 334f38e0d..e9ec20eb3 100644 --- a/src/RemoteAPI/class-base-endpoint-remote.php +++ b/src/RemoteAPI/class-base-endpoint-remote.php @@ -108,7 +108,11 @@ public function get_items( array $query, bool $associative = false ) { } if ( ! property_exists( $decoded, 'data' ) ) { - return new WP_Error( $decoded->code ?? 400, $decoded->message ?? __( 'Unable to read data from upstream API', 'wp-parsely' ) ); + return new WP_Error( + $decoded->code ?? 400, + $decoded->message ?? __( 'Unable to read data from upstream API', 'wp-parsely' ), + array( 'status' => $decoded->code ?? 400 ) + ); } if ( ! is_array( $decoded->data ) ) { diff --git a/src/rest-api/class-base-endpoint.php b/src/rest-api/class-base-endpoint.php index 3229b4bb8..2ce4f9be2 100644 --- a/src/rest-api/class-base-endpoint.php +++ b/src/rest-api/class-base-endpoint.php @@ -169,7 +169,13 @@ public function register_rest_route( string $route, array $methods, callable $ca * @return string */ public function get_full_endpoint( string $route = '' ): string { - $route = $this->get_endpoint_name() . '/' . $route; + $route = trim( $route, '/' ); + + if ( '' !== $route ) { + $route = $this->get_endpoint_name() . '/' . $route; + } else { + $route = $this->get_endpoint_name(); + } return '/' . $this->api_controller->get_full_namespace() . diff --git a/src/rest-api/class-rest-api-controller.php b/src/rest-api/class-rest-api-controller.php index e864e59fa..5ce4e76fa 100644 --- a/src/rest-api/class-rest-api-controller.php +++ b/src/rest-api/class-rest-api-controller.php @@ -11,6 +11,7 @@ namespace Parsely\REST_API; use Parsely\REST_API\Content_Helper\Content_Helper_Controller; +use Parsely\REST_API\Stats\Stats_Controller; /** * The REST API Controller. @@ -60,6 +61,7 @@ public function init(): void { // Register the controllers for each namespace. $controllers = array( new Content_Helper_Controller( $this->get_parsely() ), + new Stats_Controller( $this->get_parsely() ), ); // Initialize the controllers. diff --git a/src/rest-api/content-helper/class-endpoint-smart-linking.php b/src/rest-api/content-helper/class-endpoint-smart-linking.php index fe37e324f..cce1c99c4 100644 --- a/src/rest-api/content-helper/class-endpoint-smart-linking.php +++ b/src/rest-api/content-helper/class-endpoint-smart-linking.php @@ -14,6 +14,7 @@ use Parsely\Models\Smart_Link; use Parsely\RemoteAPI\ContentSuggestions\Suggest_Linked_Reference_API; use Parsely\REST_API\Base_Endpoint; +use Parsely\REST_API\Use_Post_ID_Parameter_Trait; use WP_Error; use WP_Post; use WP_REST_Request; @@ -28,6 +29,7 @@ */ class Endpoint_Smart_Linking extends Base_Endpoint { use Content_Helper_Feature; + use Use_Post_ID_Parameter_Trait; /** * The Suggest Linked Reference API instance. @@ -110,40 +112,28 @@ public function register_routes(): void { * GET /smart-linking/{post_id}/get * Gets the smart links for a post. */ - $this->register_rest_route( - '(?P\d+)/get', + $this->register_rest_route_with_post_id( + '/get', array( 'GET' ), - array( $this, 'get_smart_links' ), - array( - 'post_id' => array( - 'required' => true, - 'description' => __( 'The post ID.', 'wp-parsely' ), - 'validate_callback' => array( $this, 'validate_post_id' ), - ), - ) + array( $this, 'get_smart_links' ) ); /** * POST /smart-linking/{post_id}/add * Adds a smart link to a post. */ - $this->register_rest_route( - '(?P\d+)/add', + $this->register_rest_route_with_post_id( + '/add', array( 'POST' ), array( $this, 'add_smart_link' ), array( - 'post_id' => array( - 'required' => true, - 'description' => __( 'The post ID.', 'wp-parsely' ), - 'validate_callback' => array( $this, 'validate_post_id' ), - ), - 'link' => array( + 'link' => array( 'required' => true, 'type' => 'object', 'description' => __( 'The smart link data to add.', 'wp-parsely' ), 'validate_callback' => array( $this, 'validate_smart_link_params' ), ), - 'update' => array( + 'update' => array( 'type' => 'boolean', 'description' => __( 'Whether to update the existing smart link.', 'wp-parsely' ), 'default' => false, @@ -155,23 +145,18 @@ public function register_routes(): void { * POST /smart-linking/{post_id}/add-multiple * Adds multiple smart links to a post. */ - $this->register_rest_route( - '(?P\d+)/add-multiple', + $this->register_rest_route_with_post_id( + '/add-multiple', array( 'POST' ), array( $this, 'add_multiple_smart_links' ), array( - 'post_id' => array( - 'required' => true, - 'description' => __( 'The post ID.', 'wp-parsely' ), - 'validate_callback' => array( $this, 'validate_post_id' ), - ), - 'links' => array( + 'links' => array( 'required' => true, 'type' => 'array', 'description' => __( 'The multiple smart links data to add.', 'wp-parsely' ), 'validate_callback' => array( $this, 'validate_multiple_smart_links' ), ), - 'update' => array( + 'update' => array( 'type' => 'boolean', 'description' => __( 'Whether to update the existing smart links.', 'wp-parsely' ), 'default' => false, @@ -183,17 +168,12 @@ public function register_routes(): void { * POST /smart-linking/{post_id}/set * Updates the smart links of a given post and removes the ones that are not in the request. */ - $this->register_rest_route( - '(?P\d+)/set', + $this->register_rest_route_with_post_id( + '/set', array( 'POST' ), array( $this, 'set_smart_links' ), array( - 'post_id' => array( - 'required' => true, - 'description' => __( 'The post ID.', 'wp-parsely' ), - 'validate_callback' => array( $this, 'validate_post_id' ), - ), - 'links' => array( + 'links' => array( 'required' => true, 'type' => 'array', 'description' => __( 'The smart links data to set.', 'wp-parsely' ), @@ -548,37 +528,6 @@ public function url_to_post_type( WP_REST_Request $request ): WP_REST_Response { return new WP_REST_Response( $response, 200 ); } - /** - * Validates the post ID parameter. - * - * The callback sets the post object in the request object if the parameter is valid. - * - * @since 3.16.0 - * @access private - * - * @param string $param The parameter value. - * @param WP_REST_Request $request The request object. - * @return bool Whether the parameter is valid. - */ - public function validate_post_id( string $param, WP_REST_Request $request ): bool { - if ( ! is_numeric( $param ) ) { - return false; - } - - $param = filter_var( $param, FILTER_VALIDATE_INT ); - - if ( false === $param ) { - return false; - } - - // Validate if the post ID exists. - $post = get_post( $param ); - // Set the post attribute in the request. - $request->set_param( 'post', $post ); - - return null !== $post; - } - /** * Validates the URL exclusion list parameter. * diff --git a/src/rest-api/stats/class-endpoint-post.php b/src/rest-api/stats/class-endpoint-post.php new file mode 100644 index 000000000..c83713315 --- /dev/null +++ b/src/rest-api/stats/class-endpoint-post.php @@ -0,0 +1,495 @@ +analytics_post_detail_api = new Analytics_Post_Detail_API( $this->parsely ); + $this->referrers_post_detail_api = new Referrers_Post_Detail_API( $this->parsely ); + $this->related_posts_api = new Related_API( $this->parsely ); + } + + /** + * Returns the endpoint name. + * + * @since 3.17.0 + * + * @return string The endpoint name. + */ + public function get_endpoint_name(): string { + return 'post'; + } + + /** + * Registers the routes for the endpoint. + * + * @since 3.17.0 + */ + public function register_routes(): void { + /** + * GET /stats/post/{post_id}/details + * Returns the analytics details of a post. + */ + $this->register_rest_route_with_post_id( + '/details', + array( 'GET' ), + array( $this, 'get_post_details' ), + array_merge( + array( + 'period_start' => array( + 'description' => __( 'The start of the period.', 'wp-parsely' ), + 'type' => 'string', + 'required' => false, + ), + 'period_end' => array( + 'description' => __( 'The end of the period.', 'wp-parsely' ), + 'type' => 'string', + 'required' => false, + ), + ), + $this->get_itm_source_param_args() + ) + ); + + /** + * GET /stats/post/{post_id}/referrers + * Returns the referrers of a post. + */ + $this->register_rest_route_with_post_id( + '/referrers', + array( 'GET' ), + array( $this, 'get_post_referrers' ), + array( + 'period_start' => array( + 'description' => __( 'The start of the period.', 'wp-parsely' ), + 'type' => 'string', + 'required' => false, + ), + 'period_end' => array( + 'description' => __( 'The end of the period.', 'wp-parsely' ), + 'type' => 'string', + 'required' => false, + ), + 'total_views' => array( + 'description' => __( 'The total views of the post.', 'wp-parsely' ), + 'type' => 'string', + 'required' => false, + 'default' => '0', + ), + ) + ); + + /** + * GET /stats/post/{post_id}/related + * Returns the related posts of a post. + */ + $this->register_rest_route_with_post_id( + '/related', + array( 'GET' ), + array( $this, 'get_related_posts' ), + $this->get_related_posts_param_args() + ); + } + + /** + * API Endpoint: GET /stats/post/{post_id}/details + * + * Gets the details of a post. + * + * @since 3.17.0 + * + * @param WP_REST_Request $request The request object. + * @return WP_REST_Response|WP_Error The response object. + */ + public function get_post_details( WP_REST_Request $request ) { + /** + * The post object. + * + * @var WP_Post $post + */ + $post = $request->get_param( 'post' ); + $permalink = get_permalink( $post->ID ); + + // Set the itm_source parameter. + $this->set_itm_source_from_request( $request ); + + // Get the data from the API. + $analytics_request = $this->analytics_post_detail_api->get_items( + array( + 'url' => $permalink, + 'period_start' => $request->get_param( 'period_start' ), + 'period_end' => $request->get_param( 'period_end' ), + ) + ); + + if ( is_wp_error( $analytics_request ) ) { + return $analytics_request; + } + + $post_data = array(); + /** + * The analytics data object. + * + * @var array $analytics_request + */ + foreach ( $analytics_request as $data ) { + $post_data[] = $this->extract_post_data( $data ); + } + + $response = array( + 'params' => $request->get_params(), + 'data' => $post_data, + ); + + return new WP_REST_Response( $response, 200 ); + } + + /** + * API Endpoint: GET /stats/post/{post_id}/referrers + * + * Gets the referrers of a post. + * + * @since 3.17.0 + * + * @param WP_REST_Request $request The request object. + * @return WP_REST_Response|WP_Error The response object. + */ + public function get_post_referrers( WP_REST_Request $request ) { + /** + * The post object. + * + * @var WP_Post $post + */ + $post = $request->get_param( 'post' ); + $permalink = get_permalink( $post->ID ); + + // Set the itm_source parameter. + $this->set_itm_source_from_request( $request ); + + // Get the total views. + $total_views = $request->get_param( 'total_views' ) ?? 0; + + if ( is_string( $total_views ) ) { + $total_views = Utils::convert_to_positive_integer( $total_views ); + } + + $this->total_views = $total_views; + + // Do the analytics request. + $analytics_request = $this->referrers_post_detail_api->get_items( + array( + 'url' => $permalink, + 'period_start' => $request->get_param( 'period_start' ), + 'period_end' => $request->get_param( 'period_end' ), + ) + ); + + if ( is_wp_error( $analytics_request ) ) { + return $analytics_request; + } + + /** + * The analytics data object. + * + * @var array $analytics_request + */ + $referrers_types = $this->generate_referrer_types_data( $analytics_request ); + $direct_views = Utils::convert_to_positive_integer( + $referrers_types->direct->views ?? '0' + ); + $referrers_top = $this->generate_referrers_data( 5, $analytics_request, $direct_views ); + + $response_data = array( + 'params' => $request->get_params(), + 'data' => array( + 'top' => $referrers_top, + 'types' => $referrers_types, + ), + ); + + return new WP_REST_Response( $response_data, 200 ); + } + + /** + * API Endpoint: GET /stats/post/{post_id}/related + * + * Gets the related posts of a post. + * + * @since 3.17.0 + * + * @param WP_REST_Request $request The request object. + * @return WP_REST_Response|WP_Error The response data. + */ + public function get_related_posts( WP_REST_Request $request ) { + /** + * The post object. + * + * @var WP_Post $post + */ + $post = $request->get_param( 'post' ); + + /** + * The post permalink. + * + * @var string $permalink + */ + $permalink = get_permalink( $post->ID ); + + $related_posts = $this->get_related_posts_of_url( $request, $permalink ); + + $response_data = array( + 'params' => $request->get_params(), + 'data' => $related_posts, + ); + return new WP_REST_Response( $response_data, 200 ); + } + + /** + * Generates the referrer types data. + * + * Referrer types are: + * - `social`: Views coming from social media. + * - `search`: Views coming from search engines. + * - `other`: Views coming from other referrers, like external websites. + * - `internal`: Views coming from linking pages of the same website. + * + * Returned object properties: + * - `views`: The number of views. + * - `viewPercentage`: The number of views as a percentage, compared to the + * total views of all referrer types. + * + * @since 3.6.0 + * @since 3.17.0 Moved from the `Referrers_Post_Detail_API_Proxy` class. + * + * @param array $response The response received by the proxy. + * @return stdClass The generated data. + */ + private function generate_referrer_types_data( array $response ): stdClass { + $result = new stdClass(); + $total_referrer_views = 0; // Views from all referrer types combined. + + // Set referrer type order as it is displayed in the Parse.ly dashboard. + $referrer_type_keys = array( 'social', 'search', 'other', 'internal', 'direct' ); + foreach ( $referrer_type_keys as $key ) { + $result->$key = (object) array( 'views' => 0 ); + } + + // Set views and views totals. + foreach ( $response as $referrer_data ) { + /** + * Variable. + * + * @var int + */ + $current_views = $referrer_data->metrics->referrers_views ?? 0; + $total_referrer_views += $current_views; + + /** + * Variable. + * + * @var string + */ + $current_key = $referrer_data->type ?? ''; + if ( '' !== $current_key ) { + if ( ! isset( $result->$current_key->views ) ) { + $result->$current_key = (object) array( 'views' => 0 ); + } + + $result->$current_key->views += $current_views; + } + } + + // Add direct and total views to the object. + $result->direct->views = $this->total_views - $total_referrer_views; + $result->totals = (object) array( 'views' => $this->total_views ); + + // Remove referrer types without views. + foreach ( $referrer_type_keys as $key ) { + if ( 0 === $result->$key->views ) { + unset( $result->$key ); + } + } + + // Set percentage values and format numbers. + // @phpstan-ignore-next-line. + foreach ( $result as $key => $value ) { + // Set and format percentage values. + $result->{ $key }->viewsPercentage = $this->get_i18n_percentage( + absint( $value->views ), + $this->total_views + ); + + // Format views values. + $result->{ $key }->views = number_format_i18n( $result->{ $key }->views ); + } + + return $result; + } + + /** + * Generates the top referrers data. + * + * Returned object properties: + * - `views`: The number of views. + * - `viewPercentage`: The number of views as a percentage, compared to the + * total views of all referrer types. + * - `datasetViewsPercentage: The number of views as a percentage, compared + * to the total views of the current dataset. + * + * @since 3.6.0 + * @since 3.17.0 Moved from the `Referrers_Post_Detail_API_Proxy` class. + * + * @param int $limit The limit of returned referrers. + * @param array $response The response received by the proxy. + * @param int $direct_views The count of direct views. + * @return stdClass The generated data. + */ + private function generate_referrers_data( + int $limit, + array $response, + int $direct_views + ): stdClass { + $temp_views = array(); + $totals = 0; + $referrer_count = count( $response ); + + // Set views and views totals. + $loop_count = $referrer_count > $limit ? $limit : $referrer_count; + for ( $i = 0; $i < $loop_count; $i++ ) { + $data = $response[ $i ]; + + /** + * Variable. + * + * @var int + */ + $referrer_views = $data->metrics->referrers_views ?? 0; + $totals += $referrer_views; + if ( isset( $data->name ) ) { + $temp_views[ $data->name ] = $referrer_views; + } + } + + // If applicable, add the direct views. + if ( isset( $referrer_views ) && $direct_views >= $referrer_views ) { + $temp_views['direct'] = $direct_views; + $totals += $direct_views; + arsort( $temp_views ); + if ( count( $temp_views ) > $limit ) { + $totals -= array_pop( $temp_views ); + } + } + + // Convert temporary array to result object and add totals. + $result = new stdClass(); + foreach ( $temp_views as $key => $value ) { + $result->$key = (object) array( 'views' => $value ); + } + $result->totals = (object) array( 'views' => $totals ); + + // Set percentages values and format numbers. + // @phpstan-ignore-next-line. + foreach ( $result as $key => $value ) { + // Percentage against all referrer views, even those not included + // in the dataset due to the $limit argument. + $result->{ $key }->viewsPercentage = $this + ->get_i18n_percentage( absint( $value->views ), $this->total_views ); + + // Percentage against the current dataset that is limited due to the + // $limit argument. + $result->{ $key }->datasetViewsPercentage = $this + ->get_i18n_percentage( absint( $value->views ), $totals ); + + // Format views values. + $result->{ $key }->views = number_format_i18n( $result->{ $key }->views ); + } + + return $result; + } + + /** + * Returns the passed number compared to the passed total, in an + * internationalized percentage format. + * + * @since 3.6.0 + * @since 3.17.0 Moved from the `Referrers_Post_Detail_API_Proxy` class. + * + * @param int $number The number to be calculated as a percentage. + * @param int $total The total number to compare against. + * @return string|false The internationalized percentage or false on error. + */ + private function get_i18n_percentage( int $number, int $total ) { + if ( 0 === $total ) { + return false; + } + + return number_format_i18n( $number / $total * 100, 2 ); + } +} diff --git a/src/rest-api/stats/class-endpoint-posts.php b/src/rest-api/stats/class-endpoint-posts.php new file mode 100644 index 000000000..cb9731077 --- /dev/null +++ b/src/rest-api/stats/class-endpoint-posts.php @@ -0,0 +1,249 @@ +analytics_posts_api = new Analytics_Posts_API( $this->parsely ); + } + + /** + * Returns the endpoint name. + * + * @since 3.17.0 + * + * @return string + */ + public function get_endpoint_name(): string { + return 'posts'; + } + + /** + * Registers the routes for the objects of the controller. + */ + public function register_routes(): void { + /** + * GET /posts + * Retrieves the top posts for the given period. + */ + $this->register_rest_route( + '/', + array( 'GET' ), + array( $this, 'get_posts' ), + array_merge( + array( + 'period_start' => array( + 'description' => 'The start of the period to query.', + 'type' => 'string', + 'required' => false, + ), + 'period_end' => array( + 'description' => 'The end of the period to query.', + 'type' => 'string', + 'required' => false, + ), + 'pub_date_start' => array( + 'description' => 'The start of the publication date range to query.', + 'type' => 'string', + 'required' => false, + ), + 'pub_date_end' => array( + 'description' => 'The end of the publication date range to query.', + 'type' => 'string', + 'required' => false, + ), + 'limit' => array( + 'description' => 'The number of posts to return.', + 'type' => 'integer', + 'required' => false, + 'default' => self::TOP_POSTS_DEFAULT_LIMIT, + ), + 'sort' => array( + 'description' => 'The sort order of the posts.', + 'type' => 'string', + 'enum' => self::SORT_METRICS, + 'default' => self::SORT_DEFAULT, + 'required' => false, + ), + 'page' => array( + 'description' => 'The page to fetch.', + 'type' => 'integer', + 'required' => false, + 'default' => 1, + ), + 'author' => array( + 'description' => 'The author to filter by.', + 'type' => 'array', + 'items' => array( + 'type' => 'string', + ), + 'required' => false, + 'maxItems' => 5, + ), + 'section' => array( + 'description' => 'The section to filter by.', + 'type' => 'string', + 'required' => false, + ), + 'tag' => array( + 'description' => 'The tag to filter by.', + 'type' => 'array', + 'items' => array( + 'type' => 'string', + ), + 'required' => false, + 'maxItems' => 5, + ), + 'segment' => array( + 'description' => 'The segment to filter by.', + 'type' => 'string', + 'required' => false, + ), + ), + $this->get_itm_source_param_args() + ) + ); + } + + /** + * API Endpoint: GET /stats/posts + * + * Retrieves the top posts for the given query parameters. + * + * @param WP_REST_Request $request The request. + * + * @return stdClass[]|WP_Error|WP_REST_Response + */ + public function get_posts( WP_REST_Request $request ) { + $params = $request->get_params(); + + // Setup the itm_source if it is provided. + $this->set_itm_source_from_request( $request ); + + // TODO: Needed before the Public API refactor. + // Convert array of authors to a string with the first element. + if ( isset( $params['author'] ) && is_array( $params['author'] ) ) { + $params['author'] = $params['author'][0]; + } + // Convert array of tags to a string with the first element. + if ( isset( $params['tag'] ) && is_array( $params['tag'] ) ) { + $params['tag'] = $params['tag'][0]; + } + // TODO END. + + // Do the analytics request. + /** + * The raw analytics data. + * + * @var stdClass[]|WP_Error $analytics_request + */ + $analytics_request = $this->analytics_posts_api->get_items( + array( + 'period_start' => $params['period_start'] ?? null, + 'period_end' => $params['period_end'] ?? null, + 'pub_date_start' => $params['pub_date_start'] ?? null, + 'pub_date_end' => $params['pub_date_end'] ?? null, + 'limit' => $params['limit'] ?? self::TOP_POSTS_DEFAULT_LIMIT, + 'sort' => $params['sort'] ?? self::SORT_DEFAULT, + 'page' => $params['page'] ?? 1, + 'author' => $params['author'] ?? null, + 'section' => $params['section'] ?? null, + 'tag' => $params['tag'] ?? null, + 'segment' => $params['segment'] ?? null, + 'itm_source' => $params['itm_source'] ?? null, + ) + ); + + if ( is_wp_error( $analytics_request ) ) { + return $analytics_request; + } + + // Process the data. + $posts = array(); + foreach ( $analytics_request as $item ) { + $posts[] = $this->extract_post_data( $item ); + } + + $response = array( + 'params' => $params, + 'data' => $posts, + ); + + return new WP_REST_Response( $response, 200 ); + } +} diff --git a/src/rest-api/stats/class-endpoint-related.php b/src/rest-api/stats/class-endpoint-related.php new file mode 100644 index 000000000..d675e9e92 --- /dev/null +++ b/src/rest-api/stats/class-endpoint-related.php @@ -0,0 +1,112 @@ +related_posts_api = new Related_API( $this->parsely ); + } + + /** + * Returns the endpoint name. + * + * @since 3.17.0 + * + * @return string + */ + public function get_endpoint_name(): string { + return 'related'; + } + + /** + * Registers the routes for the endpoint. + * + * @since 3.17.0 + */ + public function register_routes(): void { + /** + * GET /related + * Gets related posts. + */ + $this->register_rest_route( + '/', + array( 'GET' ), + array( $this, 'get_related_posts' ), + array( + 'url' => array( + 'description' => __( 'The URL of the post.', 'wp-parsely' ), + 'type' => 'string', + 'required' => true, + ), + $this->get_related_posts_param_args(), + ) + ); + } + + /** + * API Endpoint: GET /stats/related + * + * Gets related posts for a given URL. + * + * @since 3.17.0 + * + * @param WP_REST_Request $request The request object. + * @return WP_REST_Response|WP_Error + */ + public function get_related_posts( WP_REST_Request $request ) { + $url = $request->get_param( 'url' ); + + $related_posts = $this->get_related_posts_of_url( $request, $url ); + + if ( is_wp_error( $related_posts ) ) { + return $related_posts; + } + + return new WP_REST_Response( array( 'data' => $related_posts ), 200 ); + } + + /** + * Returns whether the endpoint is available for access by the current + * user. + * + * @since 3.17.0 + * + * @param WP_REST_Request|null $request The request object. + * @return bool + */ + public function is_available_to_current_user( ?WP_REST_Request $request = null ): bool { + return true; + } +} diff --git a/src/rest-api/stats/class-stats-controller.php b/src/rest-api/stats/class-stats-controller.php new file mode 100644 index 000000000..ecae2387b --- /dev/null +++ b/src/rest-api/stats/class-stats-controller.php @@ -0,0 +1,48 @@ +register_endpoints( $endpoints ); + } +} diff --git a/src/rest-api/stats/trait-post-data.php b/src/rest-api/stats/trait-post-data.php new file mode 100644 index 000000000..4698d2a9a --- /dev/null +++ b/src/rest-api/stats/trait-post-data.php @@ -0,0 +1,145 @@ +itm_source = $source; + } + + /** + * Sets the itm_source value from the request, if it exists. + * + * @since 3.17.0 + * + * @param WP_REST_Request $request The request object. + */ + private function set_itm_source_from_request( WP_REST_Request $request ): void { + $source = $request->get_param( 'itm_source' ); + if ( null !== $source ) { + $this->set_itm_source( $source ); + } + } + + /** + * Returns the itm_source parameter arguments, to be used in the REST API + * route registration. + * + * @since 3.17.0 + * + * @return array + */ + private function get_itm_source_param_args(): array { + return array( + 'itm_source' => array( + 'description' => __( 'The source of the item.', 'wp-parsely' ), + 'type' => 'string', + 'required' => false, + 'validate_callback' => array( $this, 'validate_itm_source' ), + ), + ); + } + + /** + * Extracts the post data from the passed object. + * + * Should only be used with endpoints that return post data. + * + * @since 3.10.0 + * @since 3.17.0 Moved from the old `Base_API_Proxy` class. + * + * @param stdClass $item The object to extract the data from. + * @return array The extracted data. + */ + protected function extract_post_data( stdClass $item ): array { + $data = array(); + + if ( isset( $item->author ) ) { + $data['author'] = $item->author; + } + + if ( isset( $item->metrics->views ) ) { + $data['views'] = number_format_i18n( $item->metrics->views ); + } + + if ( isset( $item->metrics->visitors ) ) { + $data['visitors'] = number_format_i18n( $item->metrics->visitors ); + } + + // The avg_engaged metric can be in different locations depending on the + // endpoint and passed sort/url parameters. + $avg_engaged = $item->metrics->avg_engaged ?? $item->avg_engaged ?? null; + if ( null !== $avg_engaged ) { + $data['avgEngaged'] = Utils::get_formatted_duration( (float) $avg_engaged ); + } + + if ( isset( $item->pub_date ) ) { + $data['date'] = wp_date( Utils::get_date_format(), strtotime( $item->pub_date ) ); + } + + if ( isset( $item->title ) ) { + $data['title'] = $item->title; + } + + if ( isset( $item->url ) ) { + $site_id = $this->parsely->get_site_id(); + // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.url_to_postid_url_to_postid + $post_id = url_to_postid( $item->url ); // 0 if the post cannot be found. + + $post_url = Parsely::get_url_with_itm_source( $item->url, null ); + if ( Utils::parsely_is_https_supported() ) { + $post_url = str_replace( 'http://', 'https://', $post_url ); + } + + $data['rawUrl'] = $post_url; + $data['dashUrl'] = Parsely::get_dash_url( $site_id, $post_url ); + $data['id'] = Parsely::get_url_with_itm_source( $post_url, null ); // Unique. + $data['postId'] = $post_id; // Might not be unique. + $data['url'] = Parsely::get_url_with_itm_source( $post_url, $this->itm_source ); + + // Set thumbnail URL, falling back to the Parse.ly thumbnail if needed. + $thumbnail_url = get_the_post_thumbnail_url( $post_id, 'thumbnail' ); + if ( false !== $thumbnail_url ) { + $data['thumbnailUrl'] = $thumbnail_url; + } elseif ( isset( $item->thumb_url_medium ) ) { + $data['thumbnailUrl'] = $item->thumb_url_medium; + } + } + + return $data; + } +} diff --git a/src/rest-api/stats/trait-related-posts.php b/src/rest-api/stats/trait-related-posts.php new file mode 100644 index 000000000..dadab370a --- /dev/null +++ b/src/rest-api/stats/trait-related-posts.php @@ -0,0 +1,165 @@ + + */ + private function get_related_posts_param_args(): array { + return array_merge( + array( + 'sort' => array( + 'description' => __( 'The sort order.', 'wp-parsely' ), + 'type' => 'string', + 'enum' => array( '_score', 'pub_date' ), + 'required' => false, + 'default' => '_score', + ), + 'limit' => array( + 'description' => __( 'The number of related posts to return.', 'wp-parsely' ), + 'type' => 'integer', + 'required' => false, + 'default' => 10, + ), + 'pub_date_start' => array( + 'description' => __( 'The start of the publication date.', 'wp-parsely' ), + 'type' => 'string', + 'required' => false, + ), + 'pub_date_end' => array( + 'description' => __( 'The end of the publication date.', 'wp-parsely' ), + 'type' => 'string', + 'required' => false, + ), + 'page' => array( + 'description' => __( 'The page number.', 'wp-parsely' ), + 'type' => 'integer', + 'required' => false, + 'default' => 1, + ), + 'section' => array( + 'description' => __( 'The section of the post.', 'wp-parsely' ), + 'type' => 'string', + 'required' => false, + ), + 'tag' => array( + 'description' => __( 'The tag of the post.', 'wp-parsely' ), + 'type' => 'string', + 'required' => false, + ), + 'author' => array( + 'description' => __( 'The author of the post.', 'wp-parsely' ), + 'type' => 'string', + 'required' => false, + ), + ), + $this->get_itm_source_param_args() + ); + } + + /** + * Get related posts for a given URL. + * + * @since 3.17.0 + * + * @param WP_REST_Request $request The request object. + * @param string $url The URL to get related posts for. + * @return array|WP_Error + */ + public function get_related_posts_of_url( WP_REST_Request $request, string $url ) { + // Set the itm_source parameter. + $this->set_itm_source_from_request( $request ); + + // Get the data from the API. + /** + * The related posts request. + * + * @var array|WP_Error $related_posts_request + */ + $related_posts_request = $this->related_posts_api->get_items( + array( + 'url' => $url, + 'sort' => $request->get_param( 'sort' ), + 'limit' => $request->get_param( 'limit' ), + 'pub_date_start' => $request->get_param( 'pub_date_start' ), + 'pub_date_end' => $request->get_param( 'pub_date_end' ), + 'page' => $request->get_param( 'page' ), + 'section' => $request->get_param( 'section' ), + 'tag' => $request->get_param( 'tag' ), + 'author' => $request->get_param( 'author' ), + ) + ); + + if ( is_wp_error( $related_posts_request ) ) { + return $related_posts_request; + } + + $itm_source = $this->itm_source; + + $related_posts = array_map( + static function ( stdClass $item ) use ( $itm_source ) { + return (object) array( + 'image_url' => $item->image_url, + 'thumb_url_medium' => $item->thumb_url_medium, + 'title' => $item->title, + 'url' => Parsely::get_url_with_itm_source( $item->url, $itm_source ), + ); + }, + $related_posts_request + ); + + return $related_posts; + } +} diff --git a/src/rest-api/trait-use-post-id-parameter.php b/src/rest-api/trait-use-post-id-parameter.php new file mode 100644 index 000000000..4459636e9 --- /dev/null +++ b/src/rest-api/trait-use-post-id-parameter.php @@ -0,0 +1,88 @@ + $methods The HTTP methods. + * @param callable $callback The callback function. + * @param array $args The route arguments. + */ + public function register_rest_route_with_post_id( + string $route, + array $methods, + callable $callback, + array $args = array() + ): void { + // Append the post_id parameter to the route. + $route = '/(?P\d+)/' . trim( $route, '/' ); + + // Add the post_id parameter to the args. + $args = array_merge( + $args, + array( + 'post_id' => array( + 'description' => __( 'The ID of the post.', 'wp-parsely' ), + 'type' => 'integer', + 'required' => true, + 'validate_callback' => array( $this, 'validate_post_id' ), + ), + ) + ); + + // Register the route. + $this->register_rest_route( $route, $methods, $callback, $args ); + } + + /** + * Validates the post ID parameter. + * + * The callback sets the post object in the request object if the parameter is valid. + * + * @since 3.16.0 + * @access private + * + * @param string $param The parameter value. + * @param WP_REST_Request $request The request object. + * @return bool Whether the parameter is valid. + */ + public function validate_post_id( string $param, WP_REST_Request $request ): bool { + if ( ! is_numeric( $param ) ) { + return false; + } + + $param = filter_var( $param, FILTER_VALIDATE_INT ); + + if ( false === $param ) { + return false; + } + + // Validate if the post ID exists. + $post = get_post( $param ); + // Set the post attribute in the request. + $request->set_param( 'post', $post ); + + return null !== $post; + } +} From f1bb531532ad1f5c22275f2567482ff9933c49d6 Mon Sep 17 00:00:00 2001 From: Henrique Mouta Date: Thu, 29 Aug 2024 11:56:38 +0100 Subject: [PATCH 058/282] Update the UI to use the new API endpoints --- build/blocks/recommendations/edit.asset.php | 2 +- build/blocks/recommendations/edit.js | 2 +- build/blocks/recommendations/view.asset.php | 2 +- build/blocks/recommendations/view.js | 2 +- .../content-helper/dashboard-widget.asset.php | 2 +- build/content-helper/dashboard-widget.js | 2 +- build/content-helper/editor-sidebar.asset.php | 2 +- build/content-helper/editor-sidebar.js | 8 ++--- .../parsely-recommendations-fetcher.tsx | 2 +- .../dashboard-widget/provider.ts | 2 +- .../performance-stats/provider.ts | 36 +++++++++---------- .../editor-sidebar/related-posts/provider.ts | 2 +- 12 files changed, 31 insertions(+), 33 deletions(-) diff --git a/build/blocks/recommendations/edit.asset.php b/build/blocks/recommendations/edit.asset.php index 0f36c73fc..ce1f1eb73 100644 --- a/build/blocks/recommendations/edit.asset.php +++ b/build/blocks/recommendations/edit.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => '393b4c8be66f3bde527e'); + array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => 'f1121e53d4c8acf98db5'); diff --git a/build/blocks/recommendations/edit.js b/build/blocks/recommendations/edit.js index 06593e46c..c923405cf 100644 --- a/build/blocks/recommendations/edit.js +++ b/build/blocks/recommendations/edit.js @@ -1 +1 @@ -!function(){"use strict";var e,n={271:function(e,n,r){var t,o,a=r(848),i=window.wp.blockEditor,l=window.wp.blocks,s=window.wp.i18n,c=window.wp.components,u=JSON.parse('{"UU":"wp-parsely/recommendations","uK":{"imagestyle":{"type":"string","default":"original"},"limit":{"type":"number","default":3},"openlinksinnewtab":{"type":"boolean","default":false},"showimages":{"type":"boolean","default":true},"sort":{"type":"string","default":"score"},"title":{"type":"string","default":"Related Content"}}}'),d=window.wp.element;(o=t||(t={}))[o.Error=0]="Error",o[o.Loaded=1]="Loaded",o[o.Recommendations=2]="Recommendations";var p=function(){return p=Object.assign||function(e){for(var n,r=1,t=arguments.length;r0&&o[o.length-1])||6!==l[0]&&2!==l[0])){i=0;continue}if(3===l[0]&&(!o||l[1]>o[0]&&l[1]=a)&&Object.keys(t.O).every((function(e){return t.O[e](r[s])}))?r.splice(s--,1):(l=!1,a0&&e[u-1][2]>a;u--)e[u]=e[u-1];e[u]=[r,o,a]},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,{a:n}),n},t.d=function(e,n){for(var r in n)t.o(n,r)&&!t.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:n[r]})},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},function(){var e={335:0,203:0};t.O.j=function(n){return 0===e[n]};var n=function(n,r){var o,a,i=r[0],l=r[1],s=r[2],c=0;if(i.some((function(n){return 0!==e[n]}))){for(o in l)t.o(l,o)&&(t.m[o]=l[o]);if(s)var u=s(t)}for(n&&n(r);c0&&o[o.length-1])||6!==l[0]&&2!==l[0])){i=0;continue}if(3===l[0]&&(!o||l[1]>o[0]&&l[1]=a)&&Object.keys(t.O).every((function(e){return t.O[e](r[s])}))?r.splice(s--,1):(l=!1,a0&&e[u-1][2]>a;u--)e[u]=e[u-1];e[u]=[r,o,a]},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,{a:n}),n},t.d=function(e,n){for(var r in n)t.o(n,r)&&!t.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:n[r]})},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},function(){var e={335:0,203:0};t.O.j=function(n){return 0===e[n]};var n=function(n,r){var o,a,i=r[0],l=r[1],s=r[2],c=0;if(i.some((function(n){return 0!==e[n]}))){for(o in l)t.o(l,o)&&(t.m[o]=l[o]);if(s)var u=s(t)}for(n&&n(r);c array('react', 'wp-api-fetch', 'wp-components', 'wp-compose', 'wp-dom-ready', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => '827c1c0c5b711b046baf'); + array('react', 'wp-api-fetch', 'wp-components', 'wp-compose', 'wp-dom-ready', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => 'af6eb0946975f32d53b1'); diff --git a/build/blocks/recommendations/view.js b/build/blocks/recommendations/view.js index ac32818be..d8f4b4577 100644 --- a/build/blocks/recommendations/view.js +++ b/build/blocks/recommendations/view.js @@ -1 +1 @@ -!function(){"use strict";var e={20:function(e,r,n){var t=n(609),o=Symbol.for("react.element"),a=Symbol.for("react.fragment"),i=Object.prototype.hasOwnProperty,s=t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function u(e,r,n){var t,a={},u=null,c=null;for(t in void 0!==n&&(u=""+n),void 0!==r.key&&(u=""+r.key),void 0!==r.ref&&(c=r.ref),r)i.call(r,t)&&!l.hasOwnProperty(t)&&(a[t]=r[t]);if(e&&e.defaultProps)for(t in r=e.defaultProps)void 0===a[t]&&(a[t]=r[t]);return{$$typeof:o,type:e,key:u,ref:c,props:a,_owner:s.current}}r.Fragment=a,r.jsx=u,r.jsxs=u},848:function(e,r,n){e.exports=n(20)},609:function(e){e.exports=window.React}},r={};function n(t){var o=r[t];if(void 0!==o)return o.exports;var a=r[t]={exports:{}};return e[t](a,a.exports,n),a.exports}n.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(r,{a:r}),r},n.d=function(e,r){for(var t in r)n.o(r,t)&&!n.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},n.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},function(){var e,r,t=n(848),o=n(609),a=window.wp.domReady,i=n.n(a),s=window.wp.element,l=window.wp.i18n;(r=e||(e={}))[r.Error=0]="Error",r[r.Loaded=1]="Loaded",r[r.Recommendations=2]="Recommendations";var u=function(){return u=Object.assign||function(e){for(var r,n=1,t=arguments.length;n0&&o[o.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]0&&o[o.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1] array('react', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => 'a741adf6df6b723b2f3d'); + array('react', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => 'd852566173ef137708b0'); diff --git a/build/content-helper/dashboard-widget.js b/build/content-helper/dashboard-widget.js index 50392fc4b..7b17d4192 100644 --- a/build/content-helper/dashboard-widget.js +++ b/build/content-helper/dashboard-widget.js @@ -1 +1 @@ -!function(){"use strict";var e={20:function(e,t,r){var n=r(609),a=Symbol.for("react.element"),s=Symbol.for("react.fragment"),o=Object.prototype.hasOwnProperty,i=n.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function c(e,t,r){var n,s={},c=null,u=null;for(n in void 0!==r&&(c=""+r),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(u=t.ref),t)o.call(t,n)&&!l.hasOwnProperty(n)&&(s[n]=t[n]);if(e&&e.defaultProps)for(n in t=e.defaultProps)void 0===s[n]&&(s[n]=t[n]);return{$$typeof:a,type:e,key:c,ref:u,props:s,_owner:i.current}}t.Fragment=s,t.jsx=c,t.jsxs=c},848:function(e,t,r){e.exports=r(20)},609:function(e){e.exports=window.React}},t={};function r(n){var a=t[n];if(void 0!==a)return a.exports;var s=t[n]={exports:{}};return e[n](s,s.exports,r),s.exports}r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,{a:t}),t},r.d=function(e,t){for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},function(){var e,t,n,a=r(848),s=window.wp.element,o=window.wp.i18n,i=function(e){void 0===e&&(e=null);var t="";(null==e?void 0:e.children)&&(t=e.children);var r="content-helper-error-message";return(null==e?void 0:e.className)&&(r+=" "+e.className),(0,a.jsx)("div",{className:r,"data-testid":null==e?void 0:e.testId,dangerouslySetInnerHTML:{__html:t}})},l=function(e){var t;return void 0===e&&(e=null),(0,a.jsx)(i,{className:null==e?void 0:e.className,testId:"empty-credentials-message",children:null!==(t=window.wpParselyEmptyCredentialsMessage)&&void 0!==t?t:(0,o.__)("Please ensure that the Site ID and API Secret given in the plugin's settings are correct.","wp-parsely")})},c=function(){return c=Object.assign||function(e){for(var t,r=1,n=arguments.length;r0&&a[a.length-1])||6!==i[0]&&2!==i[0])){o=0;continue}if(3===i[0]&&(!a||i[1]>a[0]&&i[1]=1e4&&(clearInterval(s),r("Telemetry library not loaded"))}),100);else r("Telemetry not enabled")}))},e.prototype.trackEvent=function(t,r){var n;this.isLoaded?(0!==t.indexOf(e.TRACKS_PREFIX)&&(t=e.TRACKS_PREFIX+t),this.isEventNameValid(t)?(r=this.prepareProperties(r),null===(n=this._tkq)||void 0===n||n.push(["recordEvent",t,r])):console.error("Error tracking event: Invalid event name")):console.error("Error tracking event: Telemetry not loaded")},e.prototype.isTelemetryEnabled=function(){return this.isEnabled},e.prototype.isProprietyValid=function(t){return e.PROPERTY_REGEX.test(t)},e.prototype.isEventNameValid=function(t){return e.EVENT_NAME_REGEX.test(t)},e.prototype.prepareProperties=function(e){return(e=this.sanitizeProperties(e)).parsely_version=wpParselyTracksTelemetry.version,wpParselyTracksTelemetry.user&&(e._ut=wpParselyTracksTelemetry.user.type,e._ui=wpParselyTracksTelemetry.user.id),wpParselyTracksTelemetry.vipgo_env&&(e.vipgo_env=wpParselyTracksTelemetry.vipgo_env),this.sanitizeProperties(e)},e.prototype.sanitizeProperties=function(e){var t=this,r={};return Object.keys(e).forEach((function(n){t.isProprietyValid(n)&&(r[n]=e[n])})),r},e.TRACKS_PREFIX="wpparsely_",e.EVENT_NAME_REGEX=/^(([a-z0-9]+)_){2}([a-z0-9_]+)$/,e.PROPERTY_REGEX=/^[a-z_][a-z0-9_]*$/,e}(),h=(d.trackEvent,function(e){var t=e.defaultValue,r=e.items,n=e.onChange;return(0,a.jsx)("select",{onChange:n,value:t,children:r.map((function(e){return(0,a.jsx)("option",{value:e[0],children:e[1]},e[0])}))})}),f=window.wp.data,y=function(){return y=Object.assign||function(e){for(var t,r=1,n=arguments.length;rhere.',"wp-parsely"):s.code===j.ParselySuggestionsApiOpenAiError||s.code===j.ParselySuggestionsApiOpenAiUnavailable?s.message=(0,o.__)("The Parse.ly API returned an internal server error. Please retry with a different input, or try again later.","wp-parsely"):s.code===j.HttpRequestFailed&&s.message.includes("cURL error 28")?s.message=(0,o.__)("The Parse.ly API did not respond in a timely manner. Please try again later.","wp-parsely"):s.code===j.ParselySuggestionsApiSchemaError?s.message=(0,o.__)("The Parse.ly API returned a validation error. Please try again with different parameters.","wp-parsely"):s.code===j.ParselySuggestionsApiNoData?s.message=(0,o.__)("The Parse.ly API couldn't find any relevant data to fulfill the request. Please retry with a different input.","wp-parsely"):s.code===j.ParselySuggestionsApiOpenAiSchema?s.message=(0,o.__)("The Parse.ly API returned an incorrect response. Please try again later.","wp-parsely"):s.code===j.ParselySuggestionsApiAuthUnavailable&&(s.message=(0,o.__)("The Parse.ly API is currently unavailable. Please try again later.","wp-parsely")),s}return C(t,e),t.prototype.Message=function(e){return void 0===e&&(e=null),[j.PluginCredentialsNotSetMessageDetected,j.PluginSettingsSiteIdNotSet,j.PluginSettingsApiSecretNotSet].includes(this.code)?l(e):(this.code===j.FetchError&&(this.hint=this.Hint((0,o.__)("This error can sometimes be caused by ad-blockers or browser tracking protections. Please add this site to any applicable allow lists and try again.","wp-parsely"))),this.code!==j.ParselyApiForbidden&&this.code!==j.ParselySuggestionsApiNoAuthentication||(this.hint=this.Hint((0,o.__)("Please ensure that the Site ID and API Secret given in the plugin's settings are correct.","wp-parsely"))),this.code===j.HttpRequestFailed&&(this.hint=this.Hint((0,o.__)("The Parse.ly API cannot be reached. Please verify that you are online.","wp-parsely"))),(0,a.jsx)(i,{className:null==e?void 0:e.className,testId:"error",children:"

".concat(this.message,"

").concat(this.hint?this.hint:"")}))},t.prototype.Hint=function(e){return'

'.concat((0,o.__)("Hint:","wp-parsely")," ").concat(e,"

")},t.prototype.createErrorSnackbar=function(){//.test(this.message)||(0,f.dispatch)("core/notices").createNotice("error",this.message,{type:"snackbar"})},t}(Error),O=function(){function e(){this.abortControllers=new Map}return e.prototype.cancelRequest=function(e){if(e)(t=this.abortControllers.get(e))&&(t.abort(),this.abortControllers.delete(e));else{var t,r=Array.from(this.abortControllers.keys()).pop();r&&(t=this.abortControllers.get(r))&&(t.abort(),this.abortControllers.delete(r))}},e.prototype.cancelAll=function(){this.abortControllers.forEach((function(e){return e.abort()})),this.abortControllers.clear()},e.prototype.getOrCreateController=function(e){if(e&&this.abortControllers.has(e))return{abortController:this.abortControllers.get(e),abortId:e};var t=null!=e?e:"auto-"+Date.now(),r=new AbortController;return this.abortControllers.set(t,r),{abortController:r,abortId:t}},e.prototype.fetch=function(e,t){return r=this,n=void 0,s=function(){var r,n,a,s,i,l;return function(e,t){var r,n,a,s,o={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]};return s={next:i(0),throw:i(1),return:i(2)},"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function i(i){return function(l){return function(i){if(r)throw new TypeError("Generator is already executing.");for(;s&&(s=0,i[0]&&(o=0)),o;)try{if(r=1,n&&(a=2&i[0]?n.return:i[0]?n.throw||((a=n.return)&&a.call(n),0):n.next)&&!(a=a.call(n,i[1])).done)return a;switch(n=0,a&&(i=[2&i[0],a.value]),i[0]){case 0:case 1:a=i;break;case 4:return o.label++,{value:i[1],done:!1};case 5:o.label++,n=i[1],i=[0];continue;case 7:i=o.ops.pop(),o.trys.pop();continue;default:if(!((a=(a=o.trys).length>0&&a[a.length-1])||6!==i[0]&&2!==i[0])){o=0;continue}if(3===i[0]&&(!a||i[1]>a[0]&&i[1]0&&a[a.length-1])||6!==i[0]&&2!==i[0])){o=0;continue}if(3===i[0]&&(!a||i[1]>a[0]&&i[1]=c){var u=t;(a=n/c)%1>1/i&&(u=a>10?1:2),u=parseFloat(a.toFixed(2))===parseFloat(a.toFixed(0))?0:u,s=a.toFixed(u),o=l}i=c})),s+r+o}function z(e){var t=e.metric,r=e.post,n=e.avgEngagedIcon,s=e.viewsIcon;return"views"===t?(0,a.jsxs)("span",{className:"parsely-post-metric-data",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Number of Views","wp-parsely")}),s,$(r.views.toString())]}):"avg_engaged"===t?(0,a.jsxs)("span",{className:"parsely-post-metric-data",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Average Time","wp-parsely")}),n,r.avgEngaged]}):(0,a.jsx)("span",{className:"parsely-post-metric-data",children:"-"})}function X(e){var t,r=e.metric,n=e.post;return(0,a.jsx)("li",{className:"parsely-top-post",children:(0,a.jsxs)("div",{className:"parsely-top-post-content",children:[(0,a.jsx)(B,{post:n}),(0,a.jsxs)("div",{className:"parsely-top-post-data",children:[(0,a.jsx)(z,{metric:r,post:n}),(0,a.jsx)(Z,{post:n}),(0,a.jsxs)("a",{className:"parsely-top-post-icon-link",href:n.url,target:"_blank",rel:"noreferrer",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("View Post (opens in new tab)","wp-parsely")}),(0,a.jsx)(q,{})]}),0!==n.postId&&(0,a.jsxs)("a",{className:"parsely-top-post-icon-link",href:(t=n.postId,"/wp-admin/post.php?post=".concat(t,"&action=edit")),target:"_blank",rel:"noreferrer",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Edit Post (opens in new tab)","wp-parsely")}),(0,a.jsx)(G,{})]}),(0,a.jsxs)("div",{className:"parsely-top-post-metadata",children:[(0,a.jsxs)("span",{className:"parsely-top-post-date",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Date","wp-parsely")}),M(new Date(n.date))]}),(0,a.jsxs)("span",{className:"parsely-top-post-author",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Author","wp-parsely")}),n.author]})]})]})]})},n.id)}function B(e){var t=e.post;return t.thumbnailUrl?(0,a.jsxs)("div",{className:"parsely-top-post-thumbnail",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Thumbnail","wp-parsely")}),(0,a.jsx)("img",{src:t.thumbnailUrl,alt:(0,o.__)("Post thumbnail","wp-parsely")})]}):(0,a.jsx)("div",{className:"parsely-top-post-thumbnail",children:(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Post thumbnail not available","wp-parsely")})})}function Z(e){var t=e.post;return(0,a.jsxs)("a",{className:"parsely-top-post-title",href:t.dashUrl,target:"_blank",rel:"noreferrer",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("View in Parse.ly (opens in new tab)","wp-parsely")}),t.title]})}var W=function(){return W=Object.assign||function(e){for(var t,r=1,n=arguments.length;r0&&a[a.length-1])||6!==i[0]&&2!==i[0])){o=0;continue}if(3===i[0]&&(!a||i[1]>a[0]&&i[1]0&&e.retryFetch?[4,new Promise((function(e){return setTimeout(e,500)}))]:[3,3];case 1:return r.sent(),[4,t(n-1)];case 2:return r.sent(),[3,4];case 3:f(!1),v(e),r.label=4;case 4:return[2]}}))}))})),[2]}))}))};return f(!0),t(1),function(){f(!1),m([]),v(void 0)}}),[i,S]);var j=function(e,t){d.trackEvent("dash_widget_filter_changed",W({filter:e},t))},N=(0,a.jsxs)("div",{className:"parsely-top-posts-filters",children:[(0,a.jsx)(h,{defaultValue:i.Period,items:Object.values(e).map((function(e){return[e,A(e)]})),onChange:function(t){x(t.target.value,e)&&(l({Period:t.target.value}),j("period",{period:t.target.value}),T(1))}}),(0,a.jsx)(h,{defaultValue:i.Metric,items:Object.values(t).map((function(e){return[e,E(e)]})),onChange:function(e){x(e.target.value,t)&&(l({Metric:e.target.value}),j("metric",{metric:e.target.value}),T(1))}})]}),C=(0,a.jsxs)("div",{className:"parsely-top-posts-navigation",children:[(0,a.jsx)("button",{className:"parsely-top-posts-navigation-prev",disabled:S<=1,"aria-label":(0,o.__)("Previous page","wp-parsely"),onClick:function(){T(S-1),d.trackEvent("dash_widget_navigation",{navigation:"previous",to_page:S-1})},children:(0,o.__)("<< Previous","wp-parsely")}),(0,o.sprintf)(/* translators: 1: Current page */ /* translators: 1: Current page */(0,o.__)("Page %1$d","wp-parsely"),S),(0,a.jsx)("button",{className:"parsely-top-posts-navigation-next",disabled:!u&&_.length<5,"aria-label":(0,o.__)("Next page","wp-parsely"),onClick:function(){T(S+1),d.trackEvent("dash_widget_navigation",{navigation:"next",to_page:S+1})},children:(0,o.__)("Next >>","wp-parsely")})]});if(g)return(0,a.jsxs)(a.Fragment,{children:[N,g.Message(),S>1&&C]});var k=(0,a.jsx)("div",{className:"parsely-spinner-wrapper",children:(0,a.jsx)(p.Spinner,{})});return(0,a.jsxs)(a.Fragment,{children:[N,u?k:(0,a.jsx)("ol",{className:"parsely-top-posts",style:{counterReset:"item "+5*(S-1)},children:_.map((function(e){return(0,a.jsx)(X,{metric:i.Metric,post:e},e.id)}))}),(_.length>=5||S>1)&&C]})}var J=function(r){var n;try{n=JSON.parse(r)}catch(r){return{Metric:t.Views,Period:e.Days7}}return x(null==n?void 0:n.Metric,t)||(n.Metric=t.Views),x(null==n?void 0:n.Period,e)||(n.Period=e.Days7),n};window.addEventListener("load",(function(){var e=document.querySelector("#wp-parsely-dashboard-widget > .inside");if(null!==e){var t=(0,a.jsx)(S,{endpoint:"dashboard-widget-settings",defaultSettings:J(window.wpParselyContentHelperSettings),children:(0,a.jsx)(u,{children:(0,a.jsx)(Q,{})})});s.createRoot?(0,s.createRoot)(e).render(t):(0,s.render)(t,e)}}),!1)}()}(); \ No newline at end of file +!function(){"use strict";var e={20:function(e,t,r){var n=r(609),a=Symbol.for("react.element"),s=Symbol.for("react.fragment"),o=Object.prototype.hasOwnProperty,i=n.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function c(e,t,r){var n,s={},c=null,u=null;for(n in void 0!==r&&(c=""+r),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(u=t.ref),t)o.call(t,n)&&!l.hasOwnProperty(n)&&(s[n]=t[n]);if(e&&e.defaultProps)for(n in t=e.defaultProps)void 0===s[n]&&(s[n]=t[n]);return{$$typeof:a,type:e,key:c,ref:u,props:s,_owner:i.current}}t.Fragment=s,t.jsx=c,t.jsxs=c},848:function(e,t,r){e.exports=r(20)},609:function(e){e.exports=window.React}},t={};function r(n){var a=t[n];if(void 0!==a)return a.exports;var s=t[n]={exports:{}};return e[n](s,s.exports,r),s.exports}r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,{a:t}),t},r.d=function(e,t){for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},function(){var e,t,n,a=r(848),s=window.wp.element,o=window.wp.i18n,i=function(e){void 0===e&&(e=null);var t="";(null==e?void 0:e.children)&&(t=e.children);var r="content-helper-error-message";return(null==e?void 0:e.className)&&(r+=" "+e.className),(0,a.jsx)("div",{className:r,"data-testid":null==e?void 0:e.testId,dangerouslySetInnerHTML:{__html:t}})},l=function(e){var t;return void 0===e&&(e=null),(0,a.jsx)(i,{className:null==e?void 0:e.className,testId:"empty-credentials-message",children:null!==(t=window.wpParselyEmptyCredentialsMessage)&&void 0!==t?t:(0,o.__)("Please ensure that the Site ID and API Secret given in the plugin's settings are correct.","wp-parsely")})},c=function(){return c=Object.assign||function(e){for(var t,r=1,n=arguments.length;r0&&a[a.length-1])||6!==i[0]&&2!==i[0])){o=0;continue}if(3===i[0]&&(!a||i[1]>a[0]&&i[1]=1e4&&(clearInterval(s),r("Telemetry library not loaded"))}),100);else r("Telemetry not enabled")}))},e.prototype.trackEvent=function(t,r){var n;this.isLoaded?(0!==t.indexOf(e.TRACKS_PREFIX)&&(t=e.TRACKS_PREFIX+t),this.isEventNameValid(t)?(r=this.prepareProperties(r),null===(n=this._tkq)||void 0===n||n.push(["recordEvent",t,r])):console.error("Error tracking event: Invalid event name")):console.error("Error tracking event: Telemetry not loaded")},e.prototype.isTelemetryEnabled=function(){return this.isEnabled},e.prototype.isProprietyValid=function(t){return e.PROPERTY_REGEX.test(t)},e.prototype.isEventNameValid=function(t){return e.EVENT_NAME_REGEX.test(t)},e.prototype.prepareProperties=function(e){return(e=this.sanitizeProperties(e)).parsely_version=wpParselyTracksTelemetry.version,wpParselyTracksTelemetry.user&&(e._ut=wpParselyTracksTelemetry.user.type,e._ui=wpParselyTracksTelemetry.user.id),wpParselyTracksTelemetry.vipgo_env&&(e.vipgo_env=wpParselyTracksTelemetry.vipgo_env),this.sanitizeProperties(e)},e.prototype.sanitizeProperties=function(e){var t=this,r={};return Object.keys(e).forEach((function(n){t.isProprietyValid(n)&&(r[n]=e[n])})),r},e.TRACKS_PREFIX="wpparsely_",e.EVENT_NAME_REGEX=/^(([a-z0-9]+)_){2}([a-z0-9_]+)$/,e.PROPERTY_REGEX=/^[a-z_][a-z0-9_]*$/,e}(),h=(d.trackEvent,function(e){var t=e.defaultValue,r=e.items,n=e.onChange;return(0,a.jsx)("select",{onChange:n,value:t,children:r.map((function(e){return(0,a.jsx)("option",{value:e[0],children:e[1]},e[0])}))})}),f=window.wp.data,y=function(){return y=Object.assign||function(e){for(var t,r=1,n=arguments.length;rhere.',"wp-parsely"):s.code===j.ParselySuggestionsApiOpenAiError||s.code===j.ParselySuggestionsApiOpenAiUnavailable?s.message=(0,o.__)("The Parse.ly API returned an internal server error. Please retry with a different input, or try again later.","wp-parsely"):s.code===j.HttpRequestFailed&&s.message.includes("cURL error 28")?s.message=(0,o.__)("The Parse.ly API did not respond in a timely manner. Please try again later.","wp-parsely"):s.code===j.ParselySuggestionsApiSchemaError?s.message=(0,o.__)("The Parse.ly API returned a validation error. Please try again with different parameters.","wp-parsely"):s.code===j.ParselySuggestionsApiNoData?s.message=(0,o.__)("The Parse.ly API couldn't find any relevant data to fulfill the request. Please retry with a different input.","wp-parsely"):s.code===j.ParselySuggestionsApiOpenAiSchema?s.message=(0,o.__)("The Parse.ly API returned an incorrect response. Please try again later.","wp-parsely"):s.code===j.ParselySuggestionsApiAuthUnavailable&&(s.message=(0,o.__)("The Parse.ly API is currently unavailable. Please try again later.","wp-parsely")),s}return C(t,e),t.prototype.Message=function(e){return void 0===e&&(e=null),[j.PluginCredentialsNotSetMessageDetected,j.PluginSettingsSiteIdNotSet,j.PluginSettingsApiSecretNotSet].includes(this.code)?l(e):(this.code===j.FetchError&&(this.hint=this.Hint((0,o.__)("This error can sometimes be caused by ad-blockers or browser tracking protections. Please add this site to any applicable allow lists and try again.","wp-parsely"))),this.code!==j.ParselyApiForbidden&&this.code!==j.ParselySuggestionsApiNoAuthentication||(this.hint=this.Hint((0,o.__)("Please ensure that the Site ID and API Secret given in the plugin's settings are correct.","wp-parsely"))),this.code===j.HttpRequestFailed&&(this.hint=this.Hint((0,o.__)("The Parse.ly API cannot be reached. Please verify that you are online.","wp-parsely"))),(0,a.jsx)(i,{className:null==e?void 0:e.className,testId:"error",children:"

".concat(this.message,"

").concat(this.hint?this.hint:"")}))},t.prototype.Hint=function(e){return'

'.concat((0,o.__)("Hint:","wp-parsely")," ").concat(e,"

")},t.prototype.createErrorSnackbar=function(){//.test(this.message)||(0,f.dispatch)("core/notices").createNotice("error",this.message,{type:"snackbar"})},t}(Error),O=function(){function e(){this.abortControllers=new Map}return e.prototype.cancelRequest=function(e){if(e)(t=this.abortControllers.get(e))&&(t.abort(),this.abortControllers.delete(e));else{var t,r=Array.from(this.abortControllers.keys()).pop();r&&(t=this.abortControllers.get(r))&&(t.abort(),this.abortControllers.delete(r))}},e.prototype.cancelAll=function(){this.abortControllers.forEach((function(e){return e.abort()})),this.abortControllers.clear()},e.prototype.getOrCreateController=function(e){if(e&&this.abortControllers.has(e))return{abortController:this.abortControllers.get(e),abortId:e};var t=null!=e?e:"auto-"+Date.now(),r=new AbortController;return this.abortControllers.set(t,r),{abortController:r,abortId:t}},e.prototype.fetch=function(e,t){return r=this,n=void 0,s=function(){var r,n,a,s,i,l;return function(e,t){var r,n,a,s,o={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]};return s={next:i(0),throw:i(1),return:i(2)},"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function i(i){return function(l){return function(i){if(r)throw new TypeError("Generator is already executing.");for(;s&&(s=0,i[0]&&(o=0)),o;)try{if(r=1,n&&(a=2&i[0]?n.return:i[0]?n.throw||((a=n.return)&&a.call(n),0):n.next)&&!(a=a.call(n,i[1])).done)return a;switch(n=0,a&&(i=[2&i[0],a.value]),i[0]){case 0:case 1:a=i;break;case 4:return o.label++,{value:i[1],done:!1};case 5:o.label++,n=i[1],i=[0];continue;case 7:i=o.ops.pop(),o.trys.pop();continue;default:if(!((a=(a=o.trys).length>0&&a[a.length-1])||6!==i[0]&&2!==i[0])){o=0;continue}if(3===i[0]&&(!a||i[1]>a[0]&&i[1]0&&a[a.length-1])||6!==i[0]&&2!==i[0])){o=0;continue}if(3===i[0]&&(!a||i[1]>a[0]&&i[1]=c){var u=t;(a=n/c)%1>1/i&&(u=a>10?1:2),u=parseFloat(a.toFixed(2))===parseFloat(a.toFixed(0))?0:u,s=a.toFixed(u),o=l}i=c})),s+r+o}function z(e){var t=e.metric,r=e.post,n=e.avgEngagedIcon,s=e.viewsIcon;return"views"===t?(0,a.jsxs)("span",{className:"parsely-post-metric-data",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Number of Views","wp-parsely")}),s,$(r.views.toString())]}):"avg_engaged"===t?(0,a.jsxs)("span",{className:"parsely-post-metric-data",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Average Time","wp-parsely")}),n,r.avgEngaged]}):(0,a.jsx)("span",{className:"parsely-post-metric-data",children:"-"})}function X(e){var t,r=e.metric,n=e.post;return(0,a.jsx)("li",{className:"parsely-top-post",children:(0,a.jsxs)("div",{className:"parsely-top-post-content",children:[(0,a.jsx)(B,{post:n}),(0,a.jsxs)("div",{className:"parsely-top-post-data",children:[(0,a.jsx)(z,{metric:r,post:n}),(0,a.jsx)(Z,{post:n}),(0,a.jsxs)("a",{className:"parsely-top-post-icon-link",href:n.url,target:"_blank",rel:"noreferrer",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("View Post (opens in new tab)","wp-parsely")}),(0,a.jsx)(q,{})]}),0!==n.postId&&(0,a.jsxs)("a",{className:"parsely-top-post-icon-link",href:(t=n.postId,"/wp-admin/post.php?post=".concat(t,"&action=edit")),target:"_blank",rel:"noreferrer",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Edit Post (opens in new tab)","wp-parsely")}),(0,a.jsx)(G,{})]}),(0,a.jsxs)("div",{className:"parsely-top-post-metadata",children:[(0,a.jsxs)("span",{className:"parsely-top-post-date",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Date","wp-parsely")}),M(new Date(n.date))]}),(0,a.jsxs)("span",{className:"parsely-top-post-author",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Author","wp-parsely")}),n.author]})]})]})]})},n.id)}function B(e){var t=e.post;return t.thumbnailUrl?(0,a.jsxs)("div",{className:"parsely-top-post-thumbnail",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Thumbnail","wp-parsely")}),(0,a.jsx)("img",{src:t.thumbnailUrl,alt:(0,o.__)("Post thumbnail","wp-parsely")})]}):(0,a.jsx)("div",{className:"parsely-top-post-thumbnail",children:(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Post thumbnail not available","wp-parsely")})})}function Z(e){var t=e.post;return(0,a.jsxs)("a",{className:"parsely-top-post-title",href:t.dashUrl,target:"_blank",rel:"noreferrer",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("View in Parse.ly (opens in new tab)","wp-parsely")}),t.title]})}var W=function(){return W=Object.assign||function(e){for(var t,r=1,n=arguments.length;r0&&a[a.length-1])||6!==i[0]&&2!==i[0])){o=0;continue}if(3===i[0]&&(!a||i[1]>a[0]&&i[1]0&&e.retryFetch?[4,new Promise((function(e){return setTimeout(e,500)}))]:[3,3];case 1:return r.sent(),[4,t(n-1)];case 2:return r.sent(),[3,4];case 3:f(!1),v(e),r.label=4;case 4:return[2]}}))}))})),[2]}))}))};return f(!0),t(1),function(){f(!1),m([]),v(void 0)}}),[i,S]);var j=function(e,t){d.trackEvent("dash_widget_filter_changed",W({filter:e},t))},N=(0,a.jsxs)("div",{className:"parsely-top-posts-filters",children:[(0,a.jsx)(h,{defaultValue:i.Period,items:Object.values(e).map((function(e){return[e,A(e)]})),onChange:function(t){x(t.target.value,e)&&(l({Period:t.target.value}),j("period",{period:t.target.value}),T(1))}}),(0,a.jsx)(h,{defaultValue:i.Metric,items:Object.values(t).map((function(e){return[e,E(e)]})),onChange:function(e){x(e.target.value,t)&&(l({Metric:e.target.value}),j("metric",{metric:e.target.value}),T(1))}})]}),C=(0,a.jsxs)("div",{className:"parsely-top-posts-navigation",children:[(0,a.jsx)("button",{className:"parsely-top-posts-navigation-prev",disabled:S<=1,"aria-label":(0,o.__)("Previous page","wp-parsely"),onClick:function(){T(S-1),d.trackEvent("dash_widget_navigation",{navigation:"previous",to_page:S-1})},children:(0,o.__)("<< Previous","wp-parsely")}),(0,o.sprintf)(/* translators: 1: Current page */ /* translators: 1: Current page */(0,o.__)("Page %1$d","wp-parsely"),S),(0,a.jsx)("button",{className:"parsely-top-posts-navigation-next",disabled:!u&&_.length<5,"aria-label":(0,o.__)("Next page","wp-parsely"),onClick:function(){T(S+1),d.trackEvent("dash_widget_navigation",{navigation:"next",to_page:S+1})},children:(0,o.__)("Next >>","wp-parsely")})]});if(g)return(0,a.jsxs)(a.Fragment,{children:[N,g.Message(),S>1&&C]});var k=(0,a.jsx)("div",{className:"parsely-spinner-wrapper",children:(0,a.jsx)(p.Spinner,{})});return(0,a.jsxs)(a.Fragment,{children:[N,u?k:(0,a.jsx)("ol",{className:"parsely-top-posts",style:{counterReset:"item "+5*(S-1)},children:_.map((function(e){return(0,a.jsx)(X,{metric:i.Metric,post:e},e.id)}))}),(_.length>=5||S>1)&&C]})}var J=function(r){var n;try{n=JSON.parse(r)}catch(r){return{Metric:t.Views,Period:e.Days7}}return x(null==n?void 0:n.Metric,t)||(n.Metric=t.Views),x(null==n?void 0:n.Period,e)||(n.Period=e.Days7),n};window.addEventListener("load",(function(){var e=document.querySelector("#wp-parsely-dashboard-widget > .inside");if(null!==e){var t=(0,a.jsx)(S,{endpoint:"dashboard-widget-settings",defaultSettings:J(window.wpParselyContentHelperSettings),children:(0,a.jsx)(u,{children:(0,a.jsx)(Q,{})})});s.createRoot?(0,s.createRoot)(e).render(t):(0,s.render)(t,e)}}),!1)}()}(); \ No newline at end of file diff --git a/build/content-helper/editor-sidebar.asset.php b/build/content-helper/editor-sidebar.asset.php index 0a96a2013..a791b1c32 100644 --- a/build/content-helper/editor-sidebar.asset.php +++ b/build/content-helper/editor-sidebar.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-dom-ready', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-plugins', 'wp-primitives', 'wp-url'), 'version' => 'ceb704108c34274732ed'); + array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-dom-ready', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-plugins', 'wp-primitives', 'wp-url'), 'version' => 'eaad1ca5764f3fbdb9e6'); diff --git a/build/content-helper/editor-sidebar.js b/build/content-helper/editor-sidebar.js index 303604252..697b66067 100644 --- a/build/content-helper/editor-sidebar.js +++ b/build/content-helper/editor-sidebar.js @@ -9,11 +9,11 @@ /* translators: %s: percentage value */,{ /* translators: %s: percentage value */ text:"".concat(c(t)," - ").concat((0,_.sprintf)((0,_.__)("%s%%","wp-parsely"),n.viewsPercentage)),delay:150,children:(0,p.jsx)("div",{"aria-label":r,className:"bar-fill "+t,style:{width:n.viewsPercentage+"%"}})},t)}))}),(0,p.jsx)("div",{className:"percentage-bar-labels",children:Object.entries(t.referrers.types).map((function(e){var t=e[0],n=e[1];return(0,p.jsxs)("div",{className:"single-label "+t,children:[(0,p.jsx)("div",{className:"label-color "+t}),(0,p.jsx)("div",{className:"label-text",children:c(t)}),(0,p.jsx)("div",{className:"label-value",children:Lt(n.views)})]},t)}))})]})]})},Nt=(0,p.jsx)(x.SVG,{viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:(0,p.jsx)(x.Path,{d:"M3.99961 13C4.67043 13.3354 4.6703 13.3357 4.67017 13.3359L4.67298 13.3305C4.67621 13.3242 4.68184 13.3135 4.68988 13.2985C4.70595 13.2686 4.7316 13.2218 4.76695 13.1608C4.8377 13.0385 4.94692 12.8592 5.09541 12.6419C5.39312 12.2062 5.84436 11.624 6.45435 11.0431C7.67308 9.88241 9.49719 8.75 11.9996 8.75C14.502 8.75 16.3261 9.88241 17.5449 11.0431C18.1549 11.624 18.6061 12.2062 18.9038 12.6419C19.0523 12.8592 19.1615 13.0385 19.2323 13.1608C19.2676 13.2218 19.2933 13.2686 19.3093 13.2985C19.3174 13.3135 19.323 13.3242 19.3262 13.3305L19.3291 13.3359C19.3289 13.3357 19.3288 13.3354 19.9996 13C20.6704 12.6646 20.6703 12.6643 20.6701 12.664L20.6697 12.6632L20.6688 12.6614L20.6662 12.6563L20.6583 12.6408C20.6517 12.6282 20.6427 12.6108 20.631 12.5892C20.6078 12.5459 20.5744 12.4852 20.5306 12.4096C20.4432 12.2584 20.3141 12.0471 20.1423 11.7956C19.7994 11.2938 19.2819 10.626 18.5794 9.9569C17.1731 8.61759 14.9972 7.25 11.9996 7.25C9.00203 7.25 6.82614 8.61759 5.41987 9.9569C4.71736 10.626 4.19984 11.2938 3.85694 11.7956C3.68511 12.0471 3.55605 12.2584 3.4686 12.4096C3.42484 12.4852 3.39142 12.5459 3.36818 12.5892C3.35656 12.6108 3.34748 12.6282 3.34092 12.6408L3.33297 12.6563L3.33041 12.6614L3.32948 12.6632L3.32911 12.664C3.32894 12.6643 3.32879 12.6646 3.99961 13ZM11.9996 16C13.9326 16 15.4996 14.433 15.4996 12.5C15.4996 10.567 13.9326 9 11.9996 9C10.0666 9 8.49961 10.567 8.49961 12.5C8.49961 14.433 10.0666 16 11.9996 16Z"})}),Ct=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"M15.5 9.5a1 1 0 100-2 1 1 0 000 2zm0 1.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5zm-2.25 6v-2a2.75 2.75 0 00-2.75-2.75h-4A2.75 2.75 0 003.75 15v2h1.5v-2c0-.69.56-1.25 1.25-1.25h4c.69 0 1.25.56 1.25 1.25v2h1.5zm7-2v2h-1.5v-2c0-.69-.56-1.25-1.25-1.25H15v-1.5h2.5A2.75 2.75 0 0120.25 15zM9.5 8.5a1 1 0 11-2 0 1 1 0 012 0zm1.5 0a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0z",fillRule:"evenodd"})}),At=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"M12 4V2.2L9 4.8l3 2.5V5.5c3.6 0 6.5 2.9 6.5 6.5 0 2.9-1.9 5.3-4.5 6.2v.2l-.1-.2c-.4.1-.7.2-1.1.2l.2 1.5c.3 0 .6-.1 1-.2 3.5-.9 6-4 6-7.7 0-4.4-3.6-8-8-8zm-7.9 7l1.5.2c.1-1.2.5-2.3 1.2-3.2l-1.1-.9C4.8 8.2 4.3 9.6 4.1 11zm1.5 1.8l-1.5.2c.1.7.3 1.4.5 2 .3.7.6 1.3 1 1.8l1.2-.8c-.3-.5-.6-1-.8-1.5s-.4-1.1-.4-1.7zm1.5 5.5c1.1.9 2.4 1.4 3.8 1.6l.2-1.5c-1.1-.1-2.2-.5-3.1-1.2l-.9 1.1z"})}),Ot=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"M11 13h2v-2h-2v2zm-6 0h2v-2H5v2zm12-2v2h2v-2h-2z"})}),Rt=function(){return Rt=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]1?[2,Promise.reject(new ie((0,_.sprintf)(/* translators: URL of the published post */ /* translators: URL of the published post */ -(0,_.__)("Multiple results were returned for the post %s by the Parse.ly API.","wp-parsely"),t),$.ParselyApiReturnedTooManyResults))]:[2,n[0]]}}))}))},t.prototype.fetchReferrerDataFromWpEndpoint=function(e,t,n){return Zt(this,void 0,void 0,(function(){return $t(this,(function(r){switch(r.label){case 0:return[4,this.fetch({path:(0,Oe.addQueryArgs)("/wp-parsely/v1/referrers/post/detail",qt(qt({},zt(e)),{itm_source:this.itmSource,total_views:n,url:t}))})];case 1:return[2,r.sent()]}}))}))},t}(Re),Kt=function(){return Kt=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&e.retryFetch?[4,new Promise((function(e){return setTimeout(e,500)}))]:[3,3];case 1:return t.sent(),[4,n(r-1)];case 2:return t.sent(),[3,4];case 3:a(e),i(!1),t.label=4;case 4:return[2]}}))}))})),[2]}))}))};return i(!0),n(1),function(){a(void 0)}}),[t]),(0,p.jsxs)("div",{className:"wp-parsely-performance-panel",children:[(0,p.jsx)(Tt,{title:(0,_.__)("Performance Stats","wp-parsely"),icon:jt,dropdownChildren:function(e){var t=e.onClose;return(0,p.jsx)(tn,{onClose:t})},children:(0,p.jsx)("div",{className:"panel-settings",children:(0,p.jsx)(f.SelectControl,{size:"__unstable-large",value:h.PerformanceStats.Period,prefix:(0,p.jsx)(f.__experimentalInputControlPrefixWrapper,{children:(0,_.__)("Period: ","wp-parsely")}),onChange:function(e){D(e,y)&&(v({PerformanceStats:Kt(Kt({},h.PerformanceStats),{Period:e})}),P.trackEvent("editor_sidebar_performance_period_changed",{period:e}))},children:Object.values(y).map((function(e){return(0,p.jsx)("option",{value:e,children:F(e)},e)}))})})}),o?o.Message():(0,p.jsxs)(p.Fragment,{children:[en(h,"overview")&&(0,p.jsx)(Gt,{data:c,isLoading:r}),en(h,"categories")&&(0,p.jsx)(Et,{data:c,isLoading:r}),en(h,"referrers")&&(0,p.jsx)(Ht,{data:c,isLoading:r})]}),window.wpParselyPostUrl&&(0,p.jsx)(f.Button,{className:"wp-parsely-view-post",variant:"primary",onClick:function(){P.trackEvent("editor_sidebar_view_post_pressed")},href:window.wpParselyPostUrl,rel:"noopener",target:"_blank",children:(0,_.__)("View this in Parse.ly","wp-parsely")})]})},rn=function(e){var t=e.period;return(0,p.jsx)(f.Panel,{children:(0,p.jsx)(J,{children:(0,p.jsx)(nn,{period:t})})})},sn=function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(r=Object.getOwnPropertySymbols(e);i=1&&(0,p.jsx)(f.__experimentalToggleGroupControlOption,{value:w.Tag,label:(0,_.__)("Tag","wp-parsely")}),r.categories.length>=1&&(0,p.jsx)(f.__experimentalToggleGroupControlOption,{value:w.Section,label:(0,_.__)("Section","wp-parsely")}),r.authors.length>=1&&(0,p.jsx)(f.__experimentalToggleGroupControlOption,{value:w.Author,label:(0,_.__)("Author","wp-parsely")})]})})},an=function(e){var t=e.filter,n=e.label,r=e.postData,i=sn(e,["filter","label","postData"]);return(0,p.jsx)("div",{className:"related-posts-filter-values",children:(0,p.jsx)(f.ComboboxControl,{__next40pxDefaultSize:!0,allowReset:!0,label:n,onChange:function(e){return i.onFilterValueChange(e)},options:w.Tag===t.type?r.tags.map((function(e){return{value:e,label:e}})):w.Section===t.type?r.categories.map((function(e){return{value:e,label:e}})):w.Author===t.type?r.authors.map((function(e){return{value:e,label:e}})):[],value:t.value})})},ln=function(e){var t=e.filter,n=e.postData,r=e.label,i=sn(e,["filter","postData","label"]),s=function(){return n.authors.length>0&&n.categories.length>0||n.authors.length>0&&n.tags.length>0||n.tags.length>0&&n.categories.length>0},o=function(){return w.Tag===t.type&&n.tags.length>1||w.Section===t.type&&n.categories.length>1||w.Author===t.type&&n.authors.length>1};return s()||o()?(0,p.jsxs)("div",{className:"related-posts-filter-settings",children:[s()&&(0,p.jsx)(on,{filter:t,label:r,onFilterTypeChange:i.onFilterTypeChange,postData:n}),o()&&(0,p.jsx)(an,{filter:t,label:s()?void 0:r,onFilterValueChange:i.onFilterValueChange,postData:n})]}):null},cn=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"M10 17.389H8.444A5.194 5.194 0 1 1 8.444 7H10v1.5H8.444a3.694 3.694 0 0 0 0 7.389H10v1.5ZM14 7h1.556a5.194 5.194 0 0 1 0 10.39H14v-1.5h1.556a3.694 3.694 0 0 0 0-7.39H14V7Zm-4.5 6h5v-1.5h-5V13Z"})}),un=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M5.625 5.5h9.75c.069 0 .125.056.125.125v9.75a.125.125 0 0 1-.125.125h-9.75a.125.125 0 0 1-.125-.125v-9.75c0-.069.056-.125.125-.125ZM4 5.625C4 4.728 4.728 4 5.625 4h9.75C16.273 4 17 4.728 17 5.625v9.75c0 .898-.727 1.625-1.625 1.625h-9.75A1.625 1.625 0 0 1 4 15.375v-9.75Zm14.5 11.656v-9H20v9C20 18.8 18.77 20 17.251 20H6.25v-1.5h11.001c.69 0 1.249-.528 1.249-1.219Z"})}),dn=function(){return(0,p.jsx)(f.SVG,{xmlns:"http://www.w3.org/2000/svg",width:"1",height:"40",viewBox:"0 0 1 40",fill:"none",children:(0,p.jsx)(f.Rect,{width:"1",height:"40",fill:"#cccccc"})})};function pn(e){var t=e.metric,n=e.post,r=e.avgEngagedIcon,i=e.viewsIcon;return"views"===t?(0,p.jsxs)("span",{className:"parsely-post-metric-data",children:[(0,p.jsx)("span",{className:"screen-reader-text",children:(0,_.__)("Number of Views","wp-parsely")}),i,Lt(n.views.toString())]}):"avg_engaged"===t?(0,p.jsxs)("span",{className:"parsely-post-metric-data",children:[(0,p.jsx)("span",{className:"screen-reader-text",children:(0,_.__)("Average Time","wp-parsely")}),r,n.avgEngaged]}):(0,p.jsx)("span",{className:"parsely-post-metric-data",children:"-"})}var fn,hn=function(e){var t,n,r=e.metric,i=e.post,s=e.postContent,o=(0,h.useDispatch)("core/notices").createNotice,a=s&&(t=s,n=q(i.rawUrl),new RegExp("]*href=[\"'](http://|https://)?.*".concat(n,".*[\"'][^>]*>"),"i").test(t));return(0,p.jsxs)("div",{className:"related-post-single","data-testid":"related-post-single",children:[(0,p.jsx)("div",{className:"related-post-title",children:(0,p.jsxs)("a",{href:i.url,target:"_blank",rel:"noreferrer",children:[(0,p.jsx)("span",{className:"screen-reader-text",children:(0,_.__)("View on website (opens new tab)","wp-parsely")}),i.title]})}),(0,p.jsx)("div",{className:"related-post-actions",children:(0,p.jsxs)("div",{className:"related-post-info",children:[(0,p.jsxs)("div",{children:[(0,p.jsx)("div",{className:"related-post-metric",children:(0,p.jsx)(pn,{metric:r,post:i,viewsIcon:(0,p.jsx)(X,{icon:Nt}),avgEngagedIcon:(0,p.jsx)(f.Dashicon,{icon:"clock",size:24})})}),a&&(0,p.jsx)("div",{className:"related-post-linked",children:(0,p.jsx)(f.Tooltip,{text:(0,_.__)("This post is linked in the content","wp-parsely"),children:(0,p.jsx)(X,{icon:cn,size:24})})})]}),(0,p.jsx)(dn,{}),(0,p.jsxs)("div",{children:[(0,p.jsx)(f.Button,{icon:un,iconSize:24,onClick:function(){navigator.clipboard.writeText(i.rawUrl).then((function(){o("success",(0,_.__)("URL copied to clipboard","wp-parsely"),{type:"snackbar"})}))},label:(0,_.__)("Copy URL to clipboard","wp-parsely")}),(0,p.jsx)(f.Button,{icon:(0,p.jsx)(T,{}),iconSize:18,href:i.dashUrl,target:"_blank",label:(0,_.__)("View in Parse.ly","wp-parsely")})]})]})})]})},vn=window.wp.coreData,gn=function(){var e=function(t,n){return e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},e(t,n)};return function(t,n){if("function"!=typeof n&&null!==n)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");function __(){this.constructor=t}e(t,n),t.prototype=null===n?Object.create(n):(__.prototype=n.prototype,new __)}}(),yn=function(){return yn=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]1?[2,Promise.reject(new ie((0,_.sprintf)(/* translators: URL of the published post */ /* translators: URL of the published post */ +(0,_.__)("Multiple results were returned for the post %d by the Parse.ly API.","wp-parsely"),t),$.ParselyApiReturnedTooManyResults))]:[2,n[0]]}}))}))},t.prototype.fetchReferrerDataFromWpEndpoint=function(e,t,n){return Zt(this,void 0,void 0,(function(){return $t(this,(function(r){switch(r.label){case 0:return[4,this.fetch({path:(0,Oe.addQueryArgs)("/wp-parsely/v2/stats/post/".concat(t,"/referrers"),qt(qt({},zt(e)),{itm_source:this.itmSource,total_views:n}))})];case 1:return[2,r.sent()]}}))}))},t}(Re),Kt=function(){return Kt=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&e.retryFetch?[4,new Promise((function(e){return setTimeout(e,500)}))]:[3,3];case 1:return t.sent(),[4,n(r-1)];case 2:return t.sent(),[3,4];case 3:a(e),i(!1),t.label=4;case 4:return[2]}}))}))})),[2]}))}))};return i(!0),n(1),function(){a(void 0)}}),[t]),(0,p.jsxs)("div",{className:"wp-parsely-performance-panel",children:[(0,p.jsx)(Tt,{title:(0,_.__)("Performance Stats","wp-parsely"),icon:jt,dropdownChildren:function(e){var t=e.onClose;return(0,p.jsx)(tn,{onClose:t})},children:(0,p.jsx)("div",{className:"panel-settings",children:(0,p.jsx)(f.SelectControl,{size:"__unstable-large",value:h.PerformanceStats.Period,prefix:(0,p.jsx)(f.__experimentalInputControlPrefixWrapper,{children:(0,_.__)("Period: ","wp-parsely")}),onChange:function(e){D(e,y)&&(v({PerformanceStats:Kt(Kt({},h.PerformanceStats),{Period:e})}),P.trackEvent("editor_sidebar_performance_period_changed",{period:e}))},children:Object.values(y).map((function(e){return(0,p.jsx)("option",{value:e,children:F(e)},e)}))})})}),o?o.Message():(0,p.jsxs)(p.Fragment,{children:[en(h,"overview")&&(0,p.jsx)(Gt,{data:c,isLoading:r}),en(h,"categories")&&(0,p.jsx)(Et,{data:c,isLoading:r}),en(h,"referrers")&&(0,p.jsx)(Ht,{data:c,isLoading:r})]}),window.wpParselyPostUrl&&(0,p.jsx)(f.Button,{className:"wp-parsely-view-post",variant:"primary",onClick:function(){P.trackEvent("editor_sidebar_view_post_pressed")},href:window.wpParselyPostUrl,rel:"noopener",target:"_blank",children:(0,_.__)("View this in Parse.ly","wp-parsely")})]})},rn=function(e){var t=e.period;return(0,p.jsx)(f.Panel,{children:(0,p.jsx)(J,{children:(0,p.jsx)(nn,{period:t})})})},sn=function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(r=Object.getOwnPropertySymbols(e);i=1&&(0,p.jsx)(f.__experimentalToggleGroupControlOption,{value:w.Tag,label:(0,_.__)("Tag","wp-parsely")}),r.categories.length>=1&&(0,p.jsx)(f.__experimentalToggleGroupControlOption,{value:w.Section,label:(0,_.__)("Section","wp-parsely")}),r.authors.length>=1&&(0,p.jsx)(f.__experimentalToggleGroupControlOption,{value:w.Author,label:(0,_.__)("Author","wp-parsely")})]})})},an=function(e){var t=e.filter,n=e.label,r=e.postData,i=sn(e,["filter","label","postData"]);return(0,p.jsx)("div",{className:"related-posts-filter-values",children:(0,p.jsx)(f.ComboboxControl,{__next40pxDefaultSize:!0,allowReset:!0,label:n,onChange:function(e){return i.onFilterValueChange(e)},options:w.Tag===t.type?r.tags.map((function(e){return{value:e,label:e}})):w.Section===t.type?r.categories.map((function(e){return{value:e,label:e}})):w.Author===t.type?r.authors.map((function(e){return{value:e,label:e}})):[],value:t.value})})},ln=function(e){var t=e.filter,n=e.postData,r=e.label,i=sn(e,["filter","postData","label"]),s=function(){return n.authors.length>0&&n.categories.length>0||n.authors.length>0&&n.tags.length>0||n.tags.length>0&&n.categories.length>0},o=function(){return w.Tag===t.type&&n.tags.length>1||w.Section===t.type&&n.categories.length>1||w.Author===t.type&&n.authors.length>1};return s()||o()?(0,p.jsxs)("div",{className:"related-posts-filter-settings",children:[s()&&(0,p.jsx)(on,{filter:t,label:r,onFilterTypeChange:i.onFilterTypeChange,postData:n}),o()&&(0,p.jsx)(an,{filter:t,label:s()?void 0:r,onFilterValueChange:i.onFilterValueChange,postData:n})]}):null},cn=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"M10 17.389H8.444A5.194 5.194 0 1 1 8.444 7H10v1.5H8.444a3.694 3.694 0 0 0 0 7.389H10v1.5ZM14 7h1.556a5.194 5.194 0 0 1 0 10.39H14v-1.5h1.556a3.694 3.694 0 0 0 0-7.39H14V7Zm-4.5 6h5v-1.5h-5V13Z"})}),un=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M5.625 5.5h9.75c.069 0 .125.056.125.125v9.75a.125.125 0 0 1-.125.125h-9.75a.125.125 0 0 1-.125-.125v-9.75c0-.069.056-.125.125-.125ZM4 5.625C4 4.728 4.728 4 5.625 4h9.75C16.273 4 17 4.728 17 5.625v9.75c0 .898-.727 1.625-1.625 1.625h-9.75A1.625 1.625 0 0 1 4 15.375v-9.75Zm14.5 11.656v-9H20v9C20 18.8 18.77 20 17.251 20H6.25v-1.5h11.001c.69 0 1.249-.528 1.249-1.219Z"})}),dn=function(){return(0,p.jsx)(f.SVG,{xmlns:"http://www.w3.org/2000/svg",width:"1",height:"40",viewBox:"0 0 1 40",fill:"none",children:(0,p.jsx)(f.Rect,{width:"1",height:"40",fill:"#cccccc"})})};function pn(e){var t=e.metric,n=e.post,r=e.avgEngagedIcon,i=e.viewsIcon;return"views"===t?(0,p.jsxs)("span",{className:"parsely-post-metric-data",children:[(0,p.jsx)("span",{className:"screen-reader-text",children:(0,_.__)("Number of Views","wp-parsely")}),i,Lt(n.views.toString())]}):"avg_engaged"===t?(0,p.jsxs)("span",{className:"parsely-post-metric-data",children:[(0,p.jsx)("span",{className:"screen-reader-text",children:(0,_.__)("Average Time","wp-parsely")}),r,n.avgEngaged]}):(0,p.jsx)("span",{className:"parsely-post-metric-data",children:"-"})}var fn,hn=function(e){var t,n,r=e.metric,i=e.post,s=e.postContent,o=(0,h.useDispatch)("core/notices").createNotice,a=s&&(t=s,n=q(i.rawUrl),new RegExp("]*href=[\"'](http://|https://)?.*".concat(n,".*[\"'][^>]*>"),"i").test(t));return(0,p.jsxs)("div",{className:"related-post-single","data-testid":"related-post-single",children:[(0,p.jsx)("div",{className:"related-post-title",children:(0,p.jsxs)("a",{href:i.url,target:"_blank",rel:"noreferrer",children:[(0,p.jsx)("span",{className:"screen-reader-text",children:(0,_.__)("View on website (opens new tab)","wp-parsely")}),i.title]})}),(0,p.jsx)("div",{className:"related-post-actions",children:(0,p.jsxs)("div",{className:"related-post-info",children:[(0,p.jsxs)("div",{children:[(0,p.jsx)("div",{className:"related-post-metric",children:(0,p.jsx)(pn,{metric:r,post:i,viewsIcon:(0,p.jsx)(X,{icon:Nt}),avgEngagedIcon:(0,p.jsx)(f.Dashicon,{icon:"clock",size:24})})}),a&&(0,p.jsx)("div",{className:"related-post-linked",children:(0,p.jsx)(f.Tooltip,{text:(0,_.__)("This post is linked in the content","wp-parsely"),children:(0,p.jsx)(X,{icon:cn,size:24})})})]}),(0,p.jsx)(dn,{}),(0,p.jsxs)("div",{children:[(0,p.jsx)(f.Button,{icon:un,iconSize:24,onClick:function(){navigator.clipboard.writeText(i.rawUrl).then((function(){o("success",(0,_.__)("URL copied to clipboard","wp-parsely"),{type:"snackbar"})}))},label:(0,_.__)("Copy URL to clipboard","wp-parsely")}),(0,p.jsx)(f.Button,{icon:(0,p.jsx)(T,{}),iconSize:18,href:i.dashUrl,target:"_blank",label:(0,_.__)("View in Parse.ly","wp-parsely")})]})]})})]})},vn=window.wp.coreData,gn=function(){var e=function(t,n){return e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},e(t,n)};return function(t,n){if("function"!=typeof n&&null!==n)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");function __(){this.constructor=t}e(t,n),t.prototype=null===n?Object.create(n):(__.prototype=n.prototype,new __)}}(),yn=function(){return yn=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]>( { - path: addQueryArgs( '/wp-parsely/v1/related', { query } ), + path: addQueryArgs( '/wp-parsely/v2/stats/related', query ), } ); } catch ( wpError ) { error = wpError; diff --git a/src/content-helper/dashboard-widget/provider.ts b/src/content-helper/dashboard-widget/provider.ts index 23bc4673e..0338e490a 100644 --- a/src/content-helper/dashboard-widget/provider.ts +++ b/src/content-helper/dashboard-widget/provider.ts @@ -83,7 +83,7 @@ export class DashboardWidgetProvider extends BaseProvider { settings: TopPostsSettings, page: number ): Promise { const response = this.fetch( { - path: addQueryArgs( '/wp-parsely/v1/stats/posts/', { + path: addQueryArgs( '/wp-parsely/v2/stats/posts/', { limit: TOP_POSTS_DEFAULT_LIMIT, ...getApiPeriodParams( settings.Period ), sort: settings.Metric, diff --git a/src/content-helper/editor-sidebar/performance-stats/provider.ts b/src/content-helper/editor-sidebar/performance-stats/provider.ts index 5bc524cd6..98ad0681b 100644 --- a/src/content-helper/editor-sidebar/performance-stats/provider.ts +++ b/src/content-helper/editor-sidebar/performance-stats/provider.ts @@ -68,13 +68,13 @@ export class PerformanceStatsProvider extends BaseProvider { ); } - // Get post URL. - const postUrl = editor.getPermalink(); + // Get post ID. + const postID = editor.getCurrentPostId(); - if ( null === postUrl ) { + if ( null === postID ) { return Promise.reject( new ContentHelperError( __( - "The post's URL returned null.", + "The post's ID returned null.", 'wp-parsely' ), ContentHelperErrorCode.PostIsNotPublished ) ); @@ -84,10 +84,10 @@ export class PerformanceStatsProvider extends BaseProvider { let performanceData, referrerData; try { performanceData = await this.fetchPerformanceDataFromWpEndpoint( - period, postUrl + period, postID ); referrerData = await this.fetchReferrerDataFromWpEndpoint( - period, postUrl, performanceData.views + period, postID, performanceData.views ); } catch ( contentHelperError ) { return Promise.reject( contentHelperError ); @@ -100,20 +100,19 @@ export class PerformanceStatsProvider extends BaseProvider { * Fetches the performance data for the current post from the WordPress REST * API. * - * @param {Period} period The period for which to fetch data. - * @param {string} postUrl + * @param {Period} period The period for which to fetch data. + * @param {number} postId The post's ID. * * @return {Promise } The current post's details. */ private async fetchPerformanceDataFromWpEndpoint( - period: Period, postUrl: string + period: Period, postId: number ): Promise { const response = await this.fetch( { path: addQueryArgs( - '/wp-parsely/v1/stats/post/detail', { + `/wp-parsely/v2/stats/post/${ postId }/details`, { ...getApiPeriodParams( period ), itm_source: this.itmSource, - url: postUrl, } ), } ); @@ -122,8 +121,8 @@ export class PerformanceStatsProvider extends BaseProvider { return Promise.reject( new ContentHelperError( sprintf( /* translators: URL of the published post */ - __( 'The post %s has 0 views, or the Parse.ly API returned no data.', - 'wp-parsely' ), postUrl + __( 'The post %d has 0 views, or the Parse.ly API returned no data.', + 'wp-parsely' ), postId ), ContentHelperErrorCode.ParselyApiReturnedNoData, '' ) ); } @@ -133,8 +132,8 @@ export class PerformanceStatsProvider extends BaseProvider { return Promise.reject( new ContentHelperError( sprintf( /* translators: URL of the published post */ - __( 'Multiple results were returned for the post %s by the Parse.ly API.', - 'wp-parsely' ), postUrl + __( 'Multiple results were returned for the post %d by the Parse.ly API.', + 'wp-parsely' ), postId ), ContentHelperErrorCode.ParselyApiReturnedTooManyResults ) ); } @@ -146,21 +145,20 @@ export class PerformanceStatsProvider extends BaseProvider { * Fetches referrer data for the current post from the WordPress REST API. * * @param {Period} period The period for which to fetch data. - * @param {string} postUrl The post's URL. + * @param {number} postId The post's ID. * @param {string} totalViews Total post views (including direct views). * * @return {Promise} The post's referrer data. */ private async fetchReferrerDataFromWpEndpoint( - period: Period, postUrl: string, totalViews: string + period: Period, postId: string, totalViews: string ): Promise { const response = await this.fetch( { path: addQueryArgs( - '/wp-parsely/v1/referrers/post/detail', { + `/wp-parsely/v2/stats/post/${ postId }/referrers`, { ...getApiPeriodParams( period ), itm_source: this.itmSource, total_views: totalViews, // Needed to calculate direct views. - url: postUrl, } ), } ); diff --git a/src/content-helper/editor-sidebar/related-posts/provider.ts b/src/content-helper/editor-sidebar/related-posts/provider.ts index 6345f4f19..6051c4ca8 100644 --- a/src/content-helper/editor-sidebar/related-posts/provider.ts +++ b/src/content-helper/editor-sidebar/related-posts/provider.ts @@ -146,7 +146,7 @@ export class RelatedPostsProvider extends BaseProvider { */ private async fetchRelatedPostsFromWpEndpoint( query: RelatedPostsApiQuery ): Promise { const response = this.fetch( { - path: addQueryArgs( '/wp-parsely/v1/stats/posts', { + path: addQueryArgs( '/wp-parsely/v2/stats/posts', { ...query.query, itm_source: 'wp-parsely-content-helper', } ), From fb3941af8b41dc713c22952c526661d0029748cd Mon Sep 17 00:00:00 2001 From: Henrique Mouta Date: Thu, 29 Aug 2024 13:08:26 +0100 Subject: [PATCH 059/282] Delete the old endpoints --- .../class-analytics-post-detail-api-proxy.php | 48 --- .../class-analytics-posts-api-proxy.php | 48 --- .../class-referrers-post-detail-api-proxy.php | 259 --------------- src/Endpoints/class-related-api-proxy.php | 61 ---- .../Proxy/AnalyticsPostsProxyEndpointTest.php | 264 --------------- .../ReferrersPostDetailProxyEndpointTest.php | 305 ------------------ .../Proxy/RelatedProxyEndpointTest.php | 162 ---------- .../StatsPostDetailProxyEndpointTest.php | 206 ------------ wp-parsely.php | 27 +- 9 files changed, 1 insertion(+), 1379 deletions(-) delete mode 100644 src/Endpoints/class-analytics-post-detail-api-proxy.php delete mode 100644 src/Endpoints/class-analytics-posts-api-proxy.php delete mode 100644 src/Endpoints/class-referrers-post-detail-api-proxy.php delete mode 100644 src/Endpoints/class-related-api-proxy.php delete mode 100644 tests/Integration/Endpoints/Proxy/AnalyticsPostsProxyEndpointTest.php delete mode 100644 tests/Integration/Endpoints/Proxy/ReferrersPostDetailProxyEndpointTest.php delete mode 100644 tests/Integration/Endpoints/Proxy/RelatedProxyEndpointTest.php delete mode 100644 tests/Integration/Endpoints/Proxy/StatsPostDetailProxyEndpointTest.php diff --git a/src/Endpoints/class-analytics-post-detail-api-proxy.php b/src/Endpoints/class-analytics-post-detail-api-proxy.php deleted file mode 100644 index 787ae0e50..000000000 --- a/src/Endpoints/class-analytics-post-detail-api-proxy.php +++ /dev/null @@ -1,48 +0,0 @@ -register_endpoint( '/stats/post/detail' ); - } - - /** - * Cached "proxy" to the Parse.ly `/analytics/post/detail` API endpoint. - * - * @param WP_REST_Request $request The request object. - * @return stdClass|WP_Error stdClass containing the data or a WP_Error object on failure. - */ - public function get_items( WP_REST_Request $request ) { - return $this->get_data( $request ); - } - - /** - * Generates the final data from the passed response. - * - * @param array $response The response received by the proxy. - * @return array The generated data. - */ - protected function generate_data( $response ): array { - return $this->generate_post_data( $response ); - } -} diff --git a/src/Endpoints/class-analytics-posts-api-proxy.php b/src/Endpoints/class-analytics-posts-api-proxy.php deleted file mode 100644 index 3ee862caf..000000000 --- a/src/Endpoints/class-analytics-posts-api-proxy.php +++ /dev/null @@ -1,48 +0,0 @@ -register_endpoint( '/stats/posts' ); - } - - /** - * Cached "proxy" to the Parse.ly `/analytics/posts` API endpoint. - * - * @param WP_REST_Request $request The request object. - * @return stdClass|WP_Error stdClass containing the data or a WP_Error object on failure. - */ - public function get_items( WP_REST_Request $request ) { - return $this->get_data( $request ); - } - - /** - * Generates the final data from the passed response. - * - * @param array $response The response received by the proxy. - * @return array The generated data. - */ - protected function generate_data( $response ): array { - return $this->generate_post_data( $response ); - } -} diff --git a/src/Endpoints/class-referrers-post-detail-api-proxy.php b/src/Endpoints/class-referrers-post-detail-api-proxy.php deleted file mode 100644 index 812a9ca81..000000000 --- a/src/Endpoints/class-referrers-post-detail-api-proxy.php +++ /dev/null @@ -1,259 +0,0 @@ -register_endpoint( '/referrers/post/detail' ); - } - - /** - * Cached "proxy" to the Parse.ly `/referrers/post/detail` API endpoint. - * - * @since 3.6.0 - * - * @param WP_REST_Request $request The request object. - * @return stdClass|WP_Error stdClass containing the data or a WP_Error object on failure. - */ - public function get_items( WP_REST_Request $request ) { - $total_views = $request->get_param( 'total_views' ) ?? '0'; - - if ( ! is_string( $total_views ) ) { - $total_views = '0'; - } - - $this->total_views = Utils::convert_to_positive_integer( $total_views ); - $request->offsetUnset( 'total_views' ); // Remove param from request. - return $this->get_data( $request ); - } - - /** - * Generates the final data from the passed response. - * - * @since 3.6.0 - * - * @param array $response The response received by the proxy. - * @return array The generated data. - */ - protected function generate_data( $response ): array { - $referrers_types = $this->generate_referrer_types_data( $response ); - $direct_views = Utils::convert_to_positive_integer( - $referrers_types->direct->views ?? '0' - ); - $referrers_top = $this->generate_referrers_data( 5, $response, $direct_views ); - - return array( - 'top' => $referrers_top, - 'types' => $referrers_types, - ); - } - - /** - * Generates the referrer types data. - * - * Referrer types are: - * - `social`: Views coming from social media. - * - `search`: Views coming from search engines. - * - `other`: Views coming from other referrers, like external websites. - * - `internal`: Views coming from linking pages of the same website. - * - * Returned object properties: - * - `views`: The number of views. - * - `viewPercentage`: The number of views as a percentage, compared to the - * total views of all referrer types. - * - * @since 3.6.0 - * - * @param array $response The response received by the proxy. - * @return stdClass The generated data. - */ - private function generate_referrer_types_data( array $response ): stdClass { - $result = new stdClass(); - $total_referrer_views = 0; // Views from all referrer types combined. - - // Set referrer type order as it is displayed in the Parse.ly dashboard. - $referrer_type_keys = array( 'social', 'search', 'other', 'internal', 'direct' ); - foreach ( $referrer_type_keys as $key ) { - $result->$key = (object) array( 'views' => 0 ); - } - - // Set views and views totals. - foreach ( $response as $referrer_data ) { - /** - * Variable. - * - * @var int - */ - $current_views = $referrer_data->metrics->referrers_views ?? 0; - $total_referrer_views += $current_views; - - /** - * Variable. - * - * @var string - */ - $current_key = $referrer_data->type ?? ''; - if ( '' !== $current_key ) { - if ( ! isset( $result->$current_key->views ) ) { - $result->$current_key = (object) array( 'views' => 0 ); - } - - $result->$current_key->views += $current_views; - } - } - - // Add direct and total views to the object. - $result->direct->views = $this->total_views - $total_referrer_views; - $result->totals = (object) array( 'views' => $this->total_views ); - - // Remove referrer types without views. - foreach ( $referrer_type_keys as $key ) { - if ( 0 === $result->$key->views ) { - unset( $result->$key ); - } - } - - // Set percentage values and format numbers. - // @phpstan-ignore-next-line. - foreach ( $result as $key => $value ) { - // Set and format percentage values. - $result->{ $key }->viewsPercentage = $this->get_i18n_percentage( - absint( $value->views ), - $this->total_views - ); - - // Format views values. - $result->{ $key }->views = number_format_i18n( $result->{ $key }->views ); - } - - return $result; - } - - /** - * Generates the top referrers data. - * - * Returned object properties: - * - `views`: The number of views. - * - `viewPercentage`: The number of views as a percentage, compared to the - * total views of all referrer types. - * - `datasetViewsPercentage: The number of views as a percentage, compared - * to the total views of the current dataset. - * - * @since 3.6.0 - * - * @param int $limit The limit of returned referrers. - * @param array $response The response received by the proxy. - * @param int $direct_views The count of direct views. - * @return stdClass The generated data. - */ - private function generate_referrers_data( - int $limit, - array $response, - int $direct_views - ): stdClass { - $temp_views = array(); - $totals = 0; - $referrer_count = count( $response ); - - // Set views and views totals. - $loop_count = $referrer_count > $limit ? $limit : $referrer_count; - for ( $i = 0; $i < $loop_count; $i++ ) { - $data = $response[ $i ]; - - /** - * Variable. - * - * @var int - */ - $referrer_views = $data->metrics->referrers_views ?? 0; - $totals += $referrer_views; - if ( isset( $data->name ) ) { - $temp_views[ $data->name ] = $referrer_views; - } - } - - // If applicable, add the direct views. - if ( isset( $referrer_views ) && $direct_views >= $referrer_views ) { - $temp_views['direct'] = $direct_views; - $totals += $direct_views; - arsort( $temp_views ); - if ( count( $temp_views ) > $limit ) { - $totals -= array_pop( $temp_views ); - } - } - - // Convert temporary array to result object and add totals. - $result = new stdClass(); - foreach ( $temp_views as $key => $value ) { - $result->$key = (object) array( 'views' => $value ); - } - $result->totals = (object) array( 'views' => $totals ); - - // Set percentages values and format numbers. - // @phpstan-ignore-next-line. - foreach ( $result as $key => $value ) { - // Percentage against all referrer views, even those not included - // in the dataset due to the $limit argument. - $result->{ $key }->viewsPercentage = $this - ->get_i18n_percentage( absint( $value->views ), $this->total_views ); - - // Percentage against the current dataset that is limited due to the - // $limit argument. - $result->{ $key }->datasetViewsPercentage = $this - ->get_i18n_percentage( absint( $value->views ), $totals ); - - // Format views values. - $result->{ $key }->views = number_format_i18n( $result->{ $key }->views ); - } - - return $result; - } - - /** - * Returns the passed number compared to the passed total, in an - * internationalized percentage format. - * - * @since 3.6.0 - * - * @param int $number The number to be calculated as a percentage. - * @param int $total The total number to compare against. - * @return string|false The internationalized percentage or false on error. - */ - private function get_i18n_percentage( int $number, int $total ) { - if ( 0 === $total ) { - return false; - } - - return number_format_i18n( $number / $total * 100, 2 ); - } -} diff --git a/src/Endpoints/class-related-api-proxy.php b/src/Endpoints/class-related-api-proxy.php deleted file mode 100644 index 983536362..000000000 --- a/src/Endpoints/class-related-api-proxy.php +++ /dev/null @@ -1,61 +0,0 @@ -register_endpoint( '/related' ); - } - - /** - * Cached "proxy" to the Parse.ly `/related` API endpoint. - * - * @param WP_REST_Request $request The request object. - * @return stdClass|WP_Error stdClass containing the data or a WP_Error object on failure. - */ - public function get_items( WP_REST_Request $request ) { - return $this->get_data( $request, false, 'query' ); - } - - /** - * Generates the final data from the passed response. - * - * @param array $response The response received by the proxy. - * @return array The generated data. - */ - protected function generate_data( $response ): array { - $itm_source = $this->itm_source; - - return array_map( - static function ( stdClass $item ) use ( $itm_source ) { - return (object) array( - 'image_url' => $item->image_url, - 'thumb_url_medium' => $item->thumb_url_medium, - 'title' => $item->title, - 'url' => Parsely::get_url_with_itm_source( $item->url, $itm_source ), - ); - }, - $response - ); - } -} diff --git a/tests/Integration/Endpoints/Proxy/AnalyticsPostsProxyEndpointTest.php b/tests/Integration/Endpoints/Proxy/AnalyticsPostsProxyEndpointTest.php deleted file mode 100644 index b0a7c366b..000000000 --- a/tests/Integration/Endpoints/Proxy/AnalyticsPostsProxyEndpointTest.php +++ /dev/null @@ -1,264 +0,0 @@ -dispatch( - new WP_REST_Request( 'GET', self::$route ) - ); - /** - * Variable. - * - * @var WP_Error - */ - $error = $response->as_error(); - - self::assertSame( 401, $response->get_status() ); - self::assertSame( 'rest_forbidden', $error->get_error_code() ); - self::assertSame( - 'Sorry, you are not allowed to do that.', - $error->get_error_message() - ); - } - - /** - * Verifies that calling `GET /wp-parsely/v1/stats/posts` returns an - * error and does not perform a remote call when the Site ID is not populated - * in site options. - * - * @covers \Parsely\Endpoints\Analytics_Posts_API_Proxy::get_items - * @uses \Parsely\Endpoints\Analytics_Posts_API_Proxy::__construct - * @uses \Parsely\Endpoints\Analytics_Posts_API_Proxy::is_available_to_current_user - * @uses \Parsely\Endpoints\Analytics_Posts_API_Proxy::run - * @uses \Parsely\Parsely::site_id_is_missing - * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Parsely::get_options - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\Endpoints\Base_API_Proxy::get_data - * @uses \Parsely\Endpoints\Base_API_Proxy::register_endpoint - */ - public function test_get_items_fails_when_site_id_is_not_set(): void { - $this->set_current_user_to_admin(); - parent::run_test_get_items_fails_without_site_id_set(); - } - - /** - * Verifies that calling `GET /wp-parsely/v1/stats/posts` returns an - * error and does not perform a remote call when the API Secret is not - * populated in site options. - * - * @covers \Parsely\Endpoints\Analytics_Posts_API_Proxy::get_items - * @uses \Parsely\Endpoints\Analytics_Posts_API_Proxy::__construct - * @uses \Parsely\Endpoints\Analytics_Posts_API_Proxy::is_available_to_current_user - * @uses \Parsely\Endpoints\Analytics_Posts_API_Proxy::run - * @uses \Parsely\Parsely::site_id_is_missing - * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Parsely::api_secret_is_set - * @uses \Parsely\Parsely::get_options - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\Endpoints\Base_API_Proxy::get_data - * @uses \Parsely\Endpoints\Base_API_Proxy::register_endpoint - */ - public function test_get_items_fails_when_api_secret_is_not_set(): void { - $this->set_current_user_to_admin(); - parent::run_test_get_items_fails_without_api_secret_set(); - } - - /** - * Verifies default user capability filter. - * - * @covers \Parsely\Endpoints\Analytics_Posts_API_Proxy::is_available_to_current_user - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\RemoteAPI\Analytics_Posts_API::is_available_to_current_user - */ - public function test_user_is_allowed_to_make_proxy_api_call_if_default_user_capability_is_changed(): void { - parent::run_test_user_is_allowed_to_make_proxy_api_call_if_default_user_capability_is_changed(); - } - - /** - * Verifies endpoint specific user capability filter. - * - * @covers \Parsely\Endpoints\Analytics_Posts_API_Proxy::is_available_to_current_user - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\RemoteAPI\Analytics_Posts_API::is_available_to_current_user - */ - public function test_user_is_allowed_to_make_proxy_api_call_if_endpoint_specific_user_capability_is_changed(): void { - parent::run_test_user_is_allowed_to_make_proxy_api_call_if_endpoint_specific_user_capability_is_changed( 'analytics_posts' ); - } - - /** - * Verifies that calls to `GET /wp-parsely/v1/stats/posts` return - * results in the expected format. - * - * @covers \Parsely\Endpoints\Analytics_Posts_API_Proxy::get_items - * @uses \Parsely\Endpoints\Analytics_Posts_API_Proxy::__construct - * @uses \Parsely\Endpoints\Analytics_Posts_API_Proxy::generate_data - * @uses \Parsely\Endpoints\Analytics_Posts_API_Proxy::is_available_to_current_user - * @uses \Parsely\Endpoints\Analytics_Posts_API_Proxy::run - * @uses \Parsely\Endpoints\Base_API_Proxy::get_data - * @uses \Parsely\Endpoints\Base_API_Proxy::register_endpoint - * @uses \Parsely\Parsely::site_id_is_missing - * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Parsely::api_secret_is_set - * @uses \Parsely\Parsely::get_site_id - * @uses \Parsely\Parsely::get_api_secret - * @uses \Parsely\Parsely::get_options - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_api_url - * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_items - * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_request_options - */ - public function test_get_items(): void { - $this->set_current_user_to_admin(); - TestCase::set_options( - array( - 'apikey' => 'example.com', - 'api_secret' => 'test', - ) - ); - - $dispatched = 0; - $date_format = Utils::get_date_format(); - - add_filter( - 'pre_http_request', - function () use ( &$dispatched ): array { - $dispatched++; - return array( - 'body' => '{"data":[ - { - "author": "Aakash Shah", - "metrics": {"views": 142}, - "pub_date": "2020-04-06T13:30:58", - "thumb_url_medium": "https://images.parsely.com/XCmTXuOf8yVbUYTxj2abQ4RSDkM=/85x85/smart/https%3A//blog.parse.ly/wp-content/uploads/2021/06/Web-Analytics-Tool.png%3Fw%3D150%26h%3D150%26crop%3D1", - "title": "9 Types of Web Analytics Tools \u2014 And How to Know Which Ones You Really Need", - "url": "https://blog.parse.ly/web-analytics-software-tools/?itm_source=parsely-api" - }, - { - "author": "Stephanie Schwartz and Andrew Butler", - "metrics": {"views": 40}, - "pub_date": "2021-04-30T20:30:24", - "thumb_url_medium": "https://images.parsely.com/ap3YSufqxnLpz6zzQshoks3snXI=/85x85/smart/https%3A//blog.parse.ly/wp-content/uploads/2021/05/pexels-brett-jordan-998501-1024x768-2.jpeg%3Fw%3D150%26h%3D150%26crop%3D1", - "title": "5 Tagging Best Practices For Getting the Most Out of Your Content Strategy", - "url": "https://blog.parse.ly/5-tagging-best-practices-content-strategy/?itm_source=parsely-api" - } - ]}', - ); - } - ); - - $rest_request = new WP_REST_Request( 'GET', '/wp-parsely/v1/stats/posts' ); - $rest_request->set_param( 'itm_source', 'wp-parsely-content-helper' ); - - $response = rest_get_server()->dispatch( $rest_request ); - - self::assertSame( 1, $dispatched ); - self::assertSame( 200, $response->get_status() ); - self::assertEquals( - (object) array( - 'data' => array( - (object) array( - 'author' => 'Aakash Shah', - 'date' => wp_date( $date_format, strtotime( '2020-04-06T13:30:58' ) ), - 'id' => 'https://blog.parse.ly/web-analytics-software-tools/', - 'dashUrl' => PARSELY::DASHBOARD_BASE_URL . '/example.com/find?url=https%3A%2F%2Fblog.parse.ly%2Fweb-analytics-software-tools%2F', - 'thumbnailUrl' => 'https://images.parsely.com/XCmTXuOf8yVbUYTxj2abQ4RSDkM=/85x85/smart/https%3A//blog.parse.ly/wp-content/uploads/2021/06/Web-Analytics-Tool.png%3Fw%3D150%26h%3D150%26crop%3D1', - 'title' => '9 Types of Web Analytics Tools — And How to Know Which Ones You Really Need', - 'url' => 'https://blog.parse.ly/web-analytics-software-tools/?itm_source=wp-parsely-content-helper', - 'views' => '142', - 'postId' => 0, - 'rawUrl' => 'https://blog.parse.ly/web-analytics-software-tools/', - ), - (object) array( - 'author' => 'Stephanie Schwartz and Andrew Butler', - 'date' => wp_date( $date_format, strtotime( '2021-04-30T20:30:24' ) ), - 'id' => 'https://blog.parse.ly/5-tagging-best-practices-content-strategy/', - 'dashUrl' => PARSELY::DASHBOARD_BASE_URL . '/example.com/find?url=https%3A%2F%2Fblog.parse.ly%2F5-tagging-best-practices-content-strategy%2F', - 'thumbnailUrl' => 'https://images.parsely.com/ap3YSufqxnLpz6zzQshoks3snXI=/85x85/smart/https%3A//blog.parse.ly/wp-content/uploads/2021/05/pexels-brett-jordan-998501-1024x768-2.jpeg%3Fw%3D150%26h%3D150%26crop%3D1', - 'title' => '5 Tagging Best Practices For Getting the Most Out of Your Content Strategy', - 'url' => 'https://blog.parse.ly/5-tagging-best-practices-content-strategy/?itm_source=wp-parsely-content-helper', - 'views' => '40', - 'postId' => 0, - 'rawUrl' => 'https://blog.parse.ly/5-tagging-best-practices-content-strategy/', - ), - ), - ), - $response->get_data() - ); - } -} diff --git a/tests/Integration/Endpoints/Proxy/ReferrersPostDetailProxyEndpointTest.php b/tests/Integration/Endpoints/Proxy/ReferrersPostDetailProxyEndpointTest.php deleted file mode 100644 index 38ec499a4..000000000 --- a/tests/Integration/Endpoints/Proxy/ReferrersPostDetailProxyEndpointTest.php +++ /dev/null @@ -1,305 +0,0 @@ -set_current_user_to_admin(); - parent::run_test_get_items_fails_without_site_id_set(); - } - - /** - * Verifies that calling `GET /wp-parsely/v1/referrers/post/detail` returns - * an error and does not perform a remote call when the Site ID is not - * populated in site options. - * - * @covers \Parsely\Endpoints\Referrers_Post_Detail_API_Proxy::get_items - * @uses \Parsely\Endpoints\Base_API_Proxy::get_data - * @uses \Parsely\Endpoints\Base_API_Proxy::register_endpoint - * @uses \Parsely\Endpoints\Referrers_Post_Detail_API_Proxy::__construct - * @uses \Parsely\Endpoints\Referrers_Post_Detail_API_Proxy::is_available_to_current_user - * @uses \Parsely\Endpoints\Referrers_Post_Detail_API_Proxy::run - * @uses \Parsely\Parsely::site_id_is_missing - * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Parsely::api_secret_is_set - * @uses \Parsely\Parsely::get_options - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - */ - public function test_get_items_fails_when_api_secret_is_not_set(): void { - $this->set_current_user_to_admin(); - parent::run_test_get_items_fails_without_api_secret_set(); - } - - /** - * Verifies default user capability filter. - * - * @covers \Parsely\Endpoints\Referrers_Post_Detail_API_Proxy::is_available_to_current_user - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\RemoteAPI\Referrers_Post_Detail_API::is_available_to_current_user - */ - public function test_user_is_allowed_to_make_proxy_api_call_if_default_user_capability_is_changed(): void { - parent::run_test_user_is_allowed_to_make_proxy_api_call_if_default_user_capability_is_changed(); - } - - /** - * Verifies endpoint specific user capability filter. - * - * @covers \Parsely\Endpoints\Referrers_Post_Detail_API_Proxy::is_available_to_current_user - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\RemoteAPI\Referrers_Post_Detail_API::is_available_to_current_user - */ - public function test_user_is_allowed_to_make_proxy_api_call_if_endpoint_specific_user_capability_is_changed(): void { - parent::run_test_user_is_allowed_to_make_proxy_api_call_if_endpoint_specific_user_capability_is_changed(); - } - - /** - * Verifies that calls to `GET /wp-parsely/v1/referrers/post/detail` return - * results in the expected format. - * - * @covers \Parsely\Endpoints\Referrers_Post_Detail_API_Proxy::get_items - * @uses \Parsely\Endpoints\Base_API_Proxy::get_data - * @uses \Parsely\Endpoints\Base_API_Proxy::register_endpoint - * @uses \Parsely\Endpoints\Referrers_Post_Detail_API_Proxy::__construct - * @uses \Parsely\Endpoints\Referrers_Post_Detail_API_Proxy::generate_data - * @uses \Parsely\Endpoints\Referrers_Post_Detail_API_Proxy::is_available_to_current_user - * @uses \Parsely\Endpoints\Referrers_Post_Detail_API_Proxy::run - * @uses \Parsely\Parsely::site_id_is_missing - * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Parsely::api_secret_is_set - * @uses \Parsely\Parsely::get_site_id - * @uses \Parsely\Parsely::get_options - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_api_url - * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_items - * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_request_options - */ - public function test_get_items(): void { - $this->set_current_user_to_admin(); - TestCase::set_options( - array( - 'apikey' => 'example.com', - 'api_secret' => 'test', - ) - ); - - $dispatched = 0; - - add_filter( - 'pre_http_request', - function () use ( &$dispatched ): array { - $dispatched++; - return array( - 'body' => '{"data":[ - { - "metrics": {"referrers_views": 1500}, - "name": "google", - "type": "search" - }, - { - "metrics": {"referrers_views": 100}, - "name": "blog.parse.ly", - "type": "internal" - }, - { - "metrics": {"referrers_views": 50}, - "name": "bing", - "type": "search" - }, - { - "metrics": {"referrers_views": 30}, - "name": "facebook.com", - "type": "social" - }, - { - "metrics": {"referrers_views": 10}, - "name": "okt.to", - "type": "other" - }, - { - "metrics": {"referrers_views": 10}, - "name": "yandex", - "type": "search" - }, - { - "metrics": {"referrers_views": 10}, - "name": "parse.ly", - "type": "internal" - }, - { - "metrics": {"referrers_views": 10}, - "name": "yahoo!", - "type": "search" - }, - { - "metrics": {"referrers_views": 5}, - "name": "site1.com", - "type": "other" - }, - { - "metrics": {"referrers_views": 5}, - "name": "link.site2.com", - "type": "other" - } - ]}', - ); - } - ); - - $expected_top = (object) array( - 'direct' => (object) array( - 'views' => '770', - 'viewsPercentage' => '30.80', - 'datasetViewsPercentage' => '31.43', - ), - 'google' => (object) array( - 'views' => '1,500', - 'viewsPercentage' => '60.00', - 'datasetViewsPercentage' => '61.22', - ), - 'blog.parse.ly' => (object) array( - 'views' => '100', - 'viewsPercentage' => '4.00', - 'datasetViewsPercentage' => '4.08', - ), - 'bing' => (object) array( - 'views' => '50', - 'viewsPercentage' => '2.00', - 'datasetViewsPercentage' => '2.04', - ), - 'facebook.com' => (object) array( - 'views' => '30', - 'viewsPercentage' => '1.20', - 'datasetViewsPercentage' => '1.22', - ), - 'totals' => (object) array( - 'views' => '2,450', - 'viewsPercentage' => '98.00', - 'datasetViewsPercentage' => '100.00', - ), - ); - - $expected_types = (object) array( - 'social' => (object) array( - 'views' => '30', - 'viewsPercentage' => '1.20', - ), - 'search' => (object) array( - 'views' => '1,570', - 'viewsPercentage' => '62.80', - ), - 'other' => (object) array( - 'views' => '20', - 'viewsPercentage' => '0.80', - ), - 'internal' => (object) array( - 'views' => '110', - 'viewsPercentage' => '4.40', - ), - 'direct' => (object) array( - 'views' => '770', - 'viewsPercentage' => '30.80', - ), - 'totals' => (object) array( - 'views' => '2,500', - 'viewsPercentage' => '100.00', - ), - ); - - $request = new WP_REST_Request( 'GET', self::$route ); - $request->set_param( 'total_views', '2,500' ); - - $response = rest_get_server()->dispatch( $request ); - - self::assertSame( 1, $dispatched ); - self::assertSame( 200, $response->get_status() ); - self::assertEquals( - (object) array( - 'data' => array( - 'top' => $expected_top, - 'types' => $expected_types, - ), - ), - $response->get_data() - ); - } -} diff --git a/tests/Integration/Endpoints/Proxy/RelatedProxyEndpointTest.php b/tests/Integration/Endpoints/Proxy/RelatedProxyEndpointTest.php deleted file mode 100644 index 7584fa597..000000000 --- a/tests/Integration/Endpoints/Proxy/RelatedProxyEndpointTest.php +++ /dev/null @@ -1,162 +0,0 @@ - 'example.com' ) ); - - $dispatched = 0; - - add_filter( - 'pre_http_request', - function () use ( &$dispatched ): array { - $dispatched++; - return array( - 'body' => '{"data":[ - { - "image_url":"https:\/\/example.com\/img.png", - "thumb_url_medium":"https:\/\/example.com\/thumb.png", - "title":"something", - "url":"https:\/\/example.com" - }, - { - "image_url":"https:\/\/example.com\/img2.png", - "thumb_url_medium":"https:\/\/example.com\/thumb2.png", - "title":"something2", - "url":"https:\/\/example.com\/2" - } - ]}', - ); - } - ); - - $response = rest_get_server()->dispatch( new WP_REST_Request( 'GET', '/wp-parsely/v1/related' ) ); - - self::assertSame( 1, $dispatched ); - self::assertSame( 200, $response->get_status() ); - self::assertEquals( - (object) array( - 'data' => array( - (object) array( - 'image_url' => 'https://example.com/img.png', - 'thumb_url_medium' => 'https://example.com/thumb.png', - 'title' => 'something', - 'url' => 'https://example.com', - ), - (object) array( - 'image_url' => 'https://example.com/img2.png', - 'thumb_url_medium' => 'https://example.com/thumb2.png', - 'title' => 'something2', - 'url' => 'https://example.com/2', - ), - ), - ), - $response->get_data() - ); - } -} diff --git a/tests/Integration/Endpoints/Proxy/StatsPostDetailProxyEndpointTest.php b/tests/Integration/Endpoints/Proxy/StatsPostDetailProxyEndpointTest.php deleted file mode 100644 index c442d098a..000000000 --- a/tests/Integration/Endpoints/Proxy/StatsPostDetailProxyEndpointTest.php +++ /dev/null @@ -1,206 +0,0 @@ -set_current_user_to_admin(); - parent::run_test_get_items_fails_without_site_id_set(); - } - - /** - * Verifies that calling `GET /wp-parsely/v1/analytics/post/detail` returns - * an error and does not perform a remote call when the Site ID is not - * populated in site options. - * - * @covers \Parsely\Endpoints\Analytics_Post_Detail_API_Proxy::get_items - * @uses \Parsely\Endpoints\Base_API_Proxy::get_data - * @uses \Parsely\Endpoints\Base_API_Proxy::register_endpoint - * @uses \Parsely\Endpoints\Analytics_Post_Detail_API_Proxy::__construct - * @uses \Parsely\Endpoints\Analytics_Post_Detail_API_Proxy::is_available_to_current_user - * @uses \Parsely\Endpoints\Analytics_Post_Detail_API_Proxy::run - * @uses \Parsely\Parsely::site_id_is_missing - * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Parsely::api_secret_is_set - * @uses \Parsely\Parsely::get_options - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - */ - public function test_get_items_fails_when_api_secret_is_not_set(): void { - $this->set_current_user_to_admin(); - parent::run_test_get_items_fails_without_api_secret_set(); - } - - /** - * Verifies default user capability filter. - * - * @covers \Parsely\Endpoints\Analytics_Post_Detail_API_Proxy::is_available_to_current_user - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - */ - public function test_user_is_allowed_to_make_proxy_api_call_if_default_user_capability_is_changed(): void { - parent::run_test_user_is_allowed_to_make_proxy_api_call_if_default_user_capability_is_changed(); - } - - /** - * Verifies endpoint specific user capability filter. - * - * @covers \Parsely\Endpoints\Analytics_Post_Detail_API_Proxy::is_available_to_current_user - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - */ - public function test_user_is_allowed_to_make_proxy_api_call_if_endpoint_specific_user_capability_is_changed(): void { - parent::run_test_user_is_allowed_to_make_proxy_api_call_if_endpoint_specific_user_capability_is_changed( 'analytics_post_detail' ); - } - - /** - * Verifies that calls to `GET /wp-parsely/v1/analytics/post/detail` return - * results in the expected format. - * - * @covers \Parsely\Endpoints\Analytics_Post_Detail_API_Proxy::get_items - * @uses \Parsely\Endpoints\Base_API_Proxy::get_data - * @uses \Parsely\Endpoints\Base_API_Proxy::register_endpoint - * @uses \Parsely\Endpoints\Analytics_Post_Detail_API_Proxy::__construct - * @uses \Parsely\Endpoints\Analytics_Post_Detail_API_Proxy::generate_data - * @uses \Parsely\Endpoints\Analytics_Post_Detail_API_Proxy::is_available_to_current_user - * @uses \Parsely\Endpoints\Analytics_Post_Detail_API_Proxy::run - * @uses \Parsely\Parsely::site_id_is_missing - * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Parsely::api_secret_is_set - * @uses \Parsely\Parsely::get_site_id - * @uses \Parsely\Parsely::get_options - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_api_url - * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_items - * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_request_options - */ - public function test_get_items(): void { - $this->set_current_user_to_admin(); - TestCase::set_options( - array( - 'apikey' => 'example.com', - 'api_secret' => 'test', - ) - ); - - $dispatched = 0; - - add_filter( - 'pre_http_request', - function () use ( &$dispatched ): array { - $dispatched++; - return array( - 'body' => ' - {"data":[{ - "avg_engaged": 1.911, - "metrics": { - "views": 2158, - "visitors": 1537 - }, - "url": "https://example.com" - }]} - ', - ); - } - ); - - $response = rest_get_server()->dispatch( new WP_REST_Request( 'GET', '/wp-parsely/v1/stats/post/detail' ) ); - - self::assertSame( 1, $dispatched ); - self::assertSame( 200, $response->get_status() ); - self::assertEquals( - (object) array( - 'data' => array( - (object) array( - 'avgEngaged' => '1:55', - 'dashUrl' => Parsely::DASHBOARD_BASE_URL . '/example.com/find?url=https%3A%2F%2Fexample.com', - 'id' => 'https://example.com', - 'postId' => 0, - 'url' => 'https://example.com', - 'views' => '2,158', - 'visitors' => '1,537', - 'rawUrl' => 'https://example.com', - ), - ), - ), - $response->get_data() - ); - } -} diff --git a/wp-parsely.php b/wp-parsely.php index ae8e31331..cf5012bef 100644 --- a/wp-parsely.php +++ b/wp-parsely.php @@ -132,37 +132,12 @@ function parsely_wp_admin_early_register(): void { * @since 3.2.0 */ function parsely_rest_api_init(): void { - $wp_cache = new WordPress_Cache(); - $rest = new Rest_Metadata( $GLOBALS['parsely'] ); + $rest = new Rest_Metadata( $GLOBALS['parsely'] ); $rest->run(); // Content Helper settings endpoints. ( new Dashboard_Widget_Settings_Endpoint( $GLOBALS['parsely'] ) )->run(); ( new Editor_Sidebar_Settings_Endpoint( $GLOBALS['parsely'] ) )->run(); - - parsely_run_rest_api_endpoint( - Related_API::class, - Related_API_Proxy::class, - $wp_cache - ); - - parsely_run_rest_api_endpoint( - Analytics_Posts_API::class, - Analytics_Posts_API_Proxy::class, - $wp_cache - ); - - parsely_run_rest_api_endpoint( - Analytics_Post_Detail_API::class, - Analytics_Post_Detail_API_Proxy::class, - $wp_cache - ); - - parsely_run_rest_api_endpoint( - Referrers_Post_Detail_API::class, - Referrers_Post_Detail_API_Proxy::class, - $wp_cache - ); } add_action( 'init', __NAMESPACE__ . '\\init_recommendations_block' ); From 5d785ddcb46b9796583a12d22650b37959d8c839 Mon Sep 17 00:00:00 2001 From: Henrique Mouta Date: Thu, 29 Aug 2024 13:08:50 +0100 Subject: [PATCH 060/282] Add tests --- src/rest-api/stats/class-endpoint-related.php | 6 +- src/rest-api/stats/trait-post-data.php | 7 +- .../Integration/RestAPI/BaseEndpointTest.php | 12 + .../ContentHelperControllerTest.php | 27 +- .../ContentHelperFeatureTestTrait.php | 164 ++--- .../EndpointExcerptGeneratorTest.php | 23 +- .../EndpointSmartLinkingTest.php | 44 +- .../EndpointTitleSuggestionsTest.php | 11 +- .../RestAPI/Stats/EndpointPostTest.php | 674 ++++++++++++++++++ .../RestAPI/Stats/EndpointPostsTest.php | 347 +++++++++ .../RestAPI/Stats/EndpointRelatedTest.php | 316 ++++++++ .../RestAPI/Stats/StatsControllerTest.php | 60 ++ 12 files changed, 1552 insertions(+), 139 deletions(-) create mode 100644 tests/Integration/RestAPI/Stats/EndpointPostTest.php create mode 100644 tests/Integration/RestAPI/Stats/EndpointPostsTest.php create mode 100644 tests/Integration/RestAPI/Stats/EndpointRelatedTest.php create mode 100644 tests/Integration/RestAPI/Stats/StatsControllerTest.php diff --git a/src/rest-api/stats/class-endpoint-related.php b/src/rest-api/stats/class-endpoint-related.php index d675e9e92..d636957b8 100644 --- a/src/rest-api/stats/class-endpoint-related.php +++ b/src/rest-api/stats/class-endpoint-related.php @@ -104,9 +104,9 @@ public function get_related_posts( WP_REST_Request $request ) { * @since 3.17.0 * * @param WP_REST_Request|null $request The request object. - * @return bool + * @return bool|WP_Error */ - public function is_available_to_current_user( ?WP_REST_Request $request = null ): bool { - return true; + public function is_available_to_current_user( ?WP_REST_Request $request = null ) { + return $this->validate_site_id_and_secret( false ); } } diff --git a/src/rest-api/stats/trait-post-data.php b/src/rest-api/stats/trait-post-data.php index 4698d2a9a..0ccb0a087 100644 --- a/src/rest-api/stats/trait-post-data.php +++ b/src/rest-api/stats/trait-post-data.php @@ -66,10 +66,9 @@ private function set_itm_source_from_request( WP_REST_Request $request ): void { private function get_itm_source_param_args(): array { return array( 'itm_source' => array( - 'description' => __( 'The source of the item.', 'wp-parsely' ), - 'type' => 'string', - 'required' => false, - 'validate_callback' => array( $this, 'validate_itm_source' ), + 'description' => __( 'The source of the item.', 'wp-parsely' ), + 'type' => 'string', + 'required' => false, ), ); } diff --git a/tests/Integration/RestAPI/BaseEndpointTest.php b/tests/Integration/RestAPI/BaseEndpointTest.php index 4b0b01505..0f6ba01ec 100644 --- a/tests/Integration/RestAPI/BaseEndpointTest.php +++ b/tests/Integration/RestAPI/BaseEndpointTest.php @@ -238,11 +238,19 @@ public function test_route_is_registered(): void { * @uses \Parsely\REST_API\Base_API_Controller::__construct * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Base_API_Controller::get_route_prefix * @uses \Parsely\REST_API\Base_Endpoint::__construct * @uses \Parsely\REST_API\Base_Endpoint::get_endpoint_name * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters + * @uses \Parsely\REST_API\Base_Endpoint::get_default_access_capability + * @uses \Parsely\REST_API\Content_Helper\Content_Helper_Controller::get_route_prefix + * @uses \Parsely\REST_API\Stats\Stats_Controller::get_route_prefix * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_endpoint_is_registered_based_on_filter(): void { @@ -285,6 +293,7 @@ public function test_endpoint_is_registered_based_on_filter(): void { * @covers \Parsely\REST_API\Base_Endpoint::is_available_to_current_user * @covers \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely * @uses \Parsely\Parsely::__construct * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::are_credentials_managed @@ -324,6 +333,7 @@ public function test_is_available_to_current_user_returns_error_site_id_not_set( * @covers \Parsely\REST_API\Base_Endpoint::is_available_to_current_user * @covers \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely * @uses \Parsely\Parsely::__construct * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::api_secret_is_set @@ -361,6 +371,7 @@ public function test_is_available_to_current_user_returns_error_api_secret_not_s * * @covers \Parsely\REST_API\Base_Endpoint::apply_capability_filters * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key * @uses \Parsely\Parsely::__construct * @uses \Parsely\Parsely::allow_parsely_remote_requests @@ -387,6 +398,7 @@ function () { * * @covers \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely * @uses \Parsely\Parsely::__construct * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::api_secret_is_set diff --git a/tests/Integration/RestAPI/ContentHelper/ContentHelperControllerTest.php b/tests/Integration/RestAPI/ContentHelper/ContentHelperControllerTest.php index fcc563d07..27c9e3b19 100644 --- a/tests/Integration/RestAPI/ContentHelper/ContentHelperControllerTest.php +++ b/tests/Integration/RestAPI/ContentHelper/ContentHelperControllerTest.php @@ -55,6 +55,8 @@ public function setUp(): void { * * @covers \Parsely\REST_API\Content_Helper\Content_Helper_Controller::__construct * @uses \Parsely\REST_API\Content_Helper\Content_Helper_Controller::get_full_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version */ public function test_constructor_sets_up_namespace_and_version(): void { self::assertEquals( 'wp-parsely/v2', $this->content_helper_controller->get_full_namespace() ); @@ -77,16 +79,21 @@ public function test_route_prefix(): void { * @since 3.17.0 * * @covers \Parsely\REST_API\Content_Helper\Content_Helper_Controller::init - * @uses \Parsely\REST_API\Content_Helper\Content_Helper_Controller::register_endpoints - * @uses Parsely\Endpoints\Base_Endpoint::__construct - * @uses Parsely\REST_API\Base_API_Controller::__construct - * @uses Parsely\REST_API\Base_API_Controller::register_endpoint - * @uses Parsely\REST_API\Base_Endpoint::__construct - * @uses Parsely\REST_API\Base_Endpoint::init - * @uses Parsely\REST_API\Content_Helper\Excerpt_Generator_Endpoint::__construct - * @uses Parsely\REST_API\Content_Helper\Smart_Linking_Endpoint::__construct - * @uses Parsely\REST_API\Content_Helper\Title_Suggestions_Endpoint::__construct - * @uses Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_endpoints + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::register_endpoint + * @uses \Parsely\REST_API\Base_API_Controller::register_endpoints + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Content_Helper\Endpoint_Excerpt_Generator::__construct + * @uses \Parsely\REST_API\Content_Helper\Endpoint_Excerpt_Generator::get_endpoint_name + * @uses \Parsely\REST_API\Content_Helper\Endpoint_Smart_Linking::__construct + * @uses \Parsely\REST_API\Content_Helper\Endpoint_Smart_Linking::get_endpoint_name + * @uses \Parsely\REST_API\Content_Helper\Endpoint_Title_Suggestions::__construct + * @uses \Parsely\REST_API\Content_Helper\Endpoint_Title_Suggestions::get_endpoint_name + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_init_registers_endpoints(): void { $this->content_helper_controller->init(); diff --git a/tests/Integration/RestAPI/ContentHelper/ContentHelperFeatureTestTrait.php b/tests/Integration/RestAPI/ContentHelper/ContentHelperFeatureTestTrait.php index 47615307f..d28768d80 100644 --- a/tests/Integration/RestAPI/ContentHelper/ContentHelperFeatureTestTrait.php +++ b/tests/Integration/RestAPI/ContentHelper/ContentHelperFeatureTestTrait.php @@ -30,27 +30,23 @@ trait ContentHelperFeatureTestTrait { * @since 3.17.0 * * @covers \Parsely\REST_API\Content_Helper\Content_Helper_Feature::is_available_to_current_user - * @uses Parsely\Endpoints\Base_Endpoint::__construct - * @uses Parsely\Parsely::__construct - * @uses Parsely\Parsely::allow_parsely_remote_requests - * @uses Parsely\Parsely::api_secret_is_set - * @uses Parsely\Parsely::are_credentials_managed - * @uses Parsely\Parsely::get_managed_credentials - * @uses Parsely\Parsely::get_options - * @uses Parsely\Parsely::set_default_content_helper_settings_values - * @uses Parsely\Parsely::set_default_full_metadata_in_non_posts - * @uses Parsely\Parsely::set_managed_options - * @uses Parsely\Parsely::site_id_is_set - * @uses Parsely\Permissions::build_pch_permissions_settings_array - * @uses Parsely\Permissions::current_user_can_use_pch_feature - * @uses Parsely\Permissions::get_user_roles_with_edit_posts_cap - * @uses Parsely\REST_API\Base_API_Controller::__construct - * @uses Parsely\REST_API\Base_Endpoint::__construct - * @uses Parsely\REST_API\Base_Endpoint::init - * @uses Parsely\REST_API\Base_Endpoint::apply_capability_filters - * @uses Parsely\REST_API\Base_Endpoint::is_available_to_current_user - * @uses Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret - * @uses Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::current_user_can_use_pch_feature + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters + * @uses \Parsely\REST_API\Base_Endpoint::get_default_access_capability + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_is_available_to_current_user_returns_true_if_feature_enabled(): void { $this->enable_feature(); @@ -66,27 +62,24 @@ public function test_is_available_to_current_user_returns_true_if_feature_enable * @since 3.17.0 * * @covers \Parsely\REST_API\Content_Helper\Content_Helper_Feature::is_available_to_current_user - * @uses Parsely\Endpoints\Base_Endpoint::__construct - * @uses Parsely\Parsely::__construct - * @uses Parsely\Parsely::allow_parsely_remote_requests - * @uses Parsely\Parsely::api_secret_is_set - * @uses Parsely\Parsely::are_credentials_managed - * @uses Parsely\Parsely::get_managed_credentials - * @uses Parsely\Parsely::get_options - * @uses Parsely\Parsely::set_default_content_helper_settings_values - * @uses Parsely\Parsely::set_default_full_metadata_in_non_posts - * @uses Parsely\Parsely::set_managed_options - * @uses Parsely\Parsely::site_id_is_set - * @uses Parsely\Permissions::build_pch_permissions_settings_array - * @uses Parsely\Permissions::current_user_can_use_pch_feature - * @uses Parsely\Permissions::get_user_roles_with_edit_posts_cap - * @uses Parsely\REST_API\Base_API_Controller::__construct - * @uses Parsely\REST_API\Base_Endpoint::__construct - * @uses Parsely\REST_API\Base_Endpoint::init - * @uses Parsely\REST_API\Base_Endpoint::apply_capability_filters - * @uses Parsely\REST_API\Base_Endpoint::is_available_to_current_user - * @uses Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret - * @uses Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::current_user_can_use_pch_feature + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters + * @uses \Parsely\REST_API\Base_Endpoint::get_default_access_capability + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + * / */ public function test_is_available_to_current_user_returns_error_if_feature_disabled(): void { $this->disable_feature(); @@ -102,27 +95,23 @@ public function test_is_available_to_current_user_returns_error_if_feature_disab * @since 3.17.0 * * @covers \Parsely\REST_API\Content_Helper\Content_Helper_Feature::is_available_to_current_user - * @uses Parsely\Endpoints\Base_Endpoint::__construct - * @uses Parsely\Parsely::__construct - * @uses Parsely\Parsely::allow_parsely_remote_requests - * @uses Parsely\Parsely::api_secret_is_set - * @uses Parsely\Parsely::are_credentials_managed - * @uses Parsely\Parsely::get_managed_credentials - * @uses Parsely\Parsely::get_options - * @uses Parsely\Parsely::set_default_content_helper_settings_values - * @uses Parsely\Parsely::set_default_full_metadata_in_non_posts - * @uses Parsely\Parsely::set_managed_options - * @uses Parsely\Parsely::site_id_is_set - * @uses Parsely\Permissions::build_pch_permissions_settings_array - * @uses Parsely\Permissions::current_user_can_use_pch_feature - * @uses Parsely\Permissions::get_user_roles_with_edit_posts_cap - * @uses Parsely\REST_API\Base_API_Controller::__construct - * @uses Parsely\REST_API\Base_Endpoint::__construct - * @uses Parsely\REST_API\Base_Endpoint::init - * @uses Parsely\REST_API\Base_Endpoint::apply_capability_filters - * @uses Parsely\REST_API\Base_Endpoint::is_available_to_current_user - * @uses Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret - * @uses Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::current_user_can_use_pch_feature + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters + * @uses \Parsely\REST_API\Base_Endpoint::get_default_access_capability + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_is_available_to_current_user_returns_true_if_has_permissions(): void { $this->set_feature_options( @@ -148,27 +137,23 @@ public function test_is_available_to_current_user_returns_true_if_has_permission * @since 3.17.0 * * @covers \Parsely\REST_API\Content_Helper\Content_Helper_Feature::is_available_to_current_user - * @uses Parsely\Endpoints\Base_Endpoint::__construct - * @uses Parsely\Parsely::__construct - * @uses Parsely\Parsely::allow_parsely_remote_requests - * @uses Parsely\Parsely::api_secret_is_set - * @uses Parsely\Parsely::are_credentials_managed - * @uses Parsely\Parsely::get_managed_credentials - * @uses Parsely\Parsely::get_options - * @uses Parsely\Parsely::set_default_content_helper_settings_values - * @uses Parsely\Parsely::set_default_full_metadata_in_non_posts - * @uses Parsely\Parsely::set_managed_options - * @uses Parsely\Parsely::site_id_is_set - * @uses Parsely\Permissions::build_pch_permissions_settings_array - * @uses Parsely\Permissions::current_user_can_use_pch_feature - * @uses Parsely\Permissions::get_user_roles_with_edit_posts_cap - * @uses Parsely\REST_API\Base_API_Controller::__construct - * @uses Parsely\REST_API\Base_Endpoint::__construct - * @uses Parsely\REST_API\Base_Endpoint::init - * @uses Parsely\REST_API\Base_Endpoint::apply_capability_filters - * @uses Parsely\REST_API\Base_Endpoint::is_available_to_current_user - * @uses Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret - * @uses Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::current_user_can_use_pch_feature + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters + * @uses \Parsely\REST_API\Base_Endpoint::get_default_access_capability + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_is_available_to_current_user_returns_error_if_no_permissions(): void { $this->set_current_user_to_contributor(); @@ -192,18 +177,21 @@ public function test_is_available_to_current_user_returns_error_if_no_permission * * @covers \Parsely\REST_API\Content_Helper\Content_Helper_Feature::is_available_to_current_user * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\Parsely::__construct - * @uses \Parsely\Parsely::allow_parsely_remote_requests - * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::api_secret_is_set * @uses \Parsely\Parsely::get_managed_credentials * @uses \Parsely\Parsely::get_options * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts - * @uses \Parsely\Parsely::set_managed_options + * @uses \Parsely\Parsely::site_id_is_set * @uses \Parsely\Permissions::current_user_can_use_pch_feature * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters + * @uses \Parsely\REST_API\Base_Endpoint::get_default_access_capability * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_is_available_to_current_user_returns_error_if_no_user(): void { diff --git a/tests/Integration/RestAPI/ContentHelper/EndpointExcerptGeneratorTest.php b/tests/Integration/RestAPI/ContentHelper/EndpointExcerptGeneratorTest.php index c959a8e2d..986931374 100644 --- a/tests/Integration/RestAPI/ContentHelper/EndpointExcerptGeneratorTest.php +++ b/tests/Integration/RestAPI/ContentHelper/EndpointExcerptGeneratorTest.php @@ -68,29 +68,28 @@ public function get_endpoint(): \Parsely\REST_API\Base_Endpoint { * * @covers \Parsely\REST_API\Content_Helper\Endpoint_Excerpt_Generator::register_routes * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\Parsely::__construct - * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::api_secret_is_set - * @uses \Parsely\Parsely::are_credentials_managed * @uses \Parsely\Parsely::get_managed_credentials * @uses \Parsely\Parsely::get_options * @uses \Parsely\Parsely::set_default_content_helper_settings_values * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts - * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set * @uses \Parsely\Permissions::build_pch_permissions_settings_array * @uses \Parsely\Permissions::current_user_can_use_pch_feature * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap * @uses \Parsely\REST_API\Base_API_Controller::__construct * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely * @uses \Parsely\REST_API\Base_API_Controller::prefix_route * @uses \Parsely\REST_API\Base_Endpoint::__construct - * @uses \Parsely\REST_API\Base_Endpoint::get_endpoint_name * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint * @uses \Parsely\REST_API\Base_Endpoint::init * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\REST_API\Content_Helper\Content_Helper_Controller::get_route_prefix + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_route_is_registered(): void { @@ -114,12 +113,11 @@ public function test_route_is_registered(): void { * * @covers \Parsely\REST_API\Content_Helper\Endpoint_Excerpt_Generator::generate_excerpt * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\Parsely::__construct - * @uses \Parsely\Parsely::allow_parsely_remote_requests - * @uses \Parsely\Parsely::are_credentials_managed - * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_generate_excerpt_returns_valid_response(): void { // Mock the Suggest_Brief_API to control the response. @@ -160,12 +158,11 @@ public function test_generate_excerpt_returns_valid_response(): void { * * @covers \Parsely\REST_API\Content_Helper\Endpoint_Excerpt_Generator::generate_excerpt * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\Parsely::__construct - * @uses \Parsely\Parsely::allow_parsely_remote_requests - * @uses \Parsely\Parsely::are_credentials_managed - * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_generate_excerpt_returns_error_on_failure(): void { // Mock the Suggest_Brief_API to simulate a failure. diff --git a/tests/Integration/RestAPI/ContentHelper/EndpointSmartLinkingTest.php b/tests/Integration/RestAPI/ContentHelper/EndpointSmartLinkingTest.php index 8389bd7c0..69cc858b8 100644 --- a/tests/Integration/RestAPI/ContentHelper/EndpointSmartLinkingTest.php +++ b/tests/Integration/RestAPI/ContentHelper/EndpointSmartLinkingTest.php @@ -79,29 +79,30 @@ public function get_endpoint(): \Parsely\REST_API\Base_Endpoint { * * @covers \Parsely\REST_API\Content_Helper\Endpoint_Smart_Linking::register_routes * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\Parsely::__construct - * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::api_secret_is_set - * @uses \Parsely\Parsely::are_credentials_managed * @uses \Parsely\Parsely::get_managed_credentials * @uses \Parsely\Parsely::get_options * @uses \Parsely\Parsely::set_default_content_helper_settings_values * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts - * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set * @uses \Parsely\Permissions::build_pch_permissions_settings_array * @uses \Parsely\Permissions::current_user_can_use_pch_feature * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap * @uses \Parsely\REST_API\Base_API_Controller::__construct * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely * @uses \Parsely\REST_API\Base_API_Controller::prefix_route * @uses \Parsely\REST_API\Base_Endpoint::__construct - * @uses \Parsely\REST_API\Base_Endpoint::get_endpoint_name + * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters + * @uses \Parsely\REST_API\Base_Endpoint::get_default_access_capability * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint * @uses \Parsely\REST_API\Base_Endpoint::init * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\REST_API\Content_Helper\Content_Helper_Controller::get_route_prefix + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_route_is_registered(): void { @@ -125,12 +126,17 @@ public function test_route_is_registered(): void { * * @covers \Parsely\REST_API\Content_Helper\Endpoint_Smart_Linking::generate_smart_links * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\Parsely::__construct - * @uses \Parsely\Parsely::allow_parsely_remote_requests - * @uses \Parsely\Parsely::are_credentials_managed - * @uses \Parsely\Parsely::set_managed_options + * @uses \Parsely\Models\Base_Model::__construct + * @uses \Parsely\Models\Smart_Link::__construct + * @uses \Parsely\Models\Smart_Link::generate_uid + * @uses \Parsely\Models\Smart_Link::get_post_id_by_url + * @uses \Parsely\Models\Smart_Link::set_href + * @uses \Parsely\Models\Smart_Link::to_array * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_generate_smart_links_returns_valid_response(): void { // Mock the Suggest_Linked_Reference_API to control the response. @@ -175,12 +181,11 @@ public function test_generate_smart_links_returns_valid_response(): void { * * @covers \Parsely\REST_API\Content_Helper\Endpoint_Smart_Linking::generate_smart_links * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\Parsely::__construct - * @uses \Parsely\Parsely::allow_parsely_remote_requests - * @uses \Parsely\Parsely::are_credentials_managed - * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_generate_smart_links_returns_error_on_failure(): void { // Mock the Suggest_Linked_Reference_API to simulate a failure. @@ -238,15 +243,19 @@ public function test_generate_smart_links_returns_error_on_failure(): void { * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap * @uses \Parsely\REST_API\Base_API_Controller::__construct * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely * @uses \Parsely\REST_API\Base_API_Controller::prefix_route * @uses \Parsely\REST_API\Base_Endpoint::__construct * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters - * @uses \Parsely\REST_API\Base_Endpoint::get_endpoint_name + * @uses \Parsely\REST_API\Base_Endpoint::get_default_access_capability * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint * @uses \Parsely\REST_API\Base_Endpoint::init * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\REST_API\Content_Helper\Content_Helper_Controller::get_route_prefix + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_add_smart_link_returns_valid_response(): void { @@ -307,7 +316,6 @@ public function test_add_smart_link_returns_valid_response(): void { * @since 3.17.0 * * @covers \Parsely\REST_API\Content_Helper\Endpoint_Smart_Linking::add_multiple_smart_links - * * @uses \Parsely\Endpoints\Base_Endpoint::__construct * @uses \Parsely\Models\Base_Model::__construct * @uses \Parsely\Models\Base_Model::serialize @@ -335,15 +343,19 @@ public function test_add_smart_link_returns_valid_response(): void { * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap * @uses \Parsely\REST_API\Base_API_Controller::__construct * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely * @uses \Parsely\REST_API\Base_API_Controller::prefix_route * @uses \Parsely\REST_API\Base_Endpoint::__construct * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters - * @uses \Parsely\REST_API\Base_Endpoint::get_endpoint_name + * @uses \Parsely\REST_API\Base_Endpoint::get_default_access_capability * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint * @uses \Parsely\REST_API\Base_Endpoint::init * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\REST_API\Content_Helper\Content_Helper_Controller::get_route_prefix + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_add_multiple_smart_links_returns_valid_response(): void { diff --git a/tests/Integration/RestAPI/ContentHelper/EndpointTitleSuggestionsTest.php b/tests/Integration/RestAPI/ContentHelper/EndpointTitleSuggestionsTest.php index a54e9391b..a3a5f47fc 100644 --- a/tests/Integration/RestAPI/ContentHelper/EndpointTitleSuggestionsTest.php +++ b/tests/Integration/RestAPI/ContentHelper/EndpointTitleSuggestionsTest.php @@ -67,29 +67,28 @@ public function get_endpoint(): \Parsely\REST_API\Base_Endpoint { * * @covers \Parsely\REST_API\Content_Helper\Endpoint_Title_Suggestions::register_routes * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\Parsely::__construct - * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::api_secret_is_set - * @uses \Parsely\Parsely::are_credentials_managed * @uses \Parsely\Parsely::get_managed_credentials * @uses \Parsely\Parsely::get_options * @uses \Parsely\Parsely::set_default_content_helper_settings_values * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts - * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set * @uses \Parsely\Permissions::build_pch_permissions_settings_array * @uses \Parsely\Permissions::current_user_can_use_pch_feature * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap * @uses \Parsely\REST_API\Base_API_Controller::__construct * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely * @uses \Parsely\REST_API\Base_API_Controller::prefix_route * @uses \Parsely\REST_API\Base_Endpoint::__construct - * @uses \Parsely\REST_API\Base_Endpoint::get_endpoint_name * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint * @uses \Parsely\REST_API\Base_Endpoint::init * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\REST_API\Content_Helper\Content_Helper_Controller::get_route_prefix + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_route_is_registered(): void { @@ -116,6 +115,7 @@ public function test_route_is_registered(): void { * @uses \Parsely\Parsely::are_credentials_managed * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely * @uses \Parsely\REST_API\Base_Endpoint::__construct * @uses \Parsely\REST_API\Base_Endpoint::init * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key @@ -164,6 +164,7 @@ public function test_generate_titles_returns_valid_response(): void { * @uses \Parsely\Parsely::are_credentials_managed * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely * @uses \Parsely\REST_API\Base_Endpoint::__construct * @uses \Parsely\REST_API\Base_Endpoint::init * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key diff --git a/tests/Integration/RestAPI/Stats/EndpointPostTest.php b/tests/Integration/RestAPI/Stats/EndpointPostTest.php new file mode 100644 index 000000000..acba94a64 --- /dev/null +++ b/tests/Integration/RestAPI/Stats/EndpointPostTest.php @@ -0,0 +1,674 @@ +api_controller = new Stats_Controller( $this->parsely ); + $this->endpoint = new Endpoint_Post( $this->api_controller ); + + parent::set_up(); + } + + /** + * Get the test endpoint instance. + * + * @since 3.17.0 + * + * @return Endpoint_Post + */ + public function get_endpoint(): \Parsely\REST_API\Base_Endpoint { + return $this->endpoint; + } + + /** + * Test that the route is registered. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Stats\Endpoint_Post::register_routes + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::get_registered_routes + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Stats\Endpoint_Post::__construct + * @uses \Parsely\REST_API\Stats\Endpoint_Post::get_endpoint_name + * @uses \Parsely\REST_API\Stats\Post_Data_Trait::get_itm_source_param_args + * @uses \Parsely\REST_API\Stats\Related_Posts_Trait::get_related_posts_param_args + * @uses \Parsely\REST_API\Stats\Stats_Controller::get_route_prefix + * @uses \Parsely\REST_API\Use_Post_ID_Parameter_Trait::register_rest_route_with_post_id + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_route_is_registered(): void { + $routes = rest_get_server()->get_routes(); + $registered_routes = $this->get_endpoint()->get_registered_routes(); + + // Assert that the routes are registered when the filter returns true. + foreach ( $registered_routes as $route ) { + $expected_route = $this->get_endpoint()->get_full_endpoint( $route ); + $route_data = $routes[ $expected_route ]; + self::assertArrayHasKey( $expected_route, $routes ); + + // Check that the route is associated with the GET method, since all + // the routes in this endpoint are GET routes. + self::assertArrayHasKey( 'GET', $route_data[0]['methods'] ); + } + } + + /** + * Test that the endpoint is not available if the API key is not set. + * + * @covers \Parsely\REST_API\Stats\Endpoint_Post::is_available_to_current_user + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Stats\Endpoint_Post::__construct + * @uses \Parsely\REST_API\Stats\Endpoint_Post::get_endpoint_name + * @uses \Parsely\REST_API\Stats\Endpoint_Post::register_routes + * @uses \Parsely\REST_API\Stats\Post_Data_Trait::get_itm_source_param_args + * @uses \Parsely\REST_API\Stats\Related_Posts_Trait::get_related_posts_param_args + * @uses \Parsely\REST_API\Stats\Stats_Controller::get_route_prefix + * @uses \Parsely\REST_API\Use_Post_ID_Parameter_Trait::register_rest_route_with_post_id + * @uses \Parsely\REST_API\Use_Post_ID_Parameter_Trait::validate_post_id + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_access_error_if_api_secret_is_not_set(): void { + $test_post_id = $this->create_test_post(); + TestCase::set_options( + array( + 'apikey' => 'test', + ) + ); + $route = $this->get_endpoint()->get_full_endpoint( '/' . $test_post_id . '/details' ); + $response = rest_get_server()->dispatch( + new WP_REST_Request( 'GET', $route ) + ); + + $error = $response->as_error(); + self::assertNotNull( $error ); + self::assertSame( 403, $response->get_status() ); + self::assertSame( 'parsely_api_secret_not_set', $error->get_error_code() ); + self::assertSame( + 'A Parse.ly API Secret must be set in site options to use this endpoint', + $error->get_error_message() + ); + } + + + /** + * Verifies forbidden error when current user doesn't have proper + * capabilities. + * + * @covers \Parsely\REST_API\Stats\Endpoint_Post::is_available_to_current_user + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters + * @uses \Parsely\REST_API\Base_Endpoint::get_default_access_capability + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Stats\Endpoint_Post::__construct + * @uses \Parsely\REST_API\Stats\Endpoint_Post::get_endpoint_name + * @uses \Parsely\REST_API\Stats\Endpoint_Post::register_routes + * @uses \Parsely\REST_API\Stats\Post_Data_Trait::get_itm_source_param_args + * @uses \Parsely\REST_API\Stats\Related_Posts_Trait::get_related_posts_param_args + * @uses \Parsely\REST_API\Stats\Stats_Controller::get_route_prefix + * @uses \Parsely\REST_API\Use_Post_ID_Parameter_Trait::register_rest_route_with_post_id + * @uses \Parsely\REST_API\Use_Post_ID_Parameter_Trait::validate_post_id + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_access_of_stats_post_endpoint_is_forbidden(): void { + $test_post_id = $this->create_test_post(); + TestCase::set_options( + array( + 'apikey' => 'test-api-key', + 'api_secret' => 'test-secret', + ) + ); + $this->set_current_user_to_contributor(); + + $route = $this->get_endpoint()->get_full_endpoint( '/' . $test_post_id . '/details' ); + $response = rest_get_server()->dispatch( + new WP_REST_Request( 'GET', $route ) + ); + /** + * Variable. + * + * @var WP_Error $error + */ + $error = $response->as_error(); + + self::assertSame( 403, $response->get_status() ); + self::assertSame( 'rest_forbidden', $error->get_error_code() ); + self::assertSame( + 'Sorry, you are not allowed to do that.', + $error->get_error_message() + ); + } + + /** + * Verifies that calls to the `stats/{post_id}/details` return the expected data, in the + * expected format. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Stats\Endpoint_Post::get_post_details + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::get_api_secret + * @uses \Parsely\Parsely::get_dash_url + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::get_site_id + * @uses \Parsely\Parsely::get_url_with_itm_source + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters + * @uses \Parsely\REST_API\Base_Endpoint::get_default_access_capability + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Stats\Endpoint_Post::__construct + * @uses \Parsely\REST_API\Stats\Endpoint_Post::get_endpoint_name + * @uses \Parsely\REST_API\Stats\Endpoint_Post::register_routes + * @uses \Parsely\REST_API\Stats\Post_Data_Trait::extract_post_data + * @uses \Parsely\REST_API\Stats\Post_Data_Trait::get_itm_source_param_args + * @uses \Parsely\REST_API\Stats\Post_Data_Trait::set_itm_source_from_request + * @uses \Parsely\REST_API\Stats\Related_Posts_Trait::get_related_posts_param_args + * @uses \Parsely\REST_API\Stats\Stats_Controller::get_route_prefix + * @uses \Parsely\REST_API\Use_Post_ID_Parameter_Trait::register_rest_route_with_post_id + * @uses \Parsely\REST_API\Use_Post_ID_Parameter_Trait::validate_post_id + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_api_url + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_items + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_request_options + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::validate_required_constraints + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Utils\Utils::get_formatted_duration + * @uses \Parsely\Utils\Utils::parsely_is_https_supported + */ + public function test_get_details(): void { + $test_post_id = $this->create_test_post(); + $route = $this->get_endpoint()->get_full_endpoint( '/' . $test_post_id . '/details' ); + + TestCase::set_options( + array( + 'apikey' => 'example.com', + 'api_secret' => 'test-secret', + ) + ); + $this->set_current_user_to_admin(); + + $dispatched = 0; + + add_filter( + 'pre_http_request', + function () use ( &$dispatched ): array { + $dispatched++; + return array( + 'body' => ' + {"data":[{ + "avg_engaged": 1.911, + "metrics": { + "views": 2158, + "visitors": 1537 + }, + "url": "https://example.com" + }]} + ', + ); + } + ); + + $response = rest_get_server()->dispatch( new WP_REST_Request( 'GET', $route ) ); + + /** + * The response data. + * + * @var array $response_data + */ + $response_data = $response->get_data(); + + self::assertSame( 1, $dispatched ); + self::assertSame( 200, $response->get_status() ); + self::assertEquals( + array( + array( + 'avgEngaged' => '1:55', + 'dashUrl' => Parsely::DASHBOARD_BASE_URL . '/example.com/find?url=https%3A%2F%2Fexample.com', + 'id' => 'https://example.com', + 'postId' => 0, + 'url' => 'https://example.com', + 'views' => '2,158', + 'visitors' => '1,537', + 'rawUrl' => 'https://example.com', + ), + ), + $response_data['data'] + ); + } + + /** + * Verifies that calls to the `stats/{post_id}/referrers` return the expected data, in the + * expected format. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Stats\Endpoint_Post::get_post_referrers + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::get_api_secret + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::get_site_id + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters + * @uses \Parsely\REST_API\Base_Endpoint::get_default_access_capability + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Stats\Endpoint_Post::__construct + * @uses \Parsely\REST_API\Stats\Endpoint_Post::generate_referrer_types_data + * @uses \Parsely\REST_API\Stats\Endpoint_Post::generate_referrers_data + * @uses \Parsely\REST_API\Stats\Endpoint_Post::get_endpoint_name + * @uses \Parsely\REST_API\Stats\Endpoint_Post::get_i18n_percentage + * @uses \Parsely\REST_API\Stats\Endpoint_Post::register_routes + * @uses \Parsely\REST_API\Stats\Post_Data_Trait::get_itm_source_param_args + * @uses \Parsely\REST_API\Stats\Post_Data_Trait::set_itm_source_from_request + * @uses \Parsely\REST_API\Stats\Related_Posts_Trait::get_related_posts_param_args + * @uses \Parsely\REST_API\Stats\Stats_Controller::get_route_prefix + * @uses \Parsely\REST_API\Use_Post_ID_Parameter_Trait::register_rest_route_with_post_id + * @uses \Parsely\REST_API\Use_Post_ID_Parameter_Trait::validate_post_id + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_api_url + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_items + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_request_options + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::validate_required_constraints + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Utils\Utils::convert_to_positive_integer + */ + public function test_get_referrers(): void { + $test_post_id = $this->create_test_post(); + $route = $this->get_endpoint()->get_full_endpoint( '/' . $test_post_id . '/referrers' ); + + TestCase::set_options( + array( + 'apikey' => 'example.com', + 'api_secret' => 'test-secret', + ) + ); + $this->set_current_user_to_admin(); + + $dispatched = 0; + + add_filter( + 'pre_http_request', + function () use ( &$dispatched ): array { + $dispatched++; + return array( + 'body' => '{"data":[ + { + "metrics": {"referrers_views": 1500}, + "name": "google", + "type": "search" + }, + { + "metrics": {"referrers_views": 100}, + "name": "blog.parse.ly", + "type": "internal" + }, + { + "metrics": {"referrers_views": 50}, + "name": "bing", + "type": "search" + }, + { + "metrics": {"referrers_views": 30}, + "name": "facebook.com", + "type": "social" + }, + { + "metrics": {"referrers_views": 10}, + "name": "okt.to", + "type": "other" + }, + { + "metrics": {"referrers_views": 10}, + "name": "yandex", + "type": "search" + }, + { + "metrics": {"referrers_views": 10}, + "name": "parse.ly", + "type": "internal" + }, + { + "metrics": {"referrers_views": 10}, + "name": "yahoo!", + "type": "search" + }, + { + "metrics": {"referrers_views": 5}, + "name": "site1.com", + "type": "other" + }, + { + "metrics": {"referrers_views": 5}, + "name": "link.site2.com", + "type": "other" + } + ]}', + ); + } + ); + + $expected_top = (object) array( + 'direct' => (object) array( + 'views' => '770', + 'viewsPercentage' => '30.80', + 'datasetViewsPercentage' => '31.43', + ), + 'google' => (object) array( + 'views' => '1,500', + 'viewsPercentage' => '60.00', + 'datasetViewsPercentage' => '61.22', + ), + 'blog.parse.ly' => (object) array( + 'views' => '100', + 'viewsPercentage' => '4.00', + 'datasetViewsPercentage' => '4.08', + ), + 'bing' => (object) array( + 'views' => '50', + 'viewsPercentage' => '2.00', + 'datasetViewsPercentage' => '2.04', + ), + 'facebook.com' => (object) array( + 'views' => '30', + 'viewsPercentage' => '1.20', + 'datasetViewsPercentage' => '1.22', + ), + 'totals' => (object) array( + 'views' => '2,450', + 'viewsPercentage' => '98.00', + 'datasetViewsPercentage' => '100.00', + ), + ); + + $expected_types = (object) array( + 'social' => (object) array( + 'views' => '30', + 'viewsPercentage' => '1.20', + ), + 'search' => (object) array( + 'views' => '1,570', + 'viewsPercentage' => '62.80', + ), + 'other' => (object) array( + 'views' => '20', + 'viewsPercentage' => '0.80', + ), + 'internal' => (object) array( + 'views' => '110', + 'viewsPercentage' => '4.40', + ), + 'direct' => (object) array( + 'views' => '770', + 'viewsPercentage' => '30.80', + ), + 'totals' => (object) array( + 'views' => '2,500', + 'viewsPercentage' => '100.00', + ), + ); + + $request = new WP_REST_Request( 'GET', $route ); + $request->set_param( 'total_views', '2,500' ); + + $response = rest_get_server()->dispatch( $request ); + + /** + * The response data. + * + * @var array $response_data + */ + $response_data = $response->get_data(); + + self::assertSame( 1, $dispatched ); + self::assertSame( 200, $response->get_status() ); + self::assertEquals( + array( + 'top' => $expected_top, + 'types' => $expected_types, + ), + $response_data['data'] + ); + } + + + /** + * Verifies that calls to the `stats/{post_id}/related` return the expected data, in the + * expected format. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Stats\Endpoint_Post::get_related_posts + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::get_api_secret + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::get_site_id + * @uses \Parsely\Parsely::get_url_with_itm_source + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters + * @uses \Parsely\REST_API\Base_Endpoint::get_default_access_capability + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Stats\Endpoint_Post::__construct + * @uses \Parsely\REST_API\Stats\Endpoint_Post::get_endpoint_name + * @uses \Parsely\REST_API\Stats\Endpoint_Post::register_routes + * @uses \Parsely\REST_API\Stats\Post_Data_Trait::get_itm_source_param_args + * @uses \Parsely\REST_API\Stats\Post_Data_Trait::set_itm_source_from_request + * @uses \Parsely\REST_API\Stats\Related_Posts_Trait::get_related_posts_of_url + * @uses \Parsely\REST_API\Stats\Related_Posts_Trait::get_related_posts_param_args + * @uses \Parsely\REST_API\Stats\Stats_Controller::get_route_prefix + * @uses \Parsely\REST_API\Use_Post_ID_Parameter_Trait::register_rest_route_with_post_id + * @uses \Parsely\REST_API\Use_Post_ID_Parameter_Trait::validate_post_id + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_api_url + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_items + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_request_options + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::validate_required_constraints + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_get_related_posts(): void { + $test_post_id = $this->create_test_post(); + $route = $this->get_endpoint()->get_full_endpoint( '/' . $test_post_id . '/related' ); + + TestCase::set_options( + array( + 'apikey' => 'example.com', + 'api_secret' => 'test-secret', + ) + ); + $this->set_current_user_to_admin(); + + $dispatched = 0; + + add_filter( + 'pre_http_request', + function () use ( &$dispatched ): array { + $dispatched++; + return array( + 'body' => '{"data":[ + { + "image_url":"https:\/\/example.com\/img.png", + "thumb_url_medium":"https:\/\/example.com\/thumb.png", + "title":"something", + "url":"https:\/\/example.com" + }, + { + "image_url":"https:\/\/example.com\/img2.png", + "thumb_url_medium":"https:\/\/example.com\/thumb2.png", + "title":"something2", + "url":"https:\/\/example.com\/2" + } + ]}', + ); + } + ); + + $response = rest_get_server()->dispatch( new WP_REST_Request( 'GET', $route ) ); + /** + * The response data. + * + * @var array $response_data + */ + $response_data = $response->get_data(); + + self::assertSame( 1, $dispatched ); + self::assertSame( 200, $response->get_status() ); + self::assertEquals( + array( + (object) array( + 'image_url' => 'https://example.com/img.png', + 'thumb_url_medium' => 'https://example.com/thumb.png', + 'title' => 'something', + 'url' => 'https://example.com', + ), + (object) array( + 'image_url' => 'https://example.com/img2.png', + 'thumb_url_medium' => 'https://example.com/thumb2.png', + 'title' => 'something2', + 'url' => 'https://example.com/2', + ), + ), + $response_data['data'] + ); + } +} diff --git a/tests/Integration/RestAPI/Stats/EndpointPostsTest.php b/tests/Integration/RestAPI/Stats/EndpointPostsTest.php new file mode 100644 index 000000000..0cecdd1cb --- /dev/null +++ b/tests/Integration/RestAPI/Stats/EndpointPostsTest.php @@ -0,0 +1,347 @@ +api_controller = new Stats_Controller( $this->parsely ); + $this->endpoint = new Endpoint_Posts( $this->api_controller ); + + parent::set_up(); + } + + /** + * Get the test endpoint instance. + * + * @since 3.17.0 + * + * @return Endpoint_Posts + */ + public function get_endpoint(): \Parsely\REST_API\Base_Endpoint { + return $this->endpoint; + } + + /** + * Test the route is registered. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Stats\Endpoint_Posts::register_routes + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Stats\Stats_Controller::get_route_prefix + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_route_is_registered(): void { + $routes = rest_get_server()->get_routes(); + + // Check that the excerpt-generator/generate route is registered. + $expected_route = $this->get_endpoint()->get_full_endpoint( '/' ); + self::assertArrayHasKey( $expected_route, $routes ); + + // Check that the route is associated with the POST method. + $route_data = $routes[ $expected_route ]; + self::assertArrayHasKey( 'GET', $route_data[0]['methods'] ); + } + + /** + * Test that the endpoint is not available if the API key is not set. + * + * @covers \Parsely\REST_API\Stats\Endpoint_Posts::is_available_to_current_user + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Stats\Stats_Controller::get_route_prefix + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_access_error_if_api_secret_is_not_set(): void { + TestCase::set_options( + array( + 'apikey' => 'test', + ) + ); + $route = $this->get_endpoint()->get_full_endpoint( '/' ); + $response = rest_get_server()->dispatch( + new WP_REST_Request( 'GET', $route ) + ); + + $error = $response->as_error(); + self::assertNotNull( $error ); + self::assertSame( 403, $response->get_status() ); + self::assertSame( 'parsely_api_secret_not_set', $error->get_error_code() ); + self::assertSame( + 'A Parse.ly API Secret must be set in site options to use this endpoint', + $error->get_error_message() + ); + } + + + /** + * Verifies forbidden error when current user doesn't have proper + * capabilities. + * + * @covers \Parsely\REST_API\Stats\Endpoint_Posts::is_available_to_current_user + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters + * @uses \Parsely\REST_API\Base_Endpoint::get_default_access_capability + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Stats\Stats_Controller::get_route_prefix + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_access_of_stats_posts_endpoint_is_forbidden(): void { + TestCase::set_options( + array( + 'apikey' => 'test-api-key', + 'api_secret' => 'test-secret', + ) + ); + $this->set_current_user_to_contributor(); + + $route = $this->get_endpoint()->get_full_endpoint( '/' ); + $response = rest_get_server()->dispatch( + new WP_REST_Request( 'GET', $route ) + ); + /** + * Variable. + * + * @var WP_Error $error + */ + $error = $response->as_error(); + + self::assertSame( 403, $response->get_status() ); + self::assertSame( 'rest_forbidden', $error->get_error_code() ); + self::assertSame( + 'Sorry, you are not allowed to do that.', + $error->get_error_message() + ); + } + + /** + * Verifies that calls to the endpoint return the expected data, in the + * expected format. + * + * @covers \Parsely\REST_API\Stats\Endpoint_Posts::get_posts + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::get_api_secret + * @uses \Parsely\Parsely::get_dash_url + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::get_site_id + * @uses \Parsely\Parsely::get_url_with_itm_source + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters + * @uses \Parsely\REST_API\Base_Endpoint::get_default_access_capability + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Stats\Stats_Controller::get_route_prefix + * @uses \Parsely\RemoteAPI\Analytics_Posts_API::get_request_options + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_api_url + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_items + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::validate_required_constraints + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Utils\Utils::get_date_format + * @uses \Parsely\Utils\Utils::parsely_is_https_supported + */ + public function test_get_posts(): void { + TestCase::set_options( + array( + 'apikey' => 'example.com', + 'api_secret' => 'test-secret', + ) + ); + $this->set_current_user_to_admin(); + + $dispatched = 0; + $date_format = Utils::get_date_format(); + + add_filter( + 'pre_http_request', + function () use ( &$dispatched ): array { + $dispatched++; + + return array( + 'body' => '{"data":[ + { + "author": "Aakash Shah", + "metrics": {"views": 142}, + "pub_date": "2020-04-06T13:30:58", + "thumb_url_medium": "https://images.parsely.com/XCmTXuOf8yVbUYTxj2abQ4RSDkM=/85x85/smart/https%3A//blog.parse.ly/wp-content/uploads/2021/06/Web-Analytics-Tool.png%3Fw%3D150%26h%3D150%26crop%3D1", + "title": "9 Types of Web Analytics Tools \u2014 And How to Know Which Ones You Really Need", + "url": "https://blog.parse.ly/web-analytics-software-tools/?itm_source=parsely-api" + }, + { + "author": "Stephanie Schwartz and Andrew Butler", + "metrics": {"views": 40}, + "pub_date": "2021-04-30T20:30:24", + "thumb_url_medium": "https://images.parsely.com/ap3YSufqxnLpz6zzQshoks3snXI=/85x85/smart/https%3A//blog.parse.ly/wp-content/uploads/2021/05/pexels-brett-jordan-998501-1024x768-2.jpeg%3Fw%3D150%26h%3D150%26crop%3D1", + "title": "5 Tagging Best Practices For Getting the Most Out of Your Content Strategy", + "url": "https://blog.parse.ly/5-tagging-best-practices-content-strategy/?itm_source=parsely-api" + } + ]}', + ); + } + ); + + $rest_request = new WP_REST_Request( 'GET', '/wp-parsely/v2/stats/posts' ); + $rest_request->set_param( 'itm_source', 'wp-parsely-content-helper' ); + + $response = rest_get_server()->dispatch( $rest_request ); + + /** + * The response data. + * + * @var array $response_data + */ + $response_data = $response->get_data(); + + self::assertSame( 1, $dispatched ); + self::assertSame( 200, $response->get_status() ); + self::assertEquals( + array( + array( + 'author' => 'Aakash Shah', + 'date' => wp_date( $date_format, strtotime( '2020-04-06T13:30:58' ) ), + 'id' => 'https://blog.parse.ly/web-analytics-software-tools/', + 'dashUrl' => PARSELY::DASHBOARD_BASE_URL . '/example.com/find?url=https%3A%2F%2Fblog.parse.ly%2Fweb-analytics-software-tools%2F', + 'thumbnailUrl' => 'https://images.parsely.com/XCmTXuOf8yVbUYTxj2abQ4RSDkM=/85x85/smart/https%3A//blog.parse.ly/wp-content/uploads/2021/06/Web-Analytics-Tool.png%3Fw%3D150%26h%3D150%26crop%3D1', + 'title' => '9 Types of Web Analytics Tools — And How to Know Which Ones You Really Need', + 'url' => 'https://blog.parse.ly/web-analytics-software-tools/?itm_source=wp-parsely-content-helper', + 'views' => '142', + 'postId' => 0, + 'rawUrl' => 'https://blog.parse.ly/web-analytics-software-tools/', + ), + array( + 'author' => 'Stephanie Schwartz and Andrew Butler', + 'date' => wp_date( $date_format, strtotime( '2021-04-30T20:30:24' ) ), + 'id' => 'https://blog.parse.ly/5-tagging-best-practices-content-strategy/', + 'dashUrl' => PARSELY::DASHBOARD_BASE_URL . '/example.com/find?url=https%3A%2F%2Fblog.parse.ly%2F5-tagging-best-practices-content-strategy%2F', + 'thumbnailUrl' => 'https://images.parsely.com/ap3YSufqxnLpz6zzQshoks3snXI=/85x85/smart/https%3A//blog.parse.ly/wp-content/uploads/2021/05/pexels-brett-jordan-998501-1024x768-2.jpeg%3Fw%3D150%26h%3D150%26crop%3D1', + 'title' => '5 Tagging Best Practices For Getting the Most Out of Your Content Strategy', + 'url' => 'https://blog.parse.ly/5-tagging-best-practices-content-strategy/?itm_source=wp-parsely-content-helper', + 'views' => '40', + 'postId' => 0, + 'rawUrl' => 'https://blog.parse.ly/5-tagging-best-practices-content-strategy/', + ), + ), + $response_data['data'] + ); + + self::assertEquals( + array( + 'limit' => 5, + 'sort' => 'views', + 'page' => 1, + 'itm_source' => 'wp-parsely-content-helper', + ), + $response_data['params'] + ); + } +} diff --git a/tests/Integration/RestAPI/Stats/EndpointRelatedTest.php b/tests/Integration/RestAPI/Stats/EndpointRelatedTest.php new file mode 100644 index 000000000..463886c85 --- /dev/null +++ b/tests/Integration/RestAPI/Stats/EndpointRelatedTest.php @@ -0,0 +1,316 @@ +api_controller = new Stats_Controller( $this->parsely ); + $this->endpoint = new Endpoint_Related( $this->api_controller ); + + parent::set_up(); + } + + + /** + * Get the test endpoint instance. + * + * @since 3.17.0 + * + * @return Endpoint_Related + */ + public function get_endpoint(): \Parsely\REST_API\Base_Endpoint { + return $this->endpoint; + } + + /** + * Test the route is registered. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Stats\Endpoint_Related::register_routes + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Stats\Endpoint_Related::__construct + * @uses \Parsely\REST_API\Stats\Endpoint_Related::get_endpoint_name + * @uses \Parsely\REST_API\Stats\Endpoint_Related::is_available_to_current_user + * @uses \Parsely\REST_API\Stats\Post_Data_Trait::get_itm_source_param_args + * @uses \Parsely\REST_API\Stats\Related_Posts_Trait::get_related_posts_param_args + * @uses \Parsely\REST_API\Stats\Stats_Controller::get_route_prefix + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_route_is_registered(): void { + $routes = rest_get_server()->get_routes(); + + // Check that the excerpt-generator/generate route is registered. + $expected_route = $this->get_endpoint()->get_full_endpoint( '/' ); + self::assertArrayHasKey( $expected_route, $routes ); + + // Check that the route is associated with the POST method. + $route_data = $routes[ $expected_route ]; + self::assertArrayHasKey( 'GET', $route_data[0]['methods'] ); + } + + /** + * Test that the endpoint is available to everyone, even if they are not logged in. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Stats\Endpoint_Related::is_available_to_current_user + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::get_api_secret + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::get_site_id + * @uses \Parsely\Parsely::get_url_with_itm_source + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Stats\Endpoint_Related::__construct + * @uses \Parsely\REST_API\Stats\Endpoint_Related::get_endpoint_name + * @uses \Parsely\REST_API\Stats\Endpoint_Related::get_related_posts + * @uses \Parsely\REST_API\Stats\Endpoint_Related::register_routes + * @uses \Parsely\REST_API\Stats\Post_Data_Trait::get_itm_source_param_args + * @uses \Parsely\REST_API\Stats\Post_Data_Trait::set_itm_source_from_request + * @uses \Parsely\REST_API\Stats\Related_Posts_Trait::get_related_posts_of_url + * @uses \Parsely\REST_API\Stats\Related_Posts_Trait::get_related_posts_param_args + * @uses \Parsely\REST_API\Stats\Stats_Controller::get_route_prefix + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_api_url + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_items + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_request_options + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::validate_required_constraints + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_access_of_related_posts_is_available_to_everyone(): void { + TestCase::set_options( + array( + 'apikey' => 'test-api-key', + 'api_secret' => 'test-secret', + ) + ); + wp_set_current_user( 0 ); + + $dispatched = 0; + $this->mock_api_response( $dispatched ); + + $route = $this->get_endpoint()->get_full_endpoint( '/' ); + $request = new WP_REST_Request( 'GET', $route ); + $request->set_param( 'url', 'https://example.com/a-post' ); + $response = rest_get_server()->dispatch( $request ); + + self::assertEquals( 1, $dispatched ); + self::assertSame( 200, $response->get_status() ); + } + + /** + * Mock the API response of the Parse.ly API. + * + * @since 3.17.0 + * + * @param int &$dispatched The number of times the API was dispatched. + */ + private function mock_api_response( int &$dispatched ): void { + add_filter( + 'pre_http_request', + function () use ( &$dispatched ): array { + $dispatched++; + return array( + 'body' => '{"data":[ + { + "image_url":"https:\/\/example.com\/img.png", + "thumb_url_medium":"https:\/\/example.com\/thumb.png", + "title":"something", + "url":"https:\/\/example.com" + }, + { + "image_url":"https:\/\/example.com\/img2.png", + "thumb_url_medium":"https:\/\/example.com\/thumb2.png", + "title":"something2", + "url":"https:\/\/example.com\/2" + } + ]}', + ); + } + ); + } + + /** + * Verifies that calls to the `stats/related` return the expected data, in the + * expected format, despite the user being unauthenticated. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Stats\Endpoint_Related::get_related_posts + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::get_api_secret + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::get_site_id + * @uses \Parsely\Parsely::get_url_with_itm_source + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Stats\Endpoint_Related::__construct + * @uses \Parsely\REST_API\Stats\Endpoint_Related::get_endpoint_name + * @uses \Parsely\REST_API\Stats\Endpoint_Related::is_available_to_current_user + * @uses \Parsely\REST_API\Stats\Endpoint_Related::register_routes + * @uses \Parsely\REST_API\Stats\Post_Data_Trait::get_itm_source_param_args + * @uses \Parsely\REST_API\Stats\Post_Data_Trait::set_itm_source_from_request + * @uses \Parsely\REST_API\Stats\Related_Posts_Trait::get_related_posts_of_url + * @uses \Parsely\REST_API\Stats\Related_Posts_Trait::get_related_posts_param_args + * @uses \Parsely\REST_API\Stats\Stats_Controller::get_route_prefix + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_api_url + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_items + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_request_options + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::validate_required_constraints + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_get_related_posts(): void { + $route = $this->get_endpoint()->get_full_endpoint( '/' ); + + TestCase::set_options( + array( + 'apikey' => 'example.com', + 'api_secret' => 'test-secret', + ) + ); + + $dispatched = 0; + + add_filter( + 'pre_http_request', + function () use ( &$dispatched ): array { + $dispatched++; + return array( + 'body' => '{"data":[ + { + "image_url":"https:\/\/example.com\/img.png", + "thumb_url_medium":"https:\/\/example.com\/thumb.png", + "title":"something", + "url":"https:\/\/example.com" + }, + { + "image_url":"https:\/\/example.com\/img2.png", + "thumb_url_medium":"https:\/\/example.com\/thumb2.png", + "title":"something2", + "url":"https:\/\/example.com\/2" + } + ]}', + ); + } + ); + + $request = new WP_REST_Request( 'GET', $route ); + $request->set_param( 'url', 'https://example.com/a-post' ); + $response = rest_get_server()->dispatch( $request ); + + /** + * The response data. + * + * @var array $response_data + */ + $response_data = $response->get_data(); + + self::assertSame( 1, $dispatched ); + self::assertSame( 200, $response->get_status() ); + self::assertEquals( + array( + (object) array( + 'image_url' => 'https://example.com/img.png', + 'thumb_url_medium' => 'https://example.com/thumb.png', + 'title' => 'something', + 'url' => 'https://example.com', + ), + (object) array( + 'image_url' => 'https://example.com/img2.png', + 'thumb_url_medium' => 'https://example.com/thumb2.png', + 'title' => 'something2', + 'url' => 'https://example.com/2', + ), + ), + $response_data['data'] + ); + } + + /** + * Test that the endpoint is not available if the API secret is not set. + * This test should be disabled since the endpoint does not requires the API secret. + * + * @since 3.17.0 + * @coversNothing + */ + public function test_is_available_to_current_user_returns_error_api_secret_not_set(): void { + // This test is disabled since the endpoint does not requires the API secret. + self::assertTrue( true ); + } +} diff --git a/tests/Integration/RestAPI/Stats/StatsControllerTest.php b/tests/Integration/RestAPI/Stats/StatsControllerTest.php new file mode 100644 index 000000000..0635125f9 --- /dev/null +++ b/tests/Integration/RestAPI/Stats/StatsControllerTest.php @@ -0,0 +1,60 @@ +stats_controller = new Stats_Controller( $parsely ); + } + + /** + * Test the constructor sets up the correct namespace and version. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Stats\Stats_Controller::__construct + * @uses \Parsely\REST_API\Stats\Stats_Controller::get_full_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + */ + public function test_constructor_sets_up_namespace_and_version(): void { + self::assertEquals( 'wp-parsely/v2', $this->stats_controller->get_full_namespace() ); + } +} From 508b1997a27056892d78e567a02e1fee274ff487 Mon Sep 17 00:00:00 2001 From: Henrique Mouta Date: Thu, 29 Aug 2024 14:00:03 +0100 Subject: [PATCH 061/282] Apply code review suggestions by @acicovic --- src/rest-api/class-base-endpoint.php | 2 +- .../RestAPI/BaseAPIControllerTest.php | 23 +-- .../Integration/RestAPI/BaseEndpointTest.php | 26 +-- .../ContentHelperControllerTest.php | 10 +- .../ContentHelperFeatureTestTrait.php | 190 +++++++++--------- .../EndpointExcerptGeneratorTest.php | 12 +- .../EndpointSmartLinkingTest.php | 15 +- .../EndpointTitleSuggestionsTest.php | 12 +- .../RestAPI/RestAPIControllerTest.php | 8 +- 9 files changed, 147 insertions(+), 151 deletions(-) diff --git a/src/rest-api/class-base-endpoint.php b/src/rest-api/class-base-endpoint.php index 3229b4bb8..653a13f27 100644 --- a/src/rest-api/class-base-endpoint.php +++ b/src/rest-api/class-base-endpoint.php @@ -133,11 +133,11 @@ abstract public function register_routes(): void; * @param string[] $methods Array with the allowed methods. * @param callable $callback Callback function to call when the endpoint is hit. * @param array $args The endpoint arguments definition. - * @return void */ public function register_rest_route( string $route, array $methods, callable $callback, array $args = array() ): void { // Trim any possible slashes from the route. $route = trim( $route, '/' ); + // Store the route for later reference. $this->registered_routes[] = $route; diff --git a/tests/Integration/RestAPI/BaseAPIControllerTest.php b/tests/Integration/RestAPI/BaseAPIControllerTest.php index 3b5b03731..eef6e6d54 100644 --- a/tests/Integration/RestAPI/BaseAPIControllerTest.php +++ b/tests/Integration/RestAPI/BaseAPIControllerTest.php @@ -38,14 +38,13 @@ class BaseAPIControllerTest extends TestCase { * * @since 3.17.0 */ - public function setUp(): void { - parent::setUp(); + public function set_up(): void { + parent::set_up(); TestCase::set_options(); $parsely = self::createMock( Parsely::class ); $this->test_controller = new class($parsely) extends Base_API_Controller { - /** - * Get the namespace for the API. + * Gets the namespace for the API. * * @since 3.17.0 * @@ -56,7 +55,7 @@ protected function get_namespace(): string { } /** - * Get the version for the API. + * Gets the version for the API. * * @since 3.17.0 * @@ -67,14 +66,14 @@ protected function get_version(): string { } /** - * Initialize the test controller. + * Initializes the test controller. * * @since 3.17.0 */ protected function init(): void {} /** - * Expose the protected method for testing. + * Exposes the protected method for testing. * * @param Base_Endpoint[] $endpoints The endpoints to register. */ @@ -83,7 +82,7 @@ public function testable_register_endpoints( array $endpoints ): void { } /** - * Expose the protected method for testing. + * Exposes the protected method for testing. * * @param Base_Endpoint $endpoint The endpoint to register. */ @@ -94,7 +93,7 @@ public function testable_register_endpoint( Base_Endpoint $endpoint ): void { } /** - * Test the get_namespace method. + * Tests the get_namespace method. * * @since 3.17.0 * @@ -106,7 +105,7 @@ public function test_get_namespace(): void { } /** - * Test the prefix_route method. + * Tests the prefix_route method. * * @since 3.17.0 * @@ -152,7 +151,7 @@ public function get_route_prefix(): string { } /** - * Test that endpoints are registered correctly. + * Tests that endpoints are registered correctly. * * @since 3.17.0 * @@ -172,7 +171,7 @@ public function test_register_endpoint(): void { } /** - * Test that multiple endpoints are registered correctly using a helper method. + * Tests that multiple endpoints are registered correctly using a helper method. * * @since 3.17.0 * diff --git a/tests/Integration/RestAPI/BaseEndpointTest.php b/tests/Integration/RestAPI/BaseEndpointTest.php index 4b0b01505..f43753184 100644 --- a/tests/Integration/RestAPI/BaseEndpointTest.php +++ b/tests/Integration/RestAPI/BaseEndpointTest.php @@ -94,7 +94,7 @@ public function __construct() { } /** - * Set up the test environment. + * Sets up the test environment. * * @since 3.17.0 */ @@ -109,7 +109,7 @@ public function set_up(): void { $this->test_endpoint = new class($this->api_controller) extends Base_Endpoint { /** - * Get the endpoint name. + * Gets the endpoint name. * * @since 3.17.0 * @@ -120,7 +120,7 @@ public function get_endpoint_name(): string { } /** - * Register the test route. + * Registers the test route. * * @since 3.17.0 */ @@ -133,7 +133,7 @@ public function register_routes(): void { } /** - * Get test data. + * Gets test data. * * @since 3.17.0 * @@ -148,7 +148,7 @@ public function get_test_data(): array { } /** - * Tear down the test environment. + * Tears down the test environment. * * @since 3.17.0 */ @@ -161,7 +161,7 @@ public function tear_down(): void { } /** - * Return the test endpoint instance. + * Returns the test endpoint instance. * * @since 3.17.0 * @@ -172,7 +172,7 @@ public function get_endpoint(): Base_Endpoint { } /** - * Test that the route is correctly registered in WordPress. + * Tests that the route is correctly registered in WordPress. * * @since 3.17.0 * @@ -213,7 +213,7 @@ public function test_route_is_registered(): void { } /** - * Test that the route is correctly registered in WordPress, depending on the filter. + * Tests that the route is correctly registered in WordPress, depending on the filter. * * @since 3.17.0 * @@ -278,7 +278,7 @@ public function test_endpoint_is_registered_based_on_filter(): void { } /** - * Test is_available_to_current_user returns WP_Error if API key or secret is not set. + * Tests is_available_to_current_user returns WP_Error if API key or secret is not set. * * @since 3.17.0 * @@ -317,7 +317,7 @@ public function test_is_available_to_current_user_returns_error_site_id_not_set( } /** - * Test is_available_to_current_user returns WP_Error if API key or secret is not set. + * Tests is_available_to_current_user returns WP_Error if API key or secret is not set. * * @since 3.17.0 * @@ -357,7 +357,7 @@ public function test_is_available_to_current_user_returns_error_api_secret_not_s } /** - * Test apply_capability_filters method. + * Tests apply_capability_filters method. * * @covers \Parsely\REST_API\Base_Endpoint::apply_capability_filters * @uses \Parsely\REST_API\Base_API_Controller::__construct @@ -383,7 +383,7 @@ function () { } /** - * Test validate_apikey_and_secret returns true when API key and secret are set. + * Tests validate_apikey_and_secret returns true when API key and secret are set. * * @covers \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret * @uses \Parsely\REST_API\Base_API_Controller::__construct @@ -439,7 +439,7 @@ protected function set_protected_property( $obj, string $property_name, $value ) } /** - * Initialize the REST endpoint. + * Initializes the REST endpoint. * * @since 3.17.0 */ diff --git a/tests/Integration/RestAPI/ContentHelper/ContentHelperControllerTest.php b/tests/Integration/RestAPI/ContentHelper/ContentHelperControllerTest.php index fcc563d07..5b22320e8 100644 --- a/tests/Integration/RestAPI/ContentHelper/ContentHelperControllerTest.php +++ b/tests/Integration/RestAPI/ContentHelper/ContentHelperControllerTest.php @@ -41,15 +41,15 @@ class ContentHelperControllerTest extends RestAPIControllerTest { * * @since 3.17.0 */ - public function setUp(): void { - parent::setUp(); + public function set_up(): void { + parent::set_up(); TestCase::set_options(); $parsely = self::createMock( Parsely::class ); $this->content_helper_controller = new Content_Helper_Controller( $parsely ); } /** - * Test the constructor sets up the correct namespace and version. + * Tests the constructor sets up the correct namespace and version. * * @since 3.17.0 * @@ -61,7 +61,7 @@ public function test_constructor_sets_up_namespace_and_version(): void { } /** - * Test that the route prefix is set correctly. + * Tests that the route prefix is set correctly. * * @since 3.17.0 * @@ -72,7 +72,7 @@ public function test_route_prefix(): void { } /** - * Test that the init method registers the correct endpoints. + * Tests that the init method registers the correct endpoints. * * @since 3.17.0 * diff --git a/tests/Integration/RestAPI/ContentHelper/ContentHelperFeatureTestTrait.php b/tests/Integration/RestAPI/ContentHelper/ContentHelperFeatureTestTrait.php index 47615307f..32e859dbb 100644 --- a/tests/Integration/RestAPI/ContentHelper/ContentHelperFeatureTestTrait.php +++ b/tests/Integration/RestAPI/ContentHelper/ContentHelperFeatureTestTrait.php @@ -22,35 +22,33 @@ * @covers \Parsely\REST_API\Content_Helper\Content_Helper_Feature */ trait ContentHelperFeatureTestTrait { - - /** - * Test that the endpoint is available to the current user. + * Tests that the endpoint is available to the current user. * * @since 3.17.0 * * @covers \Parsely\REST_API\Content_Helper\Content_Helper_Feature::is_available_to_current_user - * @uses Parsely\Endpoints\Base_Endpoint::__construct - * @uses Parsely\Parsely::__construct - * @uses Parsely\Parsely::allow_parsely_remote_requests - * @uses Parsely\Parsely::api_secret_is_set - * @uses Parsely\Parsely::are_credentials_managed - * @uses Parsely\Parsely::get_managed_credentials - * @uses Parsely\Parsely::get_options - * @uses Parsely\Parsely::set_default_content_helper_settings_values - * @uses Parsely\Parsely::set_default_full_metadata_in_non_posts - * @uses Parsely\Parsely::set_managed_options - * @uses Parsely\Parsely::site_id_is_set - * @uses Parsely\Permissions::build_pch_permissions_settings_array - * @uses Parsely\Permissions::current_user_can_use_pch_feature - * @uses Parsely\Permissions::get_user_roles_with_edit_posts_cap - * @uses Parsely\REST_API\Base_API_Controller::__construct - * @uses Parsely\REST_API\Base_Endpoint::__construct - * @uses Parsely\REST_API\Base_Endpoint::init - * @uses Parsely\REST_API\Base_Endpoint::apply_capability_filters - * @uses Parsely\REST_API\Base_Endpoint::is_available_to_current_user - * @uses Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret - * @uses Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::set_managed_options + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::current_user_can_use_pch_feature + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters + * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_is_available_to_current_user_returns_true_if_feature_enabled(): void { $this->enable_feature(); @@ -61,32 +59,32 @@ public function test_is_available_to_current_user_returns_true_if_feature_enable } /** - * Test that the endpoint is not available to the current user. + * Tests that the endpoint is not available to the current user. * * @since 3.17.0 * * @covers \Parsely\REST_API\Content_Helper\Content_Helper_Feature::is_available_to_current_user - * @uses Parsely\Endpoints\Base_Endpoint::__construct - * @uses Parsely\Parsely::__construct - * @uses Parsely\Parsely::allow_parsely_remote_requests - * @uses Parsely\Parsely::api_secret_is_set - * @uses Parsely\Parsely::are_credentials_managed - * @uses Parsely\Parsely::get_managed_credentials - * @uses Parsely\Parsely::get_options - * @uses Parsely\Parsely::set_default_content_helper_settings_values - * @uses Parsely\Parsely::set_default_full_metadata_in_non_posts - * @uses Parsely\Parsely::set_managed_options - * @uses Parsely\Parsely::site_id_is_set - * @uses Parsely\Permissions::build_pch_permissions_settings_array - * @uses Parsely\Permissions::current_user_can_use_pch_feature - * @uses Parsely\Permissions::get_user_roles_with_edit_posts_cap - * @uses Parsely\REST_API\Base_API_Controller::__construct - * @uses Parsely\REST_API\Base_Endpoint::__construct - * @uses Parsely\REST_API\Base_Endpoint::init - * @uses Parsely\REST_API\Base_Endpoint::apply_capability_filters - * @uses Parsely\REST_API\Base_Endpoint::is_available_to_current_user - * @uses Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret - * @uses Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::set_managed_options + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::current_user_can_use_pch_feature + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters + * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_is_available_to_current_user_returns_error_if_feature_disabled(): void { $this->disable_feature(); @@ -97,32 +95,32 @@ public function test_is_available_to_current_user_returns_error_if_feature_disab } /** - * Test that the endpoint is available to the current user, since the user has the required role. + * Tests that the endpoint is available to the current user, since the user has the required role. * * @since 3.17.0 * * @covers \Parsely\REST_API\Content_Helper\Content_Helper_Feature::is_available_to_current_user - * @uses Parsely\Endpoints\Base_Endpoint::__construct - * @uses Parsely\Parsely::__construct - * @uses Parsely\Parsely::allow_parsely_remote_requests - * @uses Parsely\Parsely::api_secret_is_set - * @uses Parsely\Parsely::are_credentials_managed - * @uses Parsely\Parsely::get_managed_credentials - * @uses Parsely\Parsely::get_options - * @uses Parsely\Parsely::set_default_content_helper_settings_values - * @uses Parsely\Parsely::set_default_full_metadata_in_non_posts - * @uses Parsely\Parsely::set_managed_options - * @uses Parsely\Parsely::site_id_is_set - * @uses Parsely\Permissions::build_pch_permissions_settings_array - * @uses Parsely\Permissions::current_user_can_use_pch_feature - * @uses Parsely\Permissions::get_user_roles_with_edit_posts_cap - * @uses Parsely\REST_API\Base_API_Controller::__construct - * @uses Parsely\REST_API\Base_Endpoint::__construct - * @uses Parsely\REST_API\Base_Endpoint::init - * @uses Parsely\REST_API\Base_Endpoint::apply_capability_filters - * @uses Parsely\REST_API\Base_Endpoint::is_available_to_current_user - * @uses Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret - * @uses Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::set_managed_options + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::current_user_can_use_pch_feature + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters + * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_is_available_to_current_user_returns_true_if_has_permissions(): void { $this->set_feature_options( @@ -142,33 +140,33 @@ public function test_is_available_to_current_user_returns_true_if_has_permission } /** - * Test that the endpoint is not available to the current user, since the user does not have the + * Tests that the endpoint is not available to the current user, since the user does not have the * required role. * * @since 3.17.0 * * @covers \Parsely\REST_API\Content_Helper\Content_Helper_Feature::is_available_to_current_user - * @uses Parsely\Endpoints\Base_Endpoint::__construct - * @uses Parsely\Parsely::__construct - * @uses Parsely\Parsely::allow_parsely_remote_requests - * @uses Parsely\Parsely::api_secret_is_set - * @uses Parsely\Parsely::are_credentials_managed - * @uses Parsely\Parsely::get_managed_credentials - * @uses Parsely\Parsely::get_options - * @uses Parsely\Parsely::set_default_content_helper_settings_values - * @uses Parsely\Parsely::set_default_full_metadata_in_non_posts - * @uses Parsely\Parsely::set_managed_options - * @uses Parsely\Parsely::site_id_is_set - * @uses Parsely\Permissions::build_pch_permissions_settings_array - * @uses Parsely\Permissions::current_user_can_use_pch_feature - * @uses Parsely\Permissions::get_user_roles_with_edit_posts_cap - * @uses Parsely\REST_API\Base_API_Controller::__construct - * @uses Parsely\REST_API\Base_Endpoint::__construct - * @uses Parsely\REST_API\Base_Endpoint::init - * @uses Parsely\REST_API\Base_Endpoint::apply_capability_filters - * @uses Parsely\REST_API\Base_Endpoint::is_available_to_current_user - * @uses Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret - * @uses Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::__construct + * @uses \Parsely\Parsely::allow_parsely_remote_requests + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::set_managed_options + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::current_user_can_use_pch_feature + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters + * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Base_Endpoint::validate_apikey_and_secret + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_is_available_to_current_user_returns_error_if_no_permissions(): void { $this->set_current_user_to_contributor(); @@ -186,7 +184,7 @@ public function test_is_available_to_current_user_returns_error_if_no_permission /** - * Test that the endpoint is not available to the current user, since the user is not logged in. + * Tests that the endpoint is not available to the current user, since the user is not logged in. * * @since 3.17.0 * @@ -226,7 +224,7 @@ public function test_is_available_to_current_user_returns_error_if_no_user(): vo abstract protected function get_endpoint(): Base_Endpoint; /** - * Set the specific feature options. + * Sets the specific feature options. * * @since 3.17.0 * @@ -248,7 +246,7 @@ private function set_feature_options( array $options ): void { } /** - * Disable the specific feature. + * Disables the specific feature. * * @since 3.17.0 */ @@ -262,7 +260,7 @@ private function disable_feature(): void { } /** - * Enable the specific feature. + * Enables the specific feature. * * @since 3.17.0 */ @@ -278,14 +276,14 @@ private function enable_feature(): void { } /** - * Set the current user to an administrator. + * Sets the current user to an administrator. * * @since 3.17.0 */ abstract protected function set_current_user_to_admin(): void; /** - * Set the current user to a contributor. + * Sets the current user to a contributor. * * @since 3.17.0 */ diff --git a/tests/Integration/RestAPI/ContentHelper/EndpointExcerptGeneratorTest.php b/tests/Integration/RestAPI/ContentHelper/EndpointExcerptGeneratorTest.php index c959a8e2d..a7eb36d77 100644 --- a/tests/Integration/RestAPI/ContentHelper/EndpointExcerptGeneratorTest.php +++ b/tests/Integration/RestAPI/ContentHelper/EndpointExcerptGeneratorTest.php @@ -3,7 +3,7 @@ * Integration tests for the Endpoint_Excerpt_Generator class. * * @package Parsely - * @since 3.17.0 + * @since 3.17.0 */ declare(strict_types=1); @@ -38,7 +38,7 @@ class EndpointExcerptGeneratorTest extends BaseEndpointTest { private $endpoint; /** - * Set up the test environment. + * Sets up the test environment. * * @since 3.17.0 */ @@ -51,7 +51,7 @@ public function set_up(): void { } /** - * Get the test endpoint instance. + * Gets the test endpoint instance. * * @since 3.17.0 * @@ -62,7 +62,7 @@ public function get_endpoint(): \Parsely\REST_API\Base_Endpoint { } /** - * Test that the endpoint is correctly registered. + * Tests that the endpoint is correctly registered. * * @since 3.17.0 * @@ -108,7 +108,7 @@ public function test_route_is_registered(): void { } /** - * Test that the generate_excerpt method returns a valid response. + * Tests that the generate_excerpt method returns a valid response. * * @since 3.17.0 * @@ -154,7 +154,7 @@ public function test_generate_excerpt_returns_valid_response(): void { } /** - * Test that the generate_excerpt method returns an error if Suggest_Brief_API fails. + * Tests that the generate_excerpt method returns an error if Suggest_Brief_API fails. * * @since 3.17.0 * diff --git a/tests/Integration/RestAPI/ContentHelper/EndpointSmartLinkingTest.php b/tests/Integration/RestAPI/ContentHelper/EndpointSmartLinkingTest.php index 8389bd7c0..99b9c5c10 100644 --- a/tests/Integration/RestAPI/ContentHelper/EndpointSmartLinkingTest.php +++ b/tests/Integration/RestAPI/ContentHelper/EndpointSmartLinkingTest.php @@ -3,7 +3,7 @@ * Integration tests for the Endpoint_Smart_Linking class. * * @package Parsely - * @since 3.17.0 + * @since 3.17.0 */ declare(strict_types=1); @@ -41,7 +41,7 @@ class EndpointSmartLinkingTest extends BaseEndpointTest { private $endpoint; /** - * Set up the test environment. + * Sets up the test environment. * * @since 3.17.0 */ @@ -62,7 +62,7 @@ public function set_up(): void { } /** - * Get the test endpoint instance. + * Gets the test endpoint instance. * * @since 3.17.0 * @@ -73,7 +73,7 @@ public function get_endpoint(): \Parsely\REST_API\Base_Endpoint { } /** - * Test that the endpoint is correctly registered. + * Tests that the endpoint is correctly registered. * * @since 3.17.0 * @@ -119,7 +119,7 @@ public function test_route_is_registered(): void { } /** - * Test that the generate_smart_links method returns a valid response. + * Tests that the generate_smart_links method returns a valid response. * * @since 3.17.0 * @@ -169,7 +169,7 @@ public function test_generate_smart_links_returns_valid_response(): void { } /** - * Test that the generate_smart_links method returns an error if Suggest_Linked_Reference_API fails. + * Tests that the generate_smart_links method returns an error if Suggest_Linked_Reference_API fails. * * @since 3.17.0 * @@ -206,7 +206,7 @@ public function test_generate_smart_links_returns_error_on_failure(): void { } /** - * Test that the add_smart_link method returns a valid response when adding a new smart link. + * Tests that the add_smart_link method returns a valid response when adding a new smart link. * * @since 3.17.0 * @@ -307,7 +307,6 @@ public function test_add_smart_link_returns_valid_response(): void { * @since 3.17.0 * * @covers \Parsely\REST_API\Content_Helper\Endpoint_Smart_Linking::add_multiple_smart_links - * * @uses \Parsely\Endpoints\Base_Endpoint::__construct * @uses \Parsely\Models\Base_Model::__construct * @uses \Parsely\Models\Base_Model::serialize diff --git a/tests/Integration/RestAPI/ContentHelper/EndpointTitleSuggestionsTest.php b/tests/Integration/RestAPI/ContentHelper/EndpointTitleSuggestionsTest.php index a54e9391b..15fa9e622 100644 --- a/tests/Integration/RestAPI/ContentHelper/EndpointTitleSuggestionsTest.php +++ b/tests/Integration/RestAPI/ContentHelper/EndpointTitleSuggestionsTest.php @@ -3,7 +3,7 @@ * Integration tests for the Endpoint_Title_Suggestions class. * * @package Parsely - * @since 3.17.0 + * @since 3.17.0 */ declare(strict_types=1); @@ -38,7 +38,7 @@ class EndpointTitleSuggestionsTest extends BaseEndpointTest { private $endpoint; /** - * Set up the test environment. + * Sets up the test environment. * * @since 3.17.0 */ @@ -51,7 +51,7 @@ public function set_up(): void { } /** - * Get the test endpoint instance. + * Gets the test endpoint instance. * * @return Endpoint_Title_Suggestions * @since 3.17.0 @@ -61,7 +61,7 @@ public function get_endpoint(): \Parsely\REST_API\Base_Endpoint { } /** - * Test that the endpoint is correctly registered. + * Tests that the endpoint is correctly registered. * * @since 3.17.0 * @@ -105,7 +105,7 @@ public function test_route_is_registered(): void { } /** - * Test that the generate_titles method returns a valid response. + * Tests that the generate_titles method returns a valid response. * * @since 3.17.0 * @@ -153,7 +153,7 @@ public function test_generate_titles_returns_valid_response(): void { } /** - * Test that the generate_titles method returns an error if Suggest_Headline_API fails. + * Tests that the generate_titles method returns an error if Suggest_Headline_API fails. * * @since 3.17.0 * diff --git a/tests/Integration/RestAPI/RestAPIControllerTest.php b/tests/Integration/RestAPI/RestAPIControllerTest.php index 0261c5ec4..f53c8961b 100644 --- a/tests/Integration/RestAPI/RestAPIControllerTest.php +++ b/tests/Integration/RestAPI/RestAPIControllerTest.php @@ -33,19 +33,19 @@ class RestAPIControllerTest extends TestCase { private $test_controller = null; /** - * Set up the test controller. + * Sets up the test controller. * * @since 3.17.0 */ - public function setUp(): void { - parent::setUp(); + public function set_up(): void { + parent::set_up(); TestCase::set_options(); $parsely = self::createMock( Parsely::class ); $this->test_controller = new REST_API_Controller( $parsely ); } /** - * Test the constructor sets up the correct namespace and version. + * Tests the constructor sets up the correct namespace and version. * * @since 3.17.0 * From 5e606da3623f962f999e9fd21f4b22477606cc13 Mon Sep 17 00:00:00 2001 From: Henrique Mouta Date: Thu, 29 Aug 2024 11:54:54 +0100 Subject: [PATCH 062/282] Add `stats` endpoint --- src/RemoteAPI/class-base-endpoint-remote.php | 6 +- src/rest-api/class-base-endpoint.php | 8 +- src/rest-api/class-rest-api-controller.php | 2 + .../class-endpoint-smart-linking.php | 83 +-- src/rest-api/stats/class-endpoint-post.php | 495 ++++++++++++++++++ src/rest-api/stats/class-endpoint-posts.php | 249 +++++++++ src/rest-api/stats/class-endpoint-related.php | 112 ++++ src/rest-api/stats/class-stats-controller.php | 48 ++ src/rest-api/stats/trait-post-data.php | 145 +++++ src/rest-api/stats/trait-related-posts.php | 165 ++++++ src/rest-api/trait-use-post-id-parameter.php | 88 ++++ 11 files changed, 1332 insertions(+), 69 deletions(-) create mode 100644 src/rest-api/stats/class-endpoint-post.php create mode 100644 src/rest-api/stats/class-endpoint-posts.php create mode 100644 src/rest-api/stats/class-endpoint-related.php create mode 100644 src/rest-api/stats/class-stats-controller.php create mode 100644 src/rest-api/stats/trait-post-data.php create mode 100644 src/rest-api/stats/trait-related-posts.php create mode 100644 src/rest-api/trait-use-post-id-parameter.php diff --git a/src/RemoteAPI/class-base-endpoint-remote.php b/src/RemoteAPI/class-base-endpoint-remote.php index 334f38e0d..e9ec20eb3 100644 --- a/src/RemoteAPI/class-base-endpoint-remote.php +++ b/src/RemoteAPI/class-base-endpoint-remote.php @@ -108,7 +108,11 @@ public function get_items( array $query, bool $associative = false ) { } if ( ! property_exists( $decoded, 'data' ) ) { - return new WP_Error( $decoded->code ?? 400, $decoded->message ?? __( 'Unable to read data from upstream API', 'wp-parsely' ) ); + return new WP_Error( + $decoded->code ?? 400, + $decoded->message ?? __( 'Unable to read data from upstream API', 'wp-parsely' ), + array( 'status' => $decoded->code ?? 400 ) + ); } if ( ! is_array( $decoded->data ) ) { diff --git a/src/rest-api/class-base-endpoint.php b/src/rest-api/class-base-endpoint.php index 653a13f27..e48917432 100644 --- a/src/rest-api/class-base-endpoint.php +++ b/src/rest-api/class-base-endpoint.php @@ -169,7 +169,13 @@ public function register_rest_route( string $route, array $methods, callable $ca * @return string */ public function get_full_endpoint( string $route = '' ): string { - $route = $this->get_endpoint_name() . '/' . $route; + $route = trim( $route, '/' ); + + if ( '' !== $route ) { + $route = $this->get_endpoint_name() . '/' . $route; + } else { + $route = $this->get_endpoint_name(); + } return '/' . $this->api_controller->get_full_namespace() . diff --git a/src/rest-api/class-rest-api-controller.php b/src/rest-api/class-rest-api-controller.php index e864e59fa..5ce4e76fa 100644 --- a/src/rest-api/class-rest-api-controller.php +++ b/src/rest-api/class-rest-api-controller.php @@ -11,6 +11,7 @@ namespace Parsely\REST_API; use Parsely\REST_API\Content_Helper\Content_Helper_Controller; +use Parsely\REST_API\Stats\Stats_Controller; /** * The REST API Controller. @@ -60,6 +61,7 @@ public function init(): void { // Register the controllers for each namespace. $controllers = array( new Content_Helper_Controller( $this->get_parsely() ), + new Stats_Controller( $this->get_parsely() ), ); // Initialize the controllers. diff --git a/src/rest-api/content-helper/class-endpoint-smart-linking.php b/src/rest-api/content-helper/class-endpoint-smart-linking.php index fe37e324f..cce1c99c4 100644 --- a/src/rest-api/content-helper/class-endpoint-smart-linking.php +++ b/src/rest-api/content-helper/class-endpoint-smart-linking.php @@ -14,6 +14,7 @@ use Parsely\Models\Smart_Link; use Parsely\RemoteAPI\ContentSuggestions\Suggest_Linked_Reference_API; use Parsely\REST_API\Base_Endpoint; +use Parsely\REST_API\Use_Post_ID_Parameter_Trait; use WP_Error; use WP_Post; use WP_REST_Request; @@ -28,6 +29,7 @@ */ class Endpoint_Smart_Linking extends Base_Endpoint { use Content_Helper_Feature; + use Use_Post_ID_Parameter_Trait; /** * The Suggest Linked Reference API instance. @@ -110,40 +112,28 @@ public function register_routes(): void { * GET /smart-linking/{post_id}/get * Gets the smart links for a post. */ - $this->register_rest_route( - '(?P\d+)/get', + $this->register_rest_route_with_post_id( + '/get', array( 'GET' ), - array( $this, 'get_smart_links' ), - array( - 'post_id' => array( - 'required' => true, - 'description' => __( 'The post ID.', 'wp-parsely' ), - 'validate_callback' => array( $this, 'validate_post_id' ), - ), - ) + array( $this, 'get_smart_links' ) ); /** * POST /smart-linking/{post_id}/add * Adds a smart link to a post. */ - $this->register_rest_route( - '(?P\d+)/add', + $this->register_rest_route_with_post_id( + '/add', array( 'POST' ), array( $this, 'add_smart_link' ), array( - 'post_id' => array( - 'required' => true, - 'description' => __( 'The post ID.', 'wp-parsely' ), - 'validate_callback' => array( $this, 'validate_post_id' ), - ), - 'link' => array( + 'link' => array( 'required' => true, 'type' => 'object', 'description' => __( 'The smart link data to add.', 'wp-parsely' ), 'validate_callback' => array( $this, 'validate_smart_link_params' ), ), - 'update' => array( + 'update' => array( 'type' => 'boolean', 'description' => __( 'Whether to update the existing smart link.', 'wp-parsely' ), 'default' => false, @@ -155,23 +145,18 @@ public function register_routes(): void { * POST /smart-linking/{post_id}/add-multiple * Adds multiple smart links to a post. */ - $this->register_rest_route( - '(?P\d+)/add-multiple', + $this->register_rest_route_with_post_id( + '/add-multiple', array( 'POST' ), array( $this, 'add_multiple_smart_links' ), array( - 'post_id' => array( - 'required' => true, - 'description' => __( 'The post ID.', 'wp-parsely' ), - 'validate_callback' => array( $this, 'validate_post_id' ), - ), - 'links' => array( + 'links' => array( 'required' => true, 'type' => 'array', 'description' => __( 'The multiple smart links data to add.', 'wp-parsely' ), 'validate_callback' => array( $this, 'validate_multiple_smart_links' ), ), - 'update' => array( + 'update' => array( 'type' => 'boolean', 'description' => __( 'Whether to update the existing smart links.', 'wp-parsely' ), 'default' => false, @@ -183,17 +168,12 @@ public function register_routes(): void { * POST /smart-linking/{post_id}/set * Updates the smart links of a given post and removes the ones that are not in the request. */ - $this->register_rest_route( - '(?P\d+)/set', + $this->register_rest_route_with_post_id( + '/set', array( 'POST' ), array( $this, 'set_smart_links' ), array( - 'post_id' => array( - 'required' => true, - 'description' => __( 'The post ID.', 'wp-parsely' ), - 'validate_callback' => array( $this, 'validate_post_id' ), - ), - 'links' => array( + 'links' => array( 'required' => true, 'type' => 'array', 'description' => __( 'The smart links data to set.', 'wp-parsely' ), @@ -548,37 +528,6 @@ public function url_to_post_type( WP_REST_Request $request ): WP_REST_Response { return new WP_REST_Response( $response, 200 ); } - /** - * Validates the post ID parameter. - * - * The callback sets the post object in the request object if the parameter is valid. - * - * @since 3.16.0 - * @access private - * - * @param string $param The parameter value. - * @param WP_REST_Request $request The request object. - * @return bool Whether the parameter is valid. - */ - public function validate_post_id( string $param, WP_REST_Request $request ): bool { - if ( ! is_numeric( $param ) ) { - return false; - } - - $param = filter_var( $param, FILTER_VALIDATE_INT ); - - if ( false === $param ) { - return false; - } - - // Validate if the post ID exists. - $post = get_post( $param ); - // Set the post attribute in the request. - $request->set_param( 'post', $post ); - - return null !== $post; - } - /** * Validates the URL exclusion list parameter. * diff --git a/src/rest-api/stats/class-endpoint-post.php b/src/rest-api/stats/class-endpoint-post.php new file mode 100644 index 000000000..c83713315 --- /dev/null +++ b/src/rest-api/stats/class-endpoint-post.php @@ -0,0 +1,495 @@ +analytics_post_detail_api = new Analytics_Post_Detail_API( $this->parsely ); + $this->referrers_post_detail_api = new Referrers_Post_Detail_API( $this->parsely ); + $this->related_posts_api = new Related_API( $this->parsely ); + } + + /** + * Returns the endpoint name. + * + * @since 3.17.0 + * + * @return string The endpoint name. + */ + public function get_endpoint_name(): string { + return 'post'; + } + + /** + * Registers the routes for the endpoint. + * + * @since 3.17.0 + */ + public function register_routes(): void { + /** + * GET /stats/post/{post_id}/details + * Returns the analytics details of a post. + */ + $this->register_rest_route_with_post_id( + '/details', + array( 'GET' ), + array( $this, 'get_post_details' ), + array_merge( + array( + 'period_start' => array( + 'description' => __( 'The start of the period.', 'wp-parsely' ), + 'type' => 'string', + 'required' => false, + ), + 'period_end' => array( + 'description' => __( 'The end of the period.', 'wp-parsely' ), + 'type' => 'string', + 'required' => false, + ), + ), + $this->get_itm_source_param_args() + ) + ); + + /** + * GET /stats/post/{post_id}/referrers + * Returns the referrers of a post. + */ + $this->register_rest_route_with_post_id( + '/referrers', + array( 'GET' ), + array( $this, 'get_post_referrers' ), + array( + 'period_start' => array( + 'description' => __( 'The start of the period.', 'wp-parsely' ), + 'type' => 'string', + 'required' => false, + ), + 'period_end' => array( + 'description' => __( 'The end of the period.', 'wp-parsely' ), + 'type' => 'string', + 'required' => false, + ), + 'total_views' => array( + 'description' => __( 'The total views of the post.', 'wp-parsely' ), + 'type' => 'string', + 'required' => false, + 'default' => '0', + ), + ) + ); + + /** + * GET /stats/post/{post_id}/related + * Returns the related posts of a post. + */ + $this->register_rest_route_with_post_id( + '/related', + array( 'GET' ), + array( $this, 'get_related_posts' ), + $this->get_related_posts_param_args() + ); + } + + /** + * API Endpoint: GET /stats/post/{post_id}/details + * + * Gets the details of a post. + * + * @since 3.17.0 + * + * @param WP_REST_Request $request The request object. + * @return WP_REST_Response|WP_Error The response object. + */ + public function get_post_details( WP_REST_Request $request ) { + /** + * The post object. + * + * @var WP_Post $post + */ + $post = $request->get_param( 'post' ); + $permalink = get_permalink( $post->ID ); + + // Set the itm_source parameter. + $this->set_itm_source_from_request( $request ); + + // Get the data from the API. + $analytics_request = $this->analytics_post_detail_api->get_items( + array( + 'url' => $permalink, + 'period_start' => $request->get_param( 'period_start' ), + 'period_end' => $request->get_param( 'period_end' ), + ) + ); + + if ( is_wp_error( $analytics_request ) ) { + return $analytics_request; + } + + $post_data = array(); + /** + * The analytics data object. + * + * @var array $analytics_request + */ + foreach ( $analytics_request as $data ) { + $post_data[] = $this->extract_post_data( $data ); + } + + $response = array( + 'params' => $request->get_params(), + 'data' => $post_data, + ); + + return new WP_REST_Response( $response, 200 ); + } + + /** + * API Endpoint: GET /stats/post/{post_id}/referrers + * + * Gets the referrers of a post. + * + * @since 3.17.0 + * + * @param WP_REST_Request $request The request object. + * @return WP_REST_Response|WP_Error The response object. + */ + public function get_post_referrers( WP_REST_Request $request ) { + /** + * The post object. + * + * @var WP_Post $post + */ + $post = $request->get_param( 'post' ); + $permalink = get_permalink( $post->ID ); + + // Set the itm_source parameter. + $this->set_itm_source_from_request( $request ); + + // Get the total views. + $total_views = $request->get_param( 'total_views' ) ?? 0; + + if ( is_string( $total_views ) ) { + $total_views = Utils::convert_to_positive_integer( $total_views ); + } + + $this->total_views = $total_views; + + // Do the analytics request. + $analytics_request = $this->referrers_post_detail_api->get_items( + array( + 'url' => $permalink, + 'period_start' => $request->get_param( 'period_start' ), + 'period_end' => $request->get_param( 'period_end' ), + ) + ); + + if ( is_wp_error( $analytics_request ) ) { + return $analytics_request; + } + + /** + * The analytics data object. + * + * @var array $analytics_request + */ + $referrers_types = $this->generate_referrer_types_data( $analytics_request ); + $direct_views = Utils::convert_to_positive_integer( + $referrers_types->direct->views ?? '0' + ); + $referrers_top = $this->generate_referrers_data( 5, $analytics_request, $direct_views ); + + $response_data = array( + 'params' => $request->get_params(), + 'data' => array( + 'top' => $referrers_top, + 'types' => $referrers_types, + ), + ); + + return new WP_REST_Response( $response_data, 200 ); + } + + /** + * API Endpoint: GET /stats/post/{post_id}/related + * + * Gets the related posts of a post. + * + * @since 3.17.0 + * + * @param WP_REST_Request $request The request object. + * @return WP_REST_Response|WP_Error The response data. + */ + public function get_related_posts( WP_REST_Request $request ) { + /** + * The post object. + * + * @var WP_Post $post + */ + $post = $request->get_param( 'post' ); + + /** + * The post permalink. + * + * @var string $permalink + */ + $permalink = get_permalink( $post->ID ); + + $related_posts = $this->get_related_posts_of_url( $request, $permalink ); + + $response_data = array( + 'params' => $request->get_params(), + 'data' => $related_posts, + ); + return new WP_REST_Response( $response_data, 200 ); + } + + /** + * Generates the referrer types data. + * + * Referrer types are: + * - `social`: Views coming from social media. + * - `search`: Views coming from search engines. + * - `other`: Views coming from other referrers, like external websites. + * - `internal`: Views coming from linking pages of the same website. + * + * Returned object properties: + * - `views`: The number of views. + * - `viewPercentage`: The number of views as a percentage, compared to the + * total views of all referrer types. + * + * @since 3.6.0 + * @since 3.17.0 Moved from the `Referrers_Post_Detail_API_Proxy` class. + * + * @param array $response The response received by the proxy. + * @return stdClass The generated data. + */ + private function generate_referrer_types_data( array $response ): stdClass { + $result = new stdClass(); + $total_referrer_views = 0; // Views from all referrer types combined. + + // Set referrer type order as it is displayed in the Parse.ly dashboard. + $referrer_type_keys = array( 'social', 'search', 'other', 'internal', 'direct' ); + foreach ( $referrer_type_keys as $key ) { + $result->$key = (object) array( 'views' => 0 ); + } + + // Set views and views totals. + foreach ( $response as $referrer_data ) { + /** + * Variable. + * + * @var int + */ + $current_views = $referrer_data->metrics->referrers_views ?? 0; + $total_referrer_views += $current_views; + + /** + * Variable. + * + * @var string + */ + $current_key = $referrer_data->type ?? ''; + if ( '' !== $current_key ) { + if ( ! isset( $result->$current_key->views ) ) { + $result->$current_key = (object) array( 'views' => 0 ); + } + + $result->$current_key->views += $current_views; + } + } + + // Add direct and total views to the object. + $result->direct->views = $this->total_views - $total_referrer_views; + $result->totals = (object) array( 'views' => $this->total_views ); + + // Remove referrer types without views. + foreach ( $referrer_type_keys as $key ) { + if ( 0 === $result->$key->views ) { + unset( $result->$key ); + } + } + + // Set percentage values and format numbers. + // @phpstan-ignore-next-line. + foreach ( $result as $key => $value ) { + // Set and format percentage values. + $result->{ $key }->viewsPercentage = $this->get_i18n_percentage( + absint( $value->views ), + $this->total_views + ); + + // Format views values. + $result->{ $key }->views = number_format_i18n( $result->{ $key }->views ); + } + + return $result; + } + + /** + * Generates the top referrers data. + * + * Returned object properties: + * - `views`: The number of views. + * - `viewPercentage`: The number of views as a percentage, compared to the + * total views of all referrer types. + * - `datasetViewsPercentage: The number of views as a percentage, compared + * to the total views of the current dataset. + * + * @since 3.6.0 + * @since 3.17.0 Moved from the `Referrers_Post_Detail_API_Proxy` class. + * + * @param int $limit The limit of returned referrers. + * @param array $response The response received by the proxy. + * @param int $direct_views The count of direct views. + * @return stdClass The generated data. + */ + private function generate_referrers_data( + int $limit, + array $response, + int $direct_views + ): stdClass { + $temp_views = array(); + $totals = 0; + $referrer_count = count( $response ); + + // Set views and views totals. + $loop_count = $referrer_count > $limit ? $limit : $referrer_count; + for ( $i = 0; $i < $loop_count; $i++ ) { + $data = $response[ $i ]; + + /** + * Variable. + * + * @var int + */ + $referrer_views = $data->metrics->referrers_views ?? 0; + $totals += $referrer_views; + if ( isset( $data->name ) ) { + $temp_views[ $data->name ] = $referrer_views; + } + } + + // If applicable, add the direct views. + if ( isset( $referrer_views ) && $direct_views >= $referrer_views ) { + $temp_views['direct'] = $direct_views; + $totals += $direct_views; + arsort( $temp_views ); + if ( count( $temp_views ) > $limit ) { + $totals -= array_pop( $temp_views ); + } + } + + // Convert temporary array to result object and add totals. + $result = new stdClass(); + foreach ( $temp_views as $key => $value ) { + $result->$key = (object) array( 'views' => $value ); + } + $result->totals = (object) array( 'views' => $totals ); + + // Set percentages values and format numbers. + // @phpstan-ignore-next-line. + foreach ( $result as $key => $value ) { + // Percentage against all referrer views, even those not included + // in the dataset due to the $limit argument. + $result->{ $key }->viewsPercentage = $this + ->get_i18n_percentage( absint( $value->views ), $this->total_views ); + + // Percentage against the current dataset that is limited due to the + // $limit argument. + $result->{ $key }->datasetViewsPercentage = $this + ->get_i18n_percentage( absint( $value->views ), $totals ); + + // Format views values. + $result->{ $key }->views = number_format_i18n( $result->{ $key }->views ); + } + + return $result; + } + + /** + * Returns the passed number compared to the passed total, in an + * internationalized percentage format. + * + * @since 3.6.0 + * @since 3.17.0 Moved from the `Referrers_Post_Detail_API_Proxy` class. + * + * @param int $number The number to be calculated as a percentage. + * @param int $total The total number to compare against. + * @return string|false The internationalized percentage or false on error. + */ + private function get_i18n_percentage( int $number, int $total ) { + if ( 0 === $total ) { + return false; + } + + return number_format_i18n( $number / $total * 100, 2 ); + } +} diff --git a/src/rest-api/stats/class-endpoint-posts.php b/src/rest-api/stats/class-endpoint-posts.php new file mode 100644 index 000000000..cb9731077 --- /dev/null +++ b/src/rest-api/stats/class-endpoint-posts.php @@ -0,0 +1,249 @@ +analytics_posts_api = new Analytics_Posts_API( $this->parsely ); + } + + /** + * Returns the endpoint name. + * + * @since 3.17.0 + * + * @return string + */ + public function get_endpoint_name(): string { + return 'posts'; + } + + /** + * Registers the routes for the objects of the controller. + */ + public function register_routes(): void { + /** + * GET /posts + * Retrieves the top posts for the given period. + */ + $this->register_rest_route( + '/', + array( 'GET' ), + array( $this, 'get_posts' ), + array_merge( + array( + 'period_start' => array( + 'description' => 'The start of the period to query.', + 'type' => 'string', + 'required' => false, + ), + 'period_end' => array( + 'description' => 'The end of the period to query.', + 'type' => 'string', + 'required' => false, + ), + 'pub_date_start' => array( + 'description' => 'The start of the publication date range to query.', + 'type' => 'string', + 'required' => false, + ), + 'pub_date_end' => array( + 'description' => 'The end of the publication date range to query.', + 'type' => 'string', + 'required' => false, + ), + 'limit' => array( + 'description' => 'The number of posts to return.', + 'type' => 'integer', + 'required' => false, + 'default' => self::TOP_POSTS_DEFAULT_LIMIT, + ), + 'sort' => array( + 'description' => 'The sort order of the posts.', + 'type' => 'string', + 'enum' => self::SORT_METRICS, + 'default' => self::SORT_DEFAULT, + 'required' => false, + ), + 'page' => array( + 'description' => 'The page to fetch.', + 'type' => 'integer', + 'required' => false, + 'default' => 1, + ), + 'author' => array( + 'description' => 'The author to filter by.', + 'type' => 'array', + 'items' => array( + 'type' => 'string', + ), + 'required' => false, + 'maxItems' => 5, + ), + 'section' => array( + 'description' => 'The section to filter by.', + 'type' => 'string', + 'required' => false, + ), + 'tag' => array( + 'description' => 'The tag to filter by.', + 'type' => 'array', + 'items' => array( + 'type' => 'string', + ), + 'required' => false, + 'maxItems' => 5, + ), + 'segment' => array( + 'description' => 'The segment to filter by.', + 'type' => 'string', + 'required' => false, + ), + ), + $this->get_itm_source_param_args() + ) + ); + } + + /** + * API Endpoint: GET /stats/posts + * + * Retrieves the top posts for the given query parameters. + * + * @param WP_REST_Request $request The request. + * + * @return stdClass[]|WP_Error|WP_REST_Response + */ + public function get_posts( WP_REST_Request $request ) { + $params = $request->get_params(); + + // Setup the itm_source if it is provided. + $this->set_itm_source_from_request( $request ); + + // TODO: Needed before the Public API refactor. + // Convert array of authors to a string with the first element. + if ( isset( $params['author'] ) && is_array( $params['author'] ) ) { + $params['author'] = $params['author'][0]; + } + // Convert array of tags to a string with the first element. + if ( isset( $params['tag'] ) && is_array( $params['tag'] ) ) { + $params['tag'] = $params['tag'][0]; + } + // TODO END. + + // Do the analytics request. + /** + * The raw analytics data. + * + * @var stdClass[]|WP_Error $analytics_request + */ + $analytics_request = $this->analytics_posts_api->get_items( + array( + 'period_start' => $params['period_start'] ?? null, + 'period_end' => $params['period_end'] ?? null, + 'pub_date_start' => $params['pub_date_start'] ?? null, + 'pub_date_end' => $params['pub_date_end'] ?? null, + 'limit' => $params['limit'] ?? self::TOP_POSTS_DEFAULT_LIMIT, + 'sort' => $params['sort'] ?? self::SORT_DEFAULT, + 'page' => $params['page'] ?? 1, + 'author' => $params['author'] ?? null, + 'section' => $params['section'] ?? null, + 'tag' => $params['tag'] ?? null, + 'segment' => $params['segment'] ?? null, + 'itm_source' => $params['itm_source'] ?? null, + ) + ); + + if ( is_wp_error( $analytics_request ) ) { + return $analytics_request; + } + + // Process the data. + $posts = array(); + foreach ( $analytics_request as $item ) { + $posts[] = $this->extract_post_data( $item ); + } + + $response = array( + 'params' => $params, + 'data' => $posts, + ); + + return new WP_REST_Response( $response, 200 ); + } +} diff --git a/src/rest-api/stats/class-endpoint-related.php b/src/rest-api/stats/class-endpoint-related.php new file mode 100644 index 000000000..d675e9e92 --- /dev/null +++ b/src/rest-api/stats/class-endpoint-related.php @@ -0,0 +1,112 @@ +related_posts_api = new Related_API( $this->parsely ); + } + + /** + * Returns the endpoint name. + * + * @since 3.17.0 + * + * @return string + */ + public function get_endpoint_name(): string { + return 'related'; + } + + /** + * Registers the routes for the endpoint. + * + * @since 3.17.0 + */ + public function register_routes(): void { + /** + * GET /related + * Gets related posts. + */ + $this->register_rest_route( + '/', + array( 'GET' ), + array( $this, 'get_related_posts' ), + array( + 'url' => array( + 'description' => __( 'The URL of the post.', 'wp-parsely' ), + 'type' => 'string', + 'required' => true, + ), + $this->get_related_posts_param_args(), + ) + ); + } + + /** + * API Endpoint: GET /stats/related + * + * Gets related posts for a given URL. + * + * @since 3.17.0 + * + * @param WP_REST_Request $request The request object. + * @return WP_REST_Response|WP_Error + */ + public function get_related_posts( WP_REST_Request $request ) { + $url = $request->get_param( 'url' ); + + $related_posts = $this->get_related_posts_of_url( $request, $url ); + + if ( is_wp_error( $related_posts ) ) { + return $related_posts; + } + + return new WP_REST_Response( array( 'data' => $related_posts ), 200 ); + } + + /** + * Returns whether the endpoint is available for access by the current + * user. + * + * @since 3.17.0 + * + * @param WP_REST_Request|null $request The request object. + * @return bool + */ + public function is_available_to_current_user( ?WP_REST_Request $request = null ): bool { + return true; + } +} diff --git a/src/rest-api/stats/class-stats-controller.php b/src/rest-api/stats/class-stats-controller.php new file mode 100644 index 000000000..ecae2387b --- /dev/null +++ b/src/rest-api/stats/class-stats-controller.php @@ -0,0 +1,48 @@ +register_endpoints( $endpoints ); + } +} diff --git a/src/rest-api/stats/trait-post-data.php b/src/rest-api/stats/trait-post-data.php new file mode 100644 index 000000000..4698d2a9a --- /dev/null +++ b/src/rest-api/stats/trait-post-data.php @@ -0,0 +1,145 @@ +itm_source = $source; + } + + /** + * Sets the itm_source value from the request, if it exists. + * + * @since 3.17.0 + * + * @param WP_REST_Request $request The request object. + */ + private function set_itm_source_from_request( WP_REST_Request $request ): void { + $source = $request->get_param( 'itm_source' ); + if ( null !== $source ) { + $this->set_itm_source( $source ); + } + } + + /** + * Returns the itm_source parameter arguments, to be used in the REST API + * route registration. + * + * @since 3.17.0 + * + * @return array + */ + private function get_itm_source_param_args(): array { + return array( + 'itm_source' => array( + 'description' => __( 'The source of the item.', 'wp-parsely' ), + 'type' => 'string', + 'required' => false, + 'validate_callback' => array( $this, 'validate_itm_source' ), + ), + ); + } + + /** + * Extracts the post data from the passed object. + * + * Should only be used with endpoints that return post data. + * + * @since 3.10.0 + * @since 3.17.0 Moved from the old `Base_API_Proxy` class. + * + * @param stdClass $item The object to extract the data from. + * @return array The extracted data. + */ + protected function extract_post_data( stdClass $item ): array { + $data = array(); + + if ( isset( $item->author ) ) { + $data['author'] = $item->author; + } + + if ( isset( $item->metrics->views ) ) { + $data['views'] = number_format_i18n( $item->metrics->views ); + } + + if ( isset( $item->metrics->visitors ) ) { + $data['visitors'] = number_format_i18n( $item->metrics->visitors ); + } + + // The avg_engaged metric can be in different locations depending on the + // endpoint and passed sort/url parameters. + $avg_engaged = $item->metrics->avg_engaged ?? $item->avg_engaged ?? null; + if ( null !== $avg_engaged ) { + $data['avgEngaged'] = Utils::get_formatted_duration( (float) $avg_engaged ); + } + + if ( isset( $item->pub_date ) ) { + $data['date'] = wp_date( Utils::get_date_format(), strtotime( $item->pub_date ) ); + } + + if ( isset( $item->title ) ) { + $data['title'] = $item->title; + } + + if ( isset( $item->url ) ) { + $site_id = $this->parsely->get_site_id(); + // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.url_to_postid_url_to_postid + $post_id = url_to_postid( $item->url ); // 0 if the post cannot be found. + + $post_url = Parsely::get_url_with_itm_source( $item->url, null ); + if ( Utils::parsely_is_https_supported() ) { + $post_url = str_replace( 'http://', 'https://', $post_url ); + } + + $data['rawUrl'] = $post_url; + $data['dashUrl'] = Parsely::get_dash_url( $site_id, $post_url ); + $data['id'] = Parsely::get_url_with_itm_source( $post_url, null ); // Unique. + $data['postId'] = $post_id; // Might not be unique. + $data['url'] = Parsely::get_url_with_itm_source( $post_url, $this->itm_source ); + + // Set thumbnail URL, falling back to the Parse.ly thumbnail if needed. + $thumbnail_url = get_the_post_thumbnail_url( $post_id, 'thumbnail' ); + if ( false !== $thumbnail_url ) { + $data['thumbnailUrl'] = $thumbnail_url; + } elseif ( isset( $item->thumb_url_medium ) ) { + $data['thumbnailUrl'] = $item->thumb_url_medium; + } + } + + return $data; + } +} diff --git a/src/rest-api/stats/trait-related-posts.php b/src/rest-api/stats/trait-related-posts.php new file mode 100644 index 000000000..dadab370a --- /dev/null +++ b/src/rest-api/stats/trait-related-posts.php @@ -0,0 +1,165 @@ + + */ + private function get_related_posts_param_args(): array { + return array_merge( + array( + 'sort' => array( + 'description' => __( 'The sort order.', 'wp-parsely' ), + 'type' => 'string', + 'enum' => array( '_score', 'pub_date' ), + 'required' => false, + 'default' => '_score', + ), + 'limit' => array( + 'description' => __( 'The number of related posts to return.', 'wp-parsely' ), + 'type' => 'integer', + 'required' => false, + 'default' => 10, + ), + 'pub_date_start' => array( + 'description' => __( 'The start of the publication date.', 'wp-parsely' ), + 'type' => 'string', + 'required' => false, + ), + 'pub_date_end' => array( + 'description' => __( 'The end of the publication date.', 'wp-parsely' ), + 'type' => 'string', + 'required' => false, + ), + 'page' => array( + 'description' => __( 'The page number.', 'wp-parsely' ), + 'type' => 'integer', + 'required' => false, + 'default' => 1, + ), + 'section' => array( + 'description' => __( 'The section of the post.', 'wp-parsely' ), + 'type' => 'string', + 'required' => false, + ), + 'tag' => array( + 'description' => __( 'The tag of the post.', 'wp-parsely' ), + 'type' => 'string', + 'required' => false, + ), + 'author' => array( + 'description' => __( 'The author of the post.', 'wp-parsely' ), + 'type' => 'string', + 'required' => false, + ), + ), + $this->get_itm_source_param_args() + ); + } + + /** + * Get related posts for a given URL. + * + * @since 3.17.0 + * + * @param WP_REST_Request $request The request object. + * @param string $url The URL to get related posts for. + * @return array|WP_Error + */ + public function get_related_posts_of_url( WP_REST_Request $request, string $url ) { + // Set the itm_source parameter. + $this->set_itm_source_from_request( $request ); + + // Get the data from the API. + /** + * The related posts request. + * + * @var array|WP_Error $related_posts_request + */ + $related_posts_request = $this->related_posts_api->get_items( + array( + 'url' => $url, + 'sort' => $request->get_param( 'sort' ), + 'limit' => $request->get_param( 'limit' ), + 'pub_date_start' => $request->get_param( 'pub_date_start' ), + 'pub_date_end' => $request->get_param( 'pub_date_end' ), + 'page' => $request->get_param( 'page' ), + 'section' => $request->get_param( 'section' ), + 'tag' => $request->get_param( 'tag' ), + 'author' => $request->get_param( 'author' ), + ) + ); + + if ( is_wp_error( $related_posts_request ) ) { + return $related_posts_request; + } + + $itm_source = $this->itm_source; + + $related_posts = array_map( + static function ( stdClass $item ) use ( $itm_source ) { + return (object) array( + 'image_url' => $item->image_url, + 'thumb_url_medium' => $item->thumb_url_medium, + 'title' => $item->title, + 'url' => Parsely::get_url_with_itm_source( $item->url, $itm_source ), + ); + }, + $related_posts_request + ); + + return $related_posts; + } +} diff --git a/src/rest-api/trait-use-post-id-parameter.php b/src/rest-api/trait-use-post-id-parameter.php new file mode 100644 index 000000000..4459636e9 --- /dev/null +++ b/src/rest-api/trait-use-post-id-parameter.php @@ -0,0 +1,88 @@ + $methods The HTTP methods. + * @param callable $callback The callback function. + * @param array $args The route arguments. + */ + public function register_rest_route_with_post_id( + string $route, + array $methods, + callable $callback, + array $args = array() + ): void { + // Append the post_id parameter to the route. + $route = '/(?P\d+)/' . trim( $route, '/' ); + + // Add the post_id parameter to the args. + $args = array_merge( + $args, + array( + 'post_id' => array( + 'description' => __( 'The ID of the post.', 'wp-parsely' ), + 'type' => 'integer', + 'required' => true, + 'validate_callback' => array( $this, 'validate_post_id' ), + ), + ) + ); + + // Register the route. + $this->register_rest_route( $route, $methods, $callback, $args ); + } + + /** + * Validates the post ID parameter. + * + * The callback sets the post object in the request object if the parameter is valid. + * + * @since 3.16.0 + * @access private + * + * @param string $param The parameter value. + * @param WP_REST_Request $request The request object. + * @return bool Whether the parameter is valid. + */ + public function validate_post_id( string $param, WP_REST_Request $request ): bool { + if ( ! is_numeric( $param ) ) { + return false; + } + + $param = filter_var( $param, FILTER_VALIDATE_INT ); + + if ( false === $param ) { + return false; + } + + // Validate if the post ID exists. + $post = get_post( $param ); + // Set the post attribute in the request. + $request->set_param( 'post', $post ); + + return null !== $post; + } +} From 89ef1bba02293f5eeae5a63064d82843db44b23d Mon Sep 17 00:00:00 2001 From: Henrique Mouta Date: Thu, 29 Aug 2024 11:56:38 +0100 Subject: [PATCH 063/282] Update the UI to use the new API endpoints --- build/blocks/recommendations/edit.asset.php | 2 +- build/blocks/recommendations/edit.js | 2 +- build/blocks/recommendations/view.asset.php | 2 +- build/blocks/recommendations/view.js | 2 +- .../content-helper/dashboard-widget.asset.php | 2 +- build/content-helper/dashboard-widget.js | 2 +- build/content-helper/editor-sidebar.asset.php | 2 +- build/content-helper/editor-sidebar.js | 8 ++--- .../parsely-recommendations-fetcher.tsx | 2 +- .../dashboard-widget/provider.ts | 2 +- .../performance-stats/provider.ts | 36 +++++++++---------- .../editor-sidebar/related-posts/provider.ts | 2 +- 12 files changed, 31 insertions(+), 33 deletions(-) diff --git a/build/blocks/recommendations/edit.asset.php b/build/blocks/recommendations/edit.asset.php index 0f36c73fc..ce1f1eb73 100644 --- a/build/blocks/recommendations/edit.asset.php +++ b/build/blocks/recommendations/edit.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => '393b4c8be66f3bde527e'); + array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => 'f1121e53d4c8acf98db5'); diff --git a/build/blocks/recommendations/edit.js b/build/blocks/recommendations/edit.js index 06593e46c..c923405cf 100644 --- a/build/blocks/recommendations/edit.js +++ b/build/blocks/recommendations/edit.js @@ -1 +1 @@ -!function(){"use strict";var e,n={271:function(e,n,r){var t,o,a=r(848),i=window.wp.blockEditor,l=window.wp.blocks,s=window.wp.i18n,c=window.wp.components,u=JSON.parse('{"UU":"wp-parsely/recommendations","uK":{"imagestyle":{"type":"string","default":"original"},"limit":{"type":"number","default":3},"openlinksinnewtab":{"type":"boolean","default":false},"showimages":{"type":"boolean","default":true},"sort":{"type":"string","default":"score"},"title":{"type":"string","default":"Related Content"}}}'),d=window.wp.element;(o=t||(t={}))[o.Error=0]="Error",o[o.Loaded=1]="Loaded",o[o.Recommendations=2]="Recommendations";var p=function(){return p=Object.assign||function(e){for(var n,r=1,t=arguments.length;r0&&o[o.length-1])||6!==l[0]&&2!==l[0])){i=0;continue}if(3===l[0]&&(!o||l[1]>o[0]&&l[1]=a)&&Object.keys(t.O).every((function(e){return t.O[e](r[s])}))?r.splice(s--,1):(l=!1,a0&&e[u-1][2]>a;u--)e[u]=e[u-1];e[u]=[r,o,a]},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,{a:n}),n},t.d=function(e,n){for(var r in n)t.o(n,r)&&!t.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:n[r]})},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},function(){var e={335:0,203:0};t.O.j=function(n){return 0===e[n]};var n=function(n,r){var o,a,i=r[0],l=r[1],s=r[2],c=0;if(i.some((function(n){return 0!==e[n]}))){for(o in l)t.o(l,o)&&(t.m[o]=l[o]);if(s)var u=s(t)}for(n&&n(r);c0&&o[o.length-1])||6!==l[0]&&2!==l[0])){i=0;continue}if(3===l[0]&&(!o||l[1]>o[0]&&l[1]=a)&&Object.keys(t.O).every((function(e){return t.O[e](r[s])}))?r.splice(s--,1):(l=!1,a0&&e[u-1][2]>a;u--)e[u]=e[u-1];e[u]=[r,o,a]},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,{a:n}),n},t.d=function(e,n){for(var r in n)t.o(n,r)&&!t.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:n[r]})},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},function(){var e={335:0,203:0};t.O.j=function(n){return 0===e[n]};var n=function(n,r){var o,a,i=r[0],l=r[1],s=r[2],c=0;if(i.some((function(n){return 0!==e[n]}))){for(o in l)t.o(l,o)&&(t.m[o]=l[o]);if(s)var u=s(t)}for(n&&n(r);c array('react', 'wp-api-fetch', 'wp-components', 'wp-compose', 'wp-dom-ready', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => '827c1c0c5b711b046baf'); + array('react', 'wp-api-fetch', 'wp-components', 'wp-compose', 'wp-dom-ready', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => 'af6eb0946975f32d53b1'); diff --git a/build/blocks/recommendations/view.js b/build/blocks/recommendations/view.js index ac32818be..d8f4b4577 100644 --- a/build/blocks/recommendations/view.js +++ b/build/blocks/recommendations/view.js @@ -1 +1 @@ -!function(){"use strict";var e={20:function(e,r,n){var t=n(609),o=Symbol.for("react.element"),a=Symbol.for("react.fragment"),i=Object.prototype.hasOwnProperty,s=t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function u(e,r,n){var t,a={},u=null,c=null;for(t in void 0!==n&&(u=""+n),void 0!==r.key&&(u=""+r.key),void 0!==r.ref&&(c=r.ref),r)i.call(r,t)&&!l.hasOwnProperty(t)&&(a[t]=r[t]);if(e&&e.defaultProps)for(t in r=e.defaultProps)void 0===a[t]&&(a[t]=r[t]);return{$$typeof:o,type:e,key:u,ref:c,props:a,_owner:s.current}}r.Fragment=a,r.jsx=u,r.jsxs=u},848:function(e,r,n){e.exports=n(20)},609:function(e){e.exports=window.React}},r={};function n(t){var o=r[t];if(void 0!==o)return o.exports;var a=r[t]={exports:{}};return e[t](a,a.exports,n),a.exports}n.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(r,{a:r}),r},n.d=function(e,r){for(var t in r)n.o(r,t)&&!n.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},n.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},function(){var e,r,t=n(848),o=n(609),a=window.wp.domReady,i=n.n(a),s=window.wp.element,l=window.wp.i18n;(r=e||(e={}))[r.Error=0]="Error",r[r.Loaded=1]="Loaded",r[r.Recommendations=2]="Recommendations";var u=function(){return u=Object.assign||function(e){for(var r,n=1,t=arguments.length;n0&&o[o.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]0&&o[o.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1] array('react', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => 'a741adf6df6b723b2f3d'); + array('react', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => 'd852566173ef137708b0'); diff --git a/build/content-helper/dashboard-widget.js b/build/content-helper/dashboard-widget.js index 50392fc4b..7b17d4192 100644 --- a/build/content-helper/dashboard-widget.js +++ b/build/content-helper/dashboard-widget.js @@ -1 +1 @@ -!function(){"use strict";var e={20:function(e,t,r){var n=r(609),a=Symbol.for("react.element"),s=Symbol.for("react.fragment"),o=Object.prototype.hasOwnProperty,i=n.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function c(e,t,r){var n,s={},c=null,u=null;for(n in void 0!==r&&(c=""+r),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(u=t.ref),t)o.call(t,n)&&!l.hasOwnProperty(n)&&(s[n]=t[n]);if(e&&e.defaultProps)for(n in t=e.defaultProps)void 0===s[n]&&(s[n]=t[n]);return{$$typeof:a,type:e,key:c,ref:u,props:s,_owner:i.current}}t.Fragment=s,t.jsx=c,t.jsxs=c},848:function(e,t,r){e.exports=r(20)},609:function(e){e.exports=window.React}},t={};function r(n){var a=t[n];if(void 0!==a)return a.exports;var s=t[n]={exports:{}};return e[n](s,s.exports,r),s.exports}r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,{a:t}),t},r.d=function(e,t){for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},function(){var e,t,n,a=r(848),s=window.wp.element,o=window.wp.i18n,i=function(e){void 0===e&&(e=null);var t="";(null==e?void 0:e.children)&&(t=e.children);var r="content-helper-error-message";return(null==e?void 0:e.className)&&(r+=" "+e.className),(0,a.jsx)("div",{className:r,"data-testid":null==e?void 0:e.testId,dangerouslySetInnerHTML:{__html:t}})},l=function(e){var t;return void 0===e&&(e=null),(0,a.jsx)(i,{className:null==e?void 0:e.className,testId:"empty-credentials-message",children:null!==(t=window.wpParselyEmptyCredentialsMessage)&&void 0!==t?t:(0,o.__)("Please ensure that the Site ID and API Secret given in the plugin's settings are correct.","wp-parsely")})},c=function(){return c=Object.assign||function(e){for(var t,r=1,n=arguments.length;r0&&a[a.length-1])||6!==i[0]&&2!==i[0])){o=0;continue}if(3===i[0]&&(!a||i[1]>a[0]&&i[1]=1e4&&(clearInterval(s),r("Telemetry library not loaded"))}),100);else r("Telemetry not enabled")}))},e.prototype.trackEvent=function(t,r){var n;this.isLoaded?(0!==t.indexOf(e.TRACKS_PREFIX)&&(t=e.TRACKS_PREFIX+t),this.isEventNameValid(t)?(r=this.prepareProperties(r),null===(n=this._tkq)||void 0===n||n.push(["recordEvent",t,r])):console.error("Error tracking event: Invalid event name")):console.error("Error tracking event: Telemetry not loaded")},e.prototype.isTelemetryEnabled=function(){return this.isEnabled},e.prototype.isProprietyValid=function(t){return e.PROPERTY_REGEX.test(t)},e.prototype.isEventNameValid=function(t){return e.EVENT_NAME_REGEX.test(t)},e.prototype.prepareProperties=function(e){return(e=this.sanitizeProperties(e)).parsely_version=wpParselyTracksTelemetry.version,wpParselyTracksTelemetry.user&&(e._ut=wpParselyTracksTelemetry.user.type,e._ui=wpParselyTracksTelemetry.user.id),wpParselyTracksTelemetry.vipgo_env&&(e.vipgo_env=wpParselyTracksTelemetry.vipgo_env),this.sanitizeProperties(e)},e.prototype.sanitizeProperties=function(e){var t=this,r={};return Object.keys(e).forEach((function(n){t.isProprietyValid(n)&&(r[n]=e[n])})),r},e.TRACKS_PREFIX="wpparsely_",e.EVENT_NAME_REGEX=/^(([a-z0-9]+)_){2}([a-z0-9_]+)$/,e.PROPERTY_REGEX=/^[a-z_][a-z0-9_]*$/,e}(),h=(d.trackEvent,function(e){var t=e.defaultValue,r=e.items,n=e.onChange;return(0,a.jsx)("select",{onChange:n,value:t,children:r.map((function(e){return(0,a.jsx)("option",{value:e[0],children:e[1]},e[0])}))})}),f=window.wp.data,y=function(){return y=Object.assign||function(e){for(var t,r=1,n=arguments.length;rhere.',"wp-parsely"):s.code===j.ParselySuggestionsApiOpenAiError||s.code===j.ParselySuggestionsApiOpenAiUnavailable?s.message=(0,o.__)("The Parse.ly API returned an internal server error. Please retry with a different input, or try again later.","wp-parsely"):s.code===j.HttpRequestFailed&&s.message.includes("cURL error 28")?s.message=(0,o.__)("The Parse.ly API did not respond in a timely manner. Please try again later.","wp-parsely"):s.code===j.ParselySuggestionsApiSchemaError?s.message=(0,o.__)("The Parse.ly API returned a validation error. Please try again with different parameters.","wp-parsely"):s.code===j.ParselySuggestionsApiNoData?s.message=(0,o.__)("The Parse.ly API couldn't find any relevant data to fulfill the request. Please retry with a different input.","wp-parsely"):s.code===j.ParselySuggestionsApiOpenAiSchema?s.message=(0,o.__)("The Parse.ly API returned an incorrect response. Please try again later.","wp-parsely"):s.code===j.ParselySuggestionsApiAuthUnavailable&&(s.message=(0,o.__)("The Parse.ly API is currently unavailable. Please try again later.","wp-parsely")),s}return C(t,e),t.prototype.Message=function(e){return void 0===e&&(e=null),[j.PluginCredentialsNotSetMessageDetected,j.PluginSettingsSiteIdNotSet,j.PluginSettingsApiSecretNotSet].includes(this.code)?l(e):(this.code===j.FetchError&&(this.hint=this.Hint((0,o.__)("This error can sometimes be caused by ad-blockers or browser tracking protections. Please add this site to any applicable allow lists and try again.","wp-parsely"))),this.code!==j.ParselyApiForbidden&&this.code!==j.ParselySuggestionsApiNoAuthentication||(this.hint=this.Hint((0,o.__)("Please ensure that the Site ID and API Secret given in the plugin's settings are correct.","wp-parsely"))),this.code===j.HttpRequestFailed&&(this.hint=this.Hint((0,o.__)("The Parse.ly API cannot be reached. Please verify that you are online.","wp-parsely"))),(0,a.jsx)(i,{className:null==e?void 0:e.className,testId:"error",children:"

".concat(this.message,"

").concat(this.hint?this.hint:"")}))},t.prototype.Hint=function(e){return'

'.concat((0,o.__)("Hint:","wp-parsely")," ").concat(e,"

")},t.prototype.createErrorSnackbar=function(){//.test(this.message)||(0,f.dispatch)("core/notices").createNotice("error",this.message,{type:"snackbar"})},t}(Error),O=function(){function e(){this.abortControllers=new Map}return e.prototype.cancelRequest=function(e){if(e)(t=this.abortControllers.get(e))&&(t.abort(),this.abortControllers.delete(e));else{var t,r=Array.from(this.abortControllers.keys()).pop();r&&(t=this.abortControllers.get(r))&&(t.abort(),this.abortControllers.delete(r))}},e.prototype.cancelAll=function(){this.abortControllers.forEach((function(e){return e.abort()})),this.abortControllers.clear()},e.prototype.getOrCreateController=function(e){if(e&&this.abortControllers.has(e))return{abortController:this.abortControllers.get(e),abortId:e};var t=null!=e?e:"auto-"+Date.now(),r=new AbortController;return this.abortControllers.set(t,r),{abortController:r,abortId:t}},e.prototype.fetch=function(e,t){return r=this,n=void 0,s=function(){var r,n,a,s,i,l;return function(e,t){var r,n,a,s,o={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]};return s={next:i(0),throw:i(1),return:i(2)},"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function i(i){return function(l){return function(i){if(r)throw new TypeError("Generator is already executing.");for(;s&&(s=0,i[0]&&(o=0)),o;)try{if(r=1,n&&(a=2&i[0]?n.return:i[0]?n.throw||((a=n.return)&&a.call(n),0):n.next)&&!(a=a.call(n,i[1])).done)return a;switch(n=0,a&&(i=[2&i[0],a.value]),i[0]){case 0:case 1:a=i;break;case 4:return o.label++,{value:i[1],done:!1};case 5:o.label++,n=i[1],i=[0];continue;case 7:i=o.ops.pop(),o.trys.pop();continue;default:if(!((a=(a=o.trys).length>0&&a[a.length-1])||6!==i[0]&&2!==i[0])){o=0;continue}if(3===i[0]&&(!a||i[1]>a[0]&&i[1]0&&a[a.length-1])||6!==i[0]&&2!==i[0])){o=0;continue}if(3===i[0]&&(!a||i[1]>a[0]&&i[1]=c){var u=t;(a=n/c)%1>1/i&&(u=a>10?1:2),u=parseFloat(a.toFixed(2))===parseFloat(a.toFixed(0))?0:u,s=a.toFixed(u),o=l}i=c})),s+r+o}function z(e){var t=e.metric,r=e.post,n=e.avgEngagedIcon,s=e.viewsIcon;return"views"===t?(0,a.jsxs)("span",{className:"parsely-post-metric-data",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Number of Views","wp-parsely")}),s,$(r.views.toString())]}):"avg_engaged"===t?(0,a.jsxs)("span",{className:"parsely-post-metric-data",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Average Time","wp-parsely")}),n,r.avgEngaged]}):(0,a.jsx)("span",{className:"parsely-post-metric-data",children:"-"})}function X(e){var t,r=e.metric,n=e.post;return(0,a.jsx)("li",{className:"parsely-top-post",children:(0,a.jsxs)("div",{className:"parsely-top-post-content",children:[(0,a.jsx)(B,{post:n}),(0,a.jsxs)("div",{className:"parsely-top-post-data",children:[(0,a.jsx)(z,{metric:r,post:n}),(0,a.jsx)(Z,{post:n}),(0,a.jsxs)("a",{className:"parsely-top-post-icon-link",href:n.url,target:"_blank",rel:"noreferrer",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("View Post (opens in new tab)","wp-parsely")}),(0,a.jsx)(q,{})]}),0!==n.postId&&(0,a.jsxs)("a",{className:"parsely-top-post-icon-link",href:(t=n.postId,"/wp-admin/post.php?post=".concat(t,"&action=edit")),target:"_blank",rel:"noreferrer",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Edit Post (opens in new tab)","wp-parsely")}),(0,a.jsx)(G,{})]}),(0,a.jsxs)("div",{className:"parsely-top-post-metadata",children:[(0,a.jsxs)("span",{className:"parsely-top-post-date",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Date","wp-parsely")}),M(new Date(n.date))]}),(0,a.jsxs)("span",{className:"parsely-top-post-author",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Author","wp-parsely")}),n.author]})]})]})]})},n.id)}function B(e){var t=e.post;return t.thumbnailUrl?(0,a.jsxs)("div",{className:"parsely-top-post-thumbnail",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Thumbnail","wp-parsely")}),(0,a.jsx)("img",{src:t.thumbnailUrl,alt:(0,o.__)("Post thumbnail","wp-parsely")})]}):(0,a.jsx)("div",{className:"parsely-top-post-thumbnail",children:(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Post thumbnail not available","wp-parsely")})})}function Z(e){var t=e.post;return(0,a.jsxs)("a",{className:"parsely-top-post-title",href:t.dashUrl,target:"_blank",rel:"noreferrer",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("View in Parse.ly (opens in new tab)","wp-parsely")}),t.title]})}var W=function(){return W=Object.assign||function(e){for(var t,r=1,n=arguments.length;r0&&a[a.length-1])||6!==i[0]&&2!==i[0])){o=0;continue}if(3===i[0]&&(!a||i[1]>a[0]&&i[1]0&&e.retryFetch?[4,new Promise((function(e){return setTimeout(e,500)}))]:[3,3];case 1:return r.sent(),[4,t(n-1)];case 2:return r.sent(),[3,4];case 3:f(!1),v(e),r.label=4;case 4:return[2]}}))}))})),[2]}))}))};return f(!0),t(1),function(){f(!1),m([]),v(void 0)}}),[i,S]);var j=function(e,t){d.trackEvent("dash_widget_filter_changed",W({filter:e},t))},N=(0,a.jsxs)("div",{className:"parsely-top-posts-filters",children:[(0,a.jsx)(h,{defaultValue:i.Period,items:Object.values(e).map((function(e){return[e,A(e)]})),onChange:function(t){x(t.target.value,e)&&(l({Period:t.target.value}),j("period",{period:t.target.value}),T(1))}}),(0,a.jsx)(h,{defaultValue:i.Metric,items:Object.values(t).map((function(e){return[e,E(e)]})),onChange:function(e){x(e.target.value,t)&&(l({Metric:e.target.value}),j("metric",{metric:e.target.value}),T(1))}})]}),C=(0,a.jsxs)("div",{className:"parsely-top-posts-navigation",children:[(0,a.jsx)("button",{className:"parsely-top-posts-navigation-prev",disabled:S<=1,"aria-label":(0,o.__)("Previous page","wp-parsely"),onClick:function(){T(S-1),d.trackEvent("dash_widget_navigation",{navigation:"previous",to_page:S-1})},children:(0,o.__)("<< Previous","wp-parsely")}),(0,o.sprintf)(/* translators: 1: Current page */ /* translators: 1: Current page */(0,o.__)("Page %1$d","wp-parsely"),S),(0,a.jsx)("button",{className:"parsely-top-posts-navigation-next",disabled:!u&&_.length<5,"aria-label":(0,o.__)("Next page","wp-parsely"),onClick:function(){T(S+1),d.trackEvent("dash_widget_navigation",{navigation:"next",to_page:S+1})},children:(0,o.__)("Next >>","wp-parsely")})]});if(g)return(0,a.jsxs)(a.Fragment,{children:[N,g.Message(),S>1&&C]});var k=(0,a.jsx)("div",{className:"parsely-spinner-wrapper",children:(0,a.jsx)(p.Spinner,{})});return(0,a.jsxs)(a.Fragment,{children:[N,u?k:(0,a.jsx)("ol",{className:"parsely-top-posts",style:{counterReset:"item "+5*(S-1)},children:_.map((function(e){return(0,a.jsx)(X,{metric:i.Metric,post:e},e.id)}))}),(_.length>=5||S>1)&&C]})}var J=function(r){var n;try{n=JSON.parse(r)}catch(r){return{Metric:t.Views,Period:e.Days7}}return x(null==n?void 0:n.Metric,t)||(n.Metric=t.Views),x(null==n?void 0:n.Period,e)||(n.Period=e.Days7),n};window.addEventListener("load",(function(){var e=document.querySelector("#wp-parsely-dashboard-widget > .inside");if(null!==e){var t=(0,a.jsx)(S,{endpoint:"dashboard-widget-settings",defaultSettings:J(window.wpParselyContentHelperSettings),children:(0,a.jsx)(u,{children:(0,a.jsx)(Q,{})})});s.createRoot?(0,s.createRoot)(e).render(t):(0,s.render)(t,e)}}),!1)}()}(); \ No newline at end of file +!function(){"use strict";var e={20:function(e,t,r){var n=r(609),a=Symbol.for("react.element"),s=Symbol.for("react.fragment"),o=Object.prototype.hasOwnProperty,i=n.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function c(e,t,r){var n,s={},c=null,u=null;for(n in void 0!==r&&(c=""+r),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(u=t.ref),t)o.call(t,n)&&!l.hasOwnProperty(n)&&(s[n]=t[n]);if(e&&e.defaultProps)for(n in t=e.defaultProps)void 0===s[n]&&(s[n]=t[n]);return{$$typeof:a,type:e,key:c,ref:u,props:s,_owner:i.current}}t.Fragment=s,t.jsx=c,t.jsxs=c},848:function(e,t,r){e.exports=r(20)},609:function(e){e.exports=window.React}},t={};function r(n){var a=t[n];if(void 0!==a)return a.exports;var s=t[n]={exports:{}};return e[n](s,s.exports,r),s.exports}r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,{a:t}),t},r.d=function(e,t){for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},function(){var e,t,n,a=r(848),s=window.wp.element,o=window.wp.i18n,i=function(e){void 0===e&&(e=null);var t="";(null==e?void 0:e.children)&&(t=e.children);var r="content-helper-error-message";return(null==e?void 0:e.className)&&(r+=" "+e.className),(0,a.jsx)("div",{className:r,"data-testid":null==e?void 0:e.testId,dangerouslySetInnerHTML:{__html:t}})},l=function(e){var t;return void 0===e&&(e=null),(0,a.jsx)(i,{className:null==e?void 0:e.className,testId:"empty-credentials-message",children:null!==(t=window.wpParselyEmptyCredentialsMessage)&&void 0!==t?t:(0,o.__)("Please ensure that the Site ID and API Secret given in the plugin's settings are correct.","wp-parsely")})},c=function(){return c=Object.assign||function(e){for(var t,r=1,n=arguments.length;r0&&a[a.length-1])||6!==i[0]&&2!==i[0])){o=0;continue}if(3===i[0]&&(!a||i[1]>a[0]&&i[1]=1e4&&(clearInterval(s),r("Telemetry library not loaded"))}),100);else r("Telemetry not enabled")}))},e.prototype.trackEvent=function(t,r){var n;this.isLoaded?(0!==t.indexOf(e.TRACKS_PREFIX)&&(t=e.TRACKS_PREFIX+t),this.isEventNameValid(t)?(r=this.prepareProperties(r),null===(n=this._tkq)||void 0===n||n.push(["recordEvent",t,r])):console.error("Error tracking event: Invalid event name")):console.error("Error tracking event: Telemetry not loaded")},e.prototype.isTelemetryEnabled=function(){return this.isEnabled},e.prototype.isProprietyValid=function(t){return e.PROPERTY_REGEX.test(t)},e.prototype.isEventNameValid=function(t){return e.EVENT_NAME_REGEX.test(t)},e.prototype.prepareProperties=function(e){return(e=this.sanitizeProperties(e)).parsely_version=wpParselyTracksTelemetry.version,wpParselyTracksTelemetry.user&&(e._ut=wpParselyTracksTelemetry.user.type,e._ui=wpParselyTracksTelemetry.user.id),wpParselyTracksTelemetry.vipgo_env&&(e.vipgo_env=wpParselyTracksTelemetry.vipgo_env),this.sanitizeProperties(e)},e.prototype.sanitizeProperties=function(e){var t=this,r={};return Object.keys(e).forEach((function(n){t.isProprietyValid(n)&&(r[n]=e[n])})),r},e.TRACKS_PREFIX="wpparsely_",e.EVENT_NAME_REGEX=/^(([a-z0-9]+)_){2}([a-z0-9_]+)$/,e.PROPERTY_REGEX=/^[a-z_][a-z0-9_]*$/,e}(),h=(d.trackEvent,function(e){var t=e.defaultValue,r=e.items,n=e.onChange;return(0,a.jsx)("select",{onChange:n,value:t,children:r.map((function(e){return(0,a.jsx)("option",{value:e[0],children:e[1]},e[0])}))})}),f=window.wp.data,y=function(){return y=Object.assign||function(e){for(var t,r=1,n=arguments.length;rhere.',"wp-parsely"):s.code===j.ParselySuggestionsApiOpenAiError||s.code===j.ParselySuggestionsApiOpenAiUnavailable?s.message=(0,o.__)("The Parse.ly API returned an internal server error. Please retry with a different input, or try again later.","wp-parsely"):s.code===j.HttpRequestFailed&&s.message.includes("cURL error 28")?s.message=(0,o.__)("The Parse.ly API did not respond in a timely manner. Please try again later.","wp-parsely"):s.code===j.ParselySuggestionsApiSchemaError?s.message=(0,o.__)("The Parse.ly API returned a validation error. Please try again with different parameters.","wp-parsely"):s.code===j.ParselySuggestionsApiNoData?s.message=(0,o.__)("The Parse.ly API couldn't find any relevant data to fulfill the request. Please retry with a different input.","wp-parsely"):s.code===j.ParselySuggestionsApiOpenAiSchema?s.message=(0,o.__)("The Parse.ly API returned an incorrect response. Please try again later.","wp-parsely"):s.code===j.ParselySuggestionsApiAuthUnavailable&&(s.message=(0,o.__)("The Parse.ly API is currently unavailable. Please try again later.","wp-parsely")),s}return C(t,e),t.prototype.Message=function(e){return void 0===e&&(e=null),[j.PluginCredentialsNotSetMessageDetected,j.PluginSettingsSiteIdNotSet,j.PluginSettingsApiSecretNotSet].includes(this.code)?l(e):(this.code===j.FetchError&&(this.hint=this.Hint((0,o.__)("This error can sometimes be caused by ad-blockers or browser tracking protections. Please add this site to any applicable allow lists and try again.","wp-parsely"))),this.code!==j.ParselyApiForbidden&&this.code!==j.ParselySuggestionsApiNoAuthentication||(this.hint=this.Hint((0,o.__)("Please ensure that the Site ID and API Secret given in the plugin's settings are correct.","wp-parsely"))),this.code===j.HttpRequestFailed&&(this.hint=this.Hint((0,o.__)("The Parse.ly API cannot be reached. Please verify that you are online.","wp-parsely"))),(0,a.jsx)(i,{className:null==e?void 0:e.className,testId:"error",children:"

".concat(this.message,"

").concat(this.hint?this.hint:"")}))},t.prototype.Hint=function(e){return'

'.concat((0,o.__)("Hint:","wp-parsely")," ").concat(e,"

")},t.prototype.createErrorSnackbar=function(){//.test(this.message)||(0,f.dispatch)("core/notices").createNotice("error",this.message,{type:"snackbar"})},t}(Error),O=function(){function e(){this.abortControllers=new Map}return e.prototype.cancelRequest=function(e){if(e)(t=this.abortControllers.get(e))&&(t.abort(),this.abortControllers.delete(e));else{var t,r=Array.from(this.abortControllers.keys()).pop();r&&(t=this.abortControllers.get(r))&&(t.abort(),this.abortControllers.delete(r))}},e.prototype.cancelAll=function(){this.abortControllers.forEach((function(e){return e.abort()})),this.abortControllers.clear()},e.prototype.getOrCreateController=function(e){if(e&&this.abortControllers.has(e))return{abortController:this.abortControllers.get(e),abortId:e};var t=null!=e?e:"auto-"+Date.now(),r=new AbortController;return this.abortControllers.set(t,r),{abortController:r,abortId:t}},e.prototype.fetch=function(e,t){return r=this,n=void 0,s=function(){var r,n,a,s,i,l;return function(e,t){var r,n,a,s,o={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]};return s={next:i(0),throw:i(1),return:i(2)},"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function i(i){return function(l){return function(i){if(r)throw new TypeError("Generator is already executing.");for(;s&&(s=0,i[0]&&(o=0)),o;)try{if(r=1,n&&(a=2&i[0]?n.return:i[0]?n.throw||((a=n.return)&&a.call(n),0):n.next)&&!(a=a.call(n,i[1])).done)return a;switch(n=0,a&&(i=[2&i[0],a.value]),i[0]){case 0:case 1:a=i;break;case 4:return o.label++,{value:i[1],done:!1};case 5:o.label++,n=i[1],i=[0];continue;case 7:i=o.ops.pop(),o.trys.pop();continue;default:if(!((a=(a=o.trys).length>0&&a[a.length-1])||6!==i[0]&&2!==i[0])){o=0;continue}if(3===i[0]&&(!a||i[1]>a[0]&&i[1]0&&a[a.length-1])||6!==i[0]&&2!==i[0])){o=0;continue}if(3===i[0]&&(!a||i[1]>a[0]&&i[1]=c){var u=t;(a=n/c)%1>1/i&&(u=a>10?1:2),u=parseFloat(a.toFixed(2))===parseFloat(a.toFixed(0))?0:u,s=a.toFixed(u),o=l}i=c})),s+r+o}function z(e){var t=e.metric,r=e.post,n=e.avgEngagedIcon,s=e.viewsIcon;return"views"===t?(0,a.jsxs)("span",{className:"parsely-post-metric-data",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Number of Views","wp-parsely")}),s,$(r.views.toString())]}):"avg_engaged"===t?(0,a.jsxs)("span",{className:"parsely-post-metric-data",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Average Time","wp-parsely")}),n,r.avgEngaged]}):(0,a.jsx)("span",{className:"parsely-post-metric-data",children:"-"})}function X(e){var t,r=e.metric,n=e.post;return(0,a.jsx)("li",{className:"parsely-top-post",children:(0,a.jsxs)("div",{className:"parsely-top-post-content",children:[(0,a.jsx)(B,{post:n}),(0,a.jsxs)("div",{className:"parsely-top-post-data",children:[(0,a.jsx)(z,{metric:r,post:n}),(0,a.jsx)(Z,{post:n}),(0,a.jsxs)("a",{className:"parsely-top-post-icon-link",href:n.url,target:"_blank",rel:"noreferrer",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("View Post (opens in new tab)","wp-parsely")}),(0,a.jsx)(q,{})]}),0!==n.postId&&(0,a.jsxs)("a",{className:"parsely-top-post-icon-link",href:(t=n.postId,"/wp-admin/post.php?post=".concat(t,"&action=edit")),target:"_blank",rel:"noreferrer",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Edit Post (opens in new tab)","wp-parsely")}),(0,a.jsx)(G,{})]}),(0,a.jsxs)("div",{className:"parsely-top-post-metadata",children:[(0,a.jsxs)("span",{className:"parsely-top-post-date",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Date","wp-parsely")}),M(new Date(n.date))]}),(0,a.jsxs)("span",{className:"parsely-top-post-author",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Author","wp-parsely")}),n.author]})]})]})]})},n.id)}function B(e){var t=e.post;return t.thumbnailUrl?(0,a.jsxs)("div",{className:"parsely-top-post-thumbnail",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Thumbnail","wp-parsely")}),(0,a.jsx)("img",{src:t.thumbnailUrl,alt:(0,o.__)("Post thumbnail","wp-parsely")})]}):(0,a.jsx)("div",{className:"parsely-top-post-thumbnail",children:(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Post thumbnail not available","wp-parsely")})})}function Z(e){var t=e.post;return(0,a.jsxs)("a",{className:"parsely-top-post-title",href:t.dashUrl,target:"_blank",rel:"noreferrer",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("View in Parse.ly (opens in new tab)","wp-parsely")}),t.title]})}var W=function(){return W=Object.assign||function(e){for(var t,r=1,n=arguments.length;r0&&a[a.length-1])||6!==i[0]&&2!==i[0])){o=0;continue}if(3===i[0]&&(!a||i[1]>a[0]&&i[1]0&&e.retryFetch?[4,new Promise((function(e){return setTimeout(e,500)}))]:[3,3];case 1:return r.sent(),[4,t(n-1)];case 2:return r.sent(),[3,4];case 3:f(!1),v(e),r.label=4;case 4:return[2]}}))}))})),[2]}))}))};return f(!0),t(1),function(){f(!1),m([]),v(void 0)}}),[i,S]);var j=function(e,t){d.trackEvent("dash_widget_filter_changed",W({filter:e},t))},N=(0,a.jsxs)("div",{className:"parsely-top-posts-filters",children:[(0,a.jsx)(h,{defaultValue:i.Period,items:Object.values(e).map((function(e){return[e,A(e)]})),onChange:function(t){x(t.target.value,e)&&(l({Period:t.target.value}),j("period",{period:t.target.value}),T(1))}}),(0,a.jsx)(h,{defaultValue:i.Metric,items:Object.values(t).map((function(e){return[e,E(e)]})),onChange:function(e){x(e.target.value,t)&&(l({Metric:e.target.value}),j("metric",{metric:e.target.value}),T(1))}})]}),C=(0,a.jsxs)("div",{className:"parsely-top-posts-navigation",children:[(0,a.jsx)("button",{className:"parsely-top-posts-navigation-prev",disabled:S<=1,"aria-label":(0,o.__)("Previous page","wp-parsely"),onClick:function(){T(S-1),d.trackEvent("dash_widget_navigation",{navigation:"previous",to_page:S-1})},children:(0,o.__)("<< Previous","wp-parsely")}),(0,o.sprintf)(/* translators: 1: Current page */ /* translators: 1: Current page */(0,o.__)("Page %1$d","wp-parsely"),S),(0,a.jsx)("button",{className:"parsely-top-posts-navigation-next",disabled:!u&&_.length<5,"aria-label":(0,o.__)("Next page","wp-parsely"),onClick:function(){T(S+1),d.trackEvent("dash_widget_navigation",{navigation:"next",to_page:S+1})},children:(0,o.__)("Next >>","wp-parsely")})]});if(g)return(0,a.jsxs)(a.Fragment,{children:[N,g.Message(),S>1&&C]});var k=(0,a.jsx)("div",{className:"parsely-spinner-wrapper",children:(0,a.jsx)(p.Spinner,{})});return(0,a.jsxs)(a.Fragment,{children:[N,u?k:(0,a.jsx)("ol",{className:"parsely-top-posts",style:{counterReset:"item "+5*(S-1)},children:_.map((function(e){return(0,a.jsx)(X,{metric:i.Metric,post:e},e.id)}))}),(_.length>=5||S>1)&&C]})}var J=function(r){var n;try{n=JSON.parse(r)}catch(r){return{Metric:t.Views,Period:e.Days7}}return x(null==n?void 0:n.Metric,t)||(n.Metric=t.Views),x(null==n?void 0:n.Period,e)||(n.Period=e.Days7),n};window.addEventListener("load",(function(){var e=document.querySelector("#wp-parsely-dashboard-widget > .inside");if(null!==e){var t=(0,a.jsx)(S,{endpoint:"dashboard-widget-settings",defaultSettings:J(window.wpParselyContentHelperSettings),children:(0,a.jsx)(u,{children:(0,a.jsx)(Q,{})})});s.createRoot?(0,s.createRoot)(e).render(t):(0,s.render)(t,e)}}),!1)}()}(); \ No newline at end of file diff --git a/build/content-helper/editor-sidebar.asset.php b/build/content-helper/editor-sidebar.asset.php index 0a96a2013..a791b1c32 100644 --- a/build/content-helper/editor-sidebar.asset.php +++ b/build/content-helper/editor-sidebar.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-dom-ready', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-plugins', 'wp-primitives', 'wp-url'), 'version' => 'ceb704108c34274732ed'); + array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-dom-ready', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-plugins', 'wp-primitives', 'wp-url'), 'version' => 'eaad1ca5764f3fbdb9e6'); diff --git a/build/content-helper/editor-sidebar.js b/build/content-helper/editor-sidebar.js index 303604252..697b66067 100644 --- a/build/content-helper/editor-sidebar.js +++ b/build/content-helper/editor-sidebar.js @@ -9,11 +9,11 @@ /* translators: %s: percentage value */,{ /* translators: %s: percentage value */ text:"".concat(c(t)," - ").concat((0,_.sprintf)((0,_.__)("%s%%","wp-parsely"),n.viewsPercentage)),delay:150,children:(0,p.jsx)("div",{"aria-label":r,className:"bar-fill "+t,style:{width:n.viewsPercentage+"%"}})},t)}))}),(0,p.jsx)("div",{className:"percentage-bar-labels",children:Object.entries(t.referrers.types).map((function(e){var t=e[0],n=e[1];return(0,p.jsxs)("div",{className:"single-label "+t,children:[(0,p.jsx)("div",{className:"label-color "+t}),(0,p.jsx)("div",{className:"label-text",children:c(t)}),(0,p.jsx)("div",{className:"label-value",children:Lt(n.views)})]},t)}))})]})]})},Nt=(0,p.jsx)(x.SVG,{viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:(0,p.jsx)(x.Path,{d:"M3.99961 13C4.67043 13.3354 4.6703 13.3357 4.67017 13.3359L4.67298 13.3305C4.67621 13.3242 4.68184 13.3135 4.68988 13.2985C4.70595 13.2686 4.7316 13.2218 4.76695 13.1608C4.8377 13.0385 4.94692 12.8592 5.09541 12.6419C5.39312 12.2062 5.84436 11.624 6.45435 11.0431C7.67308 9.88241 9.49719 8.75 11.9996 8.75C14.502 8.75 16.3261 9.88241 17.5449 11.0431C18.1549 11.624 18.6061 12.2062 18.9038 12.6419C19.0523 12.8592 19.1615 13.0385 19.2323 13.1608C19.2676 13.2218 19.2933 13.2686 19.3093 13.2985C19.3174 13.3135 19.323 13.3242 19.3262 13.3305L19.3291 13.3359C19.3289 13.3357 19.3288 13.3354 19.9996 13C20.6704 12.6646 20.6703 12.6643 20.6701 12.664L20.6697 12.6632L20.6688 12.6614L20.6662 12.6563L20.6583 12.6408C20.6517 12.6282 20.6427 12.6108 20.631 12.5892C20.6078 12.5459 20.5744 12.4852 20.5306 12.4096C20.4432 12.2584 20.3141 12.0471 20.1423 11.7956C19.7994 11.2938 19.2819 10.626 18.5794 9.9569C17.1731 8.61759 14.9972 7.25 11.9996 7.25C9.00203 7.25 6.82614 8.61759 5.41987 9.9569C4.71736 10.626 4.19984 11.2938 3.85694 11.7956C3.68511 12.0471 3.55605 12.2584 3.4686 12.4096C3.42484 12.4852 3.39142 12.5459 3.36818 12.5892C3.35656 12.6108 3.34748 12.6282 3.34092 12.6408L3.33297 12.6563L3.33041 12.6614L3.32948 12.6632L3.32911 12.664C3.32894 12.6643 3.32879 12.6646 3.99961 13ZM11.9996 16C13.9326 16 15.4996 14.433 15.4996 12.5C15.4996 10.567 13.9326 9 11.9996 9C10.0666 9 8.49961 10.567 8.49961 12.5C8.49961 14.433 10.0666 16 11.9996 16Z"})}),Ct=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"M15.5 9.5a1 1 0 100-2 1 1 0 000 2zm0 1.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5zm-2.25 6v-2a2.75 2.75 0 00-2.75-2.75h-4A2.75 2.75 0 003.75 15v2h1.5v-2c0-.69.56-1.25 1.25-1.25h4c.69 0 1.25.56 1.25 1.25v2h1.5zm7-2v2h-1.5v-2c0-.69-.56-1.25-1.25-1.25H15v-1.5h2.5A2.75 2.75 0 0120.25 15zM9.5 8.5a1 1 0 11-2 0 1 1 0 012 0zm1.5 0a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0z",fillRule:"evenodd"})}),At=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"M12 4V2.2L9 4.8l3 2.5V5.5c3.6 0 6.5 2.9 6.5 6.5 0 2.9-1.9 5.3-4.5 6.2v.2l-.1-.2c-.4.1-.7.2-1.1.2l.2 1.5c.3 0 .6-.1 1-.2 3.5-.9 6-4 6-7.7 0-4.4-3.6-8-8-8zm-7.9 7l1.5.2c.1-1.2.5-2.3 1.2-3.2l-1.1-.9C4.8 8.2 4.3 9.6 4.1 11zm1.5 1.8l-1.5.2c.1.7.3 1.4.5 2 .3.7.6 1.3 1 1.8l1.2-.8c-.3-.5-.6-1-.8-1.5s-.4-1.1-.4-1.7zm1.5 5.5c1.1.9 2.4 1.4 3.8 1.6l.2-1.5c-1.1-.1-2.2-.5-3.1-1.2l-.9 1.1z"})}),Ot=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"M11 13h2v-2h-2v2zm-6 0h2v-2H5v2zm12-2v2h2v-2h-2z"})}),Rt=function(){return Rt=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]1?[2,Promise.reject(new ie((0,_.sprintf)(/* translators: URL of the published post */ /* translators: URL of the published post */ -(0,_.__)("Multiple results were returned for the post %s by the Parse.ly API.","wp-parsely"),t),$.ParselyApiReturnedTooManyResults))]:[2,n[0]]}}))}))},t.prototype.fetchReferrerDataFromWpEndpoint=function(e,t,n){return Zt(this,void 0,void 0,(function(){return $t(this,(function(r){switch(r.label){case 0:return[4,this.fetch({path:(0,Oe.addQueryArgs)("/wp-parsely/v1/referrers/post/detail",qt(qt({},zt(e)),{itm_source:this.itmSource,total_views:n,url:t}))})];case 1:return[2,r.sent()]}}))}))},t}(Re),Kt=function(){return Kt=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&e.retryFetch?[4,new Promise((function(e){return setTimeout(e,500)}))]:[3,3];case 1:return t.sent(),[4,n(r-1)];case 2:return t.sent(),[3,4];case 3:a(e),i(!1),t.label=4;case 4:return[2]}}))}))})),[2]}))}))};return i(!0),n(1),function(){a(void 0)}}),[t]),(0,p.jsxs)("div",{className:"wp-parsely-performance-panel",children:[(0,p.jsx)(Tt,{title:(0,_.__)("Performance Stats","wp-parsely"),icon:jt,dropdownChildren:function(e){var t=e.onClose;return(0,p.jsx)(tn,{onClose:t})},children:(0,p.jsx)("div",{className:"panel-settings",children:(0,p.jsx)(f.SelectControl,{size:"__unstable-large",value:h.PerformanceStats.Period,prefix:(0,p.jsx)(f.__experimentalInputControlPrefixWrapper,{children:(0,_.__)("Period: ","wp-parsely")}),onChange:function(e){D(e,y)&&(v({PerformanceStats:Kt(Kt({},h.PerformanceStats),{Period:e})}),P.trackEvent("editor_sidebar_performance_period_changed",{period:e}))},children:Object.values(y).map((function(e){return(0,p.jsx)("option",{value:e,children:F(e)},e)}))})})}),o?o.Message():(0,p.jsxs)(p.Fragment,{children:[en(h,"overview")&&(0,p.jsx)(Gt,{data:c,isLoading:r}),en(h,"categories")&&(0,p.jsx)(Et,{data:c,isLoading:r}),en(h,"referrers")&&(0,p.jsx)(Ht,{data:c,isLoading:r})]}),window.wpParselyPostUrl&&(0,p.jsx)(f.Button,{className:"wp-parsely-view-post",variant:"primary",onClick:function(){P.trackEvent("editor_sidebar_view_post_pressed")},href:window.wpParselyPostUrl,rel:"noopener",target:"_blank",children:(0,_.__)("View this in Parse.ly","wp-parsely")})]})},rn=function(e){var t=e.period;return(0,p.jsx)(f.Panel,{children:(0,p.jsx)(J,{children:(0,p.jsx)(nn,{period:t})})})},sn=function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(r=Object.getOwnPropertySymbols(e);i=1&&(0,p.jsx)(f.__experimentalToggleGroupControlOption,{value:w.Tag,label:(0,_.__)("Tag","wp-parsely")}),r.categories.length>=1&&(0,p.jsx)(f.__experimentalToggleGroupControlOption,{value:w.Section,label:(0,_.__)("Section","wp-parsely")}),r.authors.length>=1&&(0,p.jsx)(f.__experimentalToggleGroupControlOption,{value:w.Author,label:(0,_.__)("Author","wp-parsely")})]})})},an=function(e){var t=e.filter,n=e.label,r=e.postData,i=sn(e,["filter","label","postData"]);return(0,p.jsx)("div",{className:"related-posts-filter-values",children:(0,p.jsx)(f.ComboboxControl,{__next40pxDefaultSize:!0,allowReset:!0,label:n,onChange:function(e){return i.onFilterValueChange(e)},options:w.Tag===t.type?r.tags.map((function(e){return{value:e,label:e}})):w.Section===t.type?r.categories.map((function(e){return{value:e,label:e}})):w.Author===t.type?r.authors.map((function(e){return{value:e,label:e}})):[],value:t.value})})},ln=function(e){var t=e.filter,n=e.postData,r=e.label,i=sn(e,["filter","postData","label"]),s=function(){return n.authors.length>0&&n.categories.length>0||n.authors.length>0&&n.tags.length>0||n.tags.length>0&&n.categories.length>0},o=function(){return w.Tag===t.type&&n.tags.length>1||w.Section===t.type&&n.categories.length>1||w.Author===t.type&&n.authors.length>1};return s()||o()?(0,p.jsxs)("div",{className:"related-posts-filter-settings",children:[s()&&(0,p.jsx)(on,{filter:t,label:r,onFilterTypeChange:i.onFilterTypeChange,postData:n}),o()&&(0,p.jsx)(an,{filter:t,label:s()?void 0:r,onFilterValueChange:i.onFilterValueChange,postData:n})]}):null},cn=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"M10 17.389H8.444A5.194 5.194 0 1 1 8.444 7H10v1.5H8.444a3.694 3.694 0 0 0 0 7.389H10v1.5ZM14 7h1.556a5.194 5.194 0 0 1 0 10.39H14v-1.5h1.556a3.694 3.694 0 0 0 0-7.39H14V7Zm-4.5 6h5v-1.5h-5V13Z"})}),un=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M5.625 5.5h9.75c.069 0 .125.056.125.125v9.75a.125.125 0 0 1-.125.125h-9.75a.125.125 0 0 1-.125-.125v-9.75c0-.069.056-.125.125-.125ZM4 5.625C4 4.728 4.728 4 5.625 4h9.75C16.273 4 17 4.728 17 5.625v9.75c0 .898-.727 1.625-1.625 1.625h-9.75A1.625 1.625 0 0 1 4 15.375v-9.75Zm14.5 11.656v-9H20v9C20 18.8 18.77 20 17.251 20H6.25v-1.5h11.001c.69 0 1.249-.528 1.249-1.219Z"})}),dn=function(){return(0,p.jsx)(f.SVG,{xmlns:"http://www.w3.org/2000/svg",width:"1",height:"40",viewBox:"0 0 1 40",fill:"none",children:(0,p.jsx)(f.Rect,{width:"1",height:"40",fill:"#cccccc"})})};function pn(e){var t=e.metric,n=e.post,r=e.avgEngagedIcon,i=e.viewsIcon;return"views"===t?(0,p.jsxs)("span",{className:"parsely-post-metric-data",children:[(0,p.jsx)("span",{className:"screen-reader-text",children:(0,_.__)("Number of Views","wp-parsely")}),i,Lt(n.views.toString())]}):"avg_engaged"===t?(0,p.jsxs)("span",{className:"parsely-post-metric-data",children:[(0,p.jsx)("span",{className:"screen-reader-text",children:(0,_.__)("Average Time","wp-parsely")}),r,n.avgEngaged]}):(0,p.jsx)("span",{className:"parsely-post-metric-data",children:"-"})}var fn,hn=function(e){var t,n,r=e.metric,i=e.post,s=e.postContent,o=(0,h.useDispatch)("core/notices").createNotice,a=s&&(t=s,n=q(i.rawUrl),new RegExp("]*href=[\"'](http://|https://)?.*".concat(n,".*[\"'][^>]*>"),"i").test(t));return(0,p.jsxs)("div",{className:"related-post-single","data-testid":"related-post-single",children:[(0,p.jsx)("div",{className:"related-post-title",children:(0,p.jsxs)("a",{href:i.url,target:"_blank",rel:"noreferrer",children:[(0,p.jsx)("span",{className:"screen-reader-text",children:(0,_.__)("View on website (opens new tab)","wp-parsely")}),i.title]})}),(0,p.jsx)("div",{className:"related-post-actions",children:(0,p.jsxs)("div",{className:"related-post-info",children:[(0,p.jsxs)("div",{children:[(0,p.jsx)("div",{className:"related-post-metric",children:(0,p.jsx)(pn,{metric:r,post:i,viewsIcon:(0,p.jsx)(X,{icon:Nt}),avgEngagedIcon:(0,p.jsx)(f.Dashicon,{icon:"clock",size:24})})}),a&&(0,p.jsx)("div",{className:"related-post-linked",children:(0,p.jsx)(f.Tooltip,{text:(0,_.__)("This post is linked in the content","wp-parsely"),children:(0,p.jsx)(X,{icon:cn,size:24})})})]}),(0,p.jsx)(dn,{}),(0,p.jsxs)("div",{children:[(0,p.jsx)(f.Button,{icon:un,iconSize:24,onClick:function(){navigator.clipboard.writeText(i.rawUrl).then((function(){o("success",(0,_.__)("URL copied to clipboard","wp-parsely"),{type:"snackbar"})}))},label:(0,_.__)("Copy URL to clipboard","wp-parsely")}),(0,p.jsx)(f.Button,{icon:(0,p.jsx)(T,{}),iconSize:18,href:i.dashUrl,target:"_blank",label:(0,_.__)("View in Parse.ly","wp-parsely")})]})]})})]})},vn=window.wp.coreData,gn=function(){var e=function(t,n){return e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},e(t,n)};return function(t,n){if("function"!=typeof n&&null!==n)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");function __(){this.constructor=t}e(t,n),t.prototype=null===n?Object.create(n):(__.prototype=n.prototype,new __)}}(),yn=function(){return yn=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]1?[2,Promise.reject(new ie((0,_.sprintf)(/* translators: URL of the published post */ /* translators: URL of the published post */ +(0,_.__)("Multiple results were returned for the post %d by the Parse.ly API.","wp-parsely"),t),$.ParselyApiReturnedTooManyResults))]:[2,n[0]]}}))}))},t.prototype.fetchReferrerDataFromWpEndpoint=function(e,t,n){return Zt(this,void 0,void 0,(function(){return $t(this,(function(r){switch(r.label){case 0:return[4,this.fetch({path:(0,Oe.addQueryArgs)("/wp-parsely/v2/stats/post/".concat(t,"/referrers"),qt(qt({},zt(e)),{itm_source:this.itmSource,total_views:n}))})];case 1:return[2,r.sent()]}}))}))},t}(Re),Kt=function(){return Kt=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&e.retryFetch?[4,new Promise((function(e){return setTimeout(e,500)}))]:[3,3];case 1:return t.sent(),[4,n(r-1)];case 2:return t.sent(),[3,4];case 3:a(e),i(!1),t.label=4;case 4:return[2]}}))}))})),[2]}))}))};return i(!0),n(1),function(){a(void 0)}}),[t]),(0,p.jsxs)("div",{className:"wp-parsely-performance-panel",children:[(0,p.jsx)(Tt,{title:(0,_.__)("Performance Stats","wp-parsely"),icon:jt,dropdownChildren:function(e){var t=e.onClose;return(0,p.jsx)(tn,{onClose:t})},children:(0,p.jsx)("div",{className:"panel-settings",children:(0,p.jsx)(f.SelectControl,{size:"__unstable-large",value:h.PerformanceStats.Period,prefix:(0,p.jsx)(f.__experimentalInputControlPrefixWrapper,{children:(0,_.__)("Period: ","wp-parsely")}),onChange:function(e){D(e,y)&&(v({PerformanceStats:Kt(Kt({},h.PerformanceStats),{Period:e})}),P.trackEvent("editor_sidebar_performance_period_changed",{period:e}))},children:Object.values(y).map((function(e){return(0,p.jsx)("option",{value:e,children:F(e)},e)}))})})}),o?o.Message():(0,p.jsxs)(p.Fragment,{children:[en(h,"overview")&&(0,p.jsx)(Gt,{data:c,isLoading:r}),en(h,"categories")&&(0,p.jsx)(Et,{data:c,isLoading:r}),en(h,"referrers")&&(0,p.jsx)(Ht,{data:c,isLoading:r})]}),window.wpParselyPostUrl&&(0,p.jsx)(f.Button,{className:"wp-parsely-view-post",variant:"primary",onClick:function(){P.trackEvent("editor_sidebar_view_post_pressed")},href:window.wpParselyPostUrl,rel:"noopener",target:"_blank",children:(0,_.__)("View this in Parse.ly","wp-parsely")})]})},rn=function(e){var t=e.period;return(0,p.jsx)(f.Panel,{children:(0,p.jsx)(J,{children:(0,p.jsx)(nn,{period:t})})})},sn=function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(r=Object.getOwnPropertySymbols(e);i=1&&(0,p.jsx)(f.__experimentalToggleGroupControlOption,{value:w.Tag,label:(0,_.__)("Tag","wp-parsely")}),r.categories.length>=1&&(0,p.jsx)(f.__experimentalToggleGroupControlOption,{value:w.Section,label:(0,_.__)("Section","wp-parsely")}),r.authors.length>=1&&(0,p.jsx)(f.__experimentalToggleGroupControlOption,{value:w.Author,label:(0,_.__)("Author","wp-parsely")})]})})},an=function(e){var t=e.filter,n=e.label,r=e.postData,i=sn(e,["filter","label","postData"]);return(0,p.jsx)("div",{className:"related-posts-filter-values",children:(0,p.jsx)(f.ComboboxControl,{__next40pxDefaultSize:!0,allowReset:!0,label:n,onChange:function(e){return i.onFilterValueChange(e)},options:w.Tag===t.type?r.tags.map((function(e){return{value:e,label:e}})):w.Section===t.type?r.categories.map((function(e){return{value:e,label:e}})):w.Author===t.type?r.authors.map((function(e){return{value:e,label:e}})):[],value:t.value})})},ln=function(e){var t=e.filter,n=e.postData,r=e.label,i=sn(e,["filter","postData","label"]),s=function(){return n.authors.length>0&&n.categories.length>0||n.authors.length>0&&n.tags.length>0||n.tags.length>0&&n.categories.length>0},o=function(){return w.Tag===t.type&&n.tags.length>1||w.Section===t.type&&n.categories.length>1||w.Author===t.type&&n.authors.length>1};return s()||o()?(0,p.jsxs)("div",{className:"related-posts-filter-settings",children:[s()&&(0,p.jsx)(on,{filter:t,label:r,onFilterTypeChange:i.onFilterTypeChange,postData:n}),o()&&(0,p.jsx)(an,{filter:t,label:s()?void 0:r,onFilterValueChange:i.onFilterValueChange,postData:n})]}):null},cn=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"M10 17.389H8.444A5.194 5.194 0 1 1 8.444 7H10v1.5H8.444a3.694 3.694 0 0 0 0 7.389H10v1.5ZM14 7h1.556a5.194 5.194 0 0 1 0 10.39H14v-1.5h1.556a3.694 3.694 0 0 0 0-7.39H14V7Zm-4.5 6h5v-1.5h-5V13Z"})}),un=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M5.625 5.5h9.75c.069 0 .125.056.125.125v9.75a.125.125 0 0 1-.125.125h-9.75a.125.125 0 0 1-.125-.125v-9.75c0-.069.056-.125.125-.125ZM4 5.625C4 4.728 4.728 4 5.625 4h9.75C16.273 4 17 4.728 17 5.625v9.75c0 .898-.727 1.625-1.625 1.625h-9.75A1.625 1.625 0 0 1 4 15.375v-9.75Zm14.5 11.656v-9H20v9C20 18.8 18.77 20 17.251 20H6.25v-1.5h11.001c.69 0 1.249-.528 1.249-1.219Z"})}),dn=function(){return(0,p.jsx)(f.SVG,{xmlns:"http://www.w3.org/2000/svg",width:"1",height:"40",viewBox:"0 0 1 40",fill:"none",children:(0,p.jsx)(f.Rect,{width:"1",height:"40",fill:"#cccccc"})})};function pn(e){var t=e.metric,n=e.post,r=e.avgEngagedIcon,i=e.viewsIcon;return"views"===t?(0,p.jsxs)("span",{className:"parsely-post-metric-data",children:[(0,p.jsx)("span",{className:"screen-reader-text",children:(0,_.__)("Number of Views","wp-parsely")}),i,Lt(n.views.toString())]}):"avg_engaged"===t?(0,p.jsxs)("span",{className:"parsely-post-metric-data",children:[(0,p.jsx)("span",{className:"screen-reader-text",children:(0,_.__)("Average Time","wp-parsely")}),r,n.avgEngaged]}):(0,p.jsx)("span",{className:"parsely-post-metric-data",children:"-"})}var fn,hn=function(e){var t,n,r=e.metric,i=e.post,s=e.postContent,o=(0,h.useDispatch)("core/notices").createNotice,a=s&&(t=s,n=q(i.rawUrl),new RegExp("]*href=[\"'](http://|https://)?.*".concat(n,".*[\"'][^>]*>"),"i").test(t));return(0,p.jsxs)("div",{className:"related-post-single","data-testid":"related-post-single",children:[(0,p.jsx)("div",{className:"related-post-title",children:(0,p.jsxs)("a",{href:i.url,target:"_blank",rel:"noreferrer",children:[(0,p.jsx)("span",{className:"screen-reader-text",children:(0,_.__)("View on website (opens new tab)","wp-parsely")}),i.title]})}),(0,p.jsx)("div",{className:"related-post-actions",children:(0,p.jsxs)("div",{className:"related-post-info",children:[(0,p.jsxs)("div",{children:[(0,p.jsx)("div",{className:"related-post-metric",children:(0,p.jsx)(pn,{metric:r,post:i,viewsIcon:(0,p.jsx)(X,{icon:Nt}),avgEngagedIcon:(0,p.jsx)(f.Dashicon,{icon:"clock",size:24})})}),a&&(0,p.jsx)("div",{className:"related-post-linked",children:(0,p.jsx)(f.Tooltip,{text:(0,_.__)("This post is linked in the content","wp-parsely"),children:(0,p.jsx)(X,{icon:cn,size:24})})})]}),(0,p.jsx)(dn,{}),(0,p.jsxs)("div",{children:[(0,p.jsx)(f.Button,{icon:un,iconSize:24,onClick:function(){navigator.clipboard.writeText(i.rawUrl).then((function(){o("success",(0,_.__)("URL copied to clipboard","wp-parsely"),{type:"snackbar"})}))},label:(0,_.__)("Copy URL to clipboard","wp-parsely")}),(0,p.jsx)(f.Button,{icon:(0,p.jsx)(T,{}),iconSize:18,href:i.dashUrl,target:"_blank",label:(0,_.__)("View in Parse.ly","wp-parsely")})]})]})})]})},vn=window.wp.coreData,gn=function(){var e=function(t,n){return e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},e(t,n)};return function(t,n){if("function"!=typeof n&&null!==n)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");function __(){this.constructor=t}e(t,n),t.prototype=null===n?Object.create(n):(__.prototype=n.prototype,new __)}}(),yn=function(){return yn=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]>( { - path: addQueryArgs( '/wp-parsely/v1/related', { query } ), + path: addQueryArgs( '/wp-parsely/v2/stats/related', query ), } ); } catch ( wpError ) { error = wpError; diff --git a/src/content-helper/dashboard-widget/provider.ts b/src/content-helper/dashboard-widget/provider.ts index 23bc4673e..0338e490a 100644 --- a/src/content-helper/dashboard-widget/provider.ts +++ b/src/content-helper/dashboard-widget/provider.ts @@ -83,7 +83,7 @@ export class DashboardWidgetProvider extends BaseProvider { settings: TopPostsSettings, page: number ): Promise { const response = this.fetch( { - path: addQueryArgs( '/wp-parsely/v1/stats/posts/', { + path: addQueryArgs( '/wp-parsely/v2/stats/posts/', { limit: TOP_POSTS_DEFAULT_LIMIT, ...getApiPeriodParams( settings.Period ), sort: settings.Metric, diff --git a/src/content-helper/editor-sidebar/performance-stats/provider.ts b/src/content-helper/editor-sidebar/performance-stats/provider.ts index 5bc524cd6..98ad0681b 100644 --- a/src/content-helper/editor-sidebar/performance-stats/provider.ts +++ b/src/content-helper/editor-sidebar/performance-stats/provider.ts @@ -68,13 +68,13 @@ export class PerformanceStatsProvider extends BaseProvider { ); } - // Get post URL. - const postUrl = editor.getPermalink(); + // Get post ID. + const postID = editor.getCurrentPostId(); - if ( null === postUrl ) { + if ( null === postID ) { return Promise.reject( new ContentHelperError( __( - "The post's URL returned null.", + "The post's ID returned null.", 'wp-parsely' ), ContentHelperErrorCode.PostIsNotPublished ) ); @@ -84,10 +84,10 @@ export class PerformanceStatsProvider extends BaseProvider { let performanceData, referrerData; try { performanceData = await this.fetchPerformanceDataFromWpEndpoint( - period, postUrl + period, postID ); referrerData = await this.fetchReferrerDataFromWpEndpoint( - period, postUrl, performanceData.views + period, postID, performanceData.views ); } catch ( contentHelperError ) { return Promise.reject( contentHelperError ); @@ -100,20 +100,19 @@ export class PerformanceStatsProvider extends BaseProvider { * Fetches the performance data for the current post from the WordPress REST * API. * - * @param {Period} period The period for which to fetch data. - * @param {string} postUrl + * @param {Period} period The period for which to fetch data. + * @param {number} postId The post's ID. * * @return {Promise } The current post's details. */ private async fetchPerformanceDataFromWpEndpoint( - period: Period, postUrl: string + period: Period, postId: number ): Promise { const response = await this.fetch( { path: addQueryArgs( - '/wp-parsely/v1/stats/post/detail', { + `/wp-parsely/v2/stats/post/${ postId }/details`, { ...getApiPeriodParams( period ), itm_source: this.itmSource, - url: postUrl, } ), } ); @@ -122,8 +121,8 @@ export class PerformanceStatsProvider extends BaseProvider { return Promise.reject( new ContentHelperError( sprintf( /* translators: URL of the published post */ - __( 'The post %s has 0 views, or the Parse.ly API returned no data.', - 'wp-parsely' ), postUrl + __( 'The post %d has 0 views, or the Parse.ly API returned no data.', + 'wp-parsely' ), postId ), ContentHelperErrorCode.ParselyApiReturnedNoData, '' ) ); } @@ -133,8 +132,8 @@ export class PerformanceStatsProvider extends BaseProvider { return Promise.reject( new ContentHelperError( sprintf( /* translators: URL of the published post */ - __( 'Multiple results were returned for the post %s by the Parse.ly API.', - 'wp-parsely' ), postUrl + __( 'Multiple results were returned for the post %d by the Parse.ly API.', + 'wp-parsely' ), postId ), ContentHelperErrorCode.ParselyApiReturnedTooManyResults ) ); } @@ -146,21 +145,20 @@ export class PerformanceStatsProvider extends BaseProvider { * Fetches referrer data for the current post from the WordPress REST API. * * @param {Period} period The period for which to fetch data. - * @param {string} postUrl The post's URL. + * @param {number} postId The post's ID. * @param {string} totalViews Total post views (including direct views). * * @return {Promise} The post's referrer data. */ private async fetchReferrerDataFromWpEndpoint( - period: Period, postUrl: string, totalViews: string + period: Period, postId: string, totalViews: string ): Promise { const response = await this.fetch( { path: addQueryArgs( - '/wp-parsely/v1/referrers/post/detail', { + `/wp-parsely/v2/stats/post/${ postId }/referrers`, { ...getApiPeriodParams( period ), itm_source: this.itmSource, total_views: totalViews, // Needed to calculate direct views. - url: postUrl, } ), } ); diff --git a/src/content-helper/editor-sidebar/related-posts/provider.ts b/src/content-helper/editor-sidebar/related-posts/provider.ts index 6345f4f19..6051c4ca8 100644 --- a/src/content-helper/editor-sidebar/related-posts/provider.ts +++ b/src/content-helper/editor-sidebar/related-posts/provider.ts @@ -146,7 +146,7 @@ export class RelatedPostsProvider extends BaseProvider { */ private async fetchRelatedPostsFromWpEndpoint( query: RelatedPostsApiQuery ): Promise { const response = this.fetch( { - path: addQueryArgs( '/wp-parsely/v1/stats/posts', { + path: addQueryArgs( '/wp-parsely/v2/stats/posts', { ...query.query, itm_source: 'wp-parsely-content-helper', } ), From e14f28c2cb0615494119afb3cf00be8ebdf71745 Mon Sep 17 00:00:00 2001 From: Henrique Mouta Date: Thu, 29 Aug 2024 13:08:26 +0100 Subject: [PATCH 064/282] Delete the old endpoints --- .../class-analytics-post-detail-api-proxy.php | 48 --- .../class-analytics-posts-api-proxy.php | 48 --- .../class-referrers-post-detail-api-proxy.php | 259 --------------- src/Endpoints/class-related-api-proxy.php | 61 ---- .../Proxy/AnalyticsPostsProxyEndpointTest.php | 264 --------------- .../ReferrersPostDetailProxyEndpointTest.php | 305 ------------------ .../Proxy/RelatedProxyEndpointTest.php | 162 ---------- .../StatsPostDetailProxyEndpointTest.php | 206 ------------ wp-parsely.php | 27 +- 9 files changed, 1 insertion(+), 1379 deletions(-) delete mode 100644 src/Endpoints/class-analytics-post-detail-api-proxy.php delete mode 100644 src/Endpoints/class-analytics-posts-api-proxy.php delete mode 100644 src/Endpoints/class-referrers-post-detail-api-proxy.php delete mode 100644 src/Endpoints/class-related-api-proxy.php delete mode 100644 tests/Integration/Endpoints/Proxy/AnalyticsPostsProxyEndpointTest.php delete mode 100644 tests/Integration/Endpoints/Proxy/ReferrersPostDetailProxyEndpointTest.php delete mode 100644 tests/Integration/Endpoints/Proxy/RelatedProxyEndpointTest.php delete mode 100644 tests/Integration/Endpoints/Proxy/StatsPostDetailProxyEndpointTest.php diff --git a/src/Endpoints/class-analytics-post-detail-api-proxy.php b/src/Endpoints/class-analytics-post-detail-api-proxy.php deleted file mode 100644 index 787ae0e50..000000000 --- a/src/Endpoints/class-analytics-post-detail-api-proxy.php +++ /dev/null @@ -1,48 +0,0 @@ -register_endpoint( '/stats/post/detail' ); - } - - /** - * Cached "proxy" to the Parse.ly `/analytics/post/detail` API endpoint. - * - * @param WP_REST_Request $request The request object. - * @return stdClass|WP_Error stdClass containing the data or a WP_Error object on failure. - */ - public function get_items( WP_REST_Request $request ) { - return $this->get_data( $request ); - } - - /** - * Generates the final data from the passed response. - * - * @param array $response The response received by the proxy. - * @return array The generated data. - */ - protected function generate_data( $response ): array { - return $this->generate_post_data( $response ); - } -} diff --git a/src/Endpoints/class-analytics-posts-api-proxy.php b/src/Endpoints/class-analytics-posts-api-proxy.php deleted file mode 100644 index 3ee862caf..000000000 --- a/src/Endpoints/class-analytics-posts-api-proxy.php +++ /dev/null @@ -1,48 +0,0 @@ -register_endpoint( '/stats/posts' ); - } - - /** - * Cached "proxy" to the Parse.ly `/analytics/posts` API endpoint. - * - * @param WP_REST_Request $request The request object. - * @return stdClass|WP_Error stdClass containing the data or a WP_Error object on failure. - */ - public function get_items( WP_REST_Request $request ) { - return $this->get_data( $request ); - } - - /** - * Generates the final data from the passed response. - * - * @param array $response The response received by the proxy. - * @return array The generated data. - */ - protected function generate_data( $response ): array { - return $this->generate_post_data( $response ); - } -} diff --git a/src/Endpoints/class-referrers-post-detail-api-proxy.php b/src/Endpoints/class-referrers-post-detail-api-proxy.php deleted file mode 100644 index 812a9ca81..000000000 --- a/src/Endpoints/class-referrers-post-detail-api-proxy.php +++ /dev/null @@ -1,259 +0,0 @@ -register_endpoint( '/referrers/post/detail' ); - } - - /** - * Cached "proxy" to the Parse.ly `/referrers/post/detail` API endpoint. - * - * @since 3.6.0 - * - * @param WP_REST_Request $request The request object. - * @return stdClass|WP_Error stdClass containing the data or a WP_Error object on failure. - */ - public function get_items( WP_REST_Request $request ) { - $total_views = $request->get_param( 'total_views' ) ?? '0'; - - if ( ! is_string( $total_views ) ) { - $total_views = '0'; - } - - $this->total_views = Utils::convert_to_positive_integer( $total_views ); - $request->offsetUnset( 'total_views' ); // Remove param from request. - return $this->get_data( $request ); - } - - /** - * Generates the final data from the passed response. - * - * @since 3.6.0 - * - * @param array $response The response received by the proxy. - * @return array The generated data. - */ - protected function generate_data( $response ): array { - $referrers_types = $this->generate_referrer_types_data( $response ); - $direct_views = Utils::convert_to_positive_integer( - $referrers_types->direct->views ?? '0' - ); - $referrers_top = $this->generate_referrers_data( 5, $response, $direct_views ); - - return array( - 'top' => $referrers_top, - 'types' => $referrers_types, - ); - } - - /** - * Generates the referrer types data. - * - * Referrer types are: - * - `social`: Views coming from social media. - * - `search`: Views coming from search engines. - * - `other`: Views coming from other referrers, like external websites. - * - `internal`: Views coming from linking pages of the same website. - * - * Returned object properties: - * - `views`: The number of views. - * - `viewPercentage`: The number of views as a percentage, compared to the - * total views of all referrer types. - * - * @since 3.6.0 - * - * @param array $response The response received by the proxy. - * @return stdClass The generated data. - */ - private function generate_referrer_types_data( array $response ): stdClass { - $result = new stdClass(); - $total_referrer_views = 0; // Views from all referrer types combined. - - // Set referrer type order as it is displayed in the Parse.ly dashboard. - $referrer_type_keys = array( 'social', 'search', 'other', 'internal', 'direct' ); - foreach ( $referrer_type_keys as $key ) { - $result->$key = (object) array( 'views' => 0 ); - } - - // Set views and views totals. - foreach ( $response as $referrer_data ) { - /** - * Variable. - * - * @var int - */ - $current_views = $referrer_data->metrics->referrers_views ?? 0; - $total_referrer_views += $current_views; - - /** - * Variable. - * - * @var string - */ - $current_key = $referrer_data->type ?? ''; - if ( '' !== $current_key ) { - if ( ! isset( $result->$current_key->views ) ) { - $result->$current_key = (object) array( 'views' => 0 ); - } - - $result->$current_key->views += $current_views; - } - } - - // Add direct and total views to the object. - $result->direct->views = $this->total_views - $total_referrer_views; - $result->totals = (object) array( 'views' => $this->total_views ); - - // Remove referrer types without views. - foreach ( $referrer_type_keys as $key ) { - if ( 0 === $result->$key->views ) { - unset( $result->$key ); - } - } - - // Set percentage values and format numbers. - // @phpstan-ignore-next-line. - foreach ( $result as $key => $value ) { - // Set and format percentage values. - $result->{ $key }->viewsPercentage = $this->get_i18n_percentage( - absint( $value->views ), - $this->total_views - ); - - // Format views values. - $result->{ $key }->views = number_format_i18n( $result->{ $key }->views ); - } - - return $result; - } - - /** - * Generates the top referrers data. - * - * Returned object properties: - * - `views`: The number of views. - * - `viewPercentage`: The number of views as a percentage, compared to the - * total views of all referrer types. - * - `datasetViewsPercentage: The number of views as a percentage, compared - * to the total views of the current dataset. - * - * @since 3.6.0 - * - * @param int $limit The limit of returned referrers. - * @param array $response The response received by the proxy. - * @param int $direct_views The count of direct views. - * @return stdClass The generated data. - */ - private function generate_referrers_data( - int $limit, - array $response, - int $direct_views - ): stdClass { - $temp_views = array(); - $totals = 0; - $referrer_count = count( $response ); - - // Set views and views totals. - $loop_count = $referrer_count > $limit ? $limit : $referrer_count; - for ( $i = 0; $i < $loop_count; $i++ ) { - $data = $response[ $i ]; - - /** - * Variable. - * - * @var int - */ - $referrer_views = $data->metrics->referrers_views ?? 0; - $totals += $referrer_views; - if ( isset( $data->name ) ) { - $temp_views[ $data->name ] = $referrer_views; - } - } - - // If applicable, add the direct views. - if ( isset( $referrer_views ) && $direct_views >= $referrer_views ) { - $temp_views['direct'] = $direct_views; - $totals += $direct_views; - arsort( $temp_views ); - if ( count( $temp_views ) > $limit ) { - $totals -= array_pop( $temp_views ); - } - } - - // Convert temporary array to result object and add totals. - $result = new stdClass(); - foreach ( $temp_views as $key => $value ) { - $result->$key = (object) array( 'views' => $value ); - } - $result->totals = (object) array( 'views' => $totals ); - - // Set percentages values and format numbers. - // @phpstan-ignore-next-line. - foreach ( $result as $key => $value ) { - // Percentage against all referrer views, even those not included - // in the dataset due to the $limit argument. - $result->{ $key }->viewsPercentage = $this - ->get_i18n_percentage( absint( $value->views ), $this->total_views ); - - // Percentage against the current dataset that is limited due to the - // $limit argument. - $result->{ $key }->datasetViewsPercentage = $this - ->get_i18n_percentage( absint( $value->views ), $totals ); - - // Format views values. - $result->{ $key }->views = number_format_i18n( $result->{ $key }->views ); - } - - return $result; - } - - /** - * Returns the passed number compared to the passed total, in an - * internationalized percentage format. - * - * @since 3.6.0 - * - * @param int $number The number to be calculated as a percentage. - * @param int $total The total number to compare against. - * @return string|false The internationalized percentage or false on error. - */ - private function get_i18n_percentage( int $number, int $total ) { - if ( 0 === $total ) { - return false; - } - - return number_format_i18n( $number / $total * 100, 2 ); - } -} diff --git a/src/Endpoints/class-related-api-proxy.php b/src/Endpoints/class-related-api-proxy.php deleted file mode 100644 index 983536362..000000000 --- a/src/Endpoints/class-related-api-proxy.php +++ /dev/null @@ -1,61 +0,0 @@ -register_endpoint( '/related' ); - } - - /** - * Cached "proxy" to the Parse.ly `/related` API endpoint. - * - * @param WP_REST_Request $request The request object. - * @return stdClass|WP_Error stdClass containing the data or a WP_Error object on failure. - */ - public function get_items( WP_REST_Request $request ) { - return $this->get_data( $request, false, 'query' ); - } - - /** - * Generates the final data from the passed response. - * - * @param array $response The response received by the proxy. - * @return array The generated data. - */ - protected function generate_data( $response ): array { - $itm_source = $this->itm_source; - - return array_map( - static function ( stdClass $item ) use ( $itm_source ) { - return (object) array( - 'image_url' => $item->image_url, - 'thumb_url_medium' => $item->thumb_url_medium, - 'title' => $item->title, - 'url' => Parsely::get_url_with_itm_source( $item->url, $itm_source ), - ); - }, - $response - ); - } -} diff --git a/tests/Integration/Endpoints/Proxy/AnalyticsPostsProxyEndpointTest.php b/tests/Integration/Endpoints/Proxy/AnalyticsPostsProxyEndpointTest.php deleted file mode 100644 index b0a7c366b..000000000 --- a/tests/Integration/Endpoints/Proxy/AnalyticsPostsProxyEndpointTest.php +++ /dev/null @@ -1,264 +0,0 @@ -dispatch( - new WP_REST_Request( 'GET', self::$route ) - ); - /** - * Variable. - * - * @var WP_Error - */ - $error = $response->as_error(); - - self::assertSame( 401, $response->get_status() ); - self::assertSame( 'rest_forbidden', $error->get_error_code() ); - self::assertSame( - 'Sorry, you are not allowed to do that.', - $error->get_error_message() - ); - } - - /** - * Verifies that calling `GET /wp-parsely/v1/stats/posts` returns an - * error and does not perform a remote call when the Site ID is not populated - * in site options. - * - * @covers \Parsely\Endpoints\Analytics_Posts_API_Proxy::get_items - * @uses \Parsely\Endpoints\Analytics_Posts_API_Proxy::__construct - * @uses \Parsely\Endpoints\Analytics_Posts_API_Proxy::is_available_to_current_user - * @uses \Parsely\Endpoints\Analytics_Posts_API_Proxy::run - * @uses \Parsely\Parsely::site_id_is_missing - * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Parsely::get_options - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\Endpoints\Base_API_Proxy::get_data - * @uses \Parsely\Endpoints\Base_API_Proxy::register_endpoint - */ - public function test_get_items_fails_when_site_id_is_not_set(): void { - $this->set_current_user_to_admin(); - parent::run_test_get_items_fails_without_site_id_set(); - } - - /** - * Verifies that calling `GET /wp-parsely/v1/stats/posts` returns an - * error and does not perform a remote call when the API Secret is not - * populated in site options. - * - * @covers \Parsely\Endpoints\Analytics_Posts_API_Proxy::get_items - * @uses \Parsely\Endpoints\Analytics_Posts_API_Proxy::__construct - * @uses \Parsely\Endpoints\Analytics_Posts_API_Proxy::is_available_to_current_user - * @uses \Parsely\Endpoints\Analytics_Posts_API_Proxy::run - * @uses \Parsely\Parsely::site_id_is_missing - * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Parsely::api_secret_is_set - * @uses \Parsely\Parsely::get_options - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\Endpoints\Base_API_Proxy::get_data - * @uses \Parsely\Endpoints\Base_API_Proxy::register_endpoint - */ - public function test_get_items_fails_when_api_secret_is_not_set(): void { - $this->set_current_user_to_admin(); - parent::run_test_get_items_fails_without_api_secret_set(); - } - - /** - * Verifies default user capability filter. - * - * @covers \Parsely\Endpoints\Analytics_Posts_API_Proxy::is_available_to_current_user - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\RemoteAPI\Analytics_Posts_API::is_available_to_current_user - */ - public function test_user_is_allowed_to_make_proxy_api_call_if_default_user_capability_is_changed(): void { - parent::run_test_user_is_allowed_to_make_proxy_api_call_if_default_user_capability_is_changed(); - } - - /** - * Verifies endpoint specific user capability filter. - * - * @covers \Parsely\Endpoints\Analytics_Posts_API_Proxy::is_available_to_current_user - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\RemoteAPI\Analytics_Posts_API::is_available_to_current_user - */ - public function test_user_is_allowed_to_make_proxy_api_call_if_endpoint_specific_user_capability_is_changed(): void { - parent::run_test_user_is_allowed_to_make_proxy_api_call_if_endpoint_specific_user_capability_is_changed( 'analytics_posts' ); - } - - /** - * Verifies that calls to `GET /wp-parsely/v1/stats/posts` return - * results in the expected format. - * - * @covers \Parsely\Endpoints\Analytics_Posts_API_Proxy::get_items - * @uses \Parsely\Endpoints\Analytics_Posts_API_Proxy::__construct - * @uses \Parsely\Endpoints\Analytics_Posts_API_Proxy::generate_data - * @uses \Parsely\Endpoints\Analytics_Posts_API_Proxy::is_available_to_current_user - * @uses \Parsely\Endpoints\Analytics_Posts_API_Proxy::run - * @uses \Parsely\Endpoints\Base_API_Proxy::get_data - * @uses \Parsely\Endpoints\Base_API_Proxy::register_endpoint - * @uses \Parsely\Parsely::site_id_is_missing - * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Parsely::api_secret_is_set - * @uses \Parsely\Parsely::get_site_id - * @uses \Parsely\Parsely::get_api_secret - * @uses \Parsely\Parsely::get_options - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_api_url - * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_items - * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_request_options - */ - public function test_get_items(): void { - $this->set_current_user_to_admin(); - TestCase::set_options( - array( - 'apikey' => 'example.com', - 'api_secret' => 'test', - ) - ); - - $dispatched = 0; - $date_format = Utils::get_date_format(); - - add_filter( - 'pre_http_request', - function () use ( &$dispatched ): array { - $dispatched++; - return array( - 'body' => '{"data":[ - { - "author": "Aakash Shah", - "metrics": {"views": 142}, - "pub_date": "2020-04-06T13:30:58", - "thumb_url_medium": "https://images.parsely.com/XCmTXuOf8yVbUYTxj2abQ4RSDkM=/85x85/smart/https%3A//blog.parse.ly/wp-content/uploads/2021/06/Web-Analytics-Tool.png%3Fw%3D150%26h%3D150%26crop%3D1", - "title": "9 Types of Web Analytics Tools \u2014 And How to Know Which Ones You Really Need", - "url": "https://blog.parse.ly/web-analytics-software-tools/?itm_source=parsely-api" - }, - { - "author": "Stephanie Schwartz and Andrew Butler", - "metrics": {"views": 40}, - "pub_date": "2021-04-30T20:30:24", - "thumb_url_medium": "https://images.parsely.com/ap3YSufqxnLpz6zzQshoks3snXI=/85x85/smart/https%3A//blog.parse.ly/wp-content/uploads/2021/05/pexels-brett-jordan-998501-1024x768-2.jpeg%3Fw%3D150%26h%3D150%26crop%3D1", - "title": "5 Tagging Best Practices For Getting the Most Out of Your Content Strategy", - "url": "https://blog.parse.ly/5-tagging-best-practices-content-strategy/?itm_source=parsely-api" - } - ]}', - ); - } - ); - - $rest_request = new WP_REST_Request( 'GET', '/wp-parsely/v1/stats/posts' ); - $rest_request->set_param( 'itm_source', 'wp-parsely-content-helper' ); - - $response = rest_get_server()->dispatch( $rest_request ); - - self::assertSame( 1, $dispatched ); - self::assertSame( 200, $response->get_status() ); - self::assertEquals( - (object) array( - 'data' => array( - (object) array( - 'author' => 'Aakash Shah', - 'date' => wp_date( $date_format, strtotime( '2020-04-06T13:30:58' ) ), - 'id' => 'https://blog.parse.ly/web-analytics-software-tools/', - 'dashUrl' => PARSELY::DASHBOARD_BASE_URL . '/example.com/find?url=https%3A%2F%2Fblog.parse.ly%2Fweb-analytics-software-tools%2F', - 'thumbnailUrl' => 'https://images.parsely.com/XCmTXuOf8yVbUYTxj2abQ4RSDkM=/85x85/smart/https%3A//blog.parse.ly/wp-content/uploads/2021/06/Web-Analytics-Tool.png%3Fw%3D150%26h%3D150%26crop%3D1', - 'title' => '9 Types of Web Analytics Tools — And How to Know Which Ones You Really Need', - 'url' => 'https://blog.parse.ly/web-analytics-software-tools/?itm_source=wp-parsely-content-helper', - 'views' => '142', - 'postId' => 0, - 'rawUrl' => 'https://blog.parse.ly/web-analytics-software-tools/', - ), - (object) array( - 'author' => 'Stephanie Schwartz and Andrew Butler', - 'date' => wp_date( $date_format, strtotime( '2021-04-30T20:30:24' ) ), - 'id' => 'https://blog.parse.ly/5-tagging-best-practices-content-strategy/', - 'dashUrl' => PARSELY::DASHBOARD_BASE_URL . '/example.com/find?url=https%3A%2F%2Fblog.parse.ly%2F5-tagging-best-practices-content-strategy%2F', - 'thumbnailUrl' => 'https://images.parsely.com/ap3YSufqxnLpz6zzQshoks3snXI=/85x85/smart/https%3A//blog.parse.ly/wp-content/uploads/2021/05/pexels-brett-jordan-998501-1024x768-2.jpeg%3Fw%3D150%26h%3D150%26crop%3D1', - 'title' => '5 Tagging Best Practices For Getting the Most Out of Your Content Strategy', - 'url' => 'https://blog.parse.ly/5-tagging-best-practices-content-strategy/?itm_source=wp-parsely-content-helper', - 'views' => '40', - 'postId' => 0, - 'rawUrl' => 'https://blog.parse.ly/5-tagging-best-practices-content-strategy/', - ), - ), - ), - $response->get_data() - ); - } -} diff --git a/tests/Integration/Endpoints/Proxy/ReferrersPostDetailProxyEndpointTest.php b/tests/Integration/Endpoints/Proxy/ReferrersPostDetailProxyEndpointTest.php deleted file mode 100644 index 38ec499a4..000000000 --- a/tests/Integration/Endpoints/Proxy/ReferrersPostDetailProxyEndpointTest.php +++ /dev/null @@ -1,305 +0,0 @@ -set_current_user_to_admin(); - parent::run_test_get_items_fails_without_site_id_set(); - } - - /** - * Verifies that calling `GET /wp-parsely/v1/referrers/post/detail` returns - * an error and does not perform a remote call when the Site ID is not - * populated in site options. - * - * @covers \Parsely\Endpoints\Referrers_Post_Detail_API_Proxy::get_items - * @uses \Parsely\Endpoints\Base_API_Proxy::get_data - * @uses \Parsely\Endpoints\Base_API_Proxy::register_endpoint - * @uses \Parsely\Endpoints\Referrers_Post_Detail_API_Proxy::__construct - * @uses \Parsely\Endpoints\Referrers_Post_Detail_API_Proxy::is_available_to_current_user - * @uses \Parsely\Endpoints\Referrers_Post_Detail_API_Proxy::run - * @uses \Parsely\Parsely::site_id_is_missing - * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Parsely::api_secret_is_set - * @uses \Parsely\Parsely::get_options - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - */ - public function test_get_items_fails_when_api_secret_is_not_set(): void { - $this->set_current_user_to_admin(); - parent::run_test_get_items_fails_without_api_secret_set(); - } - - /** - * Verifies default user capability filter. - * - * @covers \Parsely\Endpoints\Referrers_Post_Detail_API_Proxy::is_available_to_current_user - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\RemoteAPI\Referrers_Post_Detail_API::is_available_to_current_user - */ - public function test_user_is_allowed_to_make_proxy_api_call_if_default_user_capability_is_changed(): void { - parent::run_test_user_is_allowed_to_make_proxy_api_call_if_default_user_capability_is_changed(); - } - - /** - * Verifies endpoint specific user capability filter. - * - * @covers \Parsely\Endpoints\Referrers_Post_Detail_API_Proxy::is_available_to_current_user - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\RemoteAPI\Referrers_Post_Detail_API::is_available_to_current_user - */ - public function test_user_is_allowed_to_make_proxy_api_call_if_endpoint_specific_user_capability_is_changed(): void { - parent::run_test_user_is_allowed_to_make_proxy_api_call_if_endpoint_specific_user_capability_is_changed(); - } - - /** - * Verifies that calls to `GET /wp-parsely/v1/referrers/post/detail` return - * results in the expected format. - * - * @covers \Parsely\Endpoints\Referrers_Post_Detail_API_Proxy::get_items - * @uses \Parsely\Endpoints\Base_API_Proxy::get_data - * @uses \Parsely\Endpoints\Base_API_Proxy::register_endpoint - * @uses \Parsely\Endpoints\Referrers_Post_Detail_API_Proxy::__construct - * @uses \Parsely\Endpoints\Referrers_Post_Detail_API_Proxy::generate_data - * @uses \Parsely\Endpoints\Referrers_Post_Detail_API_Proxy::is_available_to_current_user - * @uses \Parsely\Endpoints\Referrers_Post_Detail_API_Proxy::run - * @uses \Parsely\Parsely::site_id_is_missing - * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Parsely::api_secret_is_set - * @uses \Parsely\Parsely::get_site_id - * @uses \Parsely\Parsely::get_options - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_api_url - * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_items - * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_request_options - */ - public function test_get_items(): void { - $this->set_current_user_to_admin(); - TestCase::set_options( - array( - 'apikey' => 'example.com', - 'api_secret' => 'test', - ) - ); - - $dispatched = 0; - - add_filter( - 'pre_http_request', - function () use ( &$dispatched ): array { - $dispatched++; - return array( - 'body' => '{"data":[ - { - "metrics": {"referrers_views": 1500}, - "name": "google", - "type": "search" - }, - { - "metrics": {"referrers_views": 100}, - "name": "blog.parse.ly", - "type": "internal" - }, - { - "metrics": {"referrers_views": 50}, - "name": "bing", - "type": "search" - }, - { - "metrics": {"referrers_views": 30}, - "name": "facebook.com", - "type": "social" - }, - { - "metrics": {"referrers_views": 10}, - "name": "okt.to", - "type": "other" - }, - { - "metrics": {"referrers_views": 10}, - "name": "yandex", - "type": "search" - }, - { - "metrics": {"referrers_views": 10}, - "name": "parse.ly", - "type": "internal" - }, - { - "metrics": {"referrers_views": 10}, - "name": "yahoo!", - "type": "search" - }, - { - "metrics": {"referrers_views": 5}, - "name": "site1.com", - "type": "other" - }, - { - "metrics": {"referrers_views": 5}, - "name": "link.site2.com", - "type": "other" - } - ]}', - ); - } - ); - - $expected_top = (object) array( - 'direct' => (object) array( - 'views' => '770', - 'viewsPercentage' => '30.80', - 'datasetViewsPercentage' => '31.43', - ), - 'google' => (object) array( - 'views' => '1,500', - 'viewsPercentage' => '60.00', - 'datasetViewsPercentage' => '61.22', - ), - 'blog.parse.ly' => (object) array( - 'views' => '100', - 'viewsPercentage' => '4.00', - 'datasetViewsPercentage' => '4.08', - ), - 'bing' => (object) array( - 'views' => '50', - 'viewsPercentage' => '2.00', - 'datasetViewsPercentage' => '2.04', - ), - 'facebook.com' => (object) array( - 'views' => '30', - 'viewsPercentage' => '1.20', - 'datasetViewsPercentage' => '1.22', - ), - 'totals' => (object) array( - 'views' => '2,450', - 'viewsPercentage' => '98.00', - 'datasetViewsPercentage' => '100.00', - ), - ); - - $expected_types = (object) array( - 'social' => (object) array( - 'views' => '30', - 'viewsPercentage' => '1.20', - ), - 'search' => (object) array( - 'views' => '1,570', - 'viewsPercentage' => '62.80', - ), - 'other' => (object) array( - 'views' => '20', - 'viewsPercentage' => '0.80', - ), - 'internal' => (object) array( - 'views' => '110', - 'viewsPercentage' => '4.40', - ), - 'direct' => (object) array( - 'views' => '770', - 'viewsPercentage' => '30.80', - ), - 'totals' => (object) array( - 'views' => '2,500', - 'viewsPercentage' => '100.00', - ), - ); - - $request = new WP_REST_Request( 'GET', self::$route ); - $request->set_param( 'total_views', '2,500' ); - - $response = rest_get_server()->dispatch( $request ); - - self::assertSame( 1, $dispatched ); - self::assertSame( 200, $response->get_status() ); - self::assertEquals( - (object) array( - 'data' => array( - 'top' => $expected_top, - 'types' => $expected_types, - ), - ), - $response->get_data() - ); - } -} diff --git a/tests/Integration/Endpoints/Proxy/RelatedProxyEndpointTest.php b/tests/Integration/Endpoints/Proxy/RelatedProxyEndpointTest.php deleted file mode 100644 index 7584fa597..000000000 --- a/tests/Integration/Endpoints/Proxy/RelatedProxyEndpointTest.php +++ /dev/null @@ -1,162 +0,0 @@ - 'example.com' ) ); - - $dispatched = 0; - - add_filter( - 'pre_http_request', - function () use ( &$dispatched ): array { - $dispatched++; - return array( - 'body' => '{"data":[ - { - "image_url":"https:\/\/example.com\/img.png", - "thumb_url_medium":"https:\/\/example.com\/thumb.png", - "title":"something", - "url":"https:\/\/example.com" - }, - { - "image_url":"https:\/\/example.com\/img2.png", - "thumb_url_medium":"https:\/\/example.com\/thumb2.png", - "title":"something2", - "url":"https:\/\/example.com\/2" - } - ]}', - ); - } - ); - - $response = rest_get_server()->dispatch( new WP_REST_Request( 'GET', '/wp-parsely/v1/related' ) ); - - self::assertSame( 1, $dispatched ); - self::assertSame( 200, $response->get_status() ); - self::assertEquals( - (object) array( - 'data' => array( - (object) array( - 'image_url' => 'https://example.com/img.png', - 'thumb_url_medium' => 'https://example.com/thumb.png', - 'title' => 'something', - 'url' => 'https://example.com', - ), - (object) array( - 'image_url' => 'https://example.com/img2.png', - 'thumb_url_medium' => 'https://example.com/thumb2.png', - 'title' => 'something2', - 'url' => 'https://example.com/2', - ), - ), - ), - $response->get_data() - ); - } -} diff --git a/tests/Integration/Endpoints/Proxy/StatsPostDetailProxyEndpointTest.php b/tests/Integration/Endpoints/Proxy/StatsPostDetailProxyEndpointTest.php deleted file mode 100644 index c442d098a..000000000 --- a/tests/Integration/Endpoints/Proxy/StatsPostDetailProxyEndpointTest.php +++ /dev/null @@ -1,206 +0,0 @@ -set_current_user_to_admin(); - parent::run_test_get_items_fails_without_site_id_set(); - } - - /** - * Verifies that calling `GET /wp-parsely/v1/analytics/post/detail` returns - * an error and does not perform a remote call when the Site ID is not - * populated in site options. - * - * @covers \Parsely\Endpoints\Analytics_Post_Detail_API_Proxy::get_items - * @uses \Parsely\Endpoints\Base_API_Proxy::get_data - * @uses \Parsely\Endpoints\Base_API_Proxy::register_endpoint - * @uses \Parsely\Endpoints\Analytics_Post_Detail_API_Proxy::__construct - * @uses \Parsely\Endpoints\Analytics_Post_Detail_API_Proxy::is_available_to_current_user - * @uses \Parsely\Endpoints\Analytics_Post_Detail_API_Proxy::run - * @uses \Parsely\Parsely::site_id_is_missing - * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Parsely::api_secret_is_set - * @uses \Parsely\Parsely::get_options - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - */ - public function test_get_items_fails_when_api_secret_is_not_set(): void { - $this->set_current_user_to_admin(); - parent::run_test_get_items_fails_without_api_secret_set(); - } - - /** - * Verifies default user capability filter. - * - * @covers \Parsely\Endpoints\Analytics_Post_Detail_API_Proxy::is_available_to_current_user - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - */ - public function test_user_is_allowed_to_make_proxy_api_call_if_default_user_capability_is_changed(): void { - parent::run_test_user_is_allowed_to_make_proxy_api_call_if_default_user_capability_is_changed(); - } - - /** - * Verifies endpoint specific user capability filter. - * - * @covers \Parsely\Endpoints\Analytics_Post_Detail_API_Proxy::is_available_to_current_user - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - */ - public function test_user_is_allowed_to_make_proxy_api_call_if_endpoint_specific_user_capability_is_changed(): void { - parent::run_test_user_is_allowed_to_make_proxy_api_call_if_endpoint_specific_user_capability_is_changed( 'analytics_post_detail' ); - } - - /** - * Verifies that calls to `GET /wp-parsely/v1/analytics/post/detail` return - * results in the expected format. - * - * @covers \Parsely\Endpoints\Analytics_Post_Detail_API_Proxy::get_items - * @uses \Parsely\Endpoints\Base_API_Proxy::get_data - * @uses \Parsely\Endpoints\Base_API_Proxy::register_endpoint - * @uses \Parsely\Endpoints\Analytics_Post_Detail_API_Proxy::__construct - * @uses \Parsely\Endpoints\Analytics_Post_Detail_API_Proxy::generate_data - * @uses \Parsely\Endpoints\Analytics_Post_Detail_API_Proxy::is_available_to_current_user - * @uses \Parsely\Endpoints\Analytics_Post_Detail_API_Proxy::run - * @uses \Parsely\Parsely::site_id_is_missing - * @uses \Parsely\Parsely::site_id_is_set - * @uses \Parsely\Parsely::api_secret_is_set - * @uses \Parsely\Parsely::get_site_id - * @uses \Parsely\Parsely::get_options - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_api_url - * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_items - * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_request_options - */ - public function test_get_items(): void { - $this->set_current_user_to_admin(); - TestCase::set_options( - array( - 'apikey' => 'example.com', - 'api_secret' => 'test', - ) - ); - - $dispatched = 0; - - add_filter( - 'pre_http_request', - function () use ( &$dispatched ): array { - $dispatched++; - return array( - 'body' => ' - {"data":[{ - "avg_engaged": 1.911, - "metrics": { - "views": 2158, - "visitors": 1537 - }, - "url": "https://example.com" - }]} - ', - ); - } - ); - - $response = rest_get_server()->dispatch( new WP_REST_Request( 'GET', '/wp-parsely/v1/stats/post/detail' ) ); - - self::assertSame( 1, $dispatched ); - self::assertSame( 200, $response->get_status() ); - self::assertEquals( - (object) array( - 'data' => array( - (object) array( - 'avgEngaged' => '1:55', - 'dashUrl' => Parsely::DASHBOARD_BASE_URL . '/example.com/find?url=https%3A%2F%2Fexample.com', - 'id' => 'https://example.com', - 'postId' => 0, - 'url' => 'https://example.com', - 'views' => '2,158', - 'visitors' => '1,537', - 'rawUrl' => 'https://example.com', - ), - ), - ), - $response->get_data() - ); - } -} diff --git a/wp-parsely.php b/wp-parsely.php index ae8e31331..cf5012bef 100644 --- a/wp-parsely.php +++ b/wp-parsely.php @@ -132,37 +132,12 @@ function parsely_wp_admin_early_register(): void { * @since 3.2.0 */ function parsely_rest_api_init(): void { - $wp_cache = new WordPress_Cache(); - $rest = new Rest_Metadata( $GLOBALS['parsely'] ); + $rest = new Rest_Metadata( $GLOBALS['parsely'] ); $rest->run(); // Content Helper settings endpoints. ( new Dashboard_Widget_Settings_Endpoint( $GLOBALS['parsely'] ) )->run(); ( new Editor_Sidebar_Settings_Endpoint( $GLOBALS['parsely'] ) )->run(); - - parsely_run_rest_api_endpoint( - Related_API::class, - Related_API_Proxy::class, - $wp_cache - ); - - parsely_run_rest_api_endpoint( - Analytics_Posts_API::class, - Analytics_Posts_API_Proxy::class, - $wp_cache - ); - - parsely_run_rest_api_endpoint( - Analytics_Post_Detail_API::class, - Analytics_Post_Detail_API_Proxy::class, - $wp_cache - ); - - parsely_run_rest_api_endpoint( - Referrers_Post_Detail_API::class, - Referrers_Post_Detail_API_Proxy::class, - $wp_cache - ); } add_action( 'init', __NAMESPACE__ . '\\init_recommendations_block' ); From 5978a36710fef5ab54ca76770aaff2860589ad45 Mon Sep 17 00:00:00 2001 From: Henrique Mouta Date: Thu, 29 Aug 2024 13:08:50 +0100 Subject: [PATCH 065/282] Add tests --- src/rest-api/stats/class-endpoint-related.php | 6 +- src/rest-api/stats/trait-post-data.php | 7 +- .../Integration/RestAPI/BaseEndpointTest.php | 12 + .../ContentHelperControllerTest.php | 27 +- .../ContentHelperFeatureTestTrait.php | 11 +- .../EndpointExcerptGeneratorTest.php | 23 +- .../EndpointSmartLinkingTest.php | 43 +- .../EndpointTitleSuggestionsTest.php | 11 +- .../RestAPI/Stats/EndpointPostTest.php | 674 ++++++++++++++++++ .../RestAPI/Stats/EndpointPostsTest.php | 347 +++++++++ .../RestAPI/Stats/EndpointRelatedTest.php | 316 ++++++++ .../RestAPI/Stats/StatsControllerTest.php | 60 ++ 12 files changed, 1483 insertions(+), 54 deletions(-) create mode 100644 tests/Integration/RestAPI/Stats/EndpointPostTest.php create mode 100644 tests/Integration/RestAPI/Stats/EndpointPostsTest.php create mode 100644 tests/Integration/RestAPI/Stats/EndpointRelatedTest.php create mode 100644 tests/Integration/RestAPI/Stats/StatsControllerTest.php diff --git a/src/rest-api/stats/class-endpoint-related.php b/src/rest-api/stats/class-endpoint-related.php index d675e9e92..d636957b8 100644 --- a/src/rest-api/stats/class-endpoint-related.php +++ b/src/rest-api/stats/class-endpoint-related.php @@ -104,9 +104,9 @@ public function get_related_posts( WP_REST_Request $request ) { * @since 3.17.0 * * @param WP_REST_Request|null $request The request object. - * @return bool + * @return bool|WP_Error */ - public function is_available_to_current_user( ?WP_REST_Request $request = null ): bool { - return true; + public function is_available_to_current_user( ?WP_REST_Request $request = null ) { + return $this->validate_site_id_and_secret( false ); } } diff --git a/src/rest-api/stats/trait-post-data.php b/src/rest-api/stats/trait-post-data.php index 4698d2a9a..0ccb0a087 100644 --- a/src/rest-api/stats/trait-post-data.php +++ b/src/rest-api/stats/trait-post-data.php @@ -66,10 +66,9 @@ private function set_itm_source_from_request( WP_REST_Request $request ): void { private function get_itm_source_param_args(): array { return array( 'itm_source' => array( - 'description' => __( 'The source of the item.', 'wp-parsely' ), - 'type' => 'string', - 'required' => false, - 'validate_callback' => array( $this, 'validate_itm_source' ), + 'description' => __( 'The source of the item.', 'wp-parsely' ), + 'type' => 'string', + 'required' => false, ), ); } diff --git a/tests/Integration/RestAPI/BaseEndpointTest.php b/tests/Integration/RestAPI/BaseEndpointTest.php index f43753184..00f2f7bb8 100644 --- a/tests/Integration/RestAPI/BaseEndpointTest.php +++ b/tests/Integration/RestAPI/BaseEndpointTest.php @@ -238,11 +238,19 @@ public function test_route_is_registered(): void { * @uses \Parsely\REST_API\Base_API_Controller::__construct * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Base_API_Controller::get_route_prefix * @uses \Parsely\REST_API\Base_Endpoint::__construct * @uses \Parsely\REST_API\Base_Endpoint::get_endpoint_name * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters + * @uses \Parsely\REST_API\Base_Endpoint::get_default_access_capability + * @uses \Parsely\REST_API\Content_Helper\Content_Helper_Controller::get_route_prefix + * @uses \Parsely\REST_API\Stats\Stats_Controller::get_route_prefix * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_endpoint_is_registered_based_on_filter(): void { @@ -285,6 +293,7 @@ public function test_endpoint_is_registered_based_on_filter(): void { * @covers \Parsely\REST_API\Base_Endpoint::is_available_to_current_user * @covers \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely * @uses \Parsely\Parsely::__construct * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::are_credentials_managed @@ -324,6 +333,7 @@ public function test_is_available_to_current_user_returns_error_site_id_not_set( * @covers \Parsely\REST_API\Base_Endpoint::is_available_to_current_user * @covers \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely * @uses \Parsely\Parsely::__construct * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::api_secret_is_set @@ -361,6 +371,7 @@ public function test_is_available_to_current_user_returns_error_api_secret_not_s * * @covers \Parsely\REST_API\Base_Endpoint::apply_capability_filters * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key * @uses \Parsely\Parsely::__construct * @uses \Parsely\Parsely::allow_parsely_remote_requests @@ -387,6 +398,7 @@ function () { * * @covers \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely * @uses \Parsely\Parsely::__construct * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::api_secret_is_set diff --git a/tests/Integration/RestAPI/ContentHelper/ContentHelperControllerTest.php b/tests/Integration/RestAPI/ContentHelper/ContentHelperControllerTest.php index 5b22320e8..944dd6b81 100644 --- a/tests/Integration/RestAPI/ContentHelper/ContentHelperControllerTest.php +++ b/tests/Integration/RestAPI/ContentHelper/ContentHelperControllerTest.php @@ -55,6 +55,8 @@ public function set_up(): void { * * @covers \Parsely\REST_API\Content_Helper\Content_Helper_Controller::__construct * @uses \Parsely\REST_API\Content_Helper\Content_Helper_Controller::get_full_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version */ public function test_constructor_sets_up_namespace_and_version(): void { self::assertEquals( 'wp-parsely/v2', $this->content_helper_controller->get_full_namespace() ); @@ -77,16 +79,21 @@ public function test_route_prefix(): void { * @since 3.17.0 * * @covers \Parsely\REST_API\Content_Helper\Content_Helper_Controller::init - * @uses \Parsely\REST_API\Content_Helper\Content_Helper_Controller::register_endpoints - * @uses Parsely\Endpoints\Base_Endpoint::__construct - * @uses Parsely\REST_API\Base_API_Controller::__construct - * @uses Parsely\REST_API\Base_API_Controller::register_endpoint - * @uses Parsely\REST_API\Base_Endpoint::__construct - * @uses Parsely\REST_API\Base_Endpoint::init - * @uses Parsely\REST_API\Content_Helper\Excerpt_Generator_Endpoint::__construct - * @uses Parsely\REST_API\Content_Helper\Smart_Linking_Endpoint::__construct - * @uses Parsely\REST_API\Content_Helper\Title_Suggestions_Endpoint::__construct - * @uses Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_endpoints + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::register_endpoint + * @uses \Parsely\REST_API\Base_API_Controller::register_endpoints + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Content_Helper\Endpoint_Excerpt_Generator::__construct + * @uses \Parsely\REST_API\Content_Helper\Endpoint_Excerpt_Generator::get_endpoint_name + * @uses \Parsely\REST_API\Content_Helper\Endpoint_Smart_Linking::__construct + * @uses \Parsely\REST_API\Content_Helper\Endpoint_Smart_Linking::get_endpoint_name + * @uses \Parsely\REST_API\Content_Helper\Endpoint_Title_Suggestions::__construct + * @uses \Parsely\REST_API\Content_Helper\Endpoint_Title_Suggestions::get_endpoint_name + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_init_registers_endpoints(): void { $this->content_helper_controller->init(); diff --git a/tests/Integration/RestAPI/ContentHelper/ContentHelperFeatureTestTrait.php b/tests/Integration/RestAPI/ContentHelper/ContentHelperFeatureTestTrait.php index 32e859dbb..878cbdd44 100644 --- a/tests/Integration/RestAPI/ContentHelper/ContentHelperFeatureTestTrait.php +++ b/tests/Integration/RestAPI/ContentHelper/ContentHelperFeatureTestTrait.php @@ -190,18 +190,21 @@ public function test_is_available_to_current_user_returns_error_if_no_permission * * @covers \Parsely\REST_API\Content_Helper\Content_Helper_Feature::is_available_to_current_user * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\Parsely::__construct - * @uses \Parsely\Parsely::allow_parsely_remote_requests - * @uses \Parsely\Parsely::are_credentials_managed + * @uses \Parsely\Parsely::api_secret_is_set * @uses \Parsely\Parsely::get_managed_credentials * @uses \Parsely\Parsely::get_options * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts - * @uses \Parsely\Parsely::set_managed_options + * @uses \Parsely\Parsely::site_id_is_set * @uses \Parsely\Permissions::current_user_can_use_pch_feature * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters + * @uses \Parsely\REST_API\Base_Endpoint::get_default_access_capability * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_is_available_to_current_user_returns_error_if_no_user(): void { diff --git a/tests/Integration/RestAPI/ContentHelper/EndpointExcerptGeneratorTest.php b/tests/Integration/RestAPI/ContentHelper/EndpointExcerptGeneratorTest.php index a7eb36d77..08f07e046 100644 --- a/tests/Integration/RestAPI/ContentHelper/EndpointExcerptGeneratorTest.php +++ b/tests/Integration/RestAPI/ContentHelper/EndpointExcerptGeneratorTest.php @@ -68,29 +68,28 @@ public function get_endpoint(): \Parsely\REST_API\Base_Endpoint { * * @covers \Parsely\REST_API\Content_Helper\Endpoint_Excerpt_Generator::register_routes * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\Parsely::__construct - * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::api_secret_is_set - * @uses \Parsely\Parsely::are_credentials_managed * @uses \Parsely\Parsely::get_managed_credentials * @uses \Parsely\Parsely::get_options * @uses \Parsely\Parsely::set_default_content_helper_settings_values * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts - * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set * @uses \Parsely\Permissions::build_pch_permissions_settings_array * @uses \Parsely\Permissions::current_user_can_use_pch_feature * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap * @uses \Parsely\REST_API\Base_API_Controller::__construct * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely * @uses \Parsely\REST_API\Base_API_Controller::prefix_route * @uses \Parsely\REST_API\Base_Endpoint::__construct - * @uses \Parsely\REST_API\Base_Endpoint::get_endpoint_name * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint * @uses \Parsely\REST_API\Base_Endpoint::init * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\REST_API\Content_Helper\Content_Helper_Controller::get_route_prefix + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_route_is_registered(): void { @@ -114,12 +113,11 @@ public function test_route_is_registered(): void { * * @covers \Parsely\REST_API\Content_Helper\Endpoint_Excerpt_Generator::generate_excerpt * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\Parsely::__construct - * @uses \Parsely\Parsely::allow_parsely_remote_requests - * @uses \Parsely\Parsely::are_credentials_managed - * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_generate_excerpt_returns_valid_response(): void { // Mock the Suggest_Brief_API to control the response. @@ -160,12 +158,11 @@ public function test_generate_excerpt_returns_valid_response(): void { * * @covers \Parsely\REST_API\Content_Helper\Endpoint_Excerpt_Generator::generate_excerpt * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\Parsely::__construct - * @uses \Parsely\Parsely::allow_parsely_remote_requests - * @uses \Parsely\Parsely::are_credentials_managed - * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_generate_excerpt_returns_error_on_failure(): void { // Mock the Suggest_Brief_API to simulate a failure. diff --git a/tests/Integration/RestAPI/ContentHelper/EndpointSmartLinkingTest.php b/tests/Integration/RestAPI/ContentHelper/EndpointSmartLinkingTest.php index 99b9c5c10..9fd983fef 100644 --- a/tests/Integration/RestAPI/ContentHelper/EndpointSmartLinkingTest.php +++ b/tests/Integration/RestAPI/ContentHelper/EndpointSmartLinkingTest.php @@ -79,29 +79,30 @@ public function get_endpoint(): \Parsely\REST_API\Base_Endpoint { * * @covers \Parsely\REST_API\Content_Helper\Endpoint_Smart_Linking::register_routes * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\Parsely::__construct - * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::api_secret_is_set - * @uses \Parsely\Parsely::are_credentials_managed * @uses \Parsely\Parsely::get_managed_credentials * @uses \Parsely\Parsely::get_options * @uses \Parsely\Parsely::set_default_content_helper_settings_values * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts - * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set * @uses \Parsely\Permissions::build_pch_permissions_settings_array * @uses \Parsely\Permissions::current_user_can_use_pch_feature * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap * @uses \Parsely\REST_API\Base_API_Controller::__construct * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely * @uses \Parsely\REST_API\Base_API_Controller::prefix_route * @uses \Parsely\REST_API\Base_Endpoint::__construct - * @uses \Parsely\REST_API\Base_Endpoint::get_endpoint_name + * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters + * @uses \Parsely\REST_API\Base_Endpoint::get_default_access_capability * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint * @uses \Parsely\REST_API\Base_Endpoint::init * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\REST_API\Content_Helper\Content_Helper_Controller::get_route_prefix + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_route_is_registered(): void { @@ -125,12 +126,17 @@ public function test_route_is_registered(): void { * * @covers \Parsely\REST_API\Content_Helper\Endpoint_Smart_Linking::generate_smart_links * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\Parsely::__construct - * @uses \Parsely\Parsely::allow_parsely_remote_requests - * @uses \Parsely\Parsely::are_credentials_managed - * @uses \Parsely\Parsely::set_managed_options + * @uses \Parsely\Models\Base_Model::__construct + * @uses \Parsely\Models\Smart_Link::__construct + * @uses \Parsely\Models\Smart_Link::generate_uid + * @uses \Parsely\Models\Smart_Link::get_post_id_by_url + * @uses \Parsely\Models\Smart_Link::set_href + * @uses \Parsely\Models\Smart_Link::to_array * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_generate_smart_links_returns_valid_response(): void { // Mock the Suggest_Linked_Reference_API to control the response. @@ -175,12 +181,11 @@ public function test_generate_smart_links_returns_valid_response(): void { * * @covers \Parsely\REST_API\Content_Helper\Endpoint_Smart_Linking::generate_smart_links * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\Parsely::__construct - * @uses \Parsely\Parsely::allow_parsely_remote_requests - * @uses \Parsely\Parsely::are_credentials_managed - * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_generate_smart_links_returns_error_on_failure(): void { // Mock the Suggest_Linked_Reference_API to simulate a failure. @@ -238,15 +243,19 @@ public function test_generate_smart_links_returns_error_on_failure(): void { * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap * @uses \Parsely\REST_API\Base_API_Controller::__construct * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely * @uses \Parsely\REST_API\Base_API_Controller::prefix_route * @uses \Parsely\REST_API\Base_Endpoint::__construct * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters - * @uses \Parsely\REST_API\Base_Endpoint::get_endpoint_name + * @uses \Parsely\REST_API\Base_Endpoint::get_default_access_capability * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint * @uses \Parsely\REST_API\Base_Endpoint::init * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\REST_API\Content_Helper\Content_Helper_Controller::get_route_prefix + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_add_smart_link_returns_valid_response(): void { @@ -334,15 +343,19 @@ public function test_add_smart_link_returns_valid_response(): void { * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap * @uses \Parsely\REST_API\Base_API_Controller::__construct * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely * @uses \Parsely\REST_API\Base_API_Controller::prefix_route * @uses \Parsely\REST_API\Base_Endpoint::__construct * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters - * @uses \Parsely\REST_API\Base_Endpoint::get_endpoint_name + * @uses \Parsely\REST_API\Base_Endpoint::get_default_access_capability * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint * @uses \Parsely\REST_API\Base_Endpoint::init * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\REST_API\Content_Helper\Content_Helper_Controller::get_route_prefix + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_add_multiple_smart_links_returns_valid_response(): void { diff --git a/tests/Integration/RestAPI/ContentHelper/EndpointTitleSuggestionsTest.php b/tests/Integration/RestAPI/ContentHelper/EndpointTitleSuggestionsTest.php index 15fa9e622..508a1fbab 100644 --- a/tests/Integration/RestAPI/ContentHelper/EndpointTitleSuggestionsTest.php +++ b/tests/Integration/RestAPI/ContentHelper/EndpointTitleSuggestionsTest.php @@ -67,29 +67,28 @@ public function get_endpoint(): \Parsely\REST_API\Base_Endpoint { * * @covers \Parsely\REST_API\Content_Helper\Endpoint_Title_Suggestions::register_routes * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\Parsely::__construct - * @uses \Parsely\Parsely::allow_parsely_remote_requests * @uses \Parsely\Parsely::api_secret_is_set - * @uses \Parsely\Parsely::are_credentials_managed * @uses \Parsely\Parsely::get_managed_credentials * @uses \Parsely\Parsely::get_options * @uses \Parsely\Parsely::set_default_content_helper_settings_values * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts - * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\Parsely::site_id_is_set * @uses \Parsely\Permissions::build_pch_permissions_settings_array * @uses \Parsely\Permissions::current_user_can_use_pch_feature * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap * @uses \Parsely\REST_API\Base_API_Controller::__construct * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely * @uses \Parsely\REST_API\Base_API_Controller::prefix_route * @uses \Parsely\REST_API\Base_Endpoint::__construct - * @uses \Parsely\REST_API\Base_Endpoint::get_endpoint_name * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint * @uses \Parsely\REST_API\Base_Endpoint::init * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\REST_API\Content_Helper\Content_Helper_Controller::get_route_prefix + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key */ public function test_route_is_registered(): void { @@ -116,6 +115,7 @@ public function test_route_is_registered(): void { * @uses \Parsely\Parsely::are_credentials_managed * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely * @uses \Parsely\REST_API\Base_Endpoint::__construct * @uses \Parsely\REST_API\Base_Endpoint::init * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key @@ -164,6 +164,7 @@ public function test_generate_titles_returns_valid_response(): void { * @uses \Parsely\Parsely::are_credentials_managed * @uses \Parsely\Parsely::set_managed_options * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely * @uses \Parsely\REST_API\Base_Endpoint::__construct * @uses \Parsely\REST_API\Base_Endpoint::init * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key diff --git a/tests/Integration/RestAPI/Stats/EndpointPostTest.php b/tests/Integration/RestAPI/Stats/EndpointPostTest.php new file mode 100644 index 000000000..acba94a64 --- /dev/null +++ b/tests/Integration/RestAPI/Stats/EndpointPostTest.php @@ -0,0 +1,674 @@ +api_controller = new Stats_Controller( $this->parsely ); + $this->endpoint = new Endpoint_Post( $this->api_controller ); + + parent::set_up(); + } + + /** + * Get the test endpoint instance. + * + * @since 3.17.0 + * + * @return Endpoint_Post + */ + public function get_endpoint(): \Parsely\REST_API\Base_Endpoint { + return $this->endpoint; + } + + /** + * Test that the route is registered. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Stats\Endpoint_Post::register_routes + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::get_registered_routes + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Stats\Endpoint_Post::__construct + * @uses \Parsely\REST_API\Stats\Endpoint_Post::get_endpoint_name + * @uses \Parsely\REST_API\Stats\Post_Data_Trait::get_itm_source_param_args + * @uses \Parsely\REST_API\Stats\Related_Posts_Trait::get_related_posts_param_args + * @uses \Parsely\REST_API\Stats\Stats_Controller::get_route_prefix + * @uses \Parsely\REST_API\Use_Post_ID_Parameter_Trait::register_rest_route_with_post_id + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_route_is_registered(): void { + $routes = rest_get_server()->get_routes(); + $registered_routes = $this->get_endpoint()->get_registered_routes(); + + // Assert that the routes are registered when the filter returns true. + foreach ( $registered_routes as $route ) { + $expected_route = $this->get_endpoint()->get_full_endpoint( $route ); + $route_data = $routes[ $expected_route ]; + self::assertArrayHasKey( $expected_route, $routes ); + + // Check that the route is associated with the GET method, since all + // the routes in this endpoint are GET routes. + self::assertArrayHasKey( 'GET', $route_data[0]['methods'] ); + } + } + + /** + * Test that the endpoint is not available if the API key is not set. + * + * @covers \Parsely\REST_API\Stats\Endpoint_Post::is_available_to_current_user + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Stats\Endpoint_Post::__construct + * @uses \Parsely\REST_API\Stats\Endpoint_Post::get_endpoint_name + * @uses \Parsely\REST_API\Stats\Endpoint_Post::register_routes + * @uses \Parsely\REST_API\Stats\Post_Data_Trait::get_itm_source_param_args + * @uses \Parsely\REST_API\Stats\Related_Posts_Trait::get_related_posts_param_args + * @uses \Parsely\REST_API\Stats\Stats_Controller::get_route_prefix + * @uses \Parsely\REST_API\Use_Post_ID_Parameter_Trait::register_rest_route_with_post_id + * @uses \Parsely\REST_API\Use_Post_ID_Parameter_Trait::validate_post_id + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_access_error_if_api_secret_is_not_set(): void { + $test_post_id = $this->create_test_post(); + TestCase::set_options( + array( + 'apikey' => 'test', + ) + ); + $route = $this->get_endpoint()->get_full_endpoint( '/' . $test_post_id . '/details' ); + $response = rest_get_server()->dispatch( + new WP_REST_Request( 'GET', $route ) + ); + + $error = $response->as_error(); + self::assertNotNull( $error ); + self::assertSame( 403, $response->get_status() ); + self::assertSame( 'parsely_api_secret_not_set', $error->get_error_code() ); + self::assertSame( + 'A Parse.ly API Secret must be set in site options to use this endpoint', + $error->get_error_message() + ); + } + + + /** + * Verifies forbidden error when current user doesn't have proper + * capabilities. + * + * @covers \Parsely\REST_API\Stats\Endpoint_Post::is_available_to_current_user + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters + * @uses \Parsely\REST_API\Base_Endpoint::get_default_access_capability + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Stats\Endpoint_Post::__construct + * @uses \Parsely\REST_API\Stats\Endpoint_Post::get_endpoint_name + * @uses \Parsely\REST_API\Stats\Endpoint_Post::register_routes + * @uses \Parsely\REST_API\Stats\Post_Data_Trait::get_itm_source_param_args + * @uses \Parsely\REST_API\Stats\Related_Posts_Trait::get_related_posts_param_args + * @uses \Parsely\REST_API\Stats\Stats_Controller::get_route_prefix + * @uses \Parsely\REST_API\Use_Post_ID_Parameter_Trait::register_rest_route_with_post_id + * @uses \Parsely\REST_API\Use_Post_ID_Parameter_Trait::validate_post_id + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_access_of_stats_post_endpoint_is_forbidden(): void { + $test_post_id = $this->create_test_post(); + TestCase::set_options( + array( + 'apikey' => 'test-api-key', + 'api_secret' => 'test-secret', + ) + ); + $this->set_current_user_to_contributor(); + + $route = $this->get_endpoint()->get_full_endpoint( '/' . $test_post_id . '/details' ); + $response = rest_get_server()->dispatch( + new WP_REST_Request( 'GET', $route ) + ); + /** + * Variable. + * + * @var WP_Error $error + */ + $error = $response->as_error(); + + self::assertSame( 403, $response->get_status() ); + self::assertSame( 'rest_forbidden', $error->get_error_code() ); + self::assertSame( + 'Sorry, you are not allowed to do that.', + $error->get_error_message() + ); + } + + /** + * Verifies that calls to the `stats/{post_id}/details` return the expected data, in the + * expected format. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Stats\Endpoint_Post::get_post_details + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::get_api_secret + * @uses \Parsely\Parsely::get_dash_url + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::get_site_id + * @uses \Parsely\Parsely::get_url_with_itm_source + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters + * @uses \Parsely\REST_API\Base_Endpoint::get_default_access_capability + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Stats\Endpoint_Post::__construct + * @uses \Parsely\REST_API\Stats\Endpoint_Post::get_endpoint_name + * @uses \Parsely\REST_API\Stats\Endpoint_Post::register_routes + * @uses \Parsely\REST_API\Stats\Post_Data_Trait::extract_post_data + * @uses \Parsely\REST_API\Stats\Post_Data_Trait::get_itm_source_param_args + * @uses \Parsely\REST_API\Stats\Post_Data_Trait::set_itm_source_from_request + * @uses \Parsely\REST_API\Stats\Related_Posts_Trait::get_related_posts_param_args + * @uses \Parsely\REST_API\Stats\Stats_Controller::get_route_prefix + * @uses \Parsely\REST_API\Use_Post_ID_Parameter_Trait::register_rest_route_with_post_id + * @uses \Parsely\REST_API\Use_Post_ID_Parameter_Trait::validate_post_id + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_api_url + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_items + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_request_options + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::validate_required_constraints + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Utils\Utils::get_formatted_duration + * @uses \Parsely\Utils\Utils::parsely_is_https_supported + */ + public function test_get_details(): void { + $test_post_id = $this->create_test_post(); + $route = $this->get_endpoint()->get_full_endpoint( '/' . $test_post_id . '/details' ); + + TestCase::set_options( + array( + 'apikey' => 'example.com', + 'api_secret' => 'test-secret', + ) + ); + $this->set_current_user_to_admin(); + + $dispatched = 0; + + add_filter( + 'pre_http_request', + function () use ( &$dispatched ): array { + $dispatched++; + return array( + 'body' => ' + {"data":[{ + "avg_engaged": 1.911, + "metrics": { + "views": 2158, + "visitors": 1537 + }, + "url": "https://example.com" + }]} + ', + ); + } + ); + + $response = rest_get_server()->dispatch( new WP_REST_Request( 'GET', $route ) ); + + /** + * The response data. + * + * @var array $response_data + */ + $response_data = $response->get_data(); + + self::assertSame( 1, $dispatched ); + self::assertSame( 200, $response->get_status() ); + self::assertEquals( + array( + array( + 'avgEngaged' => '1:55', + 'dashUrl' => Parsely::DASHBOARD_BASE_URL . '/example.com/find?url=https%3A%2F%2Fexample.com', + 'id' => 'https://example.com', + 'postId' => 0, + 'url' => 'https://example.com', + 'views' => '2,158', + 'visitors' => '1,537', + 'rawUrl' => 'https://example.com', + ), + ), + $response_data['data'] + ); + } + + /** + * Verifies that calls to the `stats/{post_id}/referrers` return the expected data, in the + * expected format. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Stats\Endpoint_Post::get_post_referrers + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::get_api_secret + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::get_site_id + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters + * @uses \Parsely\REST_API\Base_Endpoint::get_default_access_capability + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Stats\Endpoint_Post::__construct + * @uses \Parsely\REST_API\Stats\Endpoint_Post::generate_referrer_types_data + * @uses \Parsely\REST_API\Stats\Endpoint_Post::generate_referrers_data + * @uses \Parsely\REST_API\Stats\Endpoint_Post::get_endpoint_name + * @uses \Parsely\REST_API\Stats\Endpoint_Post::get_i18n_percentage + * @uses \Parsely\REST_API\Stats\Endpoint_Post::register_routes + * @uses \Parsely\REST_API\Stats\Post_Data_Trait::get_itm_source_param_args + * @uses \Parsely\REST_API\Stats\Post_Data_Trait::set_itm_source_from_request + * @uses \Parsely\REST_API\Stats\Related_Posts_Trait::get_related_posts_param_args + * @uses \Parsely\REST_API\Stats\Stats_Controller::get_route_prefix + * @uses \Parsely\REST_API\Use_Post_ID_Parameter_Trait::register_rest_route_with_post_id + * @uses \Parsely\REST_API\Use_Post_ID_Parameter_Trait::validate_post_id + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_api_url + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_items + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_request_options + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::validate_required_constraints + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Utils\Utils::convert_to_positive_integer + */ + public function test_get_referrers(): void { + $test_post_id = $this->create_test_post(); + $route = $this->get_endpoint()->get_full_endpoint( '/' . $test_post_id . '/referrers' ); + + TestCase::set_options( + array( + 'apikey' => 'example.com', + 'api_secret' => 'test-secret', + ) + ); + $this->set_current_user_to_admin(); + + $dispatched = 0; + + add_filter( + 'pre_http_request', + function () use ( &$dispatched ): array { + $dispatched++; + return array( + 'body' => '{"data":[ + { + "metrics": {"referrers_views": 1500}, + "name": "google", + "type": "search" + }, + { + "metrics": {"referrers_views": 100}, + "name": "blog.parse.ly", + "type": "internal" + }, + { + "metrics": {"referrers_views": 50}, + "name": "bing", + "type": "search" + }, + { + "metrics": {"referrers_views": 30}, + "name": "facebook.com", + "type": "social" + }, + { + "metrics": {"referrers_views": 10}, + "name": "okt.to", + "type": "other" + }, + { + "metrics": {"referrers_views": 10}, + "name": "yandex", + "type": "search" + }, + { + "metrics": {"referrers_views": 10}, + "name": "parse.ly", + "type": "internal" + }, + { + "metrics": {"referrers_views": 10}, + "name": "yahoo!", + "type": "search" + }, + { + "metrics": {"referrers_views": 5}, + "name": "site1.com", + "type": "other" + }, + { + "metrics": {"referrers_views": 5}, + "name": "link.site2.com", + "type": "other" + } + ]}', + ); + } + ); + + $expected_top = (object) array( + 'direct' => (object) array( + 'views' => '770', + 'viewsPercentage' => '30.80', + 'datasetViewsPercentage' => '31.43', + ), + 'google' => (object) array( + 'views' => '1,500', + 'viewsPercentage' => '60.00', + 'datasetViewsPercentage' => '61.22', + ), + 'blog.parse.ly' => (object) array( + 'views' => '100', + 'viewsPercentage' => '4.00', + 'datasetViewsPercentage' => '4.08', + ), + 'bing' => (object) array( + 'views' => '50', + 'viewsPercentage' => '2.00', + 'datasetViewsPercentage' => '2.04', + ), + 'facebook.com' => (object) array( + 'views' => '30', + 'viewsPercentage' => '1.20', + 'datasetViewsPercentage' => '1.22', + ), + 'totals' => (object) array( + 'views' => '2,450', + 'viewsPercentage' => '98.00', + 'datasetViewsPercentage' => '100.00', + ), + ); + + $expected_types = (object) array( + 'social' => (object) array( + 'views' => '30', + 'viewsPercentage' => '1.20', + ), + 'search' => (object) array( + 'views' => '1,570', + 'viewsPercentage' => '62.80', + ), + 'other' => (object) array( + 'views' => '20', + 'viewsPercentage' => '0.80', + ), + 'internal' => (object) array( + 'views' => '110', + 'viewsPercentage' => '4.40', + ), + 'direct' => (object) array( + 'views' => '770', + 'viewsPercentage' => '30.80', + ), + 'totals' => (object) array( + 'views' => '2,500', + 'viewsPercentage' => '100.00', + ), + ); + + $request = new WP_REST_Request( 'GET', $route ); + $request->set_param( 'total_views', '2,500' ); + + $response = rest_get_server()->dispatch( $request ); + + /** + * The response data. + * + * @var array $response_data + */ + $response_data = $response->get_data(); + + self::assertSame( 1, $dispatched ); + self::assertSame( 200, $response->get_status() ); + self::assertEquals( + array( + 'top' => $expected_top, + 'types' => $expected_types, + ), + $response_data['data'] + ); + } + + + /** + * Verifies that calls to the `stats/{post_id}/related` return the expected data, in the + * expected format. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Stats\Endpoint_Post::get_related_posts + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::get_api_secret + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::get_site_id + * @uses \Parsely\Parsely::get_url_with_itm_source + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters + * @uses \Parsely\REST_API\Base_Endpoint::get_default_access_capability + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Stats\Endpoint_Post::__construct + * @uses \Parsely\REST_API\Stats\Endpoint_Post::get_endpoint_name + * @uses \Parsely\REST_API\Stats\Endpoint_Post::register_routes + * @uses \Parsely\REST_API\Stats\Post_Data_Trait::get_itm_source_param_args + * @uses \Parsely\REST_API\Stats\Post_Data_Trait::set_itm_source_from_request + * @uses \Parsely\REST_API\Stats\Related_Posts_Trait::get_related_posts_of_url + * @uses \Parsely\REST_API\Stats\Related_Posts_Trait::get_related_posts_param_args + * @uses \Parsely\REST_API\Stats\Stats_Controller::get_route_prefix + * @uses \Parsely\REST_API\Use_Post_ID_Parameter_Trait::register_rest_route_with_post_id + * @uses \Parsely\REST_API\Use_Post_ID_Parameter_Trait::validate_post_id + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_api_url + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_items + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_request_options + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::validate_required_constraints + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_get_related_posts(): void { + $test_post_id = $this->create_test_post(); + $route = $this->get_endpoint()->get_full_endpoint( '/' . $test_post_id . '/related' ); + + TestCase::set_options( + array( + 'apikey' => 'example.com', + 'api_secret' => 'test-secret', + ) + ); + $this->set_current_user_to_admin(); + + $dispatched = 0; + + add_filter( + 'pre_http_request', + function () use ( &$dispatched ): array { + $dispatched++; + return array( + 'body' => '{"data":[ + { + "image_url":"https:\/\/example.com\/img.png", + "thumb_url_medium":"https:\/\/example.com\/thumb.png", + "title":"something", + "url":"https:\/\/example.com" + }, + { + "image_url":"https:\/\/example.com\/img2.png", + "thumb_url_medium":"https:\/\/example.com\/thumb2.png", + "title":"something2", + "url":"https:\/\/example.com\/2" + } + ]}', + ); + } + ); + + $response = rest_get_server()->dispatch( new WP_REST_Request( 'GET', $route ) ); + /** + * The response data. + * + * @var array $response_data + */ + $response_data = $response->get_data(); + + self::assertSame( 1, $dispatched ); + self::assertSame( 200, $response->get_status() ); + self::assertEquals( + array( + (object) array( + 'image_url' => 'https://example.com/img.png', + 'thumb_url_medium' => 'https://example.com/thumb.png', + 'title' => 'something', + 'url' => 'https://example.com', + ), + (object) array( + 'image_url' => 'https://example.com/img2.png', + 'thumb_url_medium' => 'https://example.com/thumb2.png', + 'title' => 'something2', + 'url' => 'https://example.com/2', + ), + ), + $response_data['data'] + ); + } +} diff --git a/tests/Integration/RestAPI/Stats/EndpointPostsTest.php b/tests/Integration/RestAPI/Stats/EndpointPostsTest.php new file mode 100644 index 000000000..0cecdd1cb --- /dev/null +++ b/tests/Integration/RestAPI/Stats/EndpointPostsTest.php @@ -0,0 +1,347 @@ +api_controller = new Stats_Controller( $this->parsely ); + $this->endpoint = new Endpoint_Posts( $this->api_controller ); + + parent::set_up(); + } + + /** + * Get the test endpoint instance. + * + * @since 3.17.0 + * + * @return Endpoint_Posts + */ + public function get_endpoint(): \Parsely\REST_API\Base_Endpoint { + return $this->endpoint; + } + + /** + * Test the route is registered. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Stats\Endpoint_Posts::register_routes + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Stats\Stats_Controller::get_route_prefix + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_route_is_registered(): void { + $routes = rest_get_server()->get_routes(); + + // Check that the excerpt-generator/generate route is registered. + $expected_route = $this->get_endpoint()->get_full_endpoint( '/' ); + self::assertArrayHasKey( $expected_route, $routes ); + + // Check that the route is associated with the POST method. + $route_data = $routes[ $expected_route ]; + self::assertArrayHasKey( 'GET', $route_data[0]['methods'] ); + } + + /** + * Test that the endpoint is not available if the API key is not set. + * + * @covers \Parsely\REST_API\Stats\Endpoint_Posts::is_available_to_current_user + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Stats\Stats_Controller::get_route_prefix + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_access_error_if_api_secret_is_not_set(): void { + TestCase::set_options( + array( + 'apikey' => 'test', + ) + ); + $route = $this->get_endpoint()->get_full_endpoint( '/' ); + $response = rest_get_server()->dispatch( + new WP_REST_Request( 'GET', $route ) + ); + + $error = $response->as_error(); + self::assertNotNull( $error ); + self::assertSame( 403, $response->get_status() ); + self::assertSame( 'parsely_api_secret_not_set', $error->get_error_code() ); + self::assertSame( + 'A Parse.ly API Secret must be set in site options to use this endpoint', + $error->get_error_message() + ); + } + + + /** + * Verifies forbidden error when current user doesn't have proper + * capabilities. + * + * @covers \Parsely\REST_API\Stats\Endpoint_Posts::is_available_to_current_user + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters + * @uses \Parsely\REST_API\Base_Endpoint::get_default_access_capability + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Stats\Stats_Controller::get_route_prefix + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_access_of_stats_posts_endpoint_is_forbidden(): void { + TestCase::set_options( + array( + 'apikey' => 'test-api-key', + 'api_secret' => 'test-secret', + ) + ); + $this->set_current_user_to_contributor(); + + $route = $this->get_endpoint()->get_full_endpoint( '/' ); + $response = rest_get_server()->dispatch( + new WP_REST_Request( 'GET', $route ) + ); + /** + * Variable. + * + * @var WP_Error $error + */ + $error = $response->as_error(); + + self::assertSame( 403, $response->get_status() ); + self::assertSame( 'rest_forbidden', $error->get_error_code() ); + self::assertSame( + 'Sorry, you are not allowed to do that.', + $error->get_error_message() + ); + } + + /** + * Verifies that calls to the endpoint return the expected data, in the + * expected format. + * + * @covers \Parsely\REST_API\Stats\Endpoint_Posts::get_posts + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::get_api_secret + * @uses \Parsely\Parsely::get_dash_url + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::get_site_id + * @uses \Parsely\Parsely::get_url_with_itm_source + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::apply_capability_filters + * @uses \Parsely\REST_API\Base_Endpoint::get_default_access_capability + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Base_Endpoint::validate_site_id_and_secret + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Stats\Stats_Controller::get_route_prefix + * @uses \Parsely\RemoteAPI\Analytics_Posts_API::get_request_options + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_api_url + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_items + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::validate_required_constraints + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @uses \Parsely\Utils\Utils::get_date_format + * @uses \Parsely\Utils\Utils::parsely_is_https_supported + */ + public function test_get_posts(): void { + TestCase::set_options( + array( + 'apikey' => 'example.com', + 'api_secret' => 'test-secret', + ) + ); + $this->set_current_user_to_admin(); + + $dispatched = 0; + $date_format = Utils::get_date_format(); + + add_filter( + 'pre_http_request', + function () use ( &$dispatched ): array { + $dispatched++; + + return array( + 'body' => '{"data":[ + { + "author": "Aakash Shah", + "metrics": {"views": 142}, + "pub_date": "2020-04-06T13:30:58", + "thumb_url_medium": "https://images.parsely.com/XCmTXuOf8yVbUYTxj2abQ4RSDkM=/85x85/smart/https%3A//blog.parse.ly/wp-content/uploads/2021/06/Web-Analytics-Tool.png%3Fw%3D150%26h%3D150%26crop%3D1", + "title": "9 Types of Web Analytics Tools \u2014 And How to Know Which Ones You Really Need", + "url": "https://blog.parse.ly/web-analytics-software-tools/?itm_source=parsely-api" + }, + { + "author": "Stephanie Schwartz and Andrew Butler", + "metrics": {"views": 40}, + "pub_date": "2021-04-30T20:30:24", + "thumb_url_medium": "https://images.parsely.com/ap3YSufqxnLpz6zzQshoks3snXI=/85x85/smart/https%3A//blog.parse.ly/wp-content/uploads/2021/05/pexels-brett-jordan-998501-1024x768-2.jpeg%3Fw%3D150%26h%3D150%26crop%3D1", + "title": "5 Tagging Best Practices For Getting the Most Out of Your Content Strategy", + "url": "https://blog.parse.ly/5-tagging-best-practices-content-strategy/?itm_source=parsely-api" + } + ]}', + ); + } + ); + + $rest_request = new WP_REST_Request( 'GET', '/wp-parsely/v2/stats/posts' ); + $rest_request->set_param( 'itm_source', 'wp-parsely-content-helper' ); + + $response = rest_get_server()->dispatch( $rest_request ); + + /** + * The response data. + * + * @var array $response_data + */ + $response_data = $response->get_data(); + + self::assertSame( 1, $dispatched ); + self::assertSame( 200, $response->get_status() ); + self::assertEquals( + array( + array( + 'author' => 'Aakash Shah', + 'date' => wp_date( $date_format, strtotime( '2020-04-06T13:30:58' ) ), + 'id' => 'https://blog.parse.ly/web-analytics-software-tools/', + 'dashUrl' => PARSELY::DASHBOARD_BASE_URL . '/example.com/find?url=https%3A%2F%2Fblog.parse.ly%2Fweb-analytics-software-tools%2F', + 'thumbnailUrl' => 'https://images.parsely.com/XCmTXuOf8yVbUYTxj2abQ4RSDkM=/85x85/smart/https%3A//blog.parse.ly/wp-content/uploads/2021/06/Web-Analytics-Tool.png%3Fw%3D150%26h%3D150%26crop%3D1', + 'title' => '9 Types of Web Analytics Tools — And How to Know Which Ones You Really Need', + 'url' => 'https://blog.parse.ly/web-analytics-software-tools/?itm_source=wp-parsely-content-helper', + 'views' => '142', + 'postId' => 0, + 'rawUrl' => 'https://blog.parse.ly/web-analytics-software-tools/', + ), + array( + 'author' => 'Stephanie Schwartz and Andrew Butler', + 'date' => wp_date( $date_format, strtotime( '2021-04-30T20:30:24' ) ), + 'id' => 'https://blog.parse.ly/5-tagging-best-practices-content-strategy/', + 'dashUrl' => PARSELY::DASHBOARD_BASE_URL . '/example.com/find?url=https%3A%2F%2Fblog.parse.ly%2F5-tagging-best-practices-content-strategy%2F', + 'thumbnailUrl' => 'https://images.parsely.com/ap3YSufqxnLpz6zzQshoks3snXI=/85x85/smart/https%3A//blog.parse.ly/wp-content/uploads/2021/05/pexels-brett-jordan-998501-1024x768-2.jpeg%3Fw%3D150%26h%3D150%26crop%3D1', + 'title' => '5 Tagging Best Practices For Getting the Most Out of Your Content Strategy', + 'url' => 'https://blog.parse.ly/5-tagging-best-practices-content-strategy/?itm_source=wp-parsely-content-helper', + 'views' => '40', + 'postId' => 0, + 'rawUrl' => 'https://blog.parse.ly/5-tagging-best-practices-content-strategy/', + ), + ), + $response_data['data'] + ); + + self::assertEquals( + array( + 'limit' => 5, + 'sort' => 'views', + 'page' => 1, + 'itm_source' => 'wp-parsely-content-helper', + ), + $response_data['params'] + ); + } +} diff --git a/tests/Integration/RestAPI/Stats/EndpointRelatedTest.php b/tests/Integration/RestAPI/Stats/EndpointRelatedTest.php new file mode 100644 index 000000000..463886c85 --- /dev/null +++ b/tests/Integration/RestAPI/Stats/EndpointRelatedTest.php @@ -0,0 +1,316 @@ +api_controller = new Stats_Controller( $this->parsely ); + $this->endpoint = new Endpoint_Related( $this->api_controller ); + + parent::set_up(); + } + + + /** + * Get the test endpoint instance. + * + * @since 3.17.0 + * + * @return Endpoint_Related + */ + public function get_endpoint(): \Parsely\REST_API\Base_Endpoint { + return $this->endpoint; + } + + /** + * Test the route is registered. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Stats\Endpoint_Related::register_routes + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Stats\Endpoint_Related::__construct + * @uses \Parsely\REST_API\Stats\Endpoint_Related::get_endpoint_name + * @uses \Parsely\REST_API\Stats\Endpoint_Related::is_available_to_current_user + * @uses \Parsely\REST_API\Stats\Post_Data_Trait::get_itm_source_param_args + * @uses \Parsely\REST_API\Stats\Related_Posts_Trait::get_related_posts_param_args + * @uses \Parsely\REST_API\Stats\Stats_Controller::get_route_prefix + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_route_is_registered(): void { + $routes = rest_get_server()->get_routes(); + + // Check that the excerpt-generator/generate route is registered. + $expected_route = $this->get_endpoint()->get_full_endpoint( '/' ); + self::assertArrayHasKey( $expected_route, $routes ); + + // Check that the route is associated with the POST method. + $route_data = $routes[ $expected_route ]; + self::assertArrayHasKey( 'GET', $route_data[0]['methods'] ); + } + + /** + * Test that the endpoint is available to everyone, even if they are not logged in. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Stats\Endpoint_Related::is_available_to_current_user + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::get_api_secret + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::get_site_id + * @uses \Parsely\Parsely::get_url_with_itm_source + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Stats\Endpoint_Related::__construct + * @uses \Parsely\REST_API\Stats\Endpoint_Related::get_endpoint_name + * @uses \Parsely\REST_API\Stats\Endpoint_Related::get_related_posts + * @uses \Parsely\REST_API\Stats\Endpoint_Related::register_routes + * @uses \Parsely\REST_API\Stats\Post_Data_Trait::get_itm_source_param_args + * @uses \Parsely\REST_API\Stats\Post_Data_Trait::set_itm_source_from_request + * @uses \Parsely\REST_API\Stats\Related_Posts_Trait::get_related_posts_of_url + * @uses \Parsely\REST_API\Stats\Related_Posts_Trait::get_related_posts_param_args + * @uses \Parsely\REST_API\Stats\Stats_Controller::get_route_prefix + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_api_url + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_items + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_request_options + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::validate_required_constraints + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_access_of_related_posts_is_available_to_everyone(): void { + TestCase::set_options( + array( + 'apikey' => 'test-api-key', + 'api_secret' => 'test-secret', + ) + ); + wp_set_current_user( 0 ); + + $dispatched = 0; + $this->mock_api_response( $dispatched ); + + $route = $this->get_endpoint()->get_full_endpoint( '/' ); + $request = new WP_REST_Request( 'GET', $route ); + $request->set_param( 'url', 'https://example.com/a-post' ); + $response = rest_get_server()->dispatch( $request ); + + self::assertEquals( 1, $dispatched ); + self::assertSame( 200, $response->get_status() ); + } + + /** + * Mock the API response of the Parse.ly API. + * + * @since 3.17.0 + * + * @param int &$dispatched The number of times the API was dispatched. + */ + private function mock_api_response( int &$dispatched ): void { + add_filter( + 'pre_http_request', + function () use ( &$dispatched ): array { + $dispatched++; + return array( + 'body' => '{"data":[ + { + "image_url":"https:\/\/example.com\/img.png", + "thumb_url_medium":"https:\/\/example.com\/thumb.png", + "title":"something", + "url":"https:\/\/example.com" + }, + { + "image_url":"https:\/\/example.com\/img2.png", + "thumb_url_medium":"https:\/\/example.com\/thumb2.png", + "title":"something2", + "url":"https:\/\/example.com\/2" + } + ]}', + ); + } + ); + } + + /** + * Verifies that calls to the `stats/related` return the expected data, in the + * expected format, despite the user being unauthenticated. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Stats\Endpoint_Related::get_related_posts + * @uses \Parsely\Endpoints\Base_Endpoint::__construct + * @uses \Parsely\Parsely::api_secret_is_set + * @uses \Parsely\Parsely::get_api_secret + * @uses \Parsely\Parsely::get_managed_credentials + * @uses \Parsely\Parsely::get_options + * @uses \Parsely\Parsely::get_site_id + * @uses \Parsely\Parsely::get_url_with_itm_source + * @uses \Parsely\Parsely::set_default_content_helper_settings_values + * @uses \Parsely\Parsely::set_default_full_metadata_in_non_posts + * @uses \Parsely\Parsely::site_id_is_set + * @uses \Parsely\Permissions::build_pch_permissions_settings_array + * @uses \Parsely\Permissions::get_user_roles_with_edit_posts_cap + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Stats\Endpoint_Related::__construct + * @uses \Parsely\REST_API\Stats\Endpoint_Related::get_endpoint_name + * @uses \Parsely\REST_API\Stats\Endpoint_Related::is_available_to_current_user + * @uses \Parsely\REST_API\Stats\Endpoint_Related::register_routes + * @uses \Parsely\REST_API\Stats\Post_Data_Trait::get_itm_source_param_args + * @uses \Parsely\REST_API\Stats\Post_Data_Trait::set_itm_source_from_request + * @uses \Parsely\REST_API\Stats\Related_Posts_Trait::get_related_posts_of_url + * @uses \Parsely\REST_API\Stats\Related_Posts_Trait::get_related_posts_param_args + * @uses \Parsely\REST_API\Stats\Stats_Controller::get_route_prefix + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_api_url + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_items + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::get_request_options + * @uses \Parsely\RemoteAPI\Base_Endpoint_Remote::validate_required_constraints + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_get_related_posts(): void { + $route = $this->get_endpoint()->get_full_endpoint( '/' ); + + TestCase::set_options( + array( + 'apikey' => 'example.com', + 'api_secret' => 'test-secret', + ) + ); + + $dispatched = 0; + + add_filter( + 'pre_http_request', + function () use ( &$dispatched ): array { + $dispatched++; + return array( + 'body' => '{"data":[ + { + "image_url":"https:\/\/example.com\/img.png", + "thumb_url_medium":"https:\/\/example.com\/thumb.png", + "title":"something", + "url":"https:\/\/example.com" + }, + { + "image_url":"https:\/\/example.com\/img2.png", + "thumb_url_medium":"https:\/\/example.com\/thumb2.png", + "title":"something2", + "url":"https:\/\/example.com\/2" + } + ]}', + ); + } + ); + + $request = new WP_REST_Request( 'GET', $route ); + $request->set_param( 'url', 'https://example.com/a-post' ); + $response = rest_get_server()->dispatch( $request ); + + /** + * The response data. + * + * @var array $response_data + */ + $response_data = $response->get_data(); + + self::assertSame( 1, $dispatched ); + self::assertSame( 200, $response->get_status() ); + self::assertEquals( + array( + (object) array( + 'image_url' => 'https://example.com/img.png', + 'thumb_url_medium' => 'https://example.com/thumb.png', + 'title' => 'something', + 'url' => 'https://example.com', + ), + (object) array( + 'image_url' => 'https://example.com/img2.png', + 'thumb_url_medium' => 'https://example.com/thumb2.png', + 'title' => 'something2', + 'url' => 'https://example.com/2', + ), + ), + $response_data['data'] + ); + } + + /** + * Test that the endpoint is not available if the API secret is not set. + * This test should be disabled since the endpoint does not requires the API secret. + * + * @since 3.17.0 + * @coversNothing + */ + public function test_is_available_to_current_user_returns_error_api_secret_not_set(): void { + // This test is disabled since the endpoint does not requires the API secret. + self::assertTrue( true ); + } +} diff --git a/tests/Integration/RestAPI/Stats/StatsControllerTest.php b/tests/Integration/RestAPI/Stats/StatsControllerTest.php new file mode 100644 index 000000000..0635125f9 --- /dev/null +++ b/tests/Integration/RestAPI/Stats/StatsControllerTest.php @@ -0,0 +1,60 @@ +stats_controller = new Stats_Controller( $parsely ); + } + + /** + * Test the constructor sets up the correct namespace and version. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Stats\Stats_Controller::__construct + * @uses \Parsely\REST_API\Stats\Stats_Controller::get_full_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + */ + public function test_constructor_sets_up_namespace_and_version(): void { + self::assertEquals( 'wp-parsely/v2', $this->stats_controller->get_full_namespace() ); + } +} From fa5ee007a942085084e26168a3e40cb3c3766a6f Mon Sep 17 00:00:00 2001 From: Henrique Mouta Date: Thu, 29 Aug 2024 16:20:48 +0100 Subject: [PATCH 066/282] Fix E2E test --- build/blocks/recommendations/edit.asset.php | 2 +- build/blocks/recommendations/edit.js | 2 +- build/blocks/recommendations/view.asset.php | 2 +- build/blocks/recommendations/view.js | 2 +- .../recommendations/components/parsely-recommendations.tsx | 2 +- src/blocks/recommendations/recommendations-store.tsx | 4 +++- 6 files changed, 8 insertions(+), 6 deletions(-) diff --git a/build/blocks/recommendations/edit.asset.php b/build/blocks/recommendations/edit.asset.php index ce1f1eb73..321642357 100644 --- a/build/blocks/recommendations/edit.asset.php +++ b/build/blocks/recommendations/edit.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => 'f1121e53d4c8acf98db5'); + array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => '1752d46c4755b2406c94'); diff --git a/build/blocks/recommendations/edit.js b/build/blocks/recommendations/edit.js index c923405cf..96036490f 100644 --- a/build/blocks/recommendations/edit.js +++ b/build/blocks/recommendations/edit.js @@ -1 +1 @@ -!function(){"use strict";var e,n={271:function(e,n,r){var t,o,a=r(848),i=window.wp.blockEditor,l=window.wp.blocks,s=window.wp.i18n,c=window.wp.components,u=JSON.parse('{"UU":"wp-parsely/recommendations","uK":{"imagestyle":{"type":"string","default":"original"},"limit":{"type":"number","default":3},"openlinksinnewtab":{"type":"boolean","default":false},"showimages":{"type":"boolean","default":true},"sort":{"type":"string","default":"score"},"title":{"type":"string","default":"Related Content"}}}'),d=window.wp.element;(o=t||(t={}))[o.Error=0]="Error",o[o.Loaded=1]="Loaded",o[o.Recommendations=2]="Recommendations";var p=function(){return p=Object.assign||function(e){for(var n,r=1,t=arguments.length;r0&&o[o.length-1])||6!==l[0]&&2!==l[0])){i=0;continue}if(3===l[0]&&(!o||l[1]>o[0]&&l[1]=a)&&Object.keys(t.O).every((function(e){return t.O[e](r[s])}))?r.splice(s--,1):(l=!1,a0&&e[u-1][2]>a;u--)e[u]=e[u-1];e[u]=[r,o,a]},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,{a:n}),n},t.d=function(e,n){for(var r in n)t.o(n,r)&&!t.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:n[r]})},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},function(){var e={335:0,203:0};t.O.j=function(n){return 0===e[n]};var n=function(n,r){var o,a,i=r[0],l=r[1],s=r[2],c=0;if(i.some((function(n){return 0!==e[n]}))){for(o in l)t.o(l,o)&&(t.m[o]=l[o]);if(s)var u=s(t)}for(n&&n(r);c0&&o[o.length-1])||6!==l[0]&&2!==l[0])){i=0;continue}if(3===l[0]&&(!o||l[1]>o[0]&&l[1]=a)&&Object.keys(t.O).every((function(e){return t.O[e](r[s])}))?r.splice(s--,1):(l=!1,a0&&e[u-1][2]>a;u--)e[u]=e[u-1];e[u]=[r,o,a]},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,{a:n}),n},t.d=function(e,n){for(var r in n)t.o(n,r)&&!t.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:n[r]})},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},function(){var e={335:0,203:0};t.O.j=function(n){return 0===e[n]};var n=function(n,r){var o,a,i=r[0],l=r[1],s=r[2],c=0;if(i.some((function(n){return 0!==e[n]}))){for(o in l)t.o(l,o)&&(t.m[o]=l[o]);if(s)var u=s(t)}for(n&&n(r);c array('react', 'wp-api-fetch', 'wp-components', 'wp-compose', 'wp-dom-ready', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => 'af6eb0946975f32d53b1'); + array('react', 'wp-api-fetch', 'wp-components', 'wp-compose', 'wp-dom-ready', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => 'dd57327c2b8d1346aff3'); diff --git a/build/blocks/recommendations/view.js b/build/blocks/recommendations/view.js index d8f4b4577..053f899c3 100644 --- a/build/blocks/recommendations/view.js +++ b/build/blocks/recommendations/view.js @@ -1 +1 @@ -!function(){"use strict";var e={20:function(e,r,n){var t=n(609),o=Symbol.for("react.element"),a=Symbol.for("react.fragment"),i=Object.prototype.hasOwnProperty,s=t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function u(e,r,n){var t,a={},u=null,c=null;for(t in void 0!==n&&(u=""+n),void 0!==r.key&&(u=""+r.key),void 0!==r.ref&&(c=r.ref),r)i.call(r,t)&&!l.hasOwnProperty(t)&&(a[t]=r[t]);if(e&&e.defaultProps)for(t in r=e.defaultProps)void 0===a[t]&&(a[t]=r[t]);return{$$typeof:o,type:e,key:u,ref:c,props:a,_owner:s.current}}r.Fragment=a,r.jsx=u,r.jsxs=u},848:function(e,r,n){e.exports=n(20)},609:function(e){e.exports=window.React}},r={};function n(t){var o=r[t];if(void 0!==o)return o.exports;var a=r[t]={exports:{}};return e[t](a,a.exports,n),a.exports}n.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(r,{a:r}),r},n.d=function(e,r){for(var t in r)n.o(r,t)&&!n.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},n.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},function(){var e,r,t=n(848),o=n(609),a=window.wp.domReady,i=n.n(a),s=window.wp.element,l=window.wp.i18n;(r=e||(e={}))[r.Error=0]="Error",r[r.Loaded=1]="Loaded",r[r.Recommendations=2]="Recommendations";var u=function(){return u=Object.assign||function(e){for(var r,n=1,t=arguments.length;n0&&o[o.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]0&&o[o.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1] Date: Fri, 30 Aug 2024 10:52:36 +0100 Subject: [PATCH 067/282] Add `settings` endpoints --- src/rest-api/class-rest-api-controller.php | 2 + .../settings/class-base-settings-endpoint.php | 415 ++++++++++++++++++ ...ass-endpoint-dashboard-widget-settings.php | 66 +++ ...class-endpoint-editor-sidebar-settings.php | 114 +++++ .../settings/class-settings-controller.php | 47 ++ 5 files changed, 644 insertions(+) create mode 100644 src/rest-api/settings/class-base-settings-endpoint.php create mode 100644 src/rest-api/settings/class-endpoint-dashboard-widget-settings.php create mode 100644 src/rest-api/settings/class-endpoint-editor-sidebar-settings.php create mode 100644 src/rest-api/settings/class-settings-controller.php diff --git a/src/rest-api/class-rest-api-controller.php b/src/rest-api/class-rest-api-controller.php index 5ce4e76fa..007c49e54 100644 --- a/src/rest-api/class-rest-api-controller.php +++ b/src/rest-api/class-rest-api-controller.php @@ -11,6 +11,7 @@ namespace Parsely\REST_API; use Parsely\REST_API\Content_Helper\Content_Helper_Controller; +use Parsely\REST_API\Settings\Settings_Controller; use Parsely\REST_API\Stats\Stats_Controller; /** @@ -62,6 +63,7 @@ public function init(): void { $controllers = array( new Content_Helper_Controller( $this->get_parsely() ), new Stats_Controller( $this->get_parsely() ), + new Settings_Controller( $this->get_parsely() ), ); // Initialize the controllers. diff --git a/src/rest-api/settings/class-base-settings-endpoint.php b/src/rest-api/settings/class-base-settings-endpoint.php new file mode 100644 index 000000000..3a4b59b3b --- /dev/null +++ b/src/rest-api/settings/class-base-settings-endpoint.php @@ -0,0 +1,415 @@ +, default: mixed} + */ +abstract class Base_Settings_Endpoint extends Base_Endpoint { + /** + * The meta entry's default value. Initialized in the constructor. + * + * @since 3.13.0 + * @since 3.17.0 Moved from Base_Endpoint_User_Meta. + * + * @var array + */ + protected $default_value = array(); + + /** + * The valid values that can be used for each subvalue. Initialized in the + * constructor. + * + * @since 3.13.0 + * @since 3.17.0 Moved from Base_Endpoint_User_Meta. + * + * @var array> + */ + protected $valid_subvalues = array(); + + /** + * The current user's ID. + * + * @since 3.14.0 + * @since 3.17.0 Moved from Base_Endpoint_User_Meta. + * + * @var int + */ + protected $current_user_id = 0; + + /** + * Returns the meta entry's key. + * + * @since 3.13.0 + * @since 3.17.0 Moved from Base_Endpoint_User_Meta. + * + * @return string The meta entry's key. + */ + abstract protected function get_meta_key(): string; + + /** + * Returns the endpoint's subvalues specifications. + * + * @since 3.13.0 + * @since 3.17.0 Moved from Base_Endpoint_User_Meta. + * + * @return array + */ + abstract protected function get_subvalues_specs(): array; + + /** + * Constructor. + * + * @since 3.13.0 + * @since 3.17.0 Moved from Base_Endpoint_User_Meta. + * + * @param Base_API_Controller $controller Parsely instance. + */ + public function __construct( Base_API_Controller $controller ) { + parent::__construct( $controller ); + + $subvalues_specs = $this->get_subvalues_specs(); + + foreach ( $subvalues_specs as $key => $value ) { + $this->default_value[ $key ] = $value['default']; + $this->valid_subvalues[ $key ] = $value['values']; + } + } + + /** + * Initializes the endpoint and sets the current user ID. + * + * @since 3.17.0 + */ + public function init(): void { + parent::init(); + $this->current_user_id = get_current_user_id(); + } + + /** + * Registers the routes for the endpoint. + * + * @since 3.17.0 + */ + public function register_routes(): void { + /** + * GET settings/{endpoint}/get + * Retrieves the settings for the current user. + */ + $this->register_rest_route( + '/get', + array( 'GET' ), + array( $this, 'get_settings' ) + ); + + /** + * PUT settings/{endpoint}/set + * Updates the settings for the current user. + */ + $this->register_rest_route( + '/set', + array( 'PUT' ), + array( $this, 'set_settings' ) + ); + + /** + * GET|PUT settings/{endpoint} + * Handles direct requests to the endpoint. + */ + $this->register_rest_route( + '/', + array( 'GET', 'PUT' ), + array( $this, 'process_request' ) + ); + } + + /** + * API Endpoint: GET|PUT settings/{endpoint}/ + * + * Processes the requests sent directly to the main endpoint. + * + * @since 3.17.0 + * + * @param WP_REST_Request $request The request sent to the endpoint. + * @return WP_REST_Response|WP_Error The response object. + */ + public function process_request( WP_REST_Request $request ) { + $request_method = $request->get_method(); + + // Update the meta entry's value if the request method is PUT. + if ( 'PUT' === $request_method ) { + return $this->set_settings( $request ); + } + + return $this->get_settings(); + } + + /** + * API Endpoint: GET settings/{endpoint}/get + * + * Retrieves the settings for the current user. + * + * @since 3.17.0 + * + * @return WP_REST_Response The response object. + */ + public function get_settings(): WP_REST_Response { + $meta_key = $this->get_meta_key(); + $settings = get_user_meta( $this->current_user_id, $meta_key, true ); + + if ( ! is_array( $settings ) || 0 === count( $settings ) ) { + $settings = $this->default_value; + } + + return new WP_REST_Response( $settings, 200 ); + } + + /** + * API Endpoint: PUT settings/{endpoint}/set + * + * Updates the settings for the current user. + * + * @since 3.17.0 + * + * @param WP_REST_Request $request The request object. + * @return WP_REST_Response|WP_Error The response object. + */ + public function set_settings( WP_REST_Request $request ) { + $meta_value = $request->get_json_params(); + + // Validates the settings format. + if ( ! is_array( $meta_value ) ) { // @phpstan-ignore-line + return new WP_Error( + 'ch_settings_invalid_format', + __( 'Settings must be an valid JSON array', 'wp-parsely' ) + ); + } + + $sanitized_value = $this->sanitize_value( $meta_value ); + + // If the current settings are the same as the new settings, return early. + $current_settings = $this->get_settings(); + if ( $current_settings->get_data() === $sanitized_value ) { + return $current_settings; + } + + $update_meta = update_user_meta( + $this->current_user_id, + $this->get_meta_key(), + $sanitized_value + ); + + if ( false === $update_meta ) { + return new WP_Error( + 'ch_settings_update_failed', + __( 'Failed to update settings', 'wp-parsely' ) + ); + } + + return new WP_REST_Response( $sanitized_value, 200 ); + } + + /** + * Returns whether the endpoint is available for access by the current + * user. + * + * @since 3.14.0 + * @since 3.16.0 Added the `$request` parameter. + * @since 3.17.0 Moved from Base_Endpoint_User_Meta. + * + * @param WP_REST_Request|null $request The request object. + * @return bool + */ + public function is_available_to_current_user( ?WP_REST_Request $request = null ): bool { + return current_user_can( 'edit_user', $this->current_user_id ); + } + + /** + * Sanitizes the passed meta value. + * + * @since 3.13.0 + * @since 3.14.0 Added support for nested arrays. + * @since 3.17.0 Moved from Base_Endpoint_User_Meta. + * + * @param array $meta_value The meta value to sanitize. + * @param string $parent_key The parent key for the current level of the meta. + * @return array The sanitized meta as an array of subvalues. + */ + protected function sanitize_value( array $meta_value, string $parent_key = '' ): array { + $sanitized_value = array(); + + // Determine the current level's specifications based on the parent key. + /** + * Current level's specifications. + * + * @var array $current_specs + */ + $current_specs = ( '' === $parent_key ) ? $this->get_subvalues_specs() : $this->get_nested_specs( $parent_key ); + + foreach ( $current_specs as $key => $spec ) { + $composite_key = '' === $parent_key ? $key : $parent_key . '.' . $key; + + // Check if the key exists in the input meta value array. + if ( array_key_exists( $key, $meta_value ) ) { + $value = $meta_value[ $key ]; + } else { + // Key is missing in the input, use the default value from the specifications. + $value = $this->get_default( explode( '.', $composite_key ) ); + } + + /** + * Spec for the current key. + * + * @var array{default: mixed, values?: array} $spec + */ + if ( is_array( $value ) && isset( $spec['values'] ) ) { + // Recursively handle nested arrays if 'values' spec exists for this key. + $sanitized_value[ $key ] = $this->sanitize_value( $value, $composite_key ); + } else { + // Directly sanitize non-array values or non-nested specs. + $sanitized_value[ $key ] = $this->sanitize_subvalue( $composite_key, $value ); + } + } + + return $sanitized_value; + } + + /** + * Sanitizes the passed subvalue. + * + * @since 3.13.0 + * @since 3.14.0 Added support for nested arrays. + * @since 3.17.0 Moved from Base_Endpoint_User_Meta. + * + * @param string $composite_key The subvalue's key. + * @param mixed $value The value to sanitize. + * @return mixed The sanitized subvalue. + */ + protected function sanitize_subvalue( string $composite_key, $value ) { + $keys = explode( '.', $composite_key ); + $valid_values = $this->get_valid_values( $keys ); + + if ( is_array( $value ) ) { + // Check if $value elements are inside $valid_values + // If not, the value should be the default value. + $valid_value = array(); + foreach ( $value as $key => $val ) { + if ( in_array( $val, $valid_values, true ) ) { + $valid_value[ $key ] = $val; + } + } + return $valid_value; + } + + if ( is_string( $value ) ) { + $value = sanitize_text_field( $value ); + } + + if ( count( $valid_values ) === 0 ) { + return $value; + } + + if ( ! in_array( $value, $valid_values, true ) ) { + return $this->get_default( $keys ); + } + + return $value; + } + + /** + * Gets the valid values for a given setting path. + * + * @since 3.14.3 + * @since 3.17.0 Moved from Base_Endpoint_User_Meta. + * + * @param array $keys The path to the setting. + * @return array The valid values for the setting path. + */ + protected function get_valid_values( array $keys ): array { + $current = $this->valid_subvalues; + + foreach ( $keys as $key ) { + if ( ! is_array( $current ) || ! isset( $current[ $key ] ) ) { + return array(); // No valid values for invalid key path. + } + if ( isset( $current[ $key ]['values'] ) ) { + $current = $current[ $key ]['values']; + } else { + $current = $current[ $key ]; + } + } + + return is_array( $current ) ? $current : array(); + } + + /** + * Gets the default value for a given setting path. + * + * @since 3.14.3 + * @since 3.17.0 Moved from Base_Endpoint_User_Meta. + * + * @param array $keys The path to the setting. + * @return mixed|array|null The default value for the setting path. + */ + protected function get_default( array $keys ) { + $current = $this->default_value; + + foreach ( $keys as $key ) { + if ( ! is_array( $current ) || ! isset( $current[ $key ] ) ) { + return null; // No default value for invalid key path. + } + if ( isset( $current[ $key ]['default'] ) ) { + $current = $current[ $key ]['default']; + } else { + $current = $current[ $key ]; + } + } + + return $current; // Return default value for valid key path. + } + + + /** + * Gets the specifications for nested settings based on a composite key. + * + * @since 3.14.3 + * @since 3.17.0 Moved from Base_Endpoint_User_Meta. + * + * @param string $composite_key The composite key representing the nested path. + * @return array The specifications for the nested path. + */ + protected function get_nested_specs( string $composite_key ): array { + $keys = explode( '.', $composite_key ); + $specs = $this->get_subvalues_specs(); + + foreach ( $keys as $key ) { + if ( is_array( $specs[ $key ] ) && array_key_exists( 'values', $specs[ $key ] ) ) { + $specs = $specs[ $key ]['values']; + } else { + break; + } + } + + return $specs; + } +} diff --git a/src/rest-api/settings/class-endpoint-dashboard-widget-settings.php b/src/rest-api/settings/class-endpoint-dashboard-widget-settings.php new file mode 100644 index 000000000..bf7d429fe --- /dev/null +++ b/src/rest-api/settings/class-endpoint-dashboard-widget-settings.php @@ -0,0 +1,66 @@ + + */ + protected function get_subvalues_specs(): array { + return array( + 'Metric' => array( + 'values' => array( 'views', 'avg_engaged' ), + 'default' => 'views', + ), + 'Period' => array( + 'values' => array( '10m', '1h', '2h', '4h', '24h', '7d', '30d' ), + 'default' => '7d', + ), + ); + } +} diff --git a/src/rest-api/settings/class-endpoint-editor-sidebar-settings.php b/src/rest-api/settings/class-endpoint-editor-sidebar-settings.php new file mode 100644 index 000000000..ccbd33c82 --- /dev/null +++ b/src/rest-api/settings/class-endpoint-editor-sidebar-settings.php @@ -0,0 +1,114 @@ + + */ + protected function get_subvalues_specs(): array { + return array( + 'InitialTabName' => array( + 'values' => array( 'tools', 'performance' ), + 'default' => 'tools', + ), + 'PerformanceStats' => array( + 'values' => array( + 'Period' => array( '10m', '1h', '2h', '4h', '24h', '7d', '30d' ), + 'VisibleDataPoints' => array( 'views', 'visitors', 'avgEngaged', 'recirculation' ), + 'VisiblePanels' => array( 'overview', 'categories', 'referrers' ), + ), + 'default' => array( + 'Period' => '7d', + 'VisibleDataPoints' => array( 'views', 'visitors', 'avgEngaged', 'recirculation' ), + 'VisiblePanels' => array( 'overview', 'categories', 'referrers' ), + ), + ), + 'RelatedPosts' => array( + 'values' => array( + 'FilterBy' => array( 'unavailable', 'tag', 'section', 'author' ), + 'FilterValue' => array(), + 'Metric' => array( 'views', 'avg_engaged' ), + 'Open' => array( true, false ), + 'Period' => array( '10m', '1h', '2h', '4h', '24h', '7d', '30d' ), + ), + 'default' => array( + 'FilterBy' => 'unavailable', + 'FilterValue' => '', + 'Metric' => 'views', + 'Open' => false, + 'Period' => '7d', + ), + ), + 'SmartLinking' => array( + 'values' => array( + 'MaxLinks' => array(), + 'MaxLinkWords' => array(), + 'Open' => array( true, false ), + ), + 'default' => array( + 'MaxLinks' => 10, + 'MaxLinkWords' => 4, + 'Open' => false, + ), + ), + 'TitleSuggestions' => array( + 'values' => array( + 'Open' => array( true, false ), + 'Persona' => array(), + 'Tone' => array(), + ), + 'default' => array( + 'Open' => false, + 'Persona' => 'journalist', + 'Tone' => 'neutral', + ), + ), + ); + } +} diff --git a/src/rest-api/settings/class-settings-controller.php b/src/rest-api/settings/class-settings-controller.php new file mode 100644 index 000000000..30760c938 --- /dev/null +++ b/src/rest-api/settings/class-settings-controller.php @@ -0,0 +1,47 @@ +register_endpoints( $endpoints ); + } +} From 36ade72fc116d9ed2e2f05e1016f226dbeeb8745 Mon Sep 17 00:00:00 2001 From: Henrique Mouta Date: Fri, 30 Aug 2024 10:57:46 +0100 Subject: [PATCH 068/282] Update UI to use the new settings API --- build/content-helper/dashboard-widget.asset.php | 2 +- build/content-helper/dashboard-widget.js | 2 +- build/content-helper/editor-sidebar.asset.php | 2 +- build/content-helper/editor-sidebar.js | 6 +++--- src/content-helper/common/settings/provider.tsx | 3 ++- src/content-helper/dashboard-widget/dashboard-widget.tsx | 2 +- src/content-helper/editor-sidebar/editor-sidebar.tsx | 4 ++-- .../editor-sidebar/smart-linking/smart-linking.tsx | 2 +- 8 files changed, 12 insertions(+), 11 deletions(-) diff --git a/build/content-helper/dashboard-widget.asset.php b/build/content-helper/dashboard-widget.asset.php index a464c3757..403267823 100644 --- a/build/content-helper/dashboard-widget.asset.php +++ b/build/content-helper/dashboard-widget.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => 'd852566173ef137708b0'); + array('react', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => 'b654f2e02d29a1665104'); diff --git a/build/content-helper/dashboard-widget.js b/build/content-helper/dashboard-widget.js index 7b17d4192..83b5454f9 100644 --- a/build/content-helper/dashboard-widget.js +++ b/build/content-helper/dashboard-widget.js @@ -1 +1 @@ -!function(){"use strict";var e={20:function(e,t,r){var n=r(609),a=Symbol.for("react.element"),s=Symbol.for("react.fragment"),o=Object.prototype.hasOwnProperty,i=n.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function c(e,t,r){var n,s={},c=null,u=null;for(n in void 0!==r&&(c=""+r),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(u=t.ref),t)o.call(t,n)&&!l.hasOwnProperty(n)&&(s[n]=t[n]);if(e&&e.defaultProps)for(n in t=e.defaultProps)void 0===s[n]&&(s[n]=t[n]);return{$$typeof:a,type:e,key:c,ref:u,props:s,_owner:i.current}}t.Fragment=s,t.jsx=c,t.jsxs=c},848:function(e,t,r){e.exports=r(20)},609:function(e){e.exports=window.React}},t={};function r(n){var a=t[n];if(void 0!==a)return a.exports;var s=t[n]={exports:{}};return e[n](s,s.exports,r),s.exports}r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,{a:t}),t},r.d=function(e,t){for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},function(){var e,t,n,a=r(848),s=window.wp.element,o=window.wp.i18n,i=function(e){void 0===e&&(e=null);var t="";(null==e?void 0:e.children)&&(t=e.children);var r="content-helper-error-message";return(null==e?void 0:e.className)&&(r+=" "+e.className),(0,a.jsx)("div",{className:r,"data-testid":null==e?void 0:e.testId,dangerouslySetInnerHTML:{__html:t}})},l=function(e){var t;return void 0===e&&(e=null),(0,a.jsx)(i,{className:null==e?void 0:e.className,testId:"empty-credentials-message",children:null!==(t=window.wpParselyEmptyCredentialsMessage)&&void 0!==t?t:(0,o.__)("Please ensure that the Site ID and API Secret given in the plugin's settings are correct.","wp-parsely")})},c=function(){return c=Object.assign||function(e){for(var t,r=1,n=arguments.length;r0&&a[a.length-1])||6!==i[0]&&2!==i[0])){o=0;continue}if(3===i[0]&&(!a||i[1]>a[0]&&i[1]=1e4&&(clearInterval(s),r("Telemetry library not loaded"))}),100);else r("Telemetry not enabled")}))},e.prototype.trackEvent=function(t,r){var n;this.isLoaded?(0!==t.indexOf(e.TRACKS_PREFIX)&&(t=e.TRACKS_PREFIX+t),this.isEventNameValid(t)?(r=this.prepareProperties(r),null===(n=this._tkq)||void 0===n||n.push(["recordEvent",t,r])):console.error("Error tracking event: Invalid event name")):console.error("Error tracking event: Telemetry not loaded")},e.prototype.isTelemetryEnabled=function(){return this.isEnabled},e.prototype.isProprietyValid=function(t){return e.PROPERTY_REGEX.test(t)},e.prototype.isEventNameValid=function(t){return e.EVENT_NAME_REGEX.test(t)},e.prototype.prepareProperties=function(e){return(e=this.sanitizeProperties(e)).parsely_version=wpParselyTracksTelemetry.version,wpParselyTracksTelemetry.user&&(e._ut=wpParselyTracksTelemetry.user.type,e._ui=wpParselyTracksTelemetry.user.id),wpParselyTracksTelemetry.vipgo_env&&(e.vipgo_env=wpParselyTracksTelemetry.vipgo_env),this.sanitizeProperties(e)},e.prototype.sanitizeProperties=function(e){var t=this,r={};return Object.keys(e).forEach((function(n){t.isProprietyValid(n)&&(r[n]=e[n])})),r},e.TRACKS_PREFIX="wpparsely_",e.EVENT_NAME_REGEX=/^(([a-z0-9]+)_){2}([a-z0-9_]+)$/,e.PROPERTY_REGEX=/^[a-z_][a-z0-9_]*$/,e}(),h=(d.trackEvent,function(e){var t=e.defaultValue,r=e.items,n=e.onChange;return(0,a.jsx)("select",{onChange:n,value:t,children:r.map((function(e){return(0,a.jsx)("option",{value:e[0],children:e[1]},e[0])}))})}),f=window.wp.data,y=function(){return y=Object.assign||function(e){for(var t,r=1,n=arguments.length;rhere.',"wp-parsely"):s.code===j.ParselySuggestionsApiOpenAiError||s.code===j.ParselySuggestionsApiOpenAiUnavailable?s.message=(0,o.__)("The Parse.ly API returned an internal server error. Please retry with a different input, or try again later.","wp-parsely"):s.code===j.HttpRequestFailed&&s.message.includes("cURL error 28")?s.message=(0,o.__)("The Parse.ly API did not respond in a timely manner. Please try again later.","wp-parsely"):s.code===j.ParselySuggestionsApiSchemaError?s.message=(0,o.__)("The Parse.ly API returned a validation error. Please try again with different parameters.","wp-parsely"):s.code===j.ParselySuggestionsApiNoData?s.message=(0,o.__)("The Parse.ly API couldn't find any relevant data to fulfill the request. Please retry with a different input.","wp-parsely"):s.code===j.ParselySuggestionsApiOpenAiSchema?s.message=(0,o.__)("The Parse.ly API returned an incorrect response. Please try again later.","wp-parsely"):s.code===j.ParselySuggestionsApiAuthUnavailable&&(s.message=(0,o.__)("The Parse.ly API is currently unavailable. Please try again later.","wp-parsely")),s}return C(t,e),t.prototype.Message=function(e){return void 0===e&&(e=null),[j.PluginCredentialsNotSetMessageDetected,j.PluginSettingsSiteIdNotSet,j.PluginSettingsApiSecretNotSet].includes(this.code)?l(e):(this.code===j.FetchError&&(this.hint=this.Hint((0,o.__)("This error can sometimes be caused by ad-blockers or browser tracking protections. Please add this site to any applicable allow lists and try again.","wp-parsely"))),this.code!==j.ParselyApiForbidden&&this.code!==j.ParselySuggestionsApiNoAuthentication||(this.hint=this.Hint((0,o.__)("Please ensure that the Site ID and API Secret given in the plugin's settings are correct.","wp-parsely"))),this.code===j.HttpRequestFailed&&(this.hint=this.Hint((0,o.__)("The Parse.ly API cannot be reached. Please verify that you are online.","wp-parsely"))),(0,a.jsx)(i,{className:null==e?void 0:e.className,testId:"error",children:"

".concat(this.message,"

").concat(this.hint?this.hint:"")}))},t.prototype.Hint=function(e){return'

'.concat((0,o.__)("Hint:","wp-parsely")," ").concat(e,"

")},t.prototype.createErrorSnackbar=function(){//.test(this.message)||(0,f.dispatch)("core/notices").createNotice("error",this.message,{type:"snackbar"})},t}(Error),O=function(){function e(){this.abortControllers=new Map}return e.prototype.cancelRequest=function(e){if(e)(t=this.abortControllers.get(e))&&(t.abort(),this.abortControllers.delete(e));else{var t,r=Array.from(this.abortControllers.keys()).pop();r&&(t=this.abortControllers.get(r))&&(t.abort(),this.abortControllers.delete(r))}},e.prototype.cancelAll=function(){this.abortControllers.forEach((function(e){return e.abort()})),this.abortControllers.clear()},e.prototype.getOrCreateController=function(e){if(e&&this.abortControllers.has(e))return{abortController:this.abortControllers.get(e),abortId:e};var t=null!=e?e:"auto-"+Date.now(),r=new AbortController;return this.abortControllers.set(t,r),{abortController:r,abortId:t}},e.prototype.fetch=function(e,t){return r=this,n=void 0,s=function(){var r,n,a,s,i,l;return function(e,t){var r,n,a,s,o={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]};return s={next:i(0),throw:i(1),return:i(2)},"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function i(i){return function(l){return function(i){if(r)throw new TypeError("Generator is already executing.");for(;s&&(s=0,i[0]&&(o=0)),o;)try{if(r=1,n&&(a=2&i[0]?n.return:i[0]?n.throw||((a=n.return)&&a.call(n),0):n.next)&&!(a=a.call(n,i[1])).done)return a;switch(n=0,a&&(i=[2&i[0],a.value]),i[0]){case 0:case 1:a=i;break;case 4:return o.label++,{value:i[1],done:!1};case 5:o.label++,n=i[1],i=[0];continue;case 7:i=o.ops.pop(),o.trys.pop();continue;default:if(!((a=(a=o.trys).length>0&&a[a.length-1])||6!==i[0]&&2!==i[0])){o=0;continue}if(3===i[0]&&(!a||i[1]>a[0]&&i[1]0&&a[a.length-1])||6!==i[0]&&2!==i[0])){o=0;continue}if(3===i[0]&&(!a||i[1]>a[0]&&i[1]=c){var u=t;(a=n/c)%1>1/i&&(u=a>10?1:2),u=parseFloat(a.toFixed(2))===parseFloat(a.toFixed(0))?0:u,s=a.toFixed(u),o=l}i=c})),s+r+o}function z(e){var t=e.metric,r=e.post,n=e.avgEngagedIcon,s=e.viewsIcon;return"views"===t?(0,a.jsxs)("span",{className:"parsely-post-metric-data",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Number of Views","wp-parsely")}),s,$(r.views.toString())]}):"avg_engaged"===t?(0,a.jsxs)("span",{className:"parsely-post-metric-data",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Average Time","wp-parsely")}),n,r.avgEngaged]}):(0,a.jsx)("span",{className:"parsely-post-metric-data",children:"-"})}function X(e){var t,r=e.metric,n=e.post;return(0,a.jsx)("li",{className:"parsely-top-post",children:(0,a.jsxs)("div",{className:"parsely-top-post-content",children:[(0,a.jsx)(B,{post:n}),(0,a.jsxs)("div",{className:"parsely-top-post-data",children:[(0,a.jsx)(z,{metric:r,post:n}),(0,a.jsx)(Z,{post:n}),(0,a.jsxs)("a",{className:"parsely-top-post-icon-link",href:n.url,target:"_blank",rel:"noreferrer",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("View Post (opens in new tab)","wp-parsely")}),(0,a.jsx)(q,{})]}),0!==n.postId&&(0,a.jsxs)("a",{className:"parsely-top-post-icon-link",href:(t=n.postId,"/wp-admin/post.php?post=".concat(t,"&action=edit")),target:"_blank",rel:"noreferrer",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Edit Post (opens in new tab)","wp-parsely")}),(0,a.jsx)(G,{})]}),(0,a.jsxs)("div",{className:"parsely-top-post-metadata",children:[(0,a.jsxs)("span",{className:"parsely-top-post-date",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Date","wp-parsely")}),M(new Date(n.date))]}),(0,a.jsxs)("span",{className:"parsely-top-post-author",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Author","wp-parsely")}),n.author]})]})]})]})},n.id)}function B(e){var t=e.post;return t.thumbnailUrl?(0,a.jsxs)("div",{className:"parsely-top-post-thumbnail",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Thumbnail","wp-parsely")}),(0,a.jsx)("img",{src:t.thumbnailUrl,alt:(0,o.__)("Post thumbnail","wp-parsely")})]}):(0,a.jsx)("div",{className:"parsely-top-post-thumbnail",children:(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Post thumbnail not available","wp-parsely")})})}function Z(e){var t=e.post;return(0,a.jsxs)("a",{className:"parsely-top-post-title",href:t.dashUrl,target:"_blank",rel:"noreferrer",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("View in Parse.ly (opens in new tab)","wp-parsely")}),t.title]})}var W=function(){return W=Object.assign||function(e){for(var t,r=1,n=arguments.length;r0&&a[a.length-1])||6!==i[0]&&2!==i[0])){o=0;continue}if(3===i[0]&&(!a||i[1]>a[0]&&i[1]0&&e.retryFetch?[4,new Promise((function(e){return setTimeout(e,500)}))]:[3,3];case 1:return r.sent(),[4,t(n-1)];case 2:return r.sent(),[3,4];case 3:f(!1),v(e),r.label=4;case 4:return[2]}}))}))})),[2]}))}))};return f(!0),t(1),function(){f(!1),m([]),v(void 0)}}),[i,S]);var j=function(e,t){d.trackEvent("dash_widget_filter_changed",W({filter:e},t))},N=(0,a.jsxs)("div",{className:"parsely-top-posts-filters",children:[(0,a.jsx)(h,{defaultValue:i.Period,items:Object.values(e).map((function(e){return[e,A(e)]})),onChange:function(t){x(t.target.value,e)&&(l({Period:t.target.value}),j("period",{period:t.target.value}),T(1))}}),(0,a.jsx)(h,{defaultValue:i.Metric,items:Object.values(t).map((function(e){return[e,E(e)]})),onChange:function(e){x(e.target.value,t)&&(l({Metric:e.target.value}),j("metric",{metric:e.target.value}),T(1))}})]}),C=(0,a.jsxs)("div",{className:"parsely-top-posts-navigation",children:[(0,a.jsx)("button",{className:"parsely-top-posts-navigation-prev",disabled:S<=1,"aria-label":(0,o.__)("Previous page","wp-parsely"),onClick:function(){T(S-1),d.trackEvent("dash_widget_navigation",{navigation:"previous",to_page:S-1})},children:(0,o.__)("<< Previous","wp-parsely")}),(0,o.sprintf)(/* translators: 1: Current page */ /* translators: 1: Current page */(0,o.__)("Page %1$d","wp-parsely"),S),(0,a.jsx)("button",{className:"parsely-top-posts-navigation-next",disabled:!u&&_.length<5,"aria-label":(0,o.__)("Next page","wp-parsely"),onClick:function(){T(S+1),d.trackEvent("dash_widget_navigation",{navigation:"next",to_page:S+1})},children:(0,o.__)("Next >>","wp-parsely")})]});if(g)return(0,a.jsxs)(a.Fragment,{children:[N,g.Message(),S>1&&C]});var k=(0,a.jsx)("div",{className:"parsely-spinner-wrapper",children:(0,a.jsx)(p.Spinner,{})});return(0,a.jsxs)(a.Fragment,{children:[N,u?k:(0,a.jsx)("ol",{className:"parsely-top-posts",style:{counterReset:"item "+5*(S-1)},children:_.map((function(e){return(0,a.jsx)(X,{metric:i.Metric,post:e},e.id)}))}),(_.length>=5||S>1)&&C]})}var J=function(r){var n;try{n=JSON.parse(r)}catch(r){return{Metric:t.Views,Period:e.Days7}}return x(null==n?void 0:n.Metric,t)||(n.Metric=t.Views),x(null==n?void 0:n.Period,e)||(n.Period=e.Days7),n};window.addEventListener("load",(function(){var e=document.querySelector("#wp-parsely-dashboard-widget > .inside");if(null!==e){var t=(0,a.jsx)(S,{endpoint:"dashboard-widget-settings",defaultSettings:J(window.wpParselyContentHelperSettings),children:(0,a.jsx)(u,{children:(0,a.jsx)(Q,{})})});s.createRoot?(0,s.createRoot)(e).render(t):(0,s.render)(t,e)}}),!1)}()}(); \ No newline at end of file +!function(){"use strict";var e={20:function(e,t,r){var n=r(609),a=Symbol.for("react.element"),s=Symbol.for("react.fragment"),o=Object.prototype.hasOwnProperty,i=n.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function c(e,t,r){var n,s={},c=null,u=null;for(n in void 0!==r&&(c=""+r),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(u=t.ref),t)o.call(t,n)&&!l.hasOwnProperty(n)&&(s[n]=t[n]);if(e&&e.defaultProps)for(n in t=e.defaultProps)void 0===s[n]&&(s[n]=t[n]);return{$$typeof:a,type:e,key:c,ref:u,props:s,_owner:i.current}}t.Fragment=s,t.jsx=c,t.jsxs=c},848:function(e,t,r){e.exports=r(20)},609:function(e){e.exports=window.React}},t={};function r(n){var a=t[n];if(void 0!==a)return a.exports;var s=t[n]={exports:{}};return e[n](s,s.exports,r),s.exports}r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,{a:t}),t},r.d=function(e,t){for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},function(){var e,t,n,a=r(848),s=window.wp.element,o=window.wp.i18n,i=function(e){void 0===e&&(e=null);var t="";(null==e?void 0:e.children)&&(t=e.children);var r="content-helper-error-message";return(null==e?void 0:e.className)&&(r+=" "+e.className),(0,a.jsx)("div",{className:r,"data-testid":null==e?void 0:e.testId,dangerouslySetInnerHTML:{__html:t}})},l=function(e){var t;return void 0===e&&(e=null),(0,a.jsx)(i,{className:null==e?void 0:e.className,testId:"empty-credentials-message",children:null!==(t=window.wpParselyEmptyCredentialsMessage)&&void 0!==t?t:(0,o.__)("Please ensure that the Site ID and API Secret given in the plugin's settings are correct.","wp-parsely")})},c=function(){return c=Object.assign||function(e){for(var t,r=1,n=arguments.length;r0&&a[a.length-1])||6!==i[0]&&2!==i[0])){o=0;continue}if(3===i[0]&&(!a||i[1]>a[0]&&i[1]=1e4&&(clearInterval(s),r("Telemetry library not loaded"))}),100);else r("Telemetry not enabled")}))},e.prototype.trackEvent=function(t,r){var n;this.isLoaded?(0!==t.indexOf(e.TRACKS_PREFIX)&&(t=e.TRACKS_PREFIX+t),this.isEventNameValid(t)?(r=this.prepareProperties(r),null===(n=this._tkq)||void 0===n||n.push(["recordEvent",t,r])):console.error("Error tracking event: Invalid event name")):console.error("Error tracking event: Telemetry not loaded")},e.prototype.isTelemetryEnabled=function(){return this.isEnabled},e.prototype.isProprietyValid=function(t){return e.PROPERTY_REGEX.test(t)},e.prototype.isEventNameValid=function(t){return e.EVENT_NAME_REGEX.test(t)},e.prototype.prepareProperties=function(e){return(e=this.sanitizeProperties(e)).parsely_version=wpParselyTracksTelemetry.version,wpParselyTracksTelemetry.user&&(e._ut=wpParselyTracksTelemetry.user.type,e._ui=wpParselyTracksTelemetry.user.id),wpParselyTracksTelemetry.vipgo_env&&(e.vipgo_env=wpParselyTracksTelemetry.vipgo_env),this.sanitizeProperties(e)},e.prototype.sanitizeProperties=function(e){var t=this,r={};return Object.keys(e).forEach((function(n){t.isProprietyValid(n)&&(r[n]=e[n])})),r},e.TRACKS_PREFIX="wpparsely_",e.EVENT_NAME_REGEX=/^(([a-z0-9]+)_){2}([a-z0-9_]+)$/,e.PROPERTY_REGEX=/^[a-z_][a-z0-9_]*$/,e}(),h=(d.trackEvent,function(e){var t=e.defaultValue,r=e.items,n=e.onChange;return(0,a.jsx)("select",{onChange:n,value:t,children:r.map((function(e){return(0,a.jsx)("option",{value:e[0],children:e[1]},e[0])}))})}),f=window.wp.data,y=function(){return y=Object.assign||function(e){for(var t,r=1,n=arguments.length;rhere.',"wp-parsely"):s.code===j.ParselySuggestionsApiOpenAiError||s.code===j.ParselySuggestionsApiOpenAiUnavailable?s.message=(0,o.__)("The Parse.ly API returned an internal server error. Please retry with a different input, or try again later.","wp-parsely"):s.code===j.HttpRequestFailed&&s.message.includes("cURL error 28")?s.message=(0,o.__)("The Parse.ly API did not respond in a timely manner. Please try again later.","wp-parsely"):s.code===j.ParselySuggestionsApiSchemaError?s.message=(0,o.__)("The Parse.ly API returned a validation error. Please try again with different parameters.","wp-parsely"):s.code===j.ParselySuggestionsApiNoData?s.message=(0,o.__)("The Parse.ly API couldn't find any relevant data to fulfill the request. Please retry with a different input.","wp-parsely"):s.code===j.ParselySuggestionsApiOpenAiSchema?s.message=(0,o.__)("The Parse.ly API returned an incorrect response. Please try again later.","wp-parsely"):s.code===j.ParselySuggestionsApiAuthUnavailable&&(s.message=(0,o.__)("The Parse.ly API is currently unavailable. Please try again later.","wp-parsely")),s}return C(t,e),t.prototype.Message=function(e){return void 0===e&&(e=null),[j.PluginCredentialsNotSetMessageDetected,j.PluginSettingsSiteIdNotSet,j.PluginSettingsApiSecretNotSet].includes(this.code)?l(e):(this.code===j.FetchError&&(this.hint=this.Hint((0,o.__)("This error can sometimes be caused by ad-blockers or browser tracking protections. Please add this site to any applicable allow lists and try again.","wp-parsely"))),this.code!==j.ParselyApiForbidden&&this.code!==j.ParselySuggestionsApiNoAuthentication||(this.hint=this.Hint((0,o.__)("Please ensure that the Site ID and API Secret given in the plugin's settings are correct.","wp-parsely"))),this.code===j.HttpRequestFailed&&(this.hint=this.Hint((0,o.__)("The Parse.ly API cannot be reached. Please verify that you are online.","wp-parsely"))),(0,a.jsx)(i,{className:null==e?void 0:e.className,testId:"error",children:"

".concat(this.message,"

").concat(this.hint?this.hint:"")}))},t.prototype.Hint=function(e){return'

'.concat((0,o.__)("Hint:","wp-parsely")," ").concat(e,"

")},t.prototype.createErrorSnackbar=function(){//.test(this.message)||(0,f.dispatch)("core/notices").createNotice("error",this.message,{type:"snackbar"})},t}(Error),O=function(){function e(){this.abortControllers=new Map}return e.prototype.cancelRequest=function(e){if(e)(t=this.abortControllers.get(e))&&(t.abort(),this.abortControllers.delete(e));else{var t,r=Array.from(this.abortControllers.keys()).pop();r&&(t=this.abortControllers.get(r))&&(t.abort(),this.abortControllers.delete(r))}},e.prototype.cancelAll=function(){this.abortControllers.forEach((function(e){return e.abort()})),this.abortControllers.clear()},e.prototype.getOrCreateController=function(e){if(e&&this.abortControllers.has(e))return{abortController:this.abortControllers.get(e),abortId:e};var t=null!=e?e:"auto-"+Date.now(),r=new AbortController;return this.abortControllers.set(t,r),{abortController:r,abortId:t}},e.prototype.fetch=function(e,t){return r=this,n=void 0,s=function(){var r,n,a,s,i,l;return function(e,t){var r,n,a,s,o={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]};return s={next:i(0),throw:i(1),return:i(2)},"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function i(i){return function(l){return function(i){if(r)throw new TypeError("Generator is already executing.");for(;s&&(s=0,i[0]&&(o=0)),o;)try{if(r=1,n&&(a=2&i[0]?n.return:i[0]?n.throw||((a=n.return)&&a.call(n),0):n.next)&&!(a=a.call(n,i[1])).done)return a;switch(n=0,a&&(i=[2&i[0],a.value]),i[0]){case 0:case 1:a=i;break;case 4:return o.label++,{value:i[1],done:!1};case 5:o.label++,n=i[1],i=[0];continue;case 7:i=o.ops.pop(),o.trys.pop();continue;default:if(!((a=(a=o.trys).length>0&&a[a.length-1])||6!==i[0]&&2!==i[0])){o=0;continue}if(3===i[0]&&(!a||i[1]>a[0]&&i[1]0&&a[a.length-1])||6!==i[0]&&2!==i[0])){o=0;continue}if(3===i[0]&&(!a||i[1]>a[0]&&i[1]=c){var u=t;(a=n/c)%1>1/i&&(u=a>10?1:2),u=parseFloat(a.toFixed(2))===parseFloat(a.toFixed(0))?0:u,s=a.toFixed(u),o=l}i=c})),s+r+o}function z(e){var t=e.metric,r=e.post,n=e.avgEngagedIcon,s=e.viewsIcon;return"views"===t?(0,a.jsxs)("span",{className:"parsely-post-metric-data",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Number of Views","wp-parsely")}),s,$(r.views.toString())]}):"avg_engaged"===t?(0,a.jsxs)("span",{className:"parsely-post-metric-data",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Average Time","wp-parsely")}),n,r.avgEngaged]}):(0,a.jsx)("span",{className:"parsely-post-metric-data",children:"-"})}function X(e){var t,r=e.metric,n=e.post;return(0,a.jsx)("li",{className:"parsely-top-post",children:(0,a.jsxs)("div",{className:"parsely-top-post-content",children:[(0,a.jsx)(B,{post:n}),(0,a.jsxs)("div",{className:"parsely-top-post-data",children:[(0,a.jsx)(z,{metric:r,post:n}),(0,a.jsx)(Z,{post:n}),(0,a.jsxs)("a",{className:"parsely-top-post-icon-link",href:n.url,target:"_blank",rel:"noreferrer",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("View Post (opens in new tab)","wp-parsely")}),(0,a.jsx)(q,{})]}),0!==n.postId&&(0,a.jsxs)("a",{className:"parsely-top-post-icon-link",href:(t=n.postId,"/wp-admin/post.php?post=".concat(t,"&action=edit")),target:"_blank",rel:"noreferrer",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Edit Post (opens in new tab)","wp-parsely")}),(0,a.jsx)(G,{})]}),(0,a.jsxs)("div",{className:"parsely-top-post-metadata",children:[(0,a.jsxs)("span",{className:"parsely-top-post-date",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Date","wp-parsely")}),M(new Date(n.date))]}),(0,a.jsxs)("span",{className:"parsely-top-post-author",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Author","wp-parsely")}),n.author]})]})]})]})},n.id)}function B(e){var t=e.post;return t.thumbnailUrl?(0,a.jsxs)("div",{className:"parsely-top-post-thumbnail",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Thumbnail","wp-parsely")}),(0,a.jsx)("img",{src:t.thumbnailUrl,alt:(0,o.__)("Post thumbnail","wp-parsely")})]}):(0,a.jsx)("div",{className:"parsely-top-post-thumbnail",children:(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("Post thumbnail not available","wp-parsely")})})}function Z(e){var t=e.post;return(0,a.jsxs)("a",{className:"parsely-top-post-title",href:t.dashUrl,target:"_blank",rel:"noreferrer",children:[(0,a.jsx)("span",{className:"screen-reader-text",children:(0,o.__)("View in Parse.ly (opens in new tab)","wp-parsely")}),t.title]})}var W=function(){return W=Object.assign||function(e){for(var t,r=1,n=arguments.length;r0&&a[a.length-1])||6!==i[0]&&2!==i[0])){o=0;continue}if(3===i[0]&&(!a||i[1]>a[0]&&i[1]0&&e.retryFetch?[4,new Promise((function(e){return setTimeout(e,500)}))]:[3,3];case 1:return r.sent(),[4,t(n-1)];case 2:return r.sent(),[3,4];case 3:f(!1),v(e),r.label=4;case 4:return[2]}}))}))})),[2]}))}))};return f(!0),t(1),function(){f(!1),m([]),v(void 0)}}),[i,S]);var j=function(e,t){d.trackEvent("dash_widget_filter_changed",W({filter:e},t))},N=(0,a.jsxs)("div",{className:"parsely-top-posts-filters",children:[(0,a.jsx)(h,{defaultValue:i.Period,items:Object.values(e).map((function(e){return[e,A(e)]})),onChange:function(t){x(t.target.value,e)&&(l({Period:t.target.value}),j("period",{period:t.target.value}),T(1))}}),(0,a.jsx)(h,{defaultValue:i.Metric,items:Object.values(t).map((function(e){return[e,E(e)]})),onChange:function(e){x(e.target.value,t)&&(l({Metric:e.target.value}),j("metric",{metric:e.target.value}),T(1))}})]}),C=(0,a.jsxs)("div",{className:"parsely-top-posts-navigation",children:[(0,a.jsx)("button",{className:"parsely-top-posts-navigation-prev",disabled:S<=1,"aria-label":(0,o.__)("Previous page","wp-parsely"),onClick:function(){T(S-1),d.trackEvent("dash_widget_navigation",{navigation:"previous",to_page:S-1})},children:(0,o.__)("<< Previous","wp-parsely")}),(0,o.sprintf)(/* translators: 1: Current page */ /* translators: 1: Current page */(0,o.__)("Page %1$d","wp-parsely"),S),(0,a.jsx)("button",{className:"parsely-top-posts-navigation-next",disabled:!u&&_.length<5,"aria-label":(0,o.__)("Next page","wp-parsely"),onClick:function(){T(S+1),d.trackEvent("dash_widget_navigation",{navigation:"next",to_page:S+1})},children:(0,o.__)("Next >>","wp-parsely")})]});if(g)return(0,a.jsxs)(a.Fragment,{children:[N,g.Message(),S>1&&C]});var k=(0,a.jsx)("div",{className:"parsely-spinner-wrapper",children:(0,a.jsx)(p.Spinner,{})});return(0,a.jsxs)(a.Fragment,{children:[N,u?k:(0,a.jsx)("ol",{className:"parsely-top-posts",style:{counterReset:"item "+5*(S-1)},children:_.map((function(e){return(0,a.jsx)(X,{metric:i.Metric,post:e},e.id)}))}),(_.length>=5||S>1)&&C]})}var J=function(r){var n;try{n=JSON.parse(r)}catch(r){return{Metric:t.Views,Period:e.Days7}}return x(null==n?void 0:n.Metric,t)||(n.Metric=t.Views),x(null==n?void 0:n.Period,e)||(n.Period=e.Days7),n};window.addEventListener("load",(function(){var e=document.querySelector("#wp-parsely-dashboard-widget > .inside");if(null!==e){var t=(0,a.jsx)(S,{endpoint:"dashboard-widget",defaultSettings:J(window.wpParselyContentHelperSettings),children:(0,a.jsx)(u,{children:(0,a.jsx)(Q,{})})});s.createRoot?(0,s.createRoot)(e).render(t):(0,s.render)(t,e)}}),!1)}()}(); \ No newline at end of file diff --git a/build/content-helper/editor-sidebar.asset.php b/build/content-helper/editor-sidebar.asset.php index a791b1c32..e3d486552 100644 --- a/build/content-helper/editor-sidebar.asset.php +++ b/build/content-helper/editor-sidebar.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-dom-ready', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-plugins', 'wp-primitives', 'wp-url'), 'version' => 'eaad1ca5764f3fbdb9e6'); + array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-dom-ready', 'wp-editor', 'wp-element', 'wp-hooks', 'wp-i18n', 'wp-plugins', 'wp-primitives', 'wp-url'), 'version' => '7d87b64bdabeaf1dc579'); diff --git a/build/content-helper/editor-sidebar.js b/build/content-helper/editor-sidebar.js index 697b66067..9723913d5 100644 --- a/build/content-helper/editor-sidebar.js +++ b/build/content-helper/editor-sidebar.js @@ -1,9 +1,9 @@ -!function(){"use strict";var e={20:function(e,t,n){var r=n(609),i=Symbol.for("react.element"),s=Symbol.for("react.fragment"),o=Object.prototype.hasOwnProperty,a=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function c(e,t,n){var r,s={},c=null,u=null;for(r in void 0!==n&&(c=""+n),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(u=t.ref),t)o.call(t,r)&&!l.hasOwnProperty(r)&&(s[r]=t[r]);if(e&&e.defaultProps)for(r in t=e.defaultProps)void 0===s[r]&&(s[r]=t[r]);return{$$typeof:i,type:e,key:c,ref:u,props:s,_owner:a.current}}t.Fragment=s,t.jsx=c,t.jsxs=c},848:function(e,t,n){e.exports=n(20)},609:function(e){e.exports=window.React}},t={};function n(r){var i=t[r];if(void 0!==i)return i.exports;var s=t[r]={exports:{}};return e[r](s,s.exports,n),s.exports}n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,{a:t}),t},n.d=function(e,t){for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},function(){n.d({},{_:function(){return ur}});var e,t,r,i,s,o,a,l,c,u,d,p=n(848),f=window.wp.components,h=window.wp.data,v=window.wp.domReady,g=n.n(v);void 0!==window.wp&&(null!==(t=null===(e=window.wp.editor)||void 0===e?void 0:e.PluginDocumentSettingPanel)&&void 0!==t||(null!==(i=null===(r=window.wp.editPost)||void 0===r?void 0:r.PluginDocumentSettingPanel)&&void 0!==i||(null===(s=window.wp.editSite)||void 0===s||s.PluginDocumentSettingPanel)),d=null!==(a=null===(o=window.wp.editor)||void 0===o?void 0:o.PluginSidebar)&&void 0!==a?a:null!==(c=null===(l=window.wp.editPost)||void 0===l?void 0:l.PluginSidebar)&&void 0!==c?c:null===(u=window.wp.editSite)||void 0===u?void 0:u.PluginSidebar);var y,m,w,b=window.wp.element,_=window.wp.i18n,x=window.wp.primitives,k=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{fillRule:"evenodd",d:"M11.25 5h1.5v15h-1.5V5zM6 10h1.5v10H6V10zm12 4h-1.5v6H18v-6z",clipRule:"evenodd"})}),S=window.wp.plugins,P=function(){function e(){this._tkq=[],this.isLoaded=!1,this.isEnabled=!1,"undefined"!=typeof wpParselyTracksTelemetry&&(this.isEnabled=!0,this.loadTrackingLibrary())}return e.getInstance=function(){return window.wpParselyTelemetryInstance||Object.defineProperty(window,"wpParselyTelemetryInstance",{value:new e,writable:!1,configurable:!1,enumerable:!1}),window.wpParselyTelemetryInstance},e.prototype.loadTrackingLibrary=function(){var e=this,t=document.createElement("script");t.async=!0,t.src="//stats.wp.com/w.js",t.onload=function(){e.isLoaded=!0,e._tkq=window._tkq||[]},document.head.appendChild(t)},e.trackEvent=function(t){return n=this,r=arguments,s=function(t,n){var r;return void 0===n&&(n={}),function(e,t){var n,r,i,s,o={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return s={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function a(a){return function(l){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;s&&(s=0,a[0]&&(o=0)),o;)try{if(n=1,r&&(i=2&a[0]?r.return:a[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,a[1])).done)return i;switch(r=0,i&&(a=[2&a[0],i.value]),a[0]){case 0:case 1:i=a;break;case 4:return o.label++,{value:a[1],done:!1};case 5:o.label++,r=a[1],a=[0];continue;case 7:a=o.ops.pop(),o.trys.pop();continue;default:if(!((i=(i=o.trys).length>0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]=1e4&&(clearInterval(s),n("Telemetry library not loaded"))}),100);else n("Telemetry not enabled")}))},e.prototype.trackEvent=function(t,n){var r;this.isLoaded?(0!==t.indexOf(e.TRACKS_PREFIX)&&(t=e.TRACKS_PREFIX+t),this.isEventNameValid(t)?(n=this.prepareProperties(n),null===(r=this._tkq)||void 0===r||r.push(["recordEvent",t,n])):console.error("Error tracking event: Invalid event name")):console.error("Error tracking event: Telemetry not loaded")},e.prototype.isTelemetryEnabled=function(){return this.isEnabled},e.prototype.isProprietyValid=function(t){return e.PROPERTY_REGEX.test(t)},e.prototype.isEventNameValid=function(t){return e.EVENT_NAME_REGEX.test(t)},e.prototype.prepareProperties=function(e){return(e=this.sanitizeProperties(e)).parsely_version=wpParselyTracksTelemetry.version,wpParselyTracksTelemetry.user&&(e._ut=wpParselyTracksTelemetry.user.type,e._ui=wpParselyTracksTelemetry.user.id),wpParselyTracksTelemetry.vipgo_env&&(e.vipgo_env=wpParselyTracksTelemetry.vipgo_env),this.sanitizeProperties(e)},e.prototype.sanitizeProperties=function(e){var t=this,n={};return Object.keys(e).forEach((function(r){t.isProprietyValid(r)&&(n[r]=e[r])})),n},e.TRACKS_PREFIX="wpparsely_",e.EVENT_NAME_REGEX=/^(([a-z0-9]+)_){2}([a-z0-9_]+)$/,e.PROPERTY_REGEX=/^[a-z_][a-z0-9_]*$/,e}(),j=(P.trackEvent,function(){return(0,p.jsx)(f.SVG,{"aria-hidden":"true",version:"1.1",viewBox:"0 0 15 15",width:"15",height:"15",xmlns:"http://www.w3.org/2000/svg",children:(0,p.jsx)(f.Path,{d:"M0 14.0025V11.0025L7.5 3.5025L10.5 6.5025L3 14.0025H0ZM12 5.0025L13.56 3.4425C14.15 2.8525 14.15 1.9025 13.56 1.3225L12.68 0.4425C12.09 -0.1475 11.14 -0.1475 10.56 0.4425L9 2.0025L12 5.0025Z"})})}),T=function(e){var t=e.size,n=void 0===t?24:t,r=e.className,i=void 0===r?"wp-parsely-icon":r;return(0,p.jsxs)(f.SVG,{className:i,height:n,viewBox:"0 0 60 65",width:n,xmlns:"http://www.w3.org/2000/svg",children:[(0,p.jsx)(f.Path,{fill:"#5ba745",d:"M23.72,51.53c0-.18,0-.34-.06-.52a13.11,13.11,0,0,0-2.1-5.53A14.74,14.74,0,0,0,19.12,43c-.27-.21-.5-.11-.51.22l-.24,3.42c0,.33-.38.35-.49,0l-1.5-4.8a1.4,1.4,0,0,0-.77-.78,23.91,23.91,0,0,0-3.1-.84c-1.38-.24-3.39-.39-3.39-.39-.34,0-.45.21-.25.49l2.06,3.76c.2.27,0,.54-.29.33l-4.51-3.6a3.68,3.68,0,0,0-2.86-.48c-1,.16-2.44.46-2.44.46a.68.68,0,0,0-.39.25.73.73,0,0,0-.14.45S.41,43,.54,44a3.63,3.63,0,0,0,1.25,2.62L6.48,50c.28.2.09.49-.23.37l-4.18-.94c-.32-.12-.5,0-.4.37,0,0,.69,1.89,1.31,3.16a24,24,0,0,0,1.66,2.74,1.34,1.34,0,0,0,1,.52l5,.13c.33,0,.41.38.1.48L7.51,58c-.31.1-.34.35-.07.55a14.29,14.29,0,0,0,3.05,1.66,13.09,13.09,0,0,0,5.9.5,25.13,25.13,0,0,0,4.34-1,9.55,9.55,0,0,1-.08-1.2,9.32,9.32,0,0,1,3.07-6.91"}),(0,p.jsx)(f.Path,{fill:"#5ba745",d:"M59.7,41.53a.73.73,0,0,0-.14-.45.68.68,0,0,0-.39-.25s-1.43-.3-2.44-.46a3.64,3.64,0,0,0-2.86.48l-4.51,3.6c-.26.21-.49-.06-.29-.33l2.06-3.76c.2-.28.09-.49-.25-.49,0,0-2,.15-3.39.39a23.91,23.91,0,0,0-3.1.84,1.4,1.4,0,0,0-.77.78l-1.5,4.8c-.11.32-.48.3-.49,0l-.24-3.42c0-.33-.24-.43-.51-.22a14.74,14.74,0,0,0-2.44,2.47A13.11,13.11,0,0,0,36.34,51c0,.18,0,.34-.06.52a9.26,9.26,0,0,1,3,8.1,24.1,24.1,0,0,0,4.34,1,13.09,13.09,0,0,0,5.9-.5,14.29,14.29,0,0,0,3.05-1.66c.27-.2.24-.45-.07-.55l-3.22-1.17c-.31-.1-.23-.47.1-.48l5-.13a1.38,1.38,0,0,0,1-.52A24.6,24.6,0,0,0,57,52.92c.61-1.27,1.31-3.16,1.31-3.16.1-.33-.08-.49-.4-.37l-4.18.94c-.32.12-.51-.17-.23-.37l4.69-3.34A3.63,3.63,0,0,0,59.46,44c.13-1,.24-2.47.24-2.47"}),(0,p.jsx)(f.Path,{fill:"#5ba745",d:"M46.5,25.61c0-.53-.35-.72-.8-.43l-4.86,2.66c-.45.28-.56-.27-.23-.69l4.66-6.23a2,2,0,0,0,.28-1.68,36.51,36.51,0,0,0-2.19-4.89,34,34,0,0,0-2.81-3.94c-.33-.41-.74-.35-.91.16l-2.28,5.68c-.16.5-.6.48-.59-.05l.28-8.93a2.54,2.54,0,0,0-.66-1.64S35,4.27,33.88,3.27,30.78.69,30.78.69a1.29,1.29,0,0,0-1.54,0s-1.88,1.49-3.12,2.59-2.48,2.35-2.48,2.35A2.5,2.5,0,0,0,23,7.27l.27,8.93c0,.53-.41.55-.58.05l-2.29-5.69c-.17-.5-.57-.56-.91-.14a35.77,35.77,0,0,0-3,4.2,35.55,35.55,0,0,0-2,4.62,2,2,0,0,0,.27,1.67l4.67,6.24c.33.42.23,1-.22.69l-4.87-2.66c-.45-.29-.82-.1-.82.43a18.6,18.6,0,0,0,.83,5.07,20.16,20.16,0,0,0,5.37,7.77c3.19,3,5.93,7.8,7.45,11.08A9.6,9.6,0,0,1,30,49.09a9.31,9.31,0,0,1,2.86.45c1.52-3.28,4.26-8.11,7.44-11.09a20.46,20.46,0,0,0,5.09-7,19,19,0,0,0,1.11-5.82"}),(0,p.jsx)(f.Path,{fill:"#5ba745",d:"M36.12,58.44A6.12,6.12,0,1,1,30,52.32a6.11,6.11,0,0,1,6.12,6.12"})]})},L=function(){return L=Object.assign||function(e){for(var t,n=1,r=arguments.length;nhere.',"wp-parsely"):s.code===$.ParselySuggestionsApiOpenAiError||s.code===$.ParselySuggestionsApiOpenAiUnavailable?s.message=(0,_.__)("The Parse.ly API returned an internal server error. Please retry with a different input, or try again later.","wp-parsely"):s.code===$.HttpRequestFailed&&s.message.includes("cURL error 28")?s.message=(0,_.__)("The Parse.ly API did not respond in a timely manner. Please try again later.","wp-parsely"):s.code===$.ParselySuggestionsApiSchemaError?s.message=(0,_.__)("The Parse.ly API returned a validation error. Please try again with different parameters.","wp-parsely"):s.code===$.ParselySuggestionsApiNoData?s.message=(0,_.__)("The Parse.ly API couldn't find any relevant data to fulfill the request. Please retry with a different input.","wp-parsely"):s.code===$.ParselySuggestionsApiOpenAiSchema?s.message=(0,_.__)("The Parse.ly API returned an incorrect response. Please try again later.","wp-parsely"):s.code===$.ParselySuggestionsApiAuthUnavailable&&(s.message=(0,_.__)("The Parse.ly API is currently unavailable. Please try again later.","wp-parsely")),s}return re(t,e),t.prototype.Message=function(e){return void 0===e&&(e=null),[$.PluginCredentialsNotSetMessageDetected,$.PluginSettingsSiteIdNotSet,$.PluginSettingsApiSecretNotSet].includes(this.code)?K(e):(this.code===$.FetchError&&(this.hint=this.Hint((0,_.__)("This error can sometimes be caused by ad-blockers or browser tracking protections. Please add this site to any applicable allow lists and try again.","wp-parsely"))),this.code!==$.ParselyApiForbidden&&this.code!==$.ParselySuggestionsApiNoAuthentication||(this.hint=this.Hint((0,_.__)("Please ensure that the Site ID and API Secret given in the plugin's settings are correct.","wp-parsely"))),this.code===$.HttpRequestFailed&&(this.hint=this.Hint((0,_.__)("The Parse.ly API cannot be reached. Please verify that you are online.","wp-parsely"))),(0,p.jsx)(W,{className:null==e?void 0:e.className,testId:"error",children:"

".concat(this.message,"

").concat(this.hint?this.hint:"")}))},t.prototype.Hint=function(e){return'

'.concat((0,_.__)("Hint:","wp-parsely")," ").concat(e,"

")},t.prototype.createErrorSnackbar=function(){//.test(this.message)||(0,h.dispatch)("core/notices").createNotice("error",this.message,{type:"snackbar"})},t}(Error),se=function(e){var t=e.isDetectingEnabled,n=e.onLinkChange,r=e.onLinkRemove,i=e.onLinkAdd,s=e.debounceValue,o=void 0===s?500:s,a=(0,h.useSelect)((function(e){return{blocks:(0,e("core/block-editor").getBlocks)()}}),[]).blocks,l=(0,b.useRef)(a),c=(0,b.useRef)(t);return(0,b.useEffect)((function(){var e=(0,z.debounce)((function(){for(var t=[],s=0;s0)return r(e.innerBlocks,t[s].innerBlocks);if(JSON.stringify(e)!==JSON.stringify(t[s])){var o=t[s],a=i.parseFromString(e.attributes.content||"","text/html"),l=i.parseFromString((null==o?void 0:o.attributes.content)||"","text/html"),c=Array.from(a.querySelectorAll("a[data-smartlink]")),u=Array.from(l.querySelectorAll("a[data-smartlink]")),d=c.filter((function(e){return!u.some((function(t){return t.dataset.smartlink===e.dataset.smartlink}))})),p=u.filter((function(e){return!c.some((function(t){return t.dataset.smartlink===e.dataset.smartlink}))})),f=c.filter((function(e){var t=u.find((function(t){return t.dataset.smartlink===e.dataset.smartlink}));return t&&t.outerHTML!==e.outerHTML}));(d.length>0||p.length>0||f.length>0)&&n.push({block:e,prevBlock:o,addedLinks:d,removedLinks:p,changedLinks:f})}}}))};return r(e,t),n}(a,l.current);o.length>0&&(o.forEach((function(e){e.changedLinks.length>0&&n&&n(e),e.addedLinks.length>0&&i&&i(e),e.removedLinks.length>0&&r&&r(e)})),l.current=a)}),o);return e(t),function(){e.cancel()}}),[a,o,t,i,n,r]),null},oe=function(e){var t=e.value,n=e.onChange,r=e.max,i=e.min,s=e.suffix,o=e.size,a=e.label,l=e.initialPosition,c=e.disabled,u=e.className;return(0,p.jsxs)("div",{className:"parsely-inputrange-control ".concat(u||""),children:[(0,p.jsx)(f.__experimentalHeading,{className:"parsely-inputrange-control__label",level:3,children:a}),(0,p.jsxs)("div",{className:"parsely-inputrange-control__controls",children:[(0,p.jsx)(f.__experimentalNumberControl,{disabled:c,value:t,suffix:(0,p.jsx)(f.__experimentalInputControlSuffixWrapper,{children:s}),size:null!=o?o:"__unstable-large",min:i,max:r,onChange:function(e){var t=parseInt(e,10);isNaN(t)||n(t)}}),(0,p.jsx)(f.RangeControl,{disabled:c,value:t,showTooltip:!1,initialPosition:l,onChange:function(e){n(e)},withInputField:!1,min:i,max:r})]})]})},ae=function(e,t,n,r){return new(n||(n=Promise))((function(i,s){function o(e){try{l(r.next(e))}catch(e){s(e)}}function a(e){try{l(r.throw(e))}catch(e){s(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(o,a)}l((r=r.apply(e,t||[])).next())}))},le=function(e,t){var n,r,i,s,o={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return s={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function a(a){return function(l){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;s&&(s=0,a[0]&&(o=0)),o;)try{if(n=1,r&&(i=2&a[0]?r.return:a[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,a[1])).done)return i;switch(r=0,i&&(a=[2&a[0],i.value]),a[0]){case 0:case 1:i=a;break;case 4:return o.label++,{value:a[1],done:!1};case 5:o.label++,r=a[1],a=[0];continue;case 7:a=o.ops.pop(),o.trys.pop();continue;default:if(!((i=(i=o.trys).length>0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]=1e4&&(clearInterval(s),n("Telemetry library not loaded"))}),100);else n("Telemetry not enabled")}))},e.prototype.trackEvent=function(t,n){var r;this.isLoaded?(0!==t.indexOf(e.TRACKS_PREFIX)&&(t=e.TRACKS_PREFIX+t),this.isEventNameValid(t)?(n=this.prepareProperties(n),null===(r=this._tkq)||void 0===r||r.push(["recordEvent",t,n])):console.error("Error tracking event: Invalid event name")):console.error("Error tracking event: Telemetry not loaded")},e.prototype.isTelemetryEnabled=function(){return this.isEnabled},e.prototype.isProprietyValid=function(t){return e.PROPERTY_REGEX.test(t)},e.prototype.isEventNameValid=function(t){return e.EVENT_NAME_REGEX.test(t)},e.prototype.prepareProperties=function(e){return(e=this.sanitizeProperties(e)).parsely_version=wpParselyTracksTelemetry.version,wpParselyTracksTelemetry.user&&(e._ut=wpParselyTracksTelemetry.user.type,e._ui=wpParselyTracksTelemetry.user.id),wpParselyTracksTelemetry.vipgo_env&&(e.vipgo_env=wpParselyTracksTelemetry.vipgo_env),this.sanitizeProperties(e)},e.prototype.sanitizeProperties=function(e){var t=this,n={};return Object.keys(e).forEach((function(r){t.isProprietyValid(r)&&(n[r]=e[r])})),n},e.TRACKS_PREFIX="wpparsely_",e.EVENT_NAME_REGEX=/^(([a-z0-9]+)_){2}([a-z0-9_]+)$/,e.PROPERTY_REGEX=/^[a-z_][a-z0-9_]*$/,e}(),j=(P.trackEvent,function(){return(0,p.jsx)(f.SVG,{"aria-hidden":"true",version:"1.1",viewBox:"0 0 15 15",width:"15",height:"15",xmlns:"http://www.w3.org/2000/svg",children:(0,p.jsx)(f.Path,{d:"M0 14.0025V11.0025L7.5 3.5025L10.5 6.5025L3 14.0025H0ZM12 5.0025L13.56 3.4425C14.15 2.8525 14.15 1.9025 13.56 1.3225L12.68 0.4425C12.09 -0.1475 11.14 -0.1475 10.56 0.4425L9 2.0025L12 5.0025Z"})})}),T=function(e){var t=e.size,n=void 0===t?24:t,r=e.className,i=void 0===r?"wp-parsely-icon":r;return(0,p.jsxs)(f.SVG,{className:i,height:n,viewBox:"0 0 60 65",width:n,xmlns:"http://www.w3.org/2000/svg",children:[(0,p.jsx)(f.Path,{fill:"#5ba745",d:"M23.72,51.53c0-.18,0-.34-.06-.52a13.11,13.11,0,0,0-2.1-5.53A14.74,14.74,0,0,0,19.12,43c-.27-.21-.5-.11-.51.22l-.24,3.42c0,.33-.38.35-.49,0l-1.5-4.8a1.4,1.4,0,0,0-.77-.78,23.91,23.91,0,0,0-3.1-.84c-1.38-.24-3.39-.39-3.39-.39-.34,0-.45.21-.25.49l2.06,3.76c.2.27,0,.54-.29.33l-4.51-3.6a3.68,3.68,0,0,0-2.86-.48c-1,.16-2.44.46-2.44.46a.68.68,0,0,0-.39.25.73.73,0,0,0-.14.45S.41,43,.54,44a3.63,3.63,0,0,0,1.25,2.62L6.48,50c.28.2.09.49-.23.37l-4.18-.94c-.32-.12-.5,0-.4.37,0,0,.69,1.89,1.31,3.16a24,24,0,0,0,1.66,2.74,1.34,1.34,0,0,0,1,.52l5,.13c.33,0,.41.38.1.48L7.51,58c-.31.1-.34.35-.07.55a14.29,14.29,0,0,0,3.05,1.66,13.09,13.09,0,0,0,5.9.5,25.13,25.13,0,0,0,4.34-1,9.55,9.55,0,0,1-.08-1.2,9.32,9.32,0,0,1,3.07-6.91"}),(0,p.jsx)(f.Path,{fill:"#5ba745",d:"M59.7,41.53a.73.73,0,0,0-.14-.45.68.68,0,0,0-.39-.25s-1.43-.3-2.44-.46a3.64,3.64,0,0,0-2.86.48l-4.51,3.6c-.26.21-.49-.06-.29-.33l2.06-3.76c.2-.28.09-.49-.25-.49,0,0-2,.15-3.39.39a23.91,23.91,0,0,0-3.1.84,1.4,1.4,0,0,0-.77.78l-1.5,4.8c-.11.32-.48.3-.49,0l-.24-3.42c0-.33-.24-.43-.51-.22a14.74,14.74,0,0,0-2.44,2.47A13.11,13.11,0,0,0,36.34,51c0,.18,0,.34-.06.52a9.26,9.26,0,0,1,3,8.1,24.1,24.1,0,0,0,4.34,1,13.09,13.09,0,0,0,5.9-.5,14.29,14.29,0,0,0,3.05-1.66c.27-.2.24-.45-.07-.55l-3.22-1.17c-.31-.1-.23-.47.1-.48l5-.13a1.38,1.38,0,0,0,1-.52A24.6,24.6,0,0,0,57,52.92c.61-1.27,1.31-3.16,1.31-3.16.1-.33-.08-.49-.4-.37l-4.18.94c-.32.12-.51-.17-.23-.37l4.69-3.34A3.63,3.63,0,0,0,59.46,44c.13-1,.24-2.47.24-2.47"}),(0,p.jsx)(f.Path,{fill:"#5ba745",d:"M46.5,25.61c0-.53-.35-.72-.8-.43l-4.86,2.66c-.45.28-.56-.27-.23-.69l4.66-6.23a2,2,0,0,0,.28-1.68,36.51,36.51,0,0,0-2.19-4.89,34,34,0,0,0-2.81-3.94c-.33-.41-.74-.35-.91.16l-2.28,5.68c-.16.5-.6.48-.59-.05l.28-8.93a2.54,2.54,0,0,0-.66-1.64S35,4.27,33.88,3.27,30.78.69,30.78.69a1.29,1.29,0,0,0-1.54,0s-1.88,1.49-3.12,2.59-2.48,2.35-2.48,2.35A2.5,2.5,0,0,0,23,7.27l.27,8.93c0,.53-.41.55-.58.05l-2.29-5.69c-.17-.5-.57-.56-.91-.14a35.77,35.77,0,0,0-3,4.2,35.55,35.55,0,0,0-2,4.62,2,2,0,0,0,.27,1.67l4.67,6.24c.33.42.23,1-.22.69l-4.87-2.66c-.45-.29-.82-.1-.82.43a18.6,18.6,0,0,0,.83,5.07,20.16,20.16,0,0,0,5.37,7.77c3.19,3,5.93,7.8,7.45,11.08A9.6,9.6,0,0,1,30,49.09a9.31,9.31,0,0,1,2.86.45c1.52-3.28,4.26-8.11,7.44-11.09a20.46,20.46,0,0,0,5.09-7,19,19,0,0,0,1.11-5.82"}),(0,p.jsx)(f.Path,{fill:"#5ba745",d:"M36.12,58.44A6.12,6.12,0,1,1,30,52.32a6.11,6.11,0,0,1,6.12,6.12"})]})},L=function(){return L=Object.assign||function(e){for(var t,n=1,r=arguments.length;nhere.',"wp-parsely"):s.code===$.ParselySuggestionsApiOpenAiError||s.code===$.ParselySuggestionsApiOpenAiUnavailable?s.message=(0,_.__)("The Parse.ly API returned an internal server error. Please retry with a different input, or try again later.","wp-parsely"):s.code===$.HttpRequestFailed&&s.message.includes("cURL error 28")?s.message=(0,_.__)("The Parse.ly API did not respond in a timely manner. Please try again later.","wp-parsely"):s.code===$.ParselySuggestionsApiSchemaError?s.message=(0,_.__)("The Parse.ly API returned a validation error. Please try again with different parameters.","wp-parsely"):s.code===$.ParselySuggestionsApiNoData?s.message=(0,_.__)("The Parse.ly API couldn't find any relevant data to fulfill the request. Please retry with a different input.","wp-parsely"):s.code===$.ParselySuggestionsApiOpenAiSchema?s.message=(0,_.__)("The Parse.ly API returned an incorrect response. Please try again later.","wp-parsely"):s.code===$.ParselySuggestionsApiAuthUnavailable&&(s.message=(0,_.__)("The Parse.ly API is currently unavailable. Please try again later.","wp-parsely")),s}return re(t,e),t.prototype.Message=function(e){return void 0===e&&(e=null),[$.PluginCredentialsNotSetMessageDetected,$.PluginSettingsSiteIdNotSet,$.PluginSettingsApiSecretNotSet].includes(this.code)?K(e):(this.code===$.FetchError&&(this.hint=this.Hint((0,_.__)("This error can sometimes be caused by ad-blockers or browser tracking protections. Please add this site to any applicable allow lists and try again.","wp-parsely"))),this.code!==$.ParselyApiForbidden&&this.code!==$.ParselySuggestionsApiNoAuthentication||(this.hint=this.Hint((0,_.__)("Please ensure that the Site ID and API Secret given in the plugin's settings are correct.","wp-parsely"))),this.code===$.HttpRequestFailed&&(this.hint=this.Hint((0,_.__)("The Parse.ly API cannot be reached. Please verify that you are online.","wp-parsely"))),(0,p.jsx)(W,{className:null==e?void 0:e.className,testId:"error",children:"

".concat(this.message,"

").concat(this.hint?this.hint:"")}))},t.prototype.Hint=function(e){return'

'.concat((0,_.__)("Hint:","wp-parsely")," ").concat(e,"

")},t.prototype.createErrorSnackbar=function(){//.test(this.message)||(0,h.dispatch)("core/notices").createNotice("error",this.message,{type:"snackbar"})},t}(Error),se=function(e){var t=e.isDetectingEnabled,n=e.onLinkChange,r=e.onLinkRemove,i=e.onLinkAdd,s=e.debounceValue,o=void 0===s?500:s,a=(0,h.useSelect)((function(e){return{blocks:(0,e("core/block-editor").getBlocks)()}}),[]).blocks,l=(0,b.useRef)(a),c=(0,b.useRef)(t);return(0,b.useEffect)((function(){var e=(0,z.debounce)((function(){for(var t=[],s=0;s0)return r(e.innerBlocks,t[s].innerBlocks);if(JSON.stringify(e)!==JSON.stringify(t[s])){var o=t[s],a=i.parseFromString(e.attributes.content||"","text/html"),l=i.parseFromString((null==o?void 0:o.attributes.content)||"","text/html"),c=Array.from(a.querySelectorAll("a[data-smartlink]")),u=Array.from(l.querySelectorAll("a[data-smartlink]")),d=c.filter((function(e){return!u.some((function(t){return t.dataset.smartlink===e.dataset.smartlink}))})),p=u.filter((function(e){return!c.some((function(t){return t.dataset.smartlink===e.dataset.smartlink}))})),f=c.filter((function(e){var t=u.find((function(t){return t.dataset.smartlink===e.dataset.smartlink}));return t&&t.outerHTML!==e.outerHTML}));(d.length>0||p.length>0||f.length>0)&&n.push({block:e,prevBlock:o,addedLinks:d,removedLinks:p,changedLinks:f})}}}))};return r(e,t),n}(a,l.current);o.length>0&&(o.forEach((function(e){e.changedLinks.length>0&&n&&n(e),e.addedLinks.length>0&&i&&i(e),e.removedLinks.length>0&&r&&r(e)})),l.current=a)}),o);return e(t),function(){e.cancel()}}),[a,o,t,i,n,r]),null},oe=function(e){var t=e.value,n=e.onChange,r=e.max,i=e.min,s=e.suffix,o=e.size,a=e.label,l=e.initialPosition,c=e.disabled,u=e.className;return(0,p.jsxs)("div",{className:"parsely-inputrange-control ".concat(u||""),children:[(0,p.jsx)(f.__experimentalHeading,{className:"parsely-inputrange-control__label",level:3,children:a}),(0,p.jsxs)("div",{className:"parsely-inputrange-control__controls",children:[(0,p.jsx)(f.__experimentalNumberControl,{disabled:c,value:t,suffix:(0,p.jsx)(f.__experimentalInputControlSuffixWrapper,{children:s}),size:null!=o?o:"__unstable-large",min:i,max:r,onChange:function(e){var t=parseInt(e,10);isNaN(t)||n(t)}}),(0,p.jsx)(f.RangeControl,{disabled:c,value:t,showTooltip:!1,initialPosition:l,onChange:function(e){n(e)},withInputField:!1,min:i,max:r})]})]})},ae=function(e,t,n,r){return new(n||(n=Promise))((function(i,s){function o(e){try{l(r.next(e))}catch(e){s(e)}}function a(e){try{l(r.throw(e))}catch(e){s(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(o,a)}l((r=r.apply(e,t||[])).next())}))},le=function(e,t){var n,r,i,s,o={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return s={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function a(a){return function(l){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;s&&(s=0,a[0]&&(o=0)),o;)try{if(n=1,r&&(i=2&a[0]?r.return:a[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,a[1])).done)return i;switch(r=0,i&&(a=[2&a[0],i.value]),a[0]){case 0:case 1:i=a;break;case 4:return o.label++,{value:a[1],done:!1};case 5:o.label++,r=a[1],a=[0];continue;case 7:a=o.ops.pop(),o.trys.pop();continue;default:if(!((i=(i=o.trys).length>0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]

","\n\x3c!-- /wp:paragraph --\x3e");t&&h((0,Q.parse)(n))}),[s]),(0,p.jsxs)("div",{className:"smart-linking-review-suggestion",children:[(0,p.jsx)(f.KeyboardShortcuts,{shortcuts:{left:o,right:a,up:o,down:a}}),(0,p.jsx)("div",{className:"review-suggestion-post-title",children:null===(t=s.post_data)||void 0===t?void 0:t.title}),(0,p.jsxs)("div",{className:"review-suggestion-preview",children:[!(null===(n=s.post_data)||void 0===n?void 0:n.is_first_paragraph)&&(0,p.jsx)($e,{topOrBottom:"top"}),(0,p.jsx)(Ze,{block:d[0],link:s,useOriginalBlock:!0}),!(null===(r=s.post_data)||void 0===r?void 0:r.is_last_paragraph)&&(0,p.jsx)($e,{topOrBottom:"bottom"})]}),(0,p.jsx)(f.__experimentalDivider,{}),(0,p.jsx)(We,{link:s}),(0,p.jsxs)("div",{className:"review-controls",children:[(0,p.jsx)(f.Tooltip,{shortcut:"←",text:(0,_.__)("Previous","wp-parsely"),children:(0,p.jsx)(f.Button,{disabled:!l,className:"wp-parsely-review-suggestion-previous",onClick:o,icon:He,children:(0,_.__)("Previous","wp-parsely")})}),(0,p.jsx)("div",{className:"reviews-controls-middle",children:(0,p.jsx)(f.Button,{target:"_blank",href:(null===(i=s.post_data)||void 0===i?void 0:i.edit_link)+"&smart-link="+s.uid,variant:"secondary",onClick:function(){P.trackEvent("smart_linking_open_in_editor_pressed",{type:"inbound",uid:s.uid})},children:(0,_.__)("Open in the Editor","wp-parsely")})}),(0,p.jsx)(f.Tooltip,{shortcut:"→",text:(0,_.__)("Next","wp-parsely"),children:(0,p.jsxs)(f.Button,{disabled:!c,onClick:a,className:"wp-parsely-review-suggestion-next",children:[(0,_.__)("Next","wp-parsely"),(0,p.jsx)(X,{icon:ze})]})})]})]})},Ye=function(e){var t=e.size,n=void 0===t?24:t,r=e.className,i=void 0===r?"wp-parsely-icon":r;return(0,p.jsxs)(f.SVG,{xmlns:"http://www.w3.org/2000/svg",className:i,width:n,height:n,viewBox:"0 0 24 24",fill:"none",children:[(0,p.jsx)(f.Path,{d:"M8.18983 5.90381L8.83642 7.54325L10.4758 8.18983L8.83642 8.8364L8.18983 10.4759L7.54324 8.8364L5.90381 8.18983L7.54324 7.54325L8.18983 5.90381Z"}),(0,p.jsx)(f.Path,{d:"M15.048 5.90381L15.9101 8.08972L18.0961 8.95186L15.9101 9.81397L15.048 11.9999L14.1859 9.81397L12 8.95186L14.1859 8.08972L15.048 5.90381Z"}),(0,p.jsx)(f.Path,{d:"M11.238 10.4761L12.3157 13.2085L15.048 14.2861L12.3157 15.3638L11.238 18.0962L10.1603 15.3638L7.42798 14.2861L10.1603 13.2085L11.238 10.4761Z"})]})},Je=function(e,t,n){if(n||2===arguments.length)for(var r,i=0,s=t.length;ii.bottom)&&(n.scrollTop=r.offsetTop-n.offsetTop)}}}}),[t,l]);var u=function(){var e=document.querySelector(".smart-linking-review-sidebar-tabs [data-active-item]"),t=null==e?void 0:e.nextElementSibling;t||(t=document.querySelector('.smart-linking-review-sidebar-tabs [role="tab"]')),t&&t.click()},d=(0,p.jsxs)("span",{className:"smart-linking-menu-label",children:[(0,_.__)("NEW","wp-parsely"),(0,p.jsx)(Ye,{})]}),h=[];n&&n.length>0&&h.push({name:"outbound",title:(0,_.__)("Outbound","wp-parsely")}),r&&r.length>0&&h.push({name:"inbound",title:(0,_.__)("Inbound","wp-parsely")});var v="outbound";return h=h.filter((function(e){return"outbound"===e.name&&r&&0===r.length&&(e.title=(0,_.__)("Outbound Smart Links","wp-parsely"),v="outbound"),"inbound"===e.name&&n&&0===n.length&&(e.title=(0,_.__)("Inbound Smart Links","wp-parsely"),v="inbound"),e})),(0,p.jsxs)("div",{className:"smart-linking-review-sidebar",ref:s,children:[(0,p.jsx)(f.KeyboardShortcuts,{shortcuts:{tab:function(){return u()},"shift+tab":function(){return u()}}}),(0,p.jsx)(f.TabPanel,{className:"smart-linking-review-sidebar-tabs",initialTabName:v,tabs:h,onSelect:function(e){var t,s;"outbound"===e&&n&&n.length>0&&i(n[0]),"inbound"===e&&r&&r.length>0&&i(r[0]),P.trackEvent("smart_linking_modal_tab_selected",{tab:e,total_inbound:null!==(t=null==r?void 0:r.length)&&void 0!==t?t:0,total_outbound:null!==(s=null==n?void 0:n.length)&&void 0!==s?s:0})},children:function(e){return(0,p.jsxs)(p.Fragment,{children:["outbound"===e.name&&(0,p.jsx)(p.Fragment,{children:n&&0!==n.length?n.map((function(e,n){return(0,p.jsxs)(f.MenuItem,{ref:function(e){o.current[n]=e},className:(null==t?void 0:t.uid)===e.uid?"is-selected":"",role:"menuitemradio",isSelected:(null==t?void 0:t.uid)===e.uid,onClick:function(){return i(e)},children:[(0,p.jsx)("span",{className:"smart-linking-menu-item",children:e.text}),!e.applied&&d]},e.uid)})):(0,p.jsxs)(p.Fragment,{children:[" ",(0,_.__)("No outbound links found.","wp-parsely")]})}),"inbound"===e.name&&(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)("div",{className:"review-sidebar-tip",children:(0,_.__)("This section shows external posts that link back to the current post.","wp-parsely")}),r&&0!==r.length?r.map((function(e,r){var s;return(0,p.jsx)(f.MenuItem,{ref:function(e){o.current[(n?n.length:0)+r]=e},className:(null==t?void 0:t.uid)===e.uid?"is-selected":"",role:"menuitemradio",isSelected:(null==t?void 0:t.uid)===e.uid,onClick:function(){return i(e)},children:(0,p.jsx)("span",{className:"smart-linking-menu-item",children:null===(s=e.post_data)||void 0===s?void 0:s.title})},e.uid)})):(0,p.jsxs)(p.Fragment,{children:[" ",(0,_.__)("No inbound links found.","wp-parsely")]})]})]})}})]})},Xe=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"M12 13.06l3.712 3.713 1.061-1.06L13.061 12l3.712-3.712-1.06-1.06L12 10.938 8.288 7.227l-1.061 1.06L10.939 12l-3.712 3.712 1.06 1.061L12 13.061z"})}),et=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"M16.7 7.1l-6.3 8.5-3.3-2.5-.9 1.2 4.5 3.4L17.9 8z"})}),tt=function(e){var t,n,r,i,s=null===(t=e.link.match)||void 0===t?void 0:t.blockId,o=(0,h.useSelect)((function(e){var t=e("core/block-editor"),n=t.getBlock,r=t.getBlockParents;return s?{block:n(s),parents:r(s).map((function(e){return n(e)})).filter((function(e){return void 0!==e}))}:{block:void 0,parents:[]}}),[s]),a=o.block,l=o.parents;return a?(0,p.jsxs)("div",{className:"review-suggestions-breadcrumbs",children:[l.map((function(e,t){var n;return(0,p.jsxs)("span",{children:[(0,p.jsx)("span",{className:"breadcrumbs-parent-block",children:null===(n=(0,Q.getBlockType)(e.name))||void 0===n?void 0:n.title}),(0,p.jsx)("span",{className:"breadcrumbs-parent-separator",children:" / "})]},t)})),(0,p.jsxs)("span",{className:"breadcrumbs-current-block",children:[(0,p.jsx)("span",{className:"breadcrumbs-current-block-type",children:null===(n=(0,Q.getBlockType)(a.name))||void 0===n?void 0:n.title}),(null===(i=null===(r=a.attributes)||void 0===r?void 0:r.metadata)||void 0===i?void 0:i.name)&&(0,p.jsx)("span",{className:"breadcrumbs-current-block-name",children:a.attributes.metadata.name})]})]}):(0,p.jsx)(p.Fragment,{})},nt=function(e){var t,n=e.link,r=(0,b.useState)(n.href),i=r[0],s=r[1],o=(0,b.useState)(null===(t=n.destination)||void 0===t?void 0:t.post_type),a=o[0],l=o[1],c=(0,b.useRef)(null),u=(0,h.useDispatch)(Te).updateSmartLink;return(0,b.useEffect)((function(){n.destination?l(n.destination.post_type):(l((0,_.__)("External","wp-parsely")),De.getInstance().getPostTypeByURL(n.href).then((function(e){e&&l(e.post_type),n.destination=e,u(n)})))}),[n,u]),(0,b.useEffect)((function(){var e=function(){if(c.current){var e=c.current.offsetWidth,t=Math.floor(e/8);s(function(e,t){var n=e.replace(/(^\w+:|^)\/\//,"").replace(/^www\./,"");if(!t||n.length<=t)return n;var r=n.split("/")[0],i=n.substring(r.length);t-=r.length;var s=Math.floor((t-3)/2),o=i.substring(0,s),a=i.substring(i.length-s);return"".concat(r).concat(o,"...").concat(a)}(n.href,t))}};return e(),window.addEventListener("resize",e),function(){window.removeEventListener("resize",e)}}),[n]),(0,p.jsx)(f.MenuItem,{ref:c,info:i,iconPosition:"left",icon:Ge,shortcut:a,className:"block-editor-link-control__search-item wp-parsely-link-suggestion-link-details",children:n.title})},rt=function(e){var t=e.link,n=e.onNext,r=e.onPrevious,i=e.onAccept,s=e.onReject,o=e.onRemove,a=e.onSelectInEditor,l=e.hasPrevious,c=e.hasNext;if(t&&void 0!==t.post_data)return(0,p.jsx)(Ke,{link:t,onNext:n,onPrevious:r,onAccept:i,onReject:s,onRemove:o,onSelectInEditor:a,hasPrevious:l,hasNext:c});if(!(null==t?void 0:t.match))return(0,p.jsx)(p.Fragment,{children:(0,_.__)("This Smart Link does not have any matches in the current content.","wp-parsely")});var u=t.match.blockId,d=(0,h.select)("core/block-editor").getBlock(u),v=t.applied;return d?(0,p.jsxs)("div",{className:"smart-linking-review-suggestion",children:[(0,p.jsx)(f.KeyboardShortcuts,{shortcuts:{left:r,right:n,up:r,down:n,a:function(){t&&!t.applied&&i()},r:function(){t&&(t.applied?o():s())}}}),(0,p.jsx)(tt,{link:t}),(0,p.jsx)("div",{className:"review-suggestion-preview",children:(0,p.jsx)(Ze,{block:d,link:t})}),(0,p.jsx)(f.__experimentalDivider,{}),(0,p.jsx)(nt,{link:t}),(0,p.jsxs)("div",{className:"review-controls",children:[(0,p.jsx)(f.Tooltip,{shortcut:"←",text:(0,_.__)("Previous","wp-parsely"),children:(0,p.jsx)(f.Button,{disabled:!l,className:"wp-parsely-review-suggestion-previous",onClick:r,icon:He,children:(0,_.__)("Previous","wp-parsely")})}),(0,p.jsxs)("div",{className:"reviews-controls-middle",children:[!v&&(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)(f.Tooltip,{shortcut:"R",text:(0,_.__)("Reject","wp-parsely"),children:(0,p.jsx)(f.Button,{className:"wp-parsely-review-suggestion-reject",icon:Xe,onClick:s,variant:"secondary",children:(0,_.__)("Reject","wp-parsely")})}),(0,p.jsx)(f.Tooltip,{shortcut:"A",text:(0,_.__)("Accept","wp-parsely"),children:(0,p.jsx)(f.Button,{className:"wp-parsely-review-suggestion-accept",icon:et,onClick:i,variant:"secondary",children:(0,_.__)("Accept","wp-parsely")})})]}),v&&(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)(f.Tooltip,{shortcut:"R",text:(0,_.__)("Remove","wp-parsely"),children:(0,p.jsx)(f.Button,{className:"wp-parsely-review-suggestion-reject",icon:Xe,onClick:o,variant:"secondary",children:(0,_.__)("Remove","wp-parsely")})}),(0,p.jsx)(f.Button,{className:"wp-parsely-review-suggestion-accept",onClick:a,variant:"secondary",children:(0,_.__)("Select in Editor","wp-parsely")})]})]}),(0,p.jsx)(f.Tooltip,{shortcut:"→",text:(0,_.__)("Next","wp-parsely"),children:(0,p.jsxs)(f.Button,{disabled:!c,onClick:n,className:"wp-parsely-review-suggestion-next",children:[(0,_.__)("Next","wp-parsely"),(0,p.jsx)(X,{icon:ze})]})})]})]}):(0,p.jsx)(p.Fragment,{children:(0,_.__)("No block is selected.","wp-parsely")})},it=function(e,t,n,r){return new(n||(n=Promise))((function(i,s){function o(e){try{l(r.next(e))}catch(e){s(e)}}function a(e){try{l(r.throw(e))}catch(e){s(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(o,a)}l((r=r.apply(e,t||[])).next())}))},st=function(e,t){var n,r,i,s,o={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return s={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function a(a){return function(l){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;s&&(s=0,a[0]&&(o=0)),o;)try{if(n=1,r&&(i=2&a[0]?r.return:a[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,a[1])).done)return i;switch(r=0,i&&(a=[2&a[0],i.value]),a[0]){case 0:case 1:i=a;break;case 4:return o.label++,{value:a[1],done:!1};case 5:o.label++,r=a[1],a=[0];continue;case 7:a=o.ops.pop(),o.trys.pop();continue;default:if(!((i=(i=o.trys).length>0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&(a=o[0],(l=a.parentNode)&&(c=document.createTextNode(null!==(u=a.textContent)&&void 0!==u?u:""),l.replaceChild(c,a),te.updateBlockAttributes(n,{content:s.innerHTML}))),[4,E(t.uid)]):[2]):[2];case 1:return d.sent(),[2]}}))}))},C=(0,b.useCallback)((function(){c(!1),w().filter((function(e){return!e.applied})).length>0?o(!0):(ne.unlockPostAutosaving("smart-linking-review-modal"),t())}),[w,t]),A=function(e){o(!1),e?(c(!1),T().then((function(){C()}))):c(!0)},O=function(){if(ue(k)){var e=g.indexOf(k);if(!g[t=e+1])return;S(g[t])}else{var t;if(e=v.indexOf(k),!v[t=e+1])return;S(v[t])}},R=function(){if(ue(k)){var e=g.indexOf(k);if(!g[t=e-1])return;S(g[t])}else{var t;if(e=v.indexOf(k),!v[t=e-1])return;S(v[t])}};return(0,b.useEffect)((function(){l?ne.lockPostAutosaving("smart-linking-review-modal"):l&&0===d.length&&C()}),[l,t,d,C]),(0,b.useEffect)((function(){c(n)}),[n]),(0,p.jsxs)(p.Fragment,{children:[l&&(0,p.jsx)(f.Modal,{title:(0,_.__)("Review Smart Links","wp-parsely"),className:"wp-parsely-smart-linking-review-modal",onRequestClose:C,shouldCloseOnClickOutside:!1,shouldCloseOnEsc:!1,children:(0,p.jsxs)("div",{className:"smart-linking-modal-body",children:[(0,p.jsx)(Qe,{outboundLinks:v,inboundLinks:g,activeLink:k,setSelectedLink:S}),k&&(ue(k)?(0,p.jsx)(Ke,{link:k,onNext:O,onPrevious:R,hasNext:g.indexOf(k)0}):(0,p.jsx)(rt,{link:k,hasNext:m().indexOf(k)0,onNext:O,onPrevious:R,onAccept:function(){return it(void 0,void 0,void 0,(function(){var e,t;return st(this,(function(n){switch(n.label){case 0:return k.match?(r(k),[4,(i=k.match.blockId,s=k,it(void 0,void 0,void 0,(function(){var e,t;return st(this,(function(n){switch(n.label){case 0:return(e=document.createElement("a")).href=s.href,e.title=s.title,e.setAttribute("data-smartlink",s.uid),(t=(0,h.select)("core/block-editor").getBlock(i))?(fe(t,s,e),s.applied=!0,[4,L(s)]):[2];case 1:return n.sent(),[2]}}))})))]):[2];case 1:return n.sent(),P.trackEvent("smart_linking_link_accepted",{link:k.href,title:k.title,text:k.text,uid:k.uid}),0===y().length?(C(),[2]):(e=v.indexOf(k),v[t=e+1]?S(v[t]):S(v[0]),[2])}var i,s}))}))},onReject:function(){return it(void 0,void 0,void 0,(function(){var e,t;return st(this,(function(n){switch(n.label){case 0:return e=v.indexOf(k),v[t=e+1]?S(v[t]):v[0]?S(v[0]):C(),[4,E(k.uid)];case 1:return n.sent(),P.trackEvent("smart_linking_link_rejected",{link:k.href,title:k.title,text:k.text,uid:k.uid}),[2]}}))}))},onRemove:function(){return it(void 0,void 0,void 0,(function(){var e,t,n,r;return st(this,(function(i){switch(i.label){case 0:return k.match?(e=(0,h.select)("core/block-editor").getBlock(k.match.blockId))?(t=m(),n=t.indexOf(k),r=n-1,[4,N(e,k)]):[3,2]:[2];case 1:if(i.sent(),P.trackEvent("smart_linking_link_removed",{link:k.href,title:k.title,text:k.text,uid:k.uid}),0===(t=m()).length&&g.length>0)return S(g[0]),[2];if(0===t.length&&0===g.length)return C(),[2];if(t[r])return S(t[r]),[2];S(t[0]),i.label=2;case 2:return[2]}}))}))},onSelectInEditor:function(){if(k.match){var e=(0,h.select)("core/block-editor").getBlock(k.match.blockId);if(e){te.selectBlock(e.clientId);var t=document.querySelector('[data-block="'.concat(e.clientId,'"]'));t&&ke(t,k.uid),P.trackEvent("smart_linking_select_in_editor_pressed",{type:"outbound",uid:k.uid}),C()}}}}))]})}),s&&(0,p.jsxs)(f.Modal,{title:(0,_.__)("Review Smart Links","wp-parsely"),onRequestClose:function(){return A(!1)},className:"wp-parsely-smart-linking-close-dialog",children:[(0,_.__)("Are you sure you want to close? All un-accepted smart links will not be added.","wp-parsely"),(0,p.jsxs)("div",{className:"smart-linking-close-dialog-actions",children:[(0,p.jsx)(f.Button,{variant:"secondary",onClick:function(){return A(!1)},children:(0,_.__)("Go Back","wp-parsely")}),(0,p.jsx)(f.Button,{variant:"primary",onClick:function(){return A(!0)},children:(0,_.__)("Close","wp-parsely")})]})]})]})})),at=function(){return at=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&k("success",/* translators: %d: number of smart links applied */ /* translators: %d: number of smart links applied */ (0,_.sprintf)((0,_.__)("%s smart links successfully applied.","wp-parsely"),g),{type:"snackbar"}):y(0)}),[w]),(0,b.useEffect)((function(){if(!(Object.keys(R).length>0)){var e={maxLinksPerPost:a.SmartLinking.MaxLinks};te(e)}}),[te,a]);var he=(0,h.useSelect)((function(e){var t=e("core/block-editor"),r=t.getSelectedBlock,i=t.getBlock,s=t.getBlocks,o=e("core/editor"),a=o.getEditedPostContent,l=o.getCurrentPostAttribute;return{allBlocks:s(),selectedBlock:n?i(n):r(),postContent:a(),postPermalink:l("link")}}),[n]),ve=he.allBlocks,me=he.selectedBlock,xe=he.postContent,ke=he.postPermalink,Se=function(e){return lt(void 0,void 0,void 0,(function(){var t,n,r,i,s;return ct(this,(function(o){switch(o.label){case 0:t=[],o.label=1;case 1:return o.trys.push([1,4,,9]),[4,re((n=E||!me)?_e.All:_e.Selected)];case 2:return o.sent(),a=ke.replace(/^https?:\/\//i,""),r=["http://"+a,"https://"+a],i=function(e){return e.map((function(e){return e.href}))}(F),r.push.apply(r,i),[4,De.getInstance().generateSmartLinks(me&&!n?(0,Q.getBlockContent)(me):xe,O,r)];case 3:return t=o.sent(),[3,9];case 4:if((s=o.sent()).code&&s.code===$.ParselyAborted)throw s.numRetries=3-e,s;return e>0&&s.retryFetch?(console.error(s),[4,ce(!0)]):[3,8];case 5:return o.sent(),[4,ue()];case 6:return o.sent(),[4,Se(e-1)];case 7:return[2,o.sent()];case 8:throw s;case 9:return[2,t]}var a}))}))},Pe=function(){for(var e=[],t=0;t[type="button"]').forEach((function(e){e.setAttribute("disabled","disabled")}))},Ne=function(){document.querySelectorAll('.edit-post-header__settings>[type="button"]').forEach((function(e){e.removeAttribute("disabled")})),ne.unlockPostSaving("wp-parsely-block-overlay")};return(0,p.jsxs)("div",{className:"wp-parsely-smart-linking",children:[(0,p.jsx)(se,{isDetectingEnabled:!L,onLinkRemove:function(e){!function(e){ae(this,void 0,void 0,(function(){var t,n,r;return le(this,(function(i){switch(i.label){case 0:return[4,we((0,Q.getBlockContent)(e),e.clientId)];case 1:return t=i.sent(),n=t.missingSmartLinks,r=t.didAnyFixes,n.forEach((function(e){(0,h.dispatch)(Te).removeSmartLink(e.uid)})),[2,r]}}))}))}(e.block)}}),(0,p.jsxs)(f.PanelRow,{className:t,children:[(0,p.jsxs)("div",{className:"smart-linking-text",children:[(0,_.__)("Automatically insert links to your most relevant, top performing content.","wp-parsely"),(0,p.jsxs)(f.Button,{href:"https://docs.parse.ly/plugin-content-helper/#h-smart-linking-beta",target:"_blank",variant:"link",children:[(0,_.__)("Learn more about Parse.ly AI","wp-parsely"),(0,p.jsx)(X,{icon:ee,size:18,className:"parsely-external-link-icon"})]})]}),C&&(0,p.jsx)(f.Notice,{status:"info",onRemove:function(){return Z(null)},className:"wp-parsely-content-helper-error",children:C.Message()}),w&&g>0&&(0,p.jsx)(f.Notice,{status:"success",onRemove:function(){return x(!1)},className:"wp-parsely-smart-linking-suggested-links",children:(0,_.sprintf)(/* translators: 1 - number of smart links generated */ /* translators: 1 - number of smart links generated */ (0,_.__)("Successfully added %s smart links.","wp-parsely"),g>0?g:A.length)}),(0,p.jsx)(Ce,{disabled:T,selectedBlock:me,onSettingChange:function(e,t){var n;d({SmartLinking:at(at({},a.SmartLinking),(n={},n[e]=t,n))}),"MaxLinks"===e&&oe(t)}}),(0,p.jsx)("div",{className:"smart-linking-generate",children:(0,p.jsx)(f.Button,{onClick:function(){return lt(void 0,void 0,void 0,(function(){var e,t,n,r,s,o,a,l;return ct(this,(function(c){switch(c.label){case 0:return[4,q(!0)];case 1:return c.sent(),[4,de()];case 2:return c.sent(),[4,Z(null)];case 3:return c.sent(),x(!1),P.trackEvent("smart_linking_generate_pressed",{is_full_content:E,selected_block:null!==(o=null==me?void 0:me.name)&&void 0!==o?o:"none",context:i}),[4,Pe(E?"all":null==me?void 0:me.clientId)];case 4:c.sent(),e=setTimeout((function(){var e;q(!1),P.trackEvent("smart_linking_generate_timeout",{is_full_content:E,selected_block:null!==(e=null==me?void 0:me.name)&&void 0!==e?e:"none",context:i}),je(E?"all":null==me?void 0:me.clientId)}),18e4),t=I,c.label=5;case 5:return c.trys.push([5,8,10,15]),[4,Se(3)];case 6:return n=c.sent(),[4,(u=n,lt(void 0,void 0,void 0,(function(){var e;return ct(this,(function(t){switch(t.label){case 0:return u=u.filter((function(e){return!F.some((function(t){return t.uid===e.uid&&t.applied}))})),e=ke.replace(/^https?:\/\//,"").replace(/\/+$/,""),u=(u=u.filter((function(t){return!t.href.includes(e)||(console.warn("PCH Smart Linking: Skipping self-reference link: ".concat(t.href)),!1)}))).filter((function(e){return!F.some((function(t){return t.href===e.href?(console.warn("PCH Smart Linking: Skipping duplicate link: ".concat(e.href)),!0):t.text===e.text&&t.offset!==e.offset&&(console.warn("PCH Smart Linking: Skipping duplicate link text: ".concat(e.text)),!0)}))})),u=(u=ge(E?ve:[me],u,{}).filter((function(e){return e.match}))).filter((function(e){if(!e.match)return!1;var t=e.match.blockLinkPosition,n=t+e.text.length;return!F.some((function(r){if(!r.match)return!1;if(e.match.blockId!==r.match.blockId)return!1;var i=r.match.blockLinkPosition,s=i+r.text.length;return t>=i&&n<=s}))})),[4,W(u)];case 1:return t.sent(),[2,u]}}))})))];case 7:if(0===c.sent().length)throw new ie((0,_.__)("No smart links were generated.","wp-parsely"),$.ParselySuggestionsApiNoData,"");return pe(!0),[3,15];case 8:return r=c.sent(),s=new ie(null!==(a=r.message)&&void 0!==a?a:"An unknown error has occurred.",null!==(l=r.code)&&void 0!==l?l:$.UnknownError),r.code&&r.code===$.ParselyAborted&&(s.message=(0,_.sprintf)(/* translators: %d: number of retry attempts, %s: attempt plural */ /* translators: %d: number of retry attempts, %s: attempt plural */ (0,_.__)("The Smart Linking process was cancelled after %1$d %2$s.","wp-parsely"),r.numRetries,(0,_._n)("attempt","attempts",r.numRetries,"wp-parsely"))),console.error(r),[4,Z(s)];case 9:return c.sent(),s.createErrorSnackbar(),[3,15];case 10:return[4,q(!1)];case 11:return c.sent(),[4,re(t)];case 12:return c.sent(),[4,ce(!1)];case 13:return c.sent(),[4,je(E?"all":null==me?void 0:me.clientId)];case 14:return c.sent(),clearTimeout(e),[7];case 15:return[2]}var u}))}))},variant:"primary",isBusy:T,disabled:T,children:M?(0,_.sprintf)(/* translators: %1$d: number of retry attempts, %2$d: maximum number of retries */ /* translators: %1$d: number of retry attempts, %2$d: maximum number of retries */ -(0,_.__)("Retrying… Attempt %1$d of %2$d","wp-parsely"),D,3):T?(0,_.__)("Generating Smart Links…","wp-parsely"):(0,_.__)("Add Smart Links","wp-parsely")})}),(G.length>0||V.length>0)&&(0,p.jsx)("div",{className:"smart-linking-manage",children:(0,p.jsx)(f.Button,{onClick:function(){return lt(void 0,void 0,void 0,(function(){var e,t;return ct(this,(function(n){switch(n.label){case 0:return[4,be()];case 1:return e=n.sent(),t=ye(),[4,W(t)];case 2:return n.sent(),pe(!0),P.trackEvent("smart_linking_review_pressed",{num_smart_links:F.length,has_fixed_links:e,context:i}),[2]}}))}))},variant:"secondary",disabled:T,children:(0,_.__)("Review Smart Links","wp-parsely")})})]}),L&&(0,p.jsx)(ot,{isOpen:L,onAppliedLink:function(){y((function(e){return e+1}))},onClose:function(){x(!0),pe(!1)}})]})},ft=function(){return ft=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0)&&(t(),e())}))}))]}))},new((n=void 0)||(n=Promise))((function(i,s){function o(e){try{l(r.next(e))}catch(e){s(e)}}function a(e){try{l(r.throw(e))}catch(e){s(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(o,a)}l((r=r.apply(e,t||[])).next())}));var e,t,n,r}().then((function(){var t=document.querySelector(".wp-block-post-content");ke(t,e)}))})))},Pt=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"M7 11.5h10V13H7z"})}),jt=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"M13 19h-2v-2h2v2zm0-6h-2v-2h2v2zm0-6h-2V5h2v2z"})}),Tt=function(e){var t=e.title,n=e.icon,r=e.subtitle,i=e.level,s=void 0===i?2:i,o=e.children,a=e.controls,l=e.onClick,c=e.isOpen,u=e.isLoading,d=e.dropdownChildren;return(0,p.jsxs)("div",{className:"performance-stat-panel",children:[(0,p.jsxs)(f.__experimentalHStack,{className:"panel-header level-"+s,children:[(0,p.jsx)(f.__experimentalHeading,{level:s,children:t}),r&&!c&&(0,p.jsx)("span",{className:"panel-subtitle",children:r}),a&&!d&&(0,p.jsx)(f.DropdownMenu,{icon:n,label:(0,_.__)("Settings","wp-parsely"),className:"panel-settings-button",controls:a}),d&&(0,p.jsx)(f.DropdownMenu,{icon:n,label:(0,_.__)("Settings","wp-parsely"),className:"panel-settings-button",children:d}),n&&!d&&!a&&(0,p.jsx)(f.Button,{icon:n,className:"panel-settings-button",isPressed:c,onClick:l})]}),(0,p.jsx)("div",{className:"panel-body",children:u?(0,p.jsx)("div",{className:"parsely-spinner-wrapper","data-testid":"parsely-spinner-wrapper",children:(0,p.jsx)(f.Spinner,{})}):o})]})};function Lt(e,t,n){void 0===t&&(t=1),void 0===n&&(n="");var r=parseInt(e.replace(/\D/g,""),10);if(r<1e3)return e;r<1e4&&(t=1);var i=r,s=r.toString(),o="",a=0;return Object.entries({1e3:"k","1,000,000":"M","1,000,000,000":"B","1,000,000,000,000":"T","1,000,000,000,000,000":"Q"}).forEach((function(e){var n=e[0],l=e[1],c=parseInt(n.replace(/\D/g,""),10);if(r>=c){var u=t;(i=r/c)%1>1/a&&(u=i>10?1:2),u=parseFloat(i.toFixed(2))===parseFloat(i.toFixed(0))?0:u,s=i.toFixed(u),o=l}a=c})),s+n+o}var Et=function(e){var t=e.data,n=e.isLoading,r=(0,b.useState)(m.Views),i=r[0],s=r[1],o=(0,b.useState)(!1),a=o[0],l=o[1];n||delete t.referrers.types.totals;var c=function(e){switch(e){case"social":return(0,_.__)("Social","wp-parsely");case"search":return(0,_.__)("Search","wp-parsely");case"other":return(0,_.__)("Other","wp-parsely");case"internal":return(0,_.__)("Internal","wp-parsely");case"direct":return(0,_.__)("Direct","wp-parsely")}return e},u=(0,_.sprintf)((0,_.__)("By %s","wp-parsely"),V(i)); +(0,_.__)("Retrying… Attempt %1$d of %2$d","wp-parsely"),D,3):T?(0,_.__)("Generating Smart Links…","wp-parsely"):(0,_.__)("Add Smart Links","wp-parsely")})}),(G.length>0||V.length>0)&&(0,p.jsx)("div",{className:"smart-linking-manage",children:(0,p.jsx)(f.Button,{onClick:function(){return lt(void 0,void 0,void 0,(function(){var e,t;return ct(this,(function(n){switch(n.label){case 0:return[4,be()];case 1:return e=n.sent(),t=ye(),[4,W(t)];case 2:return n.sent(),pe(!0),P.trackEvent("smart_linking_review_pressed",{num_smart_links:F.length,has_fixed_links:e,context:i}),[2]}}))}))},variant:"secondary",disabled:T,children:(0,_.__)("Review Smart Links","wp-parsely")})})]}),L&&(0,p.jsx)(ot,{isOpen:L,onAppliedLink:function(){y((function(e){return e+1}))},onClose:function(){x(!0),pe(!1)}})]})},ft=function(){return ft=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0)&&(t(),e())}))}))]}))},new((n=void 0)||(n=Promise))((function(i,s){function o(e){try{l(r.next(e))}catch(e){s(e)}}function a(e){try{l(r.throw(e))}catch(e){s(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(o,a)}l((r=r.apply(e,t||[])).next())}));var e,t,n,r}().then((function(){var t=document.querySelector(".wp-block-post-content");ke(t,e)}))})))},Pt=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"M7 11.5h10V13H7z"})}),jt=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"M13 19h-2v-2h2v2zm0-6h-2v-2h2v2zm0-6h-2V5h2v2z"})}),Tt=function(e){var t=e.title,n=e.icon,r=e.subtitle,i=e.level,s=void 0===i?2:i,o=e.children,a=e.controls,l=e.onClick,c=e.isOpen,u=e.isLoading,d=e.dropdownChildren;return(0,p.jsxs)("div",{className:"performance-stat-panel",children:[(0,p.jsxs)(f.__experimentalHStack,{className:"panel-header level-"+s,children:[(0,p.jsx)(f.__experimentalHeading,{level:s,children:t}),r&&!c&&(0,p.jsx)("span",{className:"panel-subtitle",children:r}),a&&!d&&(0,p.jsx)(f.DropdownMenu,{icon:n,label:(0,_.__)("Settings","wp-parsely"),className:"panel-settings-button",controls:a}),d&&(0,p.jsx)(f.DropdownMenu,{icon:n,label:(0,_.__)("Settings","wp-parsely"),className:"panel-settings-button",children:d}),n&&!d&&!a&&(0,p.jsx)(f.Button,{icon:n,className:"panel-settings-button",isPressed:c,onClick:l})]}),(0,p.jsx)("div",{className:"panel-body",children:u?(0,p.jsx)("div",{className:"parsely-spinner-wrapper","data-testid":"parsely-spinner-wrapper",children:(0,p.jsx)(f.Spinner,{})}):o})]})};function Lt(e,t,n){void 0===t&&(t=1),void 0===n&&(n="");var r=parseInt(e.replace(/\D/g,""),10);if(r<1e3)return e;r<1e4&&(t=1);var i=r,s=r.toString(),o="",a=0;return Object.entries({1e3:"k","1,000,000":"M","1,000,000,000":"B","1,000,000,000,000":"T","1,000,000,000,000,000":"Q"}).forEach((function(e){var n=e[0],l=e[1],c=parseInt(n.replace(/\D/g,""),10);if(r>=c){var u=t;(i=r/c)%1>1/a&&(u=i>10?1:2),u=parseFloat(i.toFixed(2))===parseFloat(i.toFixed(0))?0:u,s=i.toFixed(u),o=l}a=c})),s+n+o}var Et=function(e){var t=e.data,n=e.isLoading,r=(0,b.useState)(m.Views),i=r[0],s=r[1],o=(0,b.useState)(!1),a=o[0],l=o[1];n||delete t.referrers.types.totals;var c=function(e){switch(e){case"social":return(0,_.__)("Social","wp-parsely");case"search":return(0,_.__)("Search","wp-parsely");case"other":return(0,_.__)("Other","wp-parsely");case"internal":return(0,_.__)("Internal","wp-parsely");case"direct":return(0,_.__)("Direct","wp-parsely")}return e},u=(0,_.sprintf)((0,_.__)("By %s","wp-parsely"),V(i)); /* translators: %s: metric description */return(0,p.jsxs)(Tt,{title:(0,_.__)("Categories","wp-parsely"),level:3,subtitle:u,isOpen:a,onClick:function(){return l(!a)},children:[a&&(0,p.jsx)("div",{className:"panel-settings",children:(0,p.jsx)(f.SelectControl,{value:i,prefix:(0,_.__)("By: ","wp-parsely"),onChange:function(e){D(e,m)&&s(e)},children:Object.values(m).map((function(e){return(0,p.jsxs)("option",{value:e,disabled:"avg_engaged"===e,children:[V(e),"avg_engaged"===e&&(0,_.__)(" (coming soon)","wp-parsely")]},e)}))})}),n?(0,p.jsx)("div",{className:"parsely-spinner-wrapper","data-testid":"parsely-spinner-wrapper",children:(0,p.jsx)(f.Spinner,{})}):(0,p.jsxs)("div",{children:[(0,p.jsx)("div",{className:"multi-percentage-bar",children:Object.entries(t.referrers.types).map((function(e){var t=e[0],n=e[1],r=(0,_.sprintf)(/* translators: 1: Referrer type, 2: Percentage value, %%: Escaped percent sign */ /* translators: 1: Referrer type, 2: Percentage value, %%: Escaped percent sign */ (0,_.__)("%1$s: %2$s%%","wp-parsely"),c(t),n.viewsPercentage);return(0,p.jsx)(f.Tooltip /* translators: %s: percentage value */,{ @@ -25,4 +25,4 @@ message:(0,_.sprintf)((0,_.__)('by author "%1$s"',"wp-parsely"),n.value)};throw (0,_.__)("Top related posts by %1$s in the %2$s.","wp-parsely"),I.value,F(r,!0)):null!=E?E:""})}),j&&j.Message(),x&&(0,p.jsx)("div",{className:"related-posts-loading-message","data-testid":"parsely-related-posts-loading-message",children:(0,_.__)("Loading…","wp-parsely")}),!x&&!j&&0===A.length&&(0,p.jsx)("div",{className:"related-posts-empty","data-testid":"parsely-related-posts-empty",children:(0,_.__)("No related posts found.","wp-parsely")}),!x&&A.length>0&&(0,p.jsx)("div",{className:"related-posts-list",children:A.map((function(e){return(0,p.jsx)(hn,{metric:i,post:e,postContent:H},e.id)}))})]})]})]})},jn=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"m19 7-3-3-8.5 8.5-1 4 4-1L19 7Zm-7 11.5H5V20h7v-1.5Z"})}),Tn=function(){return(0,p.jsx)(f.SVG,{xmlns:"http://www.w3.org/2000/svg",width:"18",height:"18",viewBox:"0 0 18 18",fill:"none",children:(0,p.jsx)(f.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M13.5034 7.91642L9 12.0104L4.49662 7.91642L5.25337 7.08398L8.99999 10.49L12.7466 7.08398L13.5034 7.91642Z",fill:"#1E1E1E"})})},Ln={journalist:{label:(0,_.__)("Journalist","wp-parsely")},editorialWriter:{label:(0,_.__)("Editorial Writer","wp-parsely")},investigativeReporter:{label:(0,_.__)("Investigative Reporter","wp-parsely")},techAnalyst:{label:(0,_.__)("Tech Analyst","wp-parsely")},businessAnalyst:{label:(0,_.__)("Business Analyst","wp-parsely")},culturalCommentator:{label:(0,_.__)("Cultural Commentator","wp-parsely")},scienceCorrespondent:{label:(0,_.__)("Science Correspondent","wp-parsely")},politicalAnalyst:{label:(0,_.__)("Political Analyst","wp-parsely")},healthWellnessAdvocate:{label:(0,_.__)("Health and Wellness Advocate","wp-parsely")},environmentalJournalist:{label:(0,_.__)("Environmental Journalist","wp-parsely")},custom:{label:(0,_.__)("Custom Persona","wp-parsely"),icon:jn}},En=Object.keys(Ln),Nn=function(e){return"custom"===e||""===e?Ln.custom.label:Cn(e)?e:Ln[e].label},Cn=function(e){return!En.includes(e)||"custom"===e},An=function(e){var t=e.value,n=e.onChange,r=(0,b.useState)(""),i=r[0],s=r[1],o=(0,z.useDebounce)(n,500);return(0,p.jsx)("div",{className:"parsely-persona-selector-custom",children:(0,p.jsx)(f.TextControl,{value:i||t,placeholder:(0,_.__)("Enter a custom persona…","wp-parsely"),onChange:function(e){if(""===e)return n(""),void s("");e.length>32&&(e=e.slice(0,32)),o(e),s(e)}})})},On=function(e){var t=e.persona,n=e.value,r=void 0===n?(0,_.__)("Select a persona…","wp-parsely"):n,i=e.label,s=void 0===i?(0,_.__)("Persona","wp-parsely"):i,o=e.onChange,a=e.onDropdownChange,l=e.disabled,c=void 0!==l&&l,u=e.allowCustom,d=void 0!==u&&u;return(0,p.jsxs)(f.Disabled,{isDisabled:c,children:[s&&(0,p.jsx)("div",{className:"wp-parsely-dropdown-label",children:s}),(0,p.jsx)(f.DropdownMenu,{label:(0,_.__)("Persona","wp-parsely"),className:"parsely-persona-selector-dropdown"+(c?" is-disabled":""),popoverProps:{className:"wp-parsely-popover"},toggleProps:{children:(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)("div",{className:"parsely-persona-selector-label",children:Cn(t)?Ln.custom.label:r}),(0,p.jsx)(Tn,{})]})},children:function(e){var n=e.onClose;return(0,p.jsx)(f.MenuGroup,{label:(0,_.__)("Persona","wp-parsely"),children:(0,p.jsx)(p.Fragment,{children:En.map((function(e){if(!d&&"custom"===e)return null;var r=Ln[e],i=e===t||Cn(t)&&"custom"===e;return(0,p.jsxs)(f.MenuItem,{isSelected:i,className:i?"is-selected":"",role:"menuitemradio",onClick:function(){null==a||a(e),o(e),n(),"custom"===e&&setTimeout((function(){var e=document.querySelector(".parsely-persona-selector-custom input");e&&e.focus()}),0)},children:[r.icon&&(0,p.jsx)(X,{icon:r.icon}),r.label]},e)}))})})}}),d&&Cn(t)&&(0,p.jsx)(An,{onChange:function(e){o(""!==e?e:"custom")},value:"custom"===t?"":t})]})},Rn={neutral:{label:(0,_.__)("Neutral","wp-parsely")},formal:{label:(0,_.__)("Formal","wp-parsely")},humorous:{label:(0,_.__)("Humorous","wp-parsely")},confident:{label:(0,_.__)("Confident","wp-parsely")},provocative:{label:(0,_.__)("Provocative","wp-parsely")},serious:{label:(0,_.__)("Serious","wp-parsely")},inspirational:{label:(0,_.__)("Inspirational","wp-parsely")},skeptical:{label:(0,_.__)("Skeptical","wp-parsely")},conversational:{label:(0,_.__)("Conversational","wp-parsely")},analytical:{label:(0,_.__)("Analytical","wp-parsely")},custom:{label:(0,_.__)("Custom Tone","wp-parsely"),icon:jn}},In=Object.keys(Rn),Bn=function(e){return"custom"===e||""===e?Rn.custom.label:Mn(e)?e:Rn[e].label},Mn=function(e){return!In.includes(e)||"custom"===e},Dn=function(e){var t=e.value,n=e.onChange,r=(0,b.useState)(""),i=r[0],s=r[1],o=(0,z.useDebounce)(n,500);return(0,p.jsx)("div",{className:"parsely-tone-selector-custom",children:(0,p.jsx)(f.TextControl,{value:i||t,placeholder:(0,_.__)("Enter a custom tone","wp-parsely"),onChange:function(e){if(""===e)return n(""),void s("");e.length>32&&(e=e.slice(0,32)),o(e),s(e)}})})},Fn=function(e){var t=e.tone,n=e.value,r=void 0===n?(0,_.__)("Select a tone","wp-parsely"):n,i=e.label,s=void 0===i?(0,_.__)("Tone","wp-parsely"):i,o=e.onChange,a=e.onDropdownChange,l=e.disabled,c=void 0!==l&&l,u=e.allowCustom,d=void 0!==u&&u;return(0,p.jsxs)(f.Disabled,{isDisabled:c,children:[(0,p.jsx)("div",{className:"wp-parsely-dropdown-label",children:s}),(0,p.jsx)(f.DropdownMenu,{label:(0,_.__)("Tone","wp-parsely"),className:"parsely-tone-selector-dropdown"+(c?" is-disabled":""),popoverProps:{className:"wp-parsely-popover"},toggleProps:{children:(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)("div",{className:"parsely-tone-selector-label",children:Mn(t)?Rn.custom.label:r}),(0,p.jsx)(Tn,{})]})},children:function(e){var n=e.onClose;return(0,p.jsx)(f.MenuGroup,{label:(0,_.__)("Select a tone","wp-parsely"),children:(0,p.jsx)(p.Fragment,{children:In.map((function(e){if(!d&&"custom"===e)return null;var r=Rn[e],i=e===t||Mn(t)&&"custom"===e;return(0,p.jsxs)(f.MenuItem,{isSelected:i,className:i?"is-selected":"",role:"menuitemradio",onClick:function(){null==a||a(e),o(e),n(),"custom"===e&&setTimeout((function(){var e=document.querySelector(".parsely-tone-selector-custom input");e&&e.focus()}),0)},children:[r.icon&&(0,p.jsx)(X,{icon:r.icon}),r.label]},e)}))})})}}),d&&Mn(t)&&(0,p.jsx)(Dn,{onChange:function(e){o(""!==e?e:"custom")},value:"custom"===t?"":t})]})},Vn=(0,p.jsx)(x.SVG,{width:"24",height:"24",viewBox:"0 0 24 24",xmlns:"http://www.w3.org/2000/svg",children:(0,p.jsx)(x.Path,{d:"M10.97 10.159a3.382 3.382 0 0 0-2.857.955l1.724 1.723-2.836 2.913L7 17h1.25l2.913-2.837 1.723 1.723a3.38 3.38 0 0 0 .606-.825c.33-.63.446-1.343.35-2.032L17 10.695 13.305 7l-2.334 3.159Z"})}),Gn=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"M18.3 11.7c-.6-.6-1.4-.9-2.3-.9H6.7l2.9-3.3-1.1-1-4.5 5L8.5 16l1-1-2.7-2.7H16c.5 0 .9.2 1.3.5 1 1 1 3.4 1 4.5v.3h1.5v-.2c0-1.5 0-4.3-1.5-5.7z"})}),Hn=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M12 5.5A2.25 2.25 0 0 0 9.878 7h4.244A2.251 2.251 0 0 0 12 5.5ZM12 4a3.751 3.751 0 0 0-3.675 3H5v1.5h1.27l.818 8.997a2.75 2.75 0 0 0 2.739 2.501h4.347a2.75 2.75 0 0 0 2.738-2.5L17.73 8.5H19V7h-3.325A3.751 3.751 0 0 0 12 4Zm4.224 4.5H7.776l.806 8.861a1.25 1.25 0 0 0 1.245 1.137h4.347a1.25 1.25 0 0 0 1.245-1.137l.805-8.861Z"})}),zn=(0,p.jsx)(x.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",children:(0,p.jsx)(x.Path,{d:"m21.5 9.1-6.6-6.6-4.2 5.6c-1.2-.1-2.4.1-3.6.7-.1 0-.1.1-.2.1-.5.3-.9.6-1.2.9l3.7 3.7-5.7 5.7v1.1h1.1l5.7-5.7 3.7 3.7c.4-.4.7-.8.9-1.2.1-.1.1-.2.2-.3.6-1.1.8-2.4.6-3.6l5.6-4.1zm-7.3 3.5.1.9c.1.9 0 1.8-.4 2.6l-6-6c.8-.4 1.7-.5 2.6-.4l.9.1L15 4.9 19.1 9l-4.9 3.6z"})}),Un=function(){return Un=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]0?(0,p.jsx)("span",{className:"parsely-write-titles-text",children:(0,b.createInterpolateElement)( // translators: %1$s is the tone, %2$s is the persona. // translators: %1$s is the tone, %2$s is the persona. -(0,_.__)("We've generated a few titles based on the content of your post, written as a .","wp-parsely"),{tone:(0,p.jsx)("strong",{children:Bn(a)}),persona:(0,p.jsx)("strong",{children:Nn(u)})})}):(0,_.__)("Use Parse.ly AI to generate a title for your post.","wp-parsely"),(0,p.jsxs)(f.Button,{href:"https://docs.parse.ly/plugin-content-helper/#h-title-suggestions-beta",target:"_blank",variant:"link",children:[(0,_.__)("Learn more about Parse.ly AI","wp-parsely"),(0,p.jsx)(X,{icon:ee,size:18,className:"parsely-external-link-icon"})]})]}),i&&(0,p.jsx)(f.Notice,{className:"wp-parsely-content-helper-error",onRemove:function(){return s(void 0)},status:"info",children:i.Message()}),void 0!==k&&(0,p.jsx)(Jn,{title:k,type:fn.PostTitle,isOriginal:!0}),00&&(0,p.jsx)(Qn,{pinnedTitles:m,isOpen:!0}),y.length>0&&(0,p.jsx)(er,{suggestions:y,isOpen:!0,isLoading:g})]}),(0,p.jsx)(Xn,{isLoading:g,onPersonaChange:function(e){C("Persona",e),d(e)},onSettingChange:C,onToneChange:function(e){C("Tone",e),l(e)},persona:t.TitleSuggestions.Persona,tone:t.TitleSuggestions.Tone}),(0,p.jsx)("div",{className:"title-suggestions-generate",children:(0,p.jsxs)(f.Button,{variant:"primary",isBusy:g,disabled:g||"custom"===a||"custom"===u,onClick:function(){return ir(void 0,void 0,void 0,(function(){return sr(this,(function(e){switch(e.label){case 0:return s(void 0),!1!==g?[3,2]:(P.trackEvent("title_suggestions_generate_pressed",{request_more:y.length>0,total_titles:y.length,total_pinned:y.filter((function(e){return e.isPinned})).length,tone:a,persona:u}),[4,(t=fn.PostTitle,n=A,r=a,i=u,ir(void 0,void 0,void 0,(function(){var e,o,a;return sr(this,(function(l){switch(l.label){case 0:return[4,T(!0)];case 1:l.sent(),e=nr.getInstance(),l.label=2;case 2:return l.trys.push([2,5,,6]),[4,e.generateTitles(n,3,r,i)];case 3:return o=l.sent(),[4,j(t,o)];case 4:return l.sent(),[3,6];case 5:return a=l.sent(),s(a),j(t,[]),[3,6];case 6:return[4,T(!1)];case 7:return l.sent(),[2]}}))})))]);case 1:e.sent(),e.label=2;case 2:return[2]}var t,n,r,i}))}))},children:[g&&(0,_.__)("Generating Titles…","wp-parsely"),!g&&w.length>0&&(0,_.__)("Generate More","wp-parsely"),!g&&0===w.length&&(0,_.__)("Generate Titles","wp-parsely")]})})]})})},ar=function(){return ar=Object.assign||function(e){for(var t,n=1,r=arguments.length;n titles based on the content of your post, written as a .","wp-parsely"),{tone:(0,p.jsx)("strong",{children:Bn(a)}),persona:(0,p.jsx)("strong",{children:Nn(u)})})}):(0,_.__)("Use Parse.ly AI to generate a title for your post.","wp-parsely"),(0,p.jsxs)(f.Button,{href:"https://docs.parse.ly/plugin-content-helper/#h-title-suggestions-beta",target:"_blank",variant:"link",children:[(0,_.__)("Learn more about Parse.ly AI","wp-parsely"),(0,p.jsx)(X,{icon:ee,size:18,className:"parsely-external-link-icon"})]})]}),i&&(0,p.jsx)(f.Notice,{className:"wp-parsely-content-helper-error",onRemove:function(){return s(void 0)},status:"info",children:i.Message()}),void 0!==k&&(0,p.jsx)(Jn,{title:k,type:fn.PostTitle,isOriginal:!0}),00&&(0,p.jsx)(Qn,{pinnedTitles:m,isOpen:!0}),y.length>0&&(0,p.jsx)(er,{suggestions:y,isOpen:!0,isLoading:g})]}),(0,p.jsx)(Xn,{isLoading:g,onPersonaChange:function(e){C("Persona",e),d(e)},onSettingChange:C,onToneChange:function(e){C("Tone",e),l(e)},persona:t.TitleSuggestions.Persona,tone:t.TitleSuggestions.Tone}),(0,p.jsx)("div",{className:"title-suggestions-generate",children:(0,p.jsxs)(f.Button,{variant:"primary",isBusy:g,disabled:g||"custom"===a||"custom"===u,onClick:function(){return ir(void 0,void 0,void 0,(function(){return sr(this,(function(e){switch(e.label){case 0:return s(void 0),!1!==g?[3,2]:(P.trackEvent("title_suggestions_generate_pressed",{request_more:y.length>0,total_titles:y.length,total_pinned:y.filter((function(e){return e.isPinned})).length,tone:a,persona:u}),[4,(t=fn.PostTitle,n=A,r=a,i=u,ir(void 0,void 0,void 0,(function(){var e,o,a;return sr(this,(function(l){switch(l.label){case 0:return[4,T(!0)];case 1:l.sent(),e=nr.getInstance(),l.label=2;case 2:return l.trys.push([2,5,,6]),[4,e.generateTitles(n,3,r,i)];case 3:return o=l.sent(),[4,j(t,o)];case 4:return l.sent(),[3,6];case 5:return a=l.sent(),s(a),j(t,[]),[3,6];case 6:return[4,T(!1)];case 7:return l.sent(),[2]}}))})))]);case 1:e.sent(),e.label=2;case 2:return[2]}var t,n,r,i}))}))},children:[g&&(0,_.__)("Generating Titles…","wp-parsely"),!g&&w.length>0&&(0,_.__)("Generate More","wp-parsely"),!g&&0===w.length&&(0,_.__)("Generate Titles","wp-parsely")]})})]})})},ar=function(){return ar=Object.assign||function(e){for(var t,n=1,r=arguments.length;n diff --git a/src/content-helper/editor-sidebar/editor-sidebar.tsx b/src/content-helper/editor-sidebar/editor-sidebar.tsx index f3e36d922..2c57a4988 100644 --- a/src/content-helper/editor-sidebar/editor-sidebar.tsx +++ b/src/content-helper/editor-sidebar/editor-sidebar.tsx @@ -228,7 +228,7 @@ const ContentHelperEditorSidebar = (): React.JSX.Element => { title={ __( 'Parse.ly', 'wp-parsely' ) } > @@ -279,7 +279,7 @@ registerPlugin( BLOCK_PLUGIN_ID, { icon: LeafIcon, render: () => ( diff --git a/src/content-helper/editor-sidebar/smart-linking/smart-linking.tsx b/src/content-helper/editor-sidebar/smart-linking/smart-linking.tsx index bdec814f6..cb40a3558 100644 --- a/src/content-helper/editor-sidebar/smart-linking/smart-linking.tsx +++ b/src/content-helper/editor-sidebar/smart-linking/smart-linking.tsx @@ -53,7 +53,7 @@ const withSettingsProvider = createHigherOrderComponent( ( BlockEdit ) => { return ( From 5b62a4e5b03df145a38a5c5deff16442c1b18ac3 Mon Sep 17 00:00:00 2001 From: Henrique Mouta Date: Fri, 30 Aug 2024 13:12:55 +0100 Subject: [PATCH 069/282] Add tests --- .../EditorSidebarSettingsEndpointTest.php | 1 - .../Integration/RestAPI/BaseEndpointTest.php | 8 +- .../Settings/BaseSettingsEndpointTest.php | 219 ++++++++++++ .../EndpointDashboardWidgetSettingsTest.php | 203 +++++++++++ .../EndpointEditorSidebarSettingsTest.php | 314 ++++++++++++++++++ 5 files changed, 742 insertions(+), 3 deletions(-) create mode 100644 tests/Integration/RestAPI/Settings/BaseSettingsEndpointTest.php create mode 100644 tests/Integration/RestAPI/Settings/EndpointDashboardWidgetSettingsTest.php create mode 100644 tests/Integration/RestAPI/Settings/EndpointEditorSidebarSettingsTest.php diff --git a/tests/Integration/Endpoints/UserMeta/EditorSidebarSettingsEndpointTest.php b/tests/Integration/Endpoints/UserMeta/EditorSidebarSettingsEndpointTest.php index 00071489b..1b16f855b 100644 --- a/tests/Integration/Endpoints/UserMeta/EditorSidebarSettingsEndpointTest.php +++ b/tests/Integration/Endpoints/UserMeta/EditorSidebarSettingsEndpointTest.php @@ -176,7 +176,6 @@ public function test_endpoint_returns_value_on_get_request(): void { * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::get_nested_specs * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::get_valid_values * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::is_available_to_current_user - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::is_valid_key * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::run * @uses \Parsely\Endpoints\User_Meta\Editor_Sidebar_Settings_Endpoint::get_meta_key * @uses \Parsely\Endpoints\User_Meta\Editor_Sidebar_Settings_Endpoint::get_route diff --git a/tests/Integration/RestAPI/BaseEndpointTest.php b/tests/Integration/RestAPI/BaseEndpointTest.php index 00f2f7bb8..ae2c3e80f 100644 --- a/tests/Integration/RestAPI/BaseEndpointTest.php +++ b/tests/Integration/RestAPI/BaseEndpointTest.php @@ -78,8 +78,12 @@ class BaseEndpointTest extends TestCase { * Constructor that initializes the Parsely and API controller instances. * * @since 3.17.0 + * + * @param string|null $name The name of the test. + * @param array $data The data for the test. + * @param string $data_name The name of the data. */ - public function __construct() { + public function __construct( $name = null, array $data = array(), $data_name = '' ) { // Create Parsely class, if not already created (by an inherited class). if ( null === $this->parsely ) { $this->parsely = new Parsely(); @@ -90,7 +94,7 @@ public function __construct() { $this->api_controller = new REST_API_Controller( $this->parsely ); } - parent::__construct(); + parent::__construct( $name, $data, $data_name ); } /** diff --git a/tests/Integration/RestAPI/Settings/BaseSettingsEndpointTest.php b/tests/Integration/RestAPI/Settings/BaseSettingsEndpointTest.php new file mode 100644 index 000000000..8d7b18f11 --- /dev/null +++ b/tests/Integration/RestAPI/Settings/BaseSettingsEndpointTest.php @@ -0,0 +1,219 @@ + $extra_data Any Extra key/value pairs to add. + * @return array The generated JSON array. + */ + abstract protected function generate_json( + ?string $metric = null, + ?string $period = null, + array $extra_data = array() + ): array; + + /** + * Returns the default value for the endpoint. + * + * @since 3.17.0 + * + * @return array The default value for the endpoint. + */ + abstract protected function get_default_value(): array; + + /** + * Verifies that the route is registered. + * + * @since 3.17.0 + */ + protected function run_test_route_is_registered(): void { + $routes = rest_get_server()->get_routes(); + + // Check that the main route is registered. + $expected_route = $this->get_endpoint()->get_full_endpoint( '/' ); + self::assertArrayHasKey( $expected_route, $routes ); + + // Check that the route is associated with the POST method. + $route_data = $routes[ $expected_route ]; + self::assertArrayHasKey( 'GET', $route_data[0]['methods'] ); + self::assertArrayHasKey( 'PUT', $route_data[0]['methods'] ); + + // Check the `/get` route. + $expected_route = $this->get_endpoint()->get_full_endpoint( '/get' ); + self::assertArrayHasKey( $expected_route, $routes ); + + // Check that the route is associated with the GET method. + $route_data = $routes[ $expected_route ]; + self::assertArrayHasKey( 'GET', $route_data[0]['methods'] ); + + // Check the `/set` route. + $expected_route = $this->get_endpoint()->get_full_endpoint( '/set' ); + self::assertArrayHasKey( $expected_route, $routes ); + + // Check that the route is associated with the PUT method. + $route_data = $routes[ $expected_route ]; + self::assertArrayHasKey( 'PUT', $route_data[0]['methods'] ); + } + + /** + * Verifies that the endpoint returns the correct default value. + * + * @since 3.13.0 + * @since 3.17.0 Moved from the old BaseUserMetaEndpointTest class. + */ + public function run_test_endpoint_returns_value_on_get_request(): void { + $this->set_current_user_to_admin(); + + $value = rest_do_request( + new WP_REST_Request( + 'GET', + $this->get_endpoint()->get_full_endpoint( '/get' ) + ) + )->get_data(); + $value = $this->wp_json_encode( $value ); + + $expected = $this->wp_json_encode( + $this->get_default_value() + ); + + self::assertSame( $expected, $value ); + } + + /** + * Provides data for testing PUT requests. + * + * @since 3.13.0 + * @since 3.17.0 Moved from the old BaseUserMetaEndpointTest class. + * + * @return iterable + */ + public function provide_put_requests_data(): iterable { + $default_value = $this->generate_json( 'views', '7d' ); + $valid_value = $this->generate_json( 'avg_engaged', '1h' ); + + // Valid non-default value. It should be returned unmodified. + yield 'valid period and metric values' => array( + 'test_data' => $valid_value, + 'expected' => $valid_value, + ); + + // Missing or problematic keys. Defaults should be used for the missing or problematic keys. + yield 'valid period value, no metric value' => array( + 'test_data' => $this->generate_json( null, '1h' ), + 'expected' => $this->generate_json( 'views', '1h' ), + ); + yield 'valid metric value, no period value' => array( + 'test_data' => $this->generate_json( 'avg_engaged' ), + 'expected' => $this->generate_json( 'avg_engaged', '7d' ), + ); + yield 'no values' => array( + 'test_data' => $this->generate_json(), + 'expected' => $default_value, + ); + + // Invalid values. They should be adjusted to their defaults. + yield 'invalid period value' => array( + 'test_data' => $this->generate_json( 'avg_engaged', 'invalid' ), + 'expected' => $this->generate_json( 'avg_engaged', '7d' ), + ); + yield 'invalid metric value' => array( + 'test_data' => $this->generate_json( 'invalid', '1h' ), + 'expected' => $this->generate_json( 'views', '1h' ), + ); + yield 'invalid period and metric values' => array( + 'test_data' => $this->generate_json( 'invalid', 'invalid' ), + 'expected' => $default_value, + ); + + // Invalid extra data passed. Any such data should be discarded. + yield 'invalid additional value' => array( + 'test_data' => $this->generate_json( + 'avg_engaged', + '1h', + array( 'invalid' ) + ), + 'expected' => $valid_value, + ); + yield 'invalid additional key/value pair' => array( + 'test_data' => $this->generate_json( + 'avg_engaged', + '1h', + array( 'invalid_key' => 'invalid_value' ) + ), + 'expected' => $valid_value, + ); + } + + /** + * Sends a PUT request to the endpoint. + * + * @since 3.13.0 + * @since 3.17.0 Moved from the old BaseUserMetaEndpointTest class. + * + * @param array $data The data to be sent in the request. + * @return array The response returned by the endpoint. + */ + protected function send_put_request( array $data ): array { + $this->set_current_user_to_admin(); + $result = $this->send_wp_rest_request( + 'PUT', + $this->get_endpoint()->get_full_endpoint( '/set' ), + $this->wp_json_encode( $data ) + ); + + if ( ! is_array( $result ) ) { + return array(); + } + + return $result; + } + + /** + * Test that the endpoint is not available if the API secret is not set. + * This test should be disabled since the endpoint does not requires the API secret. + * + * @since 3.17.0 + * @coversNothing + */ + public function test_is_available_to_current_user_returns_error_api_secret_not_set(): void { + // This test is disabled since the endpoint does not requires the API secret. + self::assertTrue( true ); + } + + /** + * Test that the endpoint is not available if the site ID is not set. + * This test should be disabled since the endpoint does not requires the site ID. + * + * @since 3.17.0 + * @coversNothing + */ + public function test_is_available_to_current_user_returns_error_site_id_not_set(): void { + // This test is disabled since the endpoint does not requires the site ID. + self::assertTrue( true ); + } +} diff --git a/tests/Integration/RestAPI/Settings/EndpointDashboardWidgetSettingsTest.php b/tests/Integration/RestAPI/Settings/EndpointDashboardWidgetSettingsTest.php new file mode 100644 index 000000000..b1ebc2035 --- /dev/null +++ b/tests/Integration/RestAPI/Settings/EndpointDashboardWidgetSettingsTest.php @@ -0,0 +1,203 @@ +api_controller = new Content_Helper_Controller( $this->parsely ); + $this->endpoint = new Endpoint_Dashboard_Widget_Settings( $this->api_controller ); + + parent::set_up(); + } + + /** + * Returns the endpoint to be used in tests. + * + * @since 3.17.0 + * + * @return \Parsely\REST_API\Base_Endpoint + */ + public function get_endpoint(): \Parsely\REST_API\Base_Endpoint { + return $this->endpoint; + } + + /** + * Returns the default value for the endpoint. + * + * @since 3.17.0 + * + * @return array The default value for the endpoint. + */ + public function get_default_value(): array { + return array( + 'Metric' => 'views', + 'Period' => '7d', + ); + } + + /** + * Generates a JSON array for the passed period, metric, and extra data. + * + * @since 3.13.0 + * + * @param string|null $metric The Metric value. + * @param string|null $period The Period value. + * @param array $extra_data Any Extra key/value pairs to add. + * @return array The generated JSON array. + */ + protected function generate_json( + ?string $metric = null, + ?string $period = null, + array $extra_data = array() + ): array { + $array = $this->get_default_value(); + unset( $array['Metric'], $array['Period'] ); + + if ( null !== $metric ) { + $array['Metric'] = $metric; + } + + if ( null !== $period ) { + $array['Period'] = $period; + } + + ksort( $array ); + + return array_merge( $array, $extra_data ); + } + + /** + * Verifies that the route is registered. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Settings\Endpoint_Dashboard_Widget_Settings::register_routes + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Content_Helper\Content_Helper_Controller::get_route_prefix + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::__construct + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::init + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Settings\Endpoint_Dashboard_Widget_Settings::get_endpoint_name + * @uses \Parsely\REST_API\Settings\Endpoint_Dashboard_Widget_Settings::get_subvalues_specs + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_route_is_registered(): void { + parent::run_test_route_is_registered(); + } + + /** + * Verifies that the endpoint returns the correct default settings. + * + * @since 3.13.0 + * @since 3.17.0 Moved from old test class. + * + * @covers \Parsely\REST_API\Settings\Endpoint_Dashboard_Widget_Settings::process_request + * @covers \Parsely\REST_API\Settings\Endpoint_Dashboard_Widget_Settings::get_settings + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Content_Helper\Content_Helper_Controller::get_route_prefix + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::__construct + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::init + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::register_routes + * @uses \Parsely\REST_API\Settings\Endpoint_Dashboard_Widget_Settings::get_endpoint_name + * @uses \Parsely\REST_API\Settings\Endpoint_Dashboard_Widget_Settings::get_meta_key + * @uses \Parsely\REST_API\Settings\Endpoint_Dashboard_Widget_Settings::get_subvalues_specs + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_endpoint_returns_value_on_get_request(): void { + parent::run_test_endpoint_returns_value_on_get_request(); + } + + /** + * Verifies that the endpoint can correctly handle PUT requests. + * + * @since 3.13.0 + * @since 3.17.0 Moved from old test class. + * + * @param array $test_data The data to send in the PUT request. + * @param array $expected The expected value of the setting after the PUT request. + * + * @covers \Parsely\REST_API\Settings\Endpoint_Dashboard_Widget_Settings::get_subvalues_specs + * @covers \Parsely\REST_API\Settings\Endpoint_Dashboard_Widget_Settings::sanitize_subvalue + * @covers \Parsely\REST_API\Settings\Endpoint_Dashboard_Widget_Settings::sanitize_value + * @covers \Parsely\REST_API\Settings\Endpoint_Dashboard_Widget_Settings::set_settings + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Content_Helper\Content_Helper_Controller::get_route_prefix + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::__construct + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::get_settings + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::get_valid_values + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::init + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::register_routes + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::get_default + * @uses \Parsely\REST_API\Settings\Endpoint_Dashboard_Widget_Settings::get_endpoint_name + * @uses \Parsely\REST_API\Settings\Endpoint_Dashboard_Widget_Settings::get_meta_key + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @dataProvider provide_put_requests_data + */ + public function test_endpoint_correctly_handles_put_requests( + array $test_data, + array $expected + ): void { + $value = $this->send_put_request( $test_data ); + self::assertSame( $expected, $value ); + } +} diff --git a/tests/Integration/RestAPI/Settings/EndpointEditorSidebarSettingsTest.php b/tests/Integration/RestAPI/Settings/EndpointEditorSidebarSettingsTest.php new file mode 100644 index 000000000..3b9bb654c --- /dev/null +++ b/tests/Integration/RestAPI/Settings/EndpointEditorSidebarSettingsTest.php @@ -0,0 +1,314 @@ +api_controller = new Content_Helper_Controller( $this->parsely ); + $this->endpoint = new Endpoint_Editor_Sidebar_Settings( $this->api_controller ); + + parent::set_up(); + } + + /** + * Returns the endpoint to be used in tests. + * + * @since 3.17.0 + * + * @return \Parsely\REST_API\Base_Endpoint + */ + public function get_endpoint(): \Parsely\REST_API\Base_Endpoint { + return $this->endpoint; + } + + /** + * Returns the default value for the endpoint. + * + * @since 3.17.0 + * + * @return array The default value for the endpoint. + */ + public function get_default_value(): array { + return array( + 'InitialTabName' => 'tools', + 'PerformanceStats' => array( + 'Period' => '7d', + 'VisibleDataPoints' => array( 'views', 'visitors', 'avgEngaged', 'recirculation' ), + 'VisiblePanels' => array( 'overview', 'categories', 'referrers' ), + ), + 'RelatedPosts' => array( + 'FilterBy' => 'unavailable', + 'FilterValue' => '', + 'Metric' => 'views', + 'Open' => false, + 'Period' => '7d', + ), + 'SmartLinking' => array( + 'MaxLinks' => 10, + 'MaxLinkWords' => 4, + 'Open' => false, + ), + 'TitleSuggestions' => array( + 'Open' => false, + 'Persona' => 'journalist', + 'Tone' => 'neutral', + ), + ); + } + + /** + * Verifies that the route is registered. + * + * @since 3.17.0 + * + * @covers \Parsely\REST_API\Settings\Endpoint_Editor_Sidebar_Settings::register_routes + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Content_Helper\Content_Helper_Controller::get_route_prefix + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::__construct + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::init + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Settings\Endpoint_Editor_Sidebar_Settings::get_endpoint_name + * @uses \Parsely\REST_API\Settings\Endpoint_Editor_Sidebar_Settings::get_subvalues_specs + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_route_is_registered(): void { + parent::run_test_route_is_registered(); + } + + /** + * Verifies that the endpoint returns the correct default settings. + * + * @since 3.13.0 + * @since 3.17.0 Moved from old test class. + * + * @covers \Parsely\REST_API\Settings\Endpoint_Editor_Sidebar_Settings::process_request + * @covers \Parsely\REST_API\Settings\Endpoint_Editor_Sidebar_Settings::get_settings + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Content_Helper\Content_Helper_Controller::get_route_prefix + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::__construct + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::init + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::register_routes + * @uses \Parsely\REST_API\Settings\Endpoint_Editor_Sidebar_Settings::get_endpoint_name + * @uses \Parsely\REST_API\Settings\Endpoint_Editor_Sidebar_Settings::get_meta_key + * @uses \Parsely\REST_API\Settings\Endpoint_Editor_Sidebar_Settings::get_subvalues_specs + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_endpoint_returns_value_on_get_request(): void { + parent::run_test_endpoint_returns_value_on_get_request(); + } + + /** + * Verifies that the endpoint can correctly handle PUT requests. + * + * @param array $test_data The data to send in the PUT request. + * @param array $expected The expected value of the setting after the PUT request. + * + * @since 3.13.0 + * @since 3.17.0 Moved from old test class. + * + * @covers \Parsely\REST_API\Settings\Endpoint_Editor_Sidebar_Settings::get_subvalues_specs + * @covers \Parsely\REST_API\Settings\Endpoint_Editor_Sidebar_Settings::sanitize_subvalue + * @covers \Parsely\REST_API\Settings\Endpoint_Editor_Sidebar_Settings::sanitize_value + * @covers \Parsely\REST_API\Settings\Endpoint_Editor_Sidebar_Settings::set_settings + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Content_Helper\Content_Helper_Controller::get_route_prefix + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::__construct + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::get_nested_specs + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::get_settings + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::get_valid_values + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::init + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::register_routes + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::get_default + * @uses \Parsely\REST_API\Settings\Endpoint_Editor_Sidebar_Settings::get_endpoint_name + * @uses \Parsely\REST_API\Settings\Endpoint_Editor_Sidebar_Settings::get_meta_key + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + * @dataProvider provide_put_requests_data* + */ + public function test_endpoint_correctly_handles_put_requests( + array $test_data, + array $expected + ): void { + $value = $this->send_put_request( $test_data ); + self::assertSame( $expected, $value ); + } + + /** + * Tests that the endpoint can correctly handle PUT requests with valid + * nested PerformanceStats values. + * + * @since 3.14.0 + * @since 3.17.0 Moved from old test class. + * + * @covers \Parsely\REST_API\Settings\Endpoint_Editor_Sidebar_Settings::sanitize_subvalue + * @uses \Parsely\REST_API\Base_API_Controller::__construct + * @uses \Parsely\REST_API\Base_API_Controller::get_full_namespace + * @uses \Parsely\REST_API\Base_API_Controller::get_parsely + * @uses \Parsely\REST_API\Base_API_Controller::prefix_route + * @uses \Parsely\REST_API\Base_Endpoint::__construct + * @uses \Parsely\REST_API\Base_Endpoint::get_full_endpoint + * @uses \Parsely\REST_API\Base_Endpoint::init + * @uses \Parsely\REST_API\Base_Endpoint::register_rest_route + * @uses \Parsely\REST_API\Content_Helper\Content_Helper_Controller::get_route_prefix + * @uses \Parsely\REST_API\REST_API_Controller::get_namespace + * @uses \Parsely\REST_API\REST_API_Controller::get_version + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::__construct + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::get_nested_specs + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::get_settings + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::get_valid_values + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::init + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::is_available_to_current_user + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::register_routes + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::sanitize_value + * @uses \Parsely\REST_API\Settings\Base_Settings_Endpoint::set_settings + * @uses \Parsely\REST_API\Settings\Endpoint_Editor_Sidebar_Settings::get_endpoint_name + * @uses \Parsely\REST_API\Settings\Endpoint_Editor_Sidebar_Settings::get_meta_key + * @uses \Parsely\REST_API\Settings\Endpoint_Editor_Sidebar_Settings::get_subvalues_specs + * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key + */ + public function test_valid_nested_performance_stats_settings_period(): void { + $this->set_current_user_to_admin(); + + $value = $this->send_put_request( + $this->generate_json( + 'views', + '7d', + array( + 'PerformanceStats' => array( + 'Period' => '1h', + 'VisibleDataPoints' => array( 'views', 'avgEngaged', 'recirculation' ), + 'VisiblePanels' => array( 'overview', 'referrers' ), + ), + ) + ) + ); + + $expected = array_merge( + $this->get_default_value(), + array( + 'PerformanceStats' => array( + 'Period' => '1h', + 'VisibleDataPoints' => array( 'views', 'avgEngaged', 'recirculation' ), + 'VisiblePanels' => array( 'overview', 'referrers' ), + ), + ) + ); + + self::assertSame( $expected, $value ); + } + + /** + * Generates a JSON array for the passed period, metric, and extra data. + * + * @since 3.13.0 + * @since 3.17.0 Moved from old test class. + * + * @param string|null $metric The RelatedPostsMetric value. + * @param string|null $period The RelatedPostsPeriod value. + * @param array $extra_data Any Extra key/value pairs to add. + * @return array The generated JSON array. + */ + protected function generate_json( + ?string $metric = null, + ?string $period = null, + array $extra_data = array() + ): array { + $array = $this->get_default_value(); + assert( is_array( $array['RelatedPosts'] ) ); + + unset( $array['RelatedPosts']['Metric'], $array['RelatedPosts']['Period'] ); + + if ( null !== $metric ) { + $array['RelatedPosts']['Metric'] = $metric; + } + + if ( null !== $period ) { + $array['RelatedPosts']['Period'] = $period; + } + + $merged_array = array_merge( $array, $extra_data ); + + $this->ksortRecursive( $merged_array, SORT_NATURAL | SORT_FLAG_CASE ); + + return $merged_array; + } + + /** + * Recursively sorts an array by key using a specified sort flag. + * + * @since 3.14.3 + * @since 3.17.0 Moved from old test class. + * + * @param array &$unsorted_array The array to be sorted, passed by reference. + * @param int $sort_flags Optional sorting flags. Defaults to SORT_REGULAR. + */ + private function ksortRecursive( array &$unsorted_array, int $sort_flags = SORT_REGULAR ): void { + ksort( $unsorted_array, $sort_flags ); + foreach ( $unsorted_array as &$value ) { + if ( is_array( $value ) ) { + $this->ksortRecursive( $value, $sort_flags ); + } + } + } +} From de7630a2f23fc975246b7b5d38721c29f2f37b5b Mon Sep 17 00:00:00 2001 From: Henrique Mouta Date: Fri, 30 Aug 2024 13:30:28 +0100 Subject: [PATCH 070/282] Remove old code --- src/Endpoints/class-base-api-proxy.php | 281 ------------- .../class-base-endpoint-user-meta.php | 391 ------------------ ...ass-dashboard-widget-settings-endpoint.php | 54 --- ...class-editor-sidebar-settings-endpoint.php | 102 ----- .../class-content-suggestions-base-api.php | 3 +- .../common/class-content-helper-feature.php | 8 +- .../class-dashboard-widget.php | 3 +- .../editor-sidebar/class-editor-sidebar.php | 4 +- ...ass-endpoint-dashboard-widget-settings.php | 4 +- ...class-endpoint-editor-sidebar-settings.php | 4 +- .../Endpoints/Proxy/BaseProxyEndpointTest.php | 245 ----------- .../Endpoints/RestMetadataTest.php | 1 - .../UserMeta/BaseUserMetaEndpointTest.php | 169 -------- .../DashboardWidgetSettingsEndpointTest.php | 204 --------- .../EditorSidebarSettingsEndpointTest.php | 308 -------------- wp-parsely.php | 47 --- 16 files changed, 10 insertions(+), 1818 deletions(-) delete mode 100644 src/Endpoints/class-base-api-proxy.php delete mode 100644 src/Endpoints/user-meta/class-base-endpoint-user-meta.php delete mode 100644 src/Endpoints/user-meta/class-dashboard-widget-settings-endpoint.php delete mode 100644 src/Endpoints/user-meta/class-editor-sidebar-settings-endpoint.php delete mode 100644 tests/Integration/Endpoints/Proxy/BaseProxyEndpointTest.php delete mode 100644 tests/Integration/Endpoints/UserMeta/BaseUserMetaEndpointTest.php delete mode 100644 tests/Integration/Endpoints/UserMeta/DashboardWidgetSettingsEndpointTest.php delete mode 100644 tests/Integration/Endpoints/UserMeta/EditorSidebarSettingsEndpointTest.php diff --git a/src/Endpoints/class-base-api-proxy.php b/src/Endpoints/class-base-api-proxy.php deleted file mode 100644 index 627543128..000000000 --- a/src/Endpoints/class-base-api-proxy.php +++ /dev/null @@ -1,281 +0,0 @@ - $response The response received by the proxy. - * @return array The generated data. - */ - abstract protected function generate_data( $response ): array; - - /** - * Cached "proxy" to the Parse.ly API endpoint. - * - * @param WP_REST_Request $request The request object. - * @return stdClass|WP_Error stdClass containing the data or a WP_Error object on failure. - */ - abstract public function get_items( WP_REST_Request $request ); - - /** - * Returns whether the endpoint is available for access by the current - * user. - * - * @since 3.14.0 Renamed from `permission_callback()`. - * - * @return bool - */ - public function is_available_to_current_user(): bool { - return $this->api->is_available_to_current_user(); - } - - /** - * Constructor. - * - * @param Parsely $parsely Instance of Parsely class. - * @param Remote_API_Interface $api API object which does the actual calls to the Parse.ly API. - */ - public function __construct( Parsely $parsely, Remote_API_Interface $api ) { - $this->parsely = $parsely; - $this->api = $api; - } - - /** - * Registers the endpoint's WP REST route. - * - * @param string $endpoint The endpoint's route (e.g. /stats/posts). - * @param array $methods The HTTP methods to use for the endpoint. - */ - protected function register_endpoint( string $endpoint, array $methods = array( WP_REST_Server::READABLE ) ): void { - if ( ! apply_filters( 'wp_parsely_enable_' . Utils::convert_endpoint_to_filter_key( $endpoint ) . '_api_proxy', true ) ) { - return; - } - - $get_items_args = array( - 'query' => array( - 'default' => array(), - 'sanitize_callback' => function ( array $query ) { - $sanitized_query = array(); - foreach ( $query as $key => $value ) { - $sanitized_query[ sanitize_key( $key ) ] = sanitize_text_field( $value ); - } - - return $sanitized_query; - }, - ), - ); - - $rest_route_args = array( - array( - 'methods' => $methods, - 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'is_available_to_current_user' ), - 'args' => $get_items_args, - 'show_in_index' => $this->is_available_to_current_user(), - ), - ); - - register_rest_route( 'wp-parsely/v1', $endpoint, $rest_route_args ); - } - - /** - * Cached "proxy" to the endpoint. - * - * @param WP_REST_Request $request The request object. - * @param bool $require_api_secret Specifies if the API Secret is required. - * @param string|null $param_item The param element to use to get the items. - * @return stdClass|WP_Error stdClass containing the data or a WP_Error object on failure. - */ - protected function get_data( WP_REST_Request $request, bool $require_api_secret = true, string $param_item = null ) { - // Validate Site ID and secret. - $validation = $this->validate_apikey_and_secret( $require_api_secret ); - if ( is_wp_error( $validation ) ) { - return $validation; - } - - if ( null !== $param_item ) { - $params = $request->get_param( $param_item ); - } else { - $params = $request->get_params(); - } - - if ( is_array( $params ) && isset( $params['itm_source'] ) ) { - $this->itm_source = $params['itm_source']; - } - - // A proxy with caching behavior is used here. - $response = $this->api->get_items( $params ); - - if ( is_wp_error( $response ) ) { - return $response; - } - - return (object) array( - 'data' => $this->generate_data( $response ), // @phpstan-ignore-line. - ); - } - - /** - * Validates that the Site ID and secret are set. - * If the API secret is not required, it will not be validated. - * - * @since 3.13.0 - * - * @param bool $require_api_secret Specifies if the API Secret is required. - * @return WP_Error|bool - */ - protected function validate_apikey_and_secret( bool $require_api_secret = true ) { - if ( false === $this->parsely->site_id_is_set() ) { - return new WP_Error( - 'parsely_site_id_not_set', - __( 'A Parse.ly Site ID must be set in site options to use this endpoint', 'wp-parsely' ), - array( 'status' => 403 ) - ); - } - - if ( $require_api_secret && false === $this->parsely->api_secret_is_set() ) { - return new WP_Error( - 'parsely_api_secret_not_set', - __( 'A Parse.ly API Secret must be set in site options to use this endpoint', 'wp-parsely' ), - array( 'status' => 403 ) - ); - } - - return true; - } - - /** - * Extracts the post data from the passed object. - * - * Should only be used with endpoints that return post data. - * - * @since 3.10.0 - * - * @param stdClass $item The object to extract the data from. - * @return array The extracted data. - */ - protected function extract_post_data( stdClass $item ): array { - $data = array(); - - if ( isset( $item->author ) ) { - $data['author'] = $item->author; - } - - if ( isset( $item->metrics->views ) ) { - $data['views'] = number_format_i18n( $item->metrics->views ); - } - - if ( isset( $item->metrics->visitors ) ) { - $data['visitors'] = number_format_i18n( $item->metrics->visitors ); - } - - // The avg_engaged metric can be in different locations depending on the - // endpoint and passed sort/url parameters. - $avg_engaged = $item->metrics->avg_engaged ?? $item->avg_engaged ?? null; - if ( null !== $avg_engaged ) { - $data['avgEngaged'] = Utils::get_formatted_duration( (float) $avg_engaged ); - } - - if ( isset( $item->pub_date ) ) { - $data['date'] = wp_date( Utils::get_date_format(), strtotime( $item->pub_date ) ); - } - - if ( isset( $item->title ) ) { - $data['title'] = $item->title; - } - - if ( isset( $item->url ) ) { - $site_id = $this->parsely->get_site_id(); - // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.url_to_postid_url_to_postid - $post_id = url_to_postid( $item->url ); // 0 if the post cannot be found. - - $post_url = Parsely::get_url_with_itm_source( $item->url, null ); - if ( Utils::parsely_is_https_supported() ) { - $post_url = str_replace( 'http://', 'https://', $post_url ); - } - - $data['rawUrl'] = $post_url; - $data['dashUrl'] = Parsely::get_dash_url( $site_id, $post_url ); - $data['id'] = Parsely::get_url_with_itm_source( $post_url, null ); // Unique. - $data['postId'] = $post_id; // Might not be unique. - $data['url'] = Parsely::get_url_with_itm_source( $post_url, $this->itm_source ); - - // Set thumbnail URL, falling back to the Parse.ly thumbnail if needed. - $thumbnail_url = get_the_post_thumbnail_url( $post_id, 'thumbnail' ); - if ( false !== $thumbnail_url ) { - $data['thumbnailUrl'] = $thumbnail_url; - } elseif ( isset( $item->thumb_url_medium ) ) { - $data['thumbnailUrl'] = $item->thumb_url_medium; - } - } - - return $data; - } - - /** - * Generates the post data from the passed response. - * - * Should only be used with endpoints that return post data. - * - * @since 3.10.0 - * - * @param array $response The response received by the proxy. - * @return array The generated data. - */ - protected function generate_post_data( array $response ): array { - $data = array(); - - foreach ( $response as $item ) { - $data [] = (object) $this->extract_post_data( $item ); - } - - return $data; - } -} diff --git a/src/Endpoints/user-meta/class-base-endpoint-user-meta.php b/src/Endpoints/user-meta/class-base-endpoint-user-meta.php deleted file mode 100644 index 72d1ca9e3..000000000 --- a/src/Endpoints/user-meta/class-base-endpoint-user-meta.php +++ /dev/null @@ -1,391 +0,0 @@ -, default: mixed} - */ -abstract class Base_Endpoint_User_Meta extends Base_Endpoint { - /** - * The meta entry's default value. Initialized in the constructor. - * - * @since 3.13.0 - * - * @var array - */ - protected $default_value = array(); - - /** - * The valid values that can be used for each subvalue. Initialized in the - * constructor. - * - * @since 3.13.0 - * - * @var array> - */ - protected $valid_subvalues = array(); - - /** - * The current user's ID. - * - * @since 3.14.0 - * - * @var int - */ - protected $current_user_id = 0; - - /** - * Returns the meta entry's key. - * - * @since 3.13.0 - * - * @return string The meta entry's key. - */ - abstract protected function get_meta_key(): string; - - /** - * Returns the endpoint's subvalues specifications. - * - * @since 3.13.0 - * - * @return array - */ - abstract protected function get_subvalues_specs(): array; - - /** - * Constructor. - * - * @since 3.13.0 - * - * @param Parsely $parsely Parsely instance. - */ - public function __construct( Parsely $parsely ) { - parent::__construct( $parsely ); - - $subvalues_specs = $this->get_subvalues_specs(); - - foreach ( $subvalues_specs as $key => $value ) { - $this->default_value[ $key ] = $value['default']; - $this->valid_subvalues[ $key ] = $value['values']; - } - } - - /** - * Registers the endpoint's WP REST route. - * - * @since 3.13.0 - */ - public function run(): void { - // Initialize the current user ID here, as doing it in the constructor - // is too early. - $this->current_user_id = get_current_user_id(); - - $this->register_endpoint( - static::get_route(), - 'process_request', - array( 'GET', 'PUT' ) - ); - } - - /** - * Returns the endpoint's route. - * - * @since 3.13.0 - * - * @return string The endpoint's route. - */ - public static function get_route(): string { - return static::ENDPOINT; - } - - /** - * Processes the requests sent to the endpoint. - * - * @since 3.13.0 - * - * @param WP_REST_Request $request The request sent to the endpoint. - * @return string The meta entry's value as JSON. - */ - public function process_request( WP_REST_Request $request ): string { - $request_method = $request->get_method(); - - // Update the meta entry's value if the request method is PUT. - if ( 'PUT' === $request_method ) { - $meta_value = $request->get_json_params(); - $this->set_value( $meta_value ); - } - - return $this->get_value(); - } - - /** - * Returns whether the endpoint is available for access by the current - * user. - * - * @since 3.14.0 - * @since 3.16.0 Added the `$request` parameter. - * - * @param WP_REST_Request|null $request The request object. - * @return bool - */ - public function is_available_to_current_user( $request = null ): bool { - return current_user_can( 'edit_user', $this->current_user_id ); - } - - /** - * Returns the meta entry's value as JSON. - * - * @since 3.13.0 - * - * @return string The meta entry's value as JSON. - */ - protected function get_value(): string { - $meta_key = $this->get_meta_key(); - $meta_value = get_user_meta( $this->current_user_id, $meta_key, true ); - - if ( ! is_array( $meta_value ) || 0 === count( $meta_value ) ) { - $meta_value = $this->default_value; - } - - $result = wp_json_encode( $meta_value ); - - return false !== $result ? $result : ''; - } - - /** - * Sets the meta entry's value. - * - * @since 3.13.0 - * - * @param array $meta_value The value to set the meta entry to. - * @return bool Whether updating the meta entry's value was successful. - */ - protected function set_value( array $meta_value ): bool { - $sanitized_value = $this->sanitize_value( $meta_value ); - - $update_meta = update_user_meta( - $this->current_user_id, - $this->get_meta_key(), - $sanitized_value - ); - - if ( false !== $update_meta ) { - return true; - } - - return false; - } - - /** - * Sanitizes the passed meta value. - * - * @since 3.13.0 - * @since 3.14.0 Added support for nested arrays. - * - * @param array $meta_value The meta value to sanitize. - * @param string $parent_key The parent key for the current level of the meta. - * @return array The sanitized meta as an array of subvalues. - */ - protected function sanitize_value( array $meta_value, string $parent_key = '' ): array { - $sanitized_value = array(); - - // Determine the current level's specifications based on the parent key. - /** - * Current level's specifications. - * - * @var array $current_specs - */ - $current_specs = ( '' === $parent_key ) ? $this->get_subvalues_specs() : $this->get_nested_specs( $parent_key ); - - foreach ( $current_specs as $key => $spec ) { - $composite_key = '' === $parent_key ? $key : $parent_key . '.' . $key; - - // Check if the key exists in the input meta value array. - if ( array_key_exists( $key, $meta_value ) ) { - $value = $meta_value[ $key ]; - } else { - // Key is missing in the input, use the default value from the specifications. - $value = $this->get_default( explode( '.', $composite_key ) ); - } - - /** - * Spec for the current key. - * - * @var array{default: mixed, values?: array} $spec - */ - if ( is_array( $value ) && isset( $spec['values'] ) ) { - // Recursively handle nested arrays if 'values' spec exists for this key. - $sanitized_value[ $key ] = $this->sanitize_value( $value, $composite_key ); - } else { - // Directly sanitize non-array values or non-nested specs. - $sanitized_value[ $key ] = $this->sanitize_subvalue( $composite_key, $value ); - } - } - - return $sanitized_value; - } - - /** - * Sanitizes the passed subvalue. - * - * @since 3.14.0 Added support for nested arrays. - * @since 3.13.0 - * - * @param string $composite_key The subvalue's key. - * @param mixed $value The value to sanitize. - * @return mixed The sanitized subvalue. - */ - protected function sanitize_subvalue( string $composite_key, $value ) { - $keys = explode( '.', $composite_key ); - $valid_values = $this->get_valid_values( $keys ); - - if ( is_array( $value ) ) { - // Check if $value elements are inside $valid_values - // If not, the value should be the default value. - $valid_value = array(); - foreach ( $value as $key => $val ) { - if ( in_array( $val, $valid_values, true ) ) { - $valid_value[ $key ] = $val; - } - } - return $valid_value; - } - - if ( is_string( $value ) ) { - $value = sanitize_text_field( $value ); - } - - if ( count( $valid_values ) === 0 ) { - return $value; - } - - if ( ! in_array( $value, $valid_values, true ) ) { - return $this->get_default( $keys ); - } - - return $value; - } - - /** - * Checks if a given composite key is valid. - * - * @since 3.14.3 - * - * @param string|mixed $composite_key The composite key representing the nested path. - * @return bool Whether the key is valid. - */ - protected function is_valid_key( $composite_key ): bool { - if ( ! is_string( $composite_key ) ) { - return false; // Key path is not a string. - } - - $keys = explode( '.', $composite_key ); - $current = $this->valid_subvalues; - - foreach ( $keys as $key ) { - if ( ! is_array( $current ) || ! isset( $current[ $key ] ) ) { - return false; // Key path is invalid. - } - - if ( isset( $current[ $key ]['values'] ) ) { - $current = $current[ $key ]['values']; - } else { - $current = $current[ $key ]; - } - } - - return true; - } - - /** - * Gets the valid values for a given setting path. - * - * @since 3.14.3 - * - * @param array $keys The path to the setting. - * @return array The valid values for the setting path. - */ - protected function get_valid_values( array $keys ): array { - $current = $this->valid_subvalues; - - foreach ( $keys as $key ) { - if ( ! is_array( $current ) || ! isset( $current[ $key ] ) ) { - return array(); // No valid values for invalid key path. - } - if ( isset( $current[ $key ]['values'] ) ) { - $current = $current[ $key ]['values']; - } else { - $current = $current[ $key ]; - } - } - - return is_array( $current ) ? $current : array(); - } - - /** - * Gets the default value for a given setting path. - * - * @since 3.14.3 - * - * @param array $keys The path to the setting. - * @return mixed|array|null The default value for the setting path. - */ - protected function get_default( array $keys ) { - $current = $this->default_value; - - foreach ( $keys as $key ) { - if ( ! is_array( $current ) || ! isset( $current[ $key ] ) ) { - return null; // No default value for invalid key path. - } - if ( isset( $current[ $key ]['default'] ) ) { - $current = $current[ $key ]['default']; - } else { - $current = $current[ $key ]; - } - } - - return $current; // Return default value for valid key path. - } - - - /** - * Gets the specifications for nested settings based on a composite key. - * - * @since 3.14.3 - * - * @param string $composite_key The composite key representing the nested path. - * @return array The specifications for the nested path. - */ - protected function get_nested_specs( string $composite_key ): array { - $keys = explode( '.', $composite_key ); - $specs = $this->get_subvalues_specs(); - - foreach ( $keys as $key ) { - if ( is_array( $specs[ $key ] ) && array_key_exists( 'values', $specs[ $key ] ) ) { - $specs = $specs[ $key ]['values']; - } else { - break; - } - } - - return $specs; - } -} diff --git a/src/Endpoints/user-meta/class-dashboard-widget-settings-endpoint.php b/src/Endpoints/user-meta/class-dashboard-widget-settings-endpoint.php deleted file mode 100644 index 32ae65efd..000000000 --- a/src/Endpoints/user-meta/class-dashboard-widget-settings-endpoint.php +++ /dev/null @@ -1,54 +0,0 @@ - - */ - protected function get_subvalues_specs(): array { - return array( - 'Metric' => array( - 'values' => array( 'views', 'avg_engaged' ), - 'default' => 'views', - ), - 'Period' => array( - 'values' => array( '10m', '1h', '2h', '4h', '24h', '7d', '30d' ), - 'default' => '7d', - ), - ); - } -} diff --git a/src/Endpoints/user-meta/class-editor-sidebar-settings-endpoint.php b/src/Endpoints/user-meta/class-editor-sidebar-settings-endpoint.php deleted file mode 100644 index 75de86489..000000000 --- a/src/Endpoints/user-meta/class-editor-sidebar-settings-endpoint.php +++ /dev/null @@ -1,102 +0,0 @@ - - */ - protected function get_subvalues_specs(): array { - return array( - 'InitialTabName' => array( - 'values' => array( 'tools', 'performance' ), - 'default' => 'tools', - ), - 'PerformanceStats' => array( - 'values' => array( - 'Period' => array( '10m', '1h', '2h', '4h', '24h', '7d', '30d' ), - 'VisibleDataPoints' => array( 'views', 'visitors', 'avgEngaged', 'recirculation' ), - 'VisiblePanels' => array( 'overview', 'categories', 'referrers' ), - ), - 'default' => array( - 'Period' => '7d', - 'VisibleDataPoints' => array( 'views', 'visitors', 'avgEngaged', 'recirculation' ), - 'VisiblePanels' => array( 'overview', 'categories', 'referrers' ), - ), - ), - 'RelatedPosts' => array( - 'values' => array( - 'FilterBy' => array( 'unavailable', 'tag', 'section', 'author' ), - 'FilterValue' => array(), - 'Metric' => array( 'views', 'avg_engaged' ), - 'Open' => array( true, false ), - 'Period' => array( '10m', '1h', '2h', '4h', '24h', '7d', '30d' ), - ), - 'default' => array( - 'FilterBy' => 'unavailable', - 'FilterValue' => '', - 'Metric' => 'views', - 'Open' => false, - 'Period' => '7d', - ), - ), - 'SmartLinking' => array( - 'values' => array( - 'MaxLinks' => array(), - 'MaxLinkWords' => array(), - 'Open' => array( true, false ), - ), - 'default' => array( - 'MaxLinks' => 10, - 'MaxLinkWords' => 4, - 'Open' => false, - ), - ), - 'TitleSuggestions' => array( - 'values' => array( - 'Open' => array( true, false ), - 'Persona' => array(), - 'Tone' => array(), - ), - 'default' => array( - 'Open' => false, - 'Persona' => 'journalist', - 'Tone' => 'neutral', - ), - ), - ); - } -} diff --git a/src/RemoteAPI/content-suggestions/class-content-suggestions-base-api.php b/src/RemoteAPI/content-suggestions/class-content-suggestions-base-api.php index 3d2a1b050..ec071681b 100644 --- a/src/RemoteAPI/content-suggestions/class-content-suggestions-base-api.php +++ b/src/RemoteAPI/content-suggestions/class-content-suggestions-base-api.php @@ -10,7 +10,6 @@ namespace Parsely\RemoteAPI\ContentSuggestions; -use Parsely\Endpoints\Base_Endpoint; use Parsely\Parsely; use Parsely\RemoteAPI\Base_Endpoint_Remote; use UnexpectedValueException; @@ -61,7 +60,7 @@ public function is_available_to_current_user( $request = null ): bool { return current_user_can( // phpcs:ignore WordPress.WP.Capabilities.Undetermined $this->apply_capability_filters( - Base_Endpoint::DEFAULT_ACCESS_CAPABILITY + self::DEFAULT_ACCESS_CAPABILITY ) ); } diff --git a/src/content-helper/common/class-content-helper-feature.php b/src/content-helper/common/class-content-helper-feature.php index b0edb6505..83c6f04b7 100644 --- a/src/content-helper/common/class-content-helper-feature.php +++ b/src/content-helper/common/class-content-helper-feature.php @@ -166,15 +166,17 @@ protected function inject_inline_scripts( $settings = rest_do_request( new WP_REST_Request( 'GET', - '/wp-parsely/v1' . $settings_route + '/wp-parsely/v2/settings/' . $settings_route ) )->get_data(); } - if ( ! is_string( $settings ) ) { - $settings = ''; + if ( ! is_array( $settings ) ) { + $settings = array(); } + $settings = wp_json_encode( $settings ); + wp_add_inline_script( static::get_script_id(), "window.wpParselyContentHelperSettings = '$settings';", diff --git a/src/content-helper/dashboard-widget/class-dashboard-widget.php b/src/content-helper/dashboard-widget/class-dashboard-widget.php index a166adff6..bab7daff5 100644 --- a/src/content-helper/dashboard-widget/class-dashboard-widget.php +++ b/src/content-helper/dashboard-widget/class-dashboard-widget.php @@ -10,7 +10,6 @@ namespace Parsely\Content_Helper; -use Parsely\Endpoints\User_Meta\Dashboard_Widget_Settings_Endpoint; use Parsely\Parsely; use Parsely\RemoteAPI\Analytics_Posts_API; @@ -136,7 +135,7 @@ public function enqueue_assets(): void { true ); - $this->inject_inline_scripts( Dashboard_Widget_Settings_Endpoint::get_route() ); + $this->inject_inline_scripts( 'dashboard-widget' ); wp_enqueue_style( static::get_style_id(), diff --git a/src/content-helper/editor-sidebar/class-editor-sidebar.php b/src/content-helper/editor-sidebar/class-editor-sidebar.php index 9d0accb25..d98e7bd19 100644 --- a/src/content-helper/editor-sidebar/class-editor-sidebar.php +++ b/src/content-helper/editor-sidebar/class-editor-sidebar.php @@ -12,9 +12,7 @@ use Parsely\Content_Helper\Editor_Sidebar\Smart_Linking; use Parsely\Dashboard_Link; -use Parsely\Endpoints\User_Meta\Editor_Sidebar_Settings_Endpoint; use Parsely\Parsely; -use Parsely\Content_Helper\Content_Helper_Feature; use Parsely\Utils\Utils; use WP_Post; @@ -163,7 +161,7 @@ public function run(): void { true ); - $this->inject_inline_scripts( Editor_Sidebar_Settings_Endpoint::get_route() ); + $this->inject_inline_scripts( 'editor-sidebar' ); // Inject inline variables for the editor sidebar, without UTM parameters. $parsely_post_url = $this->get_parsely_post_url( null, false ); diff --git a/src/rest-api/settings/class-endpoint-dashboard-widget-settings.php b/src/rest-api/settings/class-endpoint-dashboard-widget-settings.php index bf7d429fe..00473d8f8 100644 --- a/src/rest-api/settings/class-endpoint-dashboard-widget-settings.php +++ b/src/rest-api/settings/class-endpoint-dashboard-widget-settings.php @@ -10,14 +10,12 @@ namespace Parsely\REST_API\Settings; -use Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta; - /** * Endpoint for saving and retrieving Content Helper Dashboard Widget settings. * * @since 3.17.0 * - * @phpstan-import-type Subvalue_Spec from Base_Endpoint_User_Meta + * @phpstan-import-type Subvalue_Spec from Base_Settings_Endpoint */ class Endpoint_Dashboard_Widget_Settings extends Base_Settings_Endpoint { /** diff --git a/src/rest-api/settings/class-endpoint-editor-sidebar-settings.php b/src/rest-api/settings/class-endpoint-editor-sidebar-settings.php index ccbd33c82..5f600fa3c 100644 --- a/src/rest-api/settings/class-endpoint-editor-sidebar-settings.php +++ b/src/rest-api/settings/class-endpoint-editor-sidebar-settings.php @@ -10,14 +10,12 @@ namespace Parsely\REST_API\Settings; -use Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta; - /** * Endpoint for saving and retrieving Content Helper Editor Sidebar settings. * * @since 3.17.0 * - * @phpstan-import-type Subvalue_Spec from Base_Endpoint_User_Meta + * @phpstan-import-type Subvalue_Spec from Base_Settings_Endpoint */ class Endpoint_Editor_Sidebar_Settings extends Base_Settings_Endpoint { /** diff --git a/tests/Integration/Endpoints/Proxy/BaseProxyEndpointTest.php b/tests/Integration/Endpoints/Proxy/BaseProxyEndpointTest.php deleted file mode 100644 index 208e0abaa..000000000 --- a/tests/Integration/Endpoints/Proxy/BaseProxyEndpointTest.php +++ /dev/null @@ -1,245 +0,0 @@ -wp_rest_server_global_backup = $GLOBALS['wp_rest_server'] ?? null; - $endpoint = $this->get_endpoint(); - $this->rest_api_init_proxy = static function () use ( $endpoint ) { - $endpoint->run(); - }; - add_action( 'rest_api_init', $this->rest_api_init_proxy ); - } - - /** - * Teardown method called after each test. - * - * Resets globals. - */ - public function tear_down(): void { - parent::tear_down(); - remove_action( 'rest_api_init', $this->rest_api_init_proxy ); - - // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound - $GLOBALS['wp_rest_server'] = $this->wp_rest_server_global_backup; - } - - /** - * Verifies that the route is registered. - * - * @param array $methods The methods supported by the route. - */ - public function run_test_register_routes_by_default( - array $methods = array( 'GET' => true ) - ): void { - $routes = rest_get_server()->get_routes(); - self::assertArrayHasKey( self::$route, $routes ); - self::assertCount( 1, $routes[ self::$route ] ); - self::assertSame( $methods, $routes[ self::$route ][0]['methods'] ); - } - - /** - * Verifies that the route is not registered when the respective filter is - * set to false. - */ - public function run_test_do_not_register_route_when_proxy_is_disabled(): void { - // Override some setup steps in order to set the filter to false. - remove_action( 'rest_api_init', $this->rest_api_init_proxy ); - $endpoint = $this->get_endpoint(); - $this->rest_api_init_proxy = static function () use ( $endpoint ) { - add_filter( 'wp_parsely_enable_' . self::$filter_key . '_api_proxy', '__return_false' ); - $endpoint->run(); - }; - add_action( 'rest_api_init', $this->rest_api_init_proxy ); - - $routes = rest_get_server()->get_routes(); - self::assertFalse( array_key_exists( self::$route, $routes ) ); - } - - /** - * Verifies that calls return an error and do not perform a remote call when - * the Site ID is not populated in site options. - * - * @param WP_REST_Request|null $request The request object to be used. - */ - public function run_test_get_items_fails_without_site_id_set( - ?WP_REST_Request $request = null - ): void { - $this->run_test_get_items_fails( - array( 'apikey' => '' ), - 'parsely_site_id_not_set', - 'A Parse.ly Site ID must be set in site options to use this endpoint', - $request - ); - } - - /** - * Verifies that calls return an error and do not perform a remote call when - * the API Secret is not populated in site options. - * - * @param WP_REST_Request|null $request The request object to be used. - */ - public function run_test_get_items_fails_without_api_secret_set( - ?WP_REST_Request $request = null - ): void { - $this->run_test_get_items_fails( - array( - 'apikey' => 'example.com', - 'api_secret' => '', - ), - 'parsely_api_secret_not_set', - 'A Parse.ly API Secret must be set in site options to use this endpoint', - $request - ); - } - - /** - * Verifies that attempting to get items under the given conditions will - * fail. - * - * @param array $options The WordPress options to be set. - * @param string $expected_error_code The expected error code. - * @param string $expected_error_message The expected error message. - * @param WP_REST_Request|null $request The request object to be used. - */ - private function run_test_get_items_fails( - array $options, - string $expected_error_code, - string $expected_error_message, - ?WP_REST_Request $request = null - ): void { - TestCase::set_options( $options ); - if ( null === $request ) { - $request = new WP_REST_Request( 'GET', self::$route ); - } - - $response = rest_get_server()->dispatch( $request ); - /** - * Variable. - * - * @var WP_Error - */ - $error = $response->as_error(); - self::assertSame( 403, $response->get_status() ); - self::assertSame( $expected_error_code, $error->get_error_code() ); - self::assertSame( $expected_error_message, $error->get_error_message() ); - } - - /** - * Verifies default user capability filter. - */ - public function run_test_user_is_allowed_to_make_proxy_api_call_if_default_user_capability_is_changed(): void { - $this->set_current_user_to_contributor(); - add_filter( - 'wp_parsely_user_capability_for_all_private_apis', - function () { - return 'edit_posts'; - } - ); - - self::assertTrue( static::get_endpoint()->is_available_to_current_user() ); - } - - /** - * Verifies endpoint specific user capability filter. - * - * @param string|null $filter_key The key to use for the filter. - */ - public function run_test_user_is_allowed_to_make_proxy_api_call_if_endpoint_specific_user_capability_is_changed( - $filter_key = null - ): void { - $this->set_current_user_to_contributor(); - $filter_key = $filter_key ?? static::$filter_key; - - add_filter( - 'wp_parsely_user_capability_for_' . $filter_key . '_api', - function () { - return 'edit_posts'; - } - ); - - self::assertTrue( static::get_endpoint()->is_available_to_current_user() ); - } -} diff --git a/tests/Integration/Endpoints/RestMetadataTest.php b/tests/Integration/Endpoints/RestMetadataTest.php index 226e1071c..23854b34c 100644 --- a/tests/Integration/Endpoints/RestMetadataTest.php +++ b/tests/Integration/Endpoints/RestMetadataTest.php @@ -14,7 +14,6 @@ use Parsely\Endpoints\Rest_Metadata; use Parsely\Tests\Integration\TestCase; - /** * Integration Tests for the REST API Metadata Endpoint. */ diff --git a/tests/Integration/Endpoints/UserMeta/BaseUserMetaEndpointTest.php b/tests/Integration/Endpoints/UserMeta/BaseUserMetaEndpointTest.php deleted file mode 100644 index c2ad8ec40..000000000 --- a/tests/Integration/Endpoints/UserMeta/BaseUserMetaEndpointTest.php +++ /dev/null @@ -1,169 +0,0 @@ - - */ - protected $default_value = array(); - - /** - * Generates a JSON string for the passed period, metric, and extra data. - * - * @since 3.13.0 - * - * @param string|null $metric The Metric value. - * @param string|null $period The Period value. - * @param array $extra_data Any Extra key/value pairs to add. - * @return string The generated JSON string. - */ - abstract protected function generate_json( - ?string $metric = null, - ?string $period = null, - array $extra_data = array() - ): string; - - /** - * Verifies that the endpoint returns the correct default value. - * - * @since 3.13.0 - */ - public function run_test_endpoint_returns_value_on_get_request(): void { - $this->set_current_user_to_admin(); - - $value = rest_do_request( - new WP_REST_Request( - 'GET', - self::$route - ) - )->get_data(); - - $expected = $this->wp_json_encode( - $this->default_value - ); - - self::assertSame( $expected, $value ); - } - - /** - * Provides data for testing PUT requests. - * - * @since 3.13.0 - * @return iterable - */ - public function provide_put_requests_data(): iterable { - $default_value = $this->generate_json( 'views', '7d' ); - $valid_value = $this->generate_json( 'avg_engaged', '1h' ); - - // Valid non-default value. It should be returned unmodified. - yield 'valid period and metric values' => array( - 'test_data' => $valid_value, - 'expected' => $valid_value, - ); - - // Missing or problematic keys. Defaults should be used for the missing or problematic keys. - yield 'valid period value, no metric value' => array( - 'test_data' => $this->generate_json( null, '1h' ), - 'expected' => $this->generate_json( 'views', '1h' ), - ); - yield 'valid metric value, no period value' => array( - 'test_data' => $this->generate_json( 'avg_engaged' ), - 'expected' => $this->generate_json( 'avg_engaged', '7d' ), - ); - yield 'no values' => array( - 'test_data' => $this->generate_json(), - 'expected' => $default_value, - ); - - // Invalid values. They should be adjusted to their defaults. - yield 'invalid period value' => array( - 'test_data' => $this->generate_json( 'avg_engaged', 'invalid' ), - 'expected' => $this->generate_json( 'avg_engaged', '7d' ), - ); - yield 'invalid metric value' => array( - 'test_data' => $this->generate_json( 'invalid', '1h' ), - 'expected' => $this->generate_json( 'views', '1h' ), - ); - yield 'invalid period and metric values' => array( - 'test_data' => $this->generate_json( 'invalid', 'invalid' ), - 'expected' => $default_value, - ); - - // Invalid extra data passed. Any such data should be discarded. - yield 'invalid additional value' => array( - 'test_data' => $this->generate_json( - 'avg_engaged', - '1h', - array( 'invalid' ) - ), - 'expected' => $valid_value, - ); - yield 'invalid additional key/value pair' => array( - 'test_data' => $this->generate_json( - 'avg_engaged', - '1h', - array( 'invalid_key' => 'invalid_value' ) - ), - 'expected' => $valid_value, - ); - } - - /** - * Sends a PUT request to the endpoint. - * - * @since 3.13.0 - * - * @param string $data The data to be sent in the request. - * @return string The response returned by the endpoint. - */ - protected function send_put_request( string $data ): string { - $this->set_current_user_to_admin(); - $result = $this->send_wp_rest_request( 'PUT', self::$route, $data ); - - if ( ! is_string( $result ) ) { - return ''; - } - - return $result; - } - - /** - * Verifies that the route is not registered when the respective filter is - * set to false. - * - * @since 3.16.0 - */ - public function run_test_do_not_register_route_when_proxy_is_disabled(): void { - // Override some setup steps in order to set the filter to false. - remove_action( 'rest_api_init', $this->rest_api_init_proxy ); - $endpoint = $this->get_endpoint(); - $this->rest_api_init_proxy = static function () use ( $endpoint ) { - add_filter( 'wp_parsely_enable_' . self::$filter_key . '_api_proxy', '__return_false' ); - $endpoint->run(); - }; - add_action( 'rest_api_init', $this->rest_api_init_proxy ); - - $routes = rest_get_server()->get_routes(); - self::assertFalse( array_key_exists( self::$route, $routes ) ); - } -} diff --git a/tests/Integration/Endpoints/UserMeta/DashboardWidgetSettingsEndpointTest.php b/tests/Integration/Endpoints/UserMeta/DashboardWidgetSettingsEndpointTest.php deleted file mode 100644 index 7af087282..000000000 --- a/tests/Integration/Endpoints/UserMeta/DashboardWidgetSettingsEndpointTest.php +++ /dev/null @@ -1,204 +0,0 @@ - - */ - protected $default_value = array( - 'Metric' => 'views', - 'Period' => '7d', - ); - - /** - * Initializes all required values for the test. - * - * @since 3.13.0 - */ - public static function initialize(): void { - $route = Dashboard_Widget_Settings_Endpoint::get_route(); - - self::$route = '/wp-parsely/v1' . $route; - self::$filter_key = Utils::convert_endpoint_to_filter_key( $route ); - } - - /** - * Returns the endpoint to be used in tests. - * - * @since 3.13.0 - * - * @return Base_Endpoint_User_Meta The endpoint to be used in tests. - */ - public function get_endpoint(): Base_Endpoint_User_Meta { - return new Dashboard_Widget_Settings_Endpoint( new Parsely() ); - } - - /** - * Verifies that the route is registered. - * - * @since 3.13.0 - * - * @covers \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::get_route - * @covers \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::run - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\Endpoints\Base_Endpoint::register_endpoint - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::__construct - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::get_subvalues_specs - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::is_available_to_current_user - * @uses \Parsely\Endpoints\User_Meta\Dashboard_Widget_Settings_Endpoint::get_subvalues_specs - * @uses \Parsely\Parsely::__construct - * @uses \Parsely\Parsely::allow_parsely_remote_requests - * @uses \Parsely\Parsely::are_credentials_managed - * @uses \Parsely\Parsely::set_managed_options - * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key - */ - public function test_register_routes_by_default(): void { - parent::run_test_register_routes_by_default( - array( - 'GET' => true, - 'PUT' => true, - ) - ); - } - - /** - * Verifies that the route is not registered when the endpoint filter is set - * to false. - * - * @since 3.13.0 - * - * @covers \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::run - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\Endpoints\Base_Endpoint::register_endpoint - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::__construct - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::get_route - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::get_subvalues_specs - * @uses \Parsely\Endpoints\User_Meta\Dashboard_Widget_Settings_Endpoint::get_subvalues_specs - * @uses \Parsely\Parsely::__construct - * @uses \Parsely\Parsely::allow_parsely_remote_requests - * @uses \Parsely\Parsely::are_credentials_managed - * @uses \Parsely\Parsely::set_managed_options - * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key - */ - public function test_verify_that_route_is_not_registered_when_endpoint_is_disabled(): void { - parent::run_test_do_not_register_route_when_proxy_is_disabled(); - } - - /** - * Verifies that the endpoint returns the correct default settings. - * - * @since 3.13.0 - * - * @covers \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::__construct - * @covers \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::get_subvalues_specs - * @covers \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::get_value - * @covers \Parsely\Endpoints\User_Meta\Dashboard_Widget_Settings_Endpoint::get_subvalues_specs - * @covers \Parsely\Endpoints\User_Meta\Dashboard_Widget_Settings_Endpoint::process_request - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\Endpoints\Base_Endpoint::register_endpoint - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::is_available_to_current_user - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::run - * @uses \Parsely\Endpoints\User_Meta\Dashboard_Widget_Settings_Endpoint::get_meta_key - * @uses \Parsely\Endpoints\User_Meta\Dashboard_Widget_Settings_Endpoint::get_route - * @uses \Parsely\Parsely::__construct - * @uses \Parsely\Parsely::allow_parsely_remote_requests - * @uses \Parsely\Parsely::are_credentials_managed - * @uses \Parsely\Parsely::set_managed_options - * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key - */ - public function test_endpoint_returns_value_on_get_request(): void { - parent::run_test_endpoint_returns_value_on_get_request(); - } - - /** - * Verifies that the endpoint can correctly handle PUT requests. - * - * @since 3.13.0 - * - * @param string $test_data The data to send in the PUT request. - * @param string $expected The expected value of the setting after the PUT request. - * - * @covers \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::get_subvalues_specs - * @covers \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::get_value - * @covers \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::sanitize_subvalue - * @covers \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::sanitize_value - * @covers \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::set_value - * @covers \Parsely\Endpoints\User_Meta\Dashboard_Widget_Settings_Endpoint::get_subvalues_specs - * @covers \Parsely\Endpoints\User_Meta\Dashboard_Widget_Settings_Endpoint::process_request - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\Endpoints\Base_Endpoint::register_endpoint - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::__construct - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::is_available_to_current_user - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::run - * @uses \Parsely\Endpoints\User_Meta\Dashboard_Widget_Settings_Endpoint::get_meta_key - * @uses \Parsely\Endpoints\User_Meta\Dashboard_Widget_Settings_Endpoint::get_route - * @uses \Parsely\Parsely::__construct - * @uses \Parsely\Parsely::allow_parsely_remote_requests - * @uses \Parsely\Parsely::are_credentials_managed - * @uses \Parsely\Parsely::set_managed_options - * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key - * - * @dataProvider provide_put_requests_data - */ - public function test_endpoint_correctly_handles_put_requests( - string $test_data, - string $expected - ): void { - $value = $this->send_put_request( $test_data ); - self::assertSame( $expected, $value ); - } - - /** - * Generates a JSON string for the passed period, metric, and extra data. - * - * @since 3.13.0 - * - * @param string|null $metric The Metric value. - * @param string|null $period The Period value. - * @param array $extra_data Any Extra key/value pairs to add. - * @return string The generated JSON string. - */ - protected function generate_json( - ?string $metric = null, - ?string $period = null, - array $extra_data = array() - ): string { - $array = $this->default_value; - unset( $array['Metric'], $array['Period'] ); - - if ( null !== $metric ) { - $array['Metric'] = $metric; - } - - if ( null !== $period ) { - $array['Period'] = $period; - } - - ksort( $array ); - - return $this->wp_json_encode( array_merge( $array, $extra_data ) ); - } -} diff --git a/tests/Integration/Endpoints/UserMeta/EditorSidebarSettingsEndpointTest.php b/tests/Integration/Endpoints/UserMeta/EditorSidebarSettingsEndpointTest.php deleted file mode 100644 index 1b16f855b..000000000 --- a/tests/Integration/Endpoints/UserMeta/EditorSidebarSettingsEndpointTest.php +++ /dev/null @@ -1,308 +0,0 @@ - - */ - protected $default_value = array( - 'InitialTabName' => 'tools', - 'PerformanceStats' => array( - 'Period' => '7d', - 'VisibleDataPoints' => array( 'views', 'visitors', 'avgEngaged', 'recirculation' ), - 'VisiblePanels' => array( 'overview', 'categories', 'referrers' ), - ), - 'RelatedPosts' => array( - 'FilterBy' => 'unavailable', - 'FilterValue' => '', - 'Metric' => 'views', - 'Open' => false, - 'Period' => '7d', - ), - 'SmartLinking' => array( - 'MaxLinks' => 10, - 'MaxLinkWords' => 4, - 'Open' => false, - ), - 'TitleSuggestions' => array( - 'Open' => false, - 'Persona' => 'journalist', - 'Tone' => 'neutral', - ), - ); - - /** - * Initializes all required values for the test. - * - * @since 3.13.0 - */ - public static function initialize(): void { - $route = Editor_Sidebar_Settings_Endpoint::get_route(); - - self::$route = '/wp-parsely/v1' . $route; - self::$filter_key = Utils::convert_endpoint_to_filter_key( $route ); - } - - /** - * Returns the endpoint to be used in tests. - * - * @since 3.13.0 - * - * @return Base_Endpoint_User_Meta The endpoint to be used in tests. - */ - public function get_endpoint(): Base_Endpoint_User_Meta { - return new Editor_Sidebar_Settings_Endpoint( new Parsely() ); - } - - /** - * Verifies that the route is registered. - * - * @since 3.13.0 - * - * @covers \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::get_route - * @covers \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::run - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\Endpoints\Base_Endpoint::register_endpoint - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::__construct - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::get_subvalues_specs - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::is_available_to_current_user - * @uses \Parsely\Endpoints\User_Meta\Editor_Sidebar_Settings_Endpoint::get_subvalues_specs - * @uses \Parsely\Parsely::__construct - * @uses \Parsely\Parsely::allow_parsely_remote_requests - * @uses \Parsely\Parsely::are_credentials_managed - * @uses \Parsely\Parsely::set_managed_options - * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key - */ - public function test_register_routes_by_default(): void { - parent::run_test_register_routes_by_default( - array( - 'GET' => true, - 'PUT' => true, - ) - ); - } - - /** - * Verifies that the route is not registered when the endpoint filter is set - * to false. - * - * @since 3.13.0 - * - * @covers \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::run - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\Endpoints\Base_Endpoint::register_endpoint - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::__construct - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::get_route - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::get_subvalues_specs - * @uses \Parsely\Endpoints\User_Meta\Editor_Sidebar_Settings_Endpoint::get_subvalues_specs - * @uses \Parsely\Parsely::__construct - * @uses \Parsely\Parsely::allow_parsely_remote_requests - * @uses \Parsely\Parsely::are_credentials_managed - * @uses \Parsely\Parsely::set_managed_options - * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key - */ - public function test_verify_that_route_is_not_registered_when_endpoint_is_disabled(): void { - parent::run_test_do_not_register_route_when_proxy_is_disabled(); - } - - /** - * Verifies that the endpoint returns the correct default settings. - * - * @since 3.13.0 - * - * @covers \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::__construct - * @covers \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::get_subvalues_specs - * @covers \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::get_value - * @covers \Parsely\Endpoints\User_Meta\Editor_Sidebar_Settings_Endpoint::get_subvalues_specs - * @covers \Parsely\Endpoints\User_Meta\Editor_Sidebar_Settings_Endpoint::process_request - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\Endpoints\Base_Endpoint::register_endpoint - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::is_available_to_current_user - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::run - * @uses \Parsely\Endpoints\User_Meta\Editor_Sidebar_Settings_Endpoint::get_meta_key - * @uses \Parsely\Endpoints\User_Meta\Editor_Sidebar_Settings_Endpoint::get_route - * @uses \Parsely\Parsely::__construct - * @uses \Parsely\Parsely::allow_parsely_remote_requests - * @uses \Parsely\Parsely::are_credentials_managed - * @uses \Parsely\Parsely::set_managed_options - * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key - */ - public function test_endpoint_returns_value_on_get_request(): void { - parent::run_test_endpoint_returns_value_on_get_request(); - } - - /** - * Verifies that the endpoint can correctly handle PUT requests. - * - * @since 3.13.0 - * - * @param string $test_data The data to send in the PUT request. - * @param string $expected The expected value of the setting after the PUT request. - * - * @covers \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::get_subvalues_specs - * @covers \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::get_value - * @covers \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::sanitize_subvalue - * @covers \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::sanitize_value - * @covers \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::set_value - * @covers \Parsely\Endpoints\User_Meta\Editor_Sidebar_Settings_Endpoint::get_subvalues_specs - * @covers \Parsely\Endpoints\User_Meta\Editor_Sidebar_Settings_Endpoint::process_request - * @uses \Parsely\Endpoints\Base_Endpoint::__construct - * @uses \Parsely\Endpoints\Base_Endpoint::register_endpoint - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::__construct - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::get_default - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::get_nested_specs - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::get_valid_values - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::is_available_to_current_user - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::run - * @uses \Parsely\Endpoints\User_Meta\Editor_Sidebar_Settings_Endpoint::get_meta_key - * @uses \Parsely\Endpoints\User_Meta\Editor_Sidebar_Settings_Endpoint::get_route - * @uses \Parsely\Parsely::__construct - * @uses \Parsely\Parsely::allow_parsely_remote_requests - * @uses \Parsely\Parsely::are_credentials_managed - * @uses \Parsely\Parsely::set_managed_options - * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key - * @dataProvider provide_put_requests_data - */ - public function test_endpoint_correctly_handles_put_requests( - string $test_data, - string $expected - ): void { - $value = $this->send_put_request( $test_data ); - self::assertSame( $expected, $value ); - } - - /** - * Tests that the endpoint can correctly handle PUT requests with valid - * nested PerformanceStats values. - * - * @since 3.14.0 - * - * @covers \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::sanitize_subvalue - * @uses \Parsely\Endpoints\Base_Endpoint::__construct() - * @uses \Parsely\Endpoints\Base_Endpoint::register_endpoint() - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::__construct() - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::get_route() - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::get_value() - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::is_available_to_current_user() - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::process_request() - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::run() - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::sanitize_value() - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::set_value() - * @uses \Parsely\Endpoints\User_Meta\Editor_Sidebar_Settings_Endpoint::get_meta_key() - * @uses \Parsely\Endpoints\User_Meta\Editor_Sidebar_Settings_Endpoint::get_subvalues_specs() - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::get_nested_specs - * @uses \Parsely\Endpoints\User_Meta\Base_Endpoint_User_Meta::get_valid_values - * @uses \Parsely\Parsely::__construct() - * @uses \Parsely\Parsely::allow_parsely_remote_requests() - * @uses \Parsely\Parsely::are_credentials_managed() - * @uses \Parsely\Parsely::set_managed_options() - * @uses \Parsely\Utils\Utils::convert_endpoint_to_filter_key() - */ - public function test_valid_nested_performance_stats_settings_period(): void { - $this->set_current_user_to_admin(); - - $value = $this->send_put_request( - $this->generate_json( - 'views', - '7d', - array( - 'PerformanceStats' => array( - 'Period' => '1h', - 'VisibleDataPoints' => array( 'views', 'avgEngaged', 'recirculation' ), - 'VisiblePanels' => array( 'overview', 'referrers' ), - ), - ) - ) - ); - - $expected = $this->wp_json_encode( - array_merge( - $this->default_value, - array( - 'PerformanceStats' => array( - 'Period' => '1h', - 'VisibleDataPoints' => array( 'views', 'avgEngaged', 'recirculation' ), - 'VisiblePanels' => array( 'overview', 'referrers' ), - ), - ) - ) - ); - - self::assertSame( $expected, $value ); - } - - /** - * Generates a JSON string for the passed period, metric, and extra data. - * - * @since 3.13.0 - * - * @param string|null $metric The RelatedPostsMetric value. - * @param string|null $period The RelatedPostsPeriod value. - * @param array $extra_data Any Extra key/value pairs to add. - * @return string The generated JSON string. - */ - protected function generate_json( - ?string $metric = null, - ?string $period = null, - array $extra_data = array() - ): string { - $array = $this->default_value; - assert( is_array( $array['RelatedPosts'] ) ); - - unset( $array['RelatedPosts']['Metric'], $array['RelatedPosts']['Period'] ); - - if ( null !== $metric ) { - $array['RelatedPosts']['Metric'] = $metric; - } - - if ( null !== $period ) { - $array['RelatedPosts']['Period'] = $period; - } - - $merged_array = array_merge( $array, $extra_data ); - - $this->ksortRecursive( $merged_array, SORT_NATURAL | SORT_FLAG_CASE ); - - return $this->wp_json_encode( $merged_array ); - } - - /** - * Recursively sorts an array by key using a specified sort flag. - * - * @since 3.14.3 - * - * @param array &$unsorted_array The array to be sorted, passed by reference. - * @param int $sort_flags Optional sorting flags. Defaults to SORT_REGULAR. - */ - private function ksortRecursive( array &$unsorted_array, int $sort_flags = SORT_REGULAR ): void { - ksort( $unsorted_array, $sort_flags ); - foreach ( $unsorted_array as &$value ) { - if ( is_array( $value ) ) { - $this->ksortRecursive( $value, $sort_flags ); - } - } - } -} diff --git a/wp-parsely.php b/wp-parsely.php index cf5012bef..29997ea08 100644 --- a/wp-parsely.php +++ b/wp-parsely.php @@ -30,23 +30,11 @@ use Parsely\Content_Helper\Editor_Sidebar; use Parsely\Content_Helper\Excerpt_Generator; use Parsely\Content_Helper\Post_List_Stats; -use Parsely\Endpoints\Analytics_Post_Detail_API_Proxy; -use Parsely\Endpoints\Analytics_Posts_API_Proxy; use Parsely\Endpoints\GraphQL_Metadata; -use Parsely\Endpoints\Referrers_Post_Detail_API_Proxy; -use Parsely\Endpoints\Related_API_Proxy; use Parsely\Endpoints\Rest_Metadata; -use Parsely\Endpoints\User_Meta\Dashboard_Widget_Settings_Endpoint; -use Parsely\Endpoints\User_Meta\Editor_Sidebar_Settings_Endpoint; use Parsely\Integrations\Amp; use Parsely\Integrations\Google_Web_Stories; use Parsely\Integrations\Integrations; -use Parsely\RemoteAPI\Analytics_Post_Detail_API; -use Parsely\RemoteAPI\Analytics_Posts_API; -use Parsely\RemoteAPI\Referrers_Post_Detail_API; -use Parsely\RemoteAPI\Related_API; -use Parsely\RemoteAPI\Remote_API_Cache; -use Parsely\RemoteAPI\WordPress_Cache; use Parsely\REST_API\REST_API_Controller; use Parsely\UI\Admin_Bar; use Parsely\UI\Admin_Warning; @@ -134,10 +122,6 @@ function parsely_wp_admin_early_register(): void { function parsely_rest_api_init(): void { $rest = new Rest_Metadata( $GLOBALS['parsely'] ); $rest->run(); - - // Content Helper settings endpoints. - ( new Dashboard_Widget_Settings_Endpoint( $GLOBALS['parsely'] ) )->run(); - ( new Editor_Sidebar_Settings_Endpoint( $GLOBALS['parsely'] ) )->run(); } add_action( 'init', __NAMESPACE__ . '\\init_recommendations_block' ); @@ -225,34 +209,3 @@ function parsely_integrations( $parsely = null ): Integrations { return $parsely_integrations; } - -/** - * Instantiates and runs the specified API endpoint. - * - * @since 3.6.0 - * - * @param string $api_class_name The proxy class to instantiate. - * @param string $proxy_api_class_name The API proxy class to instantiate and run. - * @param WordPress_Cache $wp_cache The WordPress cache instance to be used. - */ -function parsely_run_rest_api_endpoint( - string $api_class_name, - string $proxy_api_class_name, - WordPress_Cache &$wp_cache -): void { - /** - * Internal Variable. - * - * @var RemoteAPI\Base_Endpoint_Remote $remote_api - */ - $remote_api = new $api_class_name( $GLOBALS['parsely'] ); - $remote_api_cache = new Remote_API_Cache( $remote_api, $wp_cache ); - - /** - * Internal Variable. - * - * @var Endpoints\Base_API_Proxy $remote_api_proxy - */ - $remote_api_proxy = new $proxy_api_class_name( $GLOBALS['parsely'], $remote_api_cache ); - $remote_api_proxy->run(); -} From 03da17cd2547cd55eb17b1d9d7f1aa3651487ddc Mon Sep 17 00:00:00 2001 From: Alex Cicovic <23142906+acicovic@users.noreply.github.com> Date: Tue, 3 Sep 2024 09:17:08 +0300 Subject: [PATCH 071/282] Migrate E2E tests to Playwright --- build/blocks/recommendations/edit.asset.php | 2 +- build/blocks/recommendations/edit.js | 2 +- build/blocks/recommendations/view.asset.php | 2 +- build/blocks/recommendations/view.js | 2 +- package.json | 4 +- .../components/parsely-recommendations.tsx | 2 + test/e2e/specs/plugin-action-link.spec.ts | 15 -- {test => tests}/e2e/playwright.config.ts | 0 tests/e2e/specs/activation-flow.spec.ts | 144 +++++++---- .../blocks/recommendations/errors.spec.ts | 80 +++--- .../blocks/recommendations/settings.spec.ts | 194 +++++++------- tests/e2e/specs/browse-logo-button.spec.ts | 121 ++++----- tests/e2e/specs/content-helper/errors.spec.ts | 57 +++-- .../related-posts-panel-filters.spec.ts | 47 ++-- .../specs/content-helper/top-bar-icon.spec.ts | 191 +++++++++----- tests/e2e/specs/front-end-metadata.spec.ts | 179 ++++++++----- tests/e2e/specs/front-end-tracker.spec.ts | 75 ++++-- tests/e2e/specs/plugin-action-link.spec.ts | 33 +++ tests/e2e/specs/recommended-widget.spec.ts | 148 +++++++---- .../settings-track-post-types-as.spec.ts | 240 +++++++++++------ tests/e2e/utils.ts | 242 ++++-------------- 21 files changed, 1022 insertions(+), 758 deletions(-) delete mode 100644 test/e2e/specs/plugin-action-link.spec.ts rename {test => tests}/e2e/playwright.config.ts (100%) create mode 100644 tests/e2e/specs/plugin-action-link.spec.ts diff --git a/build/blocks/recommendations/edit.asset.php b/build/blocks/recommendations/edit.asset.php index 0f36c73fc..71f3d5703 100644 --- a/build/blocks/recommendations/edit.asset.php +++ b/build/blocks/recommendations/edit.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => '393b4c8be66f3bde527e'); + array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => 'a4028c5cfac2fd68afd1'); diff --git a/build/blocks/recommendations/edit.js b/build/blocks/recommendations/edit.js index 06593e46c..7425806d6 100644 --- a/build/blocks/recommendations/edit.js +++ b/build/blocks/recommendations/edit.js @@ -1 +1 @@ -!function(){"use strict";var e,n={271:function(e,n,r){var t,o,a=r(848),i=window.wp.blockEditor,l=window.wp.blocks,s=window.wp.i18n,c=window.wp.components,u=JSON.parse('{"UU":"wp-parsely/recommendations","uK":{"imagestyle":{"type":"string","default":"original"},"limit":{"type":"number","default":3},"openlinksinnewtab":{"type":"boolean","default":false},"showimages":{"type":"boolean","default":true},"sort":{"type":"string","default":"score"},"title":{"type":"string","default":"Related Content"}}}'),d=window.wp.element;(o=t||(t={}))[o.Error=0]="Error",o[o.Loaded=1]="Loaded",o[o.Recommendations=2]="Recommendations";var p=function(){return p=Object.assign||function(e){for(var n,r=1,t=arguments.length;r0&&o[o.length-1])||6!==l[0]&&2!==l[0])){i=0;continue}if(3===l[0]&&(!o||l[1]>o[0]&&l[1]=a)&&Object.keys(t.O).every((function(e){return t.O[e](r[s])}))?r.splice(s--,1):(l=!1,a0&&e[u-1][2]>a;u--)e[u]=e[u-1];e[u]=[r,o,a]},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,{a:n}),n},t.d=function(e,n){for(var r in n)t.o(n,r)&&!t.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:n[r]})},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},function(){var e={335:0,203:0};t.O.j=function(n){return 0===e[n]};var n=function(n,r){var o,a,i=r[0],l=r[1],s=r[2],c=0;if(i.some((function(n){return 0!==e[n]}))){for(o in l)t.o(l,o)&&(t.m[o]=l[o]);if(s)var u=s(t)}for(n&&n(r);c0&&o[o.length-1])||6!==l[0]&&2!==l[0])){i=0;continue}if(3===l[0]&&(!o||l[1]>o[0]&&l[1]=a)&&Object.keys(t.O).every((function(e){return t.O[e](r[s])}))?r.splice(s--,1):(l=!1,a0&&e[u-1][2]>a;u--)e[u]=e[u-1];e[u]=[r,o,a]},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,{a:n}),n},t.d=function(e,n){for(var r in n)t.o(n,r)&&!t.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:n[r]})},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},function(){var e={335:0,203:0};t.O.j=function(n){return 0===e[n]};var n=function(n,r){var o,a,i=r[0],l=r[1],s=r[2],c=0;if(i.some((function(n){return 0!==e[n]}))){for(o in l)t.o(l,o)&&(t.m[o]=l[o]);if(s)var u=s(t)}for(n&&n(r);c array('react', 'wp-api-fetch', 'wp-components', 'wp-compose', 'wp-dom-ready', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => '827c1c0c5b711b046baf'); + array('react', 'wp-api-fetch', 'wp-components', 'wp-compose', 'wp-dom-ready', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => '1b69b5bbddfa836a0957'); diff --git a/build/blocks/recommendations/view.js b/build/blocks/recommendations/view.js index ac32818be..e2c42c333 100644 --- a/build/blocks/recommendations/view.js +++ b/build/blocks/recommendations/view.js @@ -1 +1 @@ -!function(){"use strict";var e={20:function(e,r,n){var t=n(609),o=Symbol.for("react.element"),a=Symbol.for("react.fragment"),i=Object.prototype.hasOwnProperty,s=t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function u(e,r,n){var t,a={},u=null,c=null;for(t in void 0!==n&&(u=""+n),void 0!==r.key&&(u=""+r.key),void 0!==r.ref&&(c=r.ref),r)i.call(r,t)&&!l.hasOwnProperty(t)&&(a[t]=r[t]);if(e&&e.defaultProps)for(t in r=e.defaultProps)void 0===a[t]&&(a[t]=r[t]);return{$$typeof:o,type:e,key:u,ref:c,props:a,_owner:s.current}}r.Fragment=a,r.jsx=u,r.jsxs=u},848:function(e,r,n){e.exports=n(20)},609:function(e){e.exports=window.React}},r={};function n(t){var o=r[t];if(void 0!==o)return o.exports;var a=r[t]={exports:{}};return e[t](a,a.exports,n),a.exports}n.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(r,{a:r}),r},n.d=function(e,r){for(var t in r)n.o(r,t)&&!n.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},n.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},function(){var e,r,t=n(848),o=n(609),a=window.wp.domReady,i=n.n(a),s=window.wp.element,l=window.wp.i18n;(r=e||(e={}))[r.Error=0]="Error",r[r.Loaded=1]="Loaded",r[r.Recommendations=2]="Recommendations";var u=function(){return u=Object.assign||function(e){for(var r,n=1,t=arguments.length;n0&&o[o.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]0&&o[o.length-1])||6!==s[0]&&2!==s[0])){a=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1] { - test( 'Should link to the plugin\'s settings page', async ( { admin, page } ) => { - await admin.visitAdminPage( '/plugins.php' ); - await page.locator( '#the-list' ).getByRole( 'link', { name: 'Settings' } ).click(); - - // Check loaded page's URL and heading. - await page.waitForURL( '**/wp-admin/options-general.php?page=parsely' ); - await expect( page.getByText( 'Parse.ly Settings' ) ).toBeVisible(); - } ); -} ); diff --git a/test/e2e/playwright.config.ts b/tests/e2e/playwright.config.ts similarity index 100% rename from test/e2e/playwright.config.ts rename to tests/e2e/playwright.config.ts diff --git a/tests/e2e/specs/activation-flow.spec.ts b/tests/e2e/specs/activation-flow.spec.ts index 6cdd20750..b918b602c 100644 --- a/tests/e2e/specs/activation-flow.spec.ts +++ b/tests/e2e/specs/activation-flow.spec.ts @@ -1,7 +1,10 @@ /** * WordPress dependencies */ -import { visitAdminPage } from '@wordpress/e2e-test-utils'; +import { + expect, + test, +} from '@wordpress/e2e-test-utils-playwright'; /** * Internal dependencies @@ -9,67 +12,96 @@ import { visitAdminPage } from '@wordpress/e2e-test-utils'; import { VALID_SITE_ID, setSiteKeys, - waitForWpAdmin, } from '../utils'; -describe( 'Activation flow', (): void => { - it( 'Should progress as intended', async (): Promise => { - await setSiteKeys( '', '' ); - - await visitAdminPage( '/options-general.php', '?page=parsely' ); - - const versionText: string = await page.$eval( '#wp-parsely_version', ( el : Element ) => el.textContent ?? '' ); - expect( versionText ).toMatch( /^Version \d+.\d+/ ); - - const errorData = await page.$eval( '#wp-parsely-site-id-error-notice', ( el: Element ) => ( { - classes: el.classList.value, - message: el.textContent, - } ) ); - - expect( errorData.classes ).toBe( 'notice notice-error' ); - expect( errorData.message ).toBe( - 'The Parse.ly plugin is not active. You need to provide your Parse.ly Dash Site ID before things get cooking.' +/** + * Tests for the activation flow of the plugin. + * + * @since 3.17.0 Migrated to Playwright. + */ +test.describe( 'Activation flow', (): void => { + /** + * Verifies that the plugin displays an error when the Site ID is not provided. + * + * @since 3.17.0 Migrated to Playwright. + */ + test( 'Should show an error message when no Site ID is provided', async ( { admin } ): Promise => { + const page = admin.page; + + await setSiteKeys( page, '', '' ); + + await admin.visitAdminPage( '/options-general.php?page=parsely' ); + + const errorMessage = page.getByText( + 'The Parse.ly plugin is not active. You need to provide your Parse.ly Dash Site ID before things get cooking.', + { exact: true } ); - await setSiteKeys( VALID_SITE_ID, '' ); - - await waitForWpAdmin(); - expect( await page.$( '#message.error' ) ).toBe( null ); - } ); - - it( 'Should display all admin sections', async (): Promise => { - await visitAdminPage( '/options-general.php', '?page=parsely' ); - - // Default tab. - expect( page ).not.toBe( null ); - await testSectionsVisibility( [ 'initial', 'none', 'none' ] ); - - // Basic Settings Tab. - await page.click( '.basic-section-tab' ); - await testSectionsVisibility( [ 'initial', 'none', 'none' ] ); + await expect( errorMessage ).toBeVisible(); - // Recrawl Settings Tab. - await page.click( '.recrawl-section-tab' ); - await testSectionsVisibility( [ 'none', 'initial', 'none' ] ); + await setSiteKeys( page, VALID_SITE_ID, '' ); - // Advanced Settings Tab. - await page.click( '.advanced-section-tab' ); - await testSectionsVisibility( [ 'none', 'none', 'initial' ] ); - - await page.click( '.basic-section-tab' ); // Revert to initial state + await expect( errorMessage ).toBeHidden(); } ); - async function testSectionsVisibility( displayValues: string[] ): Promise { - const basicSectionSelector = '.basic-section'; - const recrawlSectionSelector = '.recrawl-section'; - const advancedSectionSelector = '.advanced-section'; - - expect( await getSectionStyles( basicSectionSelector ) ).toContain( `display: ${ displayValues[ 0 ] }` ); - expect( await getSectionStyles( recrawlSectionSelector ) ).toContain( `display: ${ displayValues[ 1 ] }` ); - expect( await getSectionStyles( advancedSectionSelector ) ).toContain( `display: ${ displayValues[ 2 ] }` ); - } - - async function getSectionStyles( selector: string ): Promise { - return await page.$eval( selector, ( e: Element ): string => e.getAttribute( 'style' ) ?? '' ); - } + /** + * Verifies that the Settings page behaves as expected. + * + * @since 3.17.0 Migrated to Playwright. + */ + test( 'Should present a settings page that behaves as expected', async ( { admin } ): Promise => { + const page = admin.page; + + await admin.visitAdminPage( '/options-general.php?page=parsely' ); + + // Initialize locators. + const basicTab = page.getByRole( 'link', { name: 'Basic' } ); + const basicSection = page.locator( '.basic-section' ); + const contentHelperTab = page.getByRole( 'link', { name: 'Content Helper' } ); + const contentHelperSection = page.locator( '.content-helper-section' ); + const recrawlTab = page.getByRole( 'link', { name: 'Recrawl' } ); + const recrawlSection = page.locator( '.recrawl-section' ); + const advancedTab = page.getByRole( 'link', { name: 'Advanced' } ); + const advancedSection = page.locator( '.advanced-section' ); + + // Check that all tabs are present in the Settings page. + await expect( basicTab ).toBeVisible(); + await expect( contentHelperTab ).toBeVisible(); + await expect( recrawlTab ).toBeVisible(); + await expect( advancedTab ).toBeVisible(); + + // Check that by default, the Basic Settings section is active. + await expect( basicSection ).toBeVisible(); + await expect( contentHelperSection ).toBeHidden(); + await expect( recrawlSection ).toBeHidden(); + await expect( advancedSection ).toBeHidden(); + + // Test section visibility when the Basic tab is clicked. + await basicSection.click(); + await expect( basicSection ).toBeVisible(); + await expect( contentHelperSection ).toBeHidden(); + await expect( recrawlSection ).toBeHidden(); + await expect( advancedSection ).toBeHidden(); + + // Test section visibility when the Content Helper tab is clicked. + await contentHelperTab.click(); + await expect( basicSection ).toBeHidden(); + await expect( contentHelperSection ).toBeVisible(); + await expect( recrawlSection ).toBeHidden(); + await expect( advancedSection ).toBeHidden(); + + // Test section visibility when the Recrawl tab is clicked. + await recrawlTab.click(); + await expect( basicSection ).toBeHidden(); + await expect( contentHelperSection ).toBeHidden(); + await expect( recrawlSection ).toBeVisible(); + await expect( advancedSection ).toBeHidden(); + + // Test section visibility when the Advanced tab is clicked. + await advancedTab.click(); + await expect( basicSection ).toBeHidden(); + await expect( contentHelperSection ).toBeHidden(); + await expect( recrawlSection ).toBeHidden(); + await expect( advancedSection ).toBeVisible(); + } ); } ); diff --git a/tests/e2e/specs/blocks/recommendations/errors.spec.ts b/tests/e2e/specs/blocks/recommendations/errors.spec.ts index c04db1ddc..da9c52020 100644 --- a/tests/e2e/specs/blocks/recommendations/errors.spec.ts +++ b/tests/e2e/specs/blocks/recommendations/errors.spec.ts @@ -2,10 +2,9 @@ * WordPress dependencies */ import { - createNewPost, - enablePageDialogAccept, - insertBlock, -} from '@wordpress/e2e-test-utils'; + expect, + test, +} from '@wordpress/e2e-test-utils-playwright'; /** * Internal dependencies @@ -18,56 +17,65 @@ import { /** * Tests for the Recommendations Block. + * + * @since 3.17.0 Migrated to Playwright. */ -describe( 'Recommendations Block', () => { - /** - * Prevents browser from locking with dialogs, logs in to WordPress, - * and activates the Parse.ly plugin. - */ - beforeAll( async () => { - enablePageDialogAccept(); - } ); - +test.describe( 'Recommendations Block', () => { /** * Verifies that the block will display an error when an invalid Site ID is provided. + * + * @since 3.17.0 Migrated to Playwright. */ - it( 'Should display an error when an invalid Site ID is provided', async () => { - await setSiteKeys( INVALID_SITE_ID, '' ); - await createNewPost(); - await insertBlock( 'Parse.ly' ); + test( 'Should display an error when an invalid Site ID is provided', async ( { admin } ) => { + const page = admin.page; + + await setSiteKeys( page, INVALID_SITE_ID, '' ); + await admin.createNewPost(); + await admin.editor.insertBlock( { name: 'wp-parsely/recommendations' } ); - await page.waitForSelector( '.parsely-recommendations-error' ); - const text = await page.$eval( '.parsely-recommendations-error', ( element: Element ) => element.textContent ); - expect( text ).toMatch( 'Access denied. Please verify that your Site ID is valid.' ); + await expect( page.getByText( + 'Access denied. Please verify that your Site ID is valid.', + { exact: true } + ) ).toBeVisible(); } ); /** * Verifies that the block will display an error when an empty Site ID is provided. + * + * @since 3.17.0 Migrated to Playwright. */ - it( 'Should display an error when an empty Site ID is provided', async () => { - await setSiteKeys( '', '' ); - await createNewPost(); - await insertBlock( 'Parse.ly' ); + test( 'Should display an error when an empty Site ID is provided', async ( { admin } ) => { + const page = admin.page; + + await setSiteKeys( page, '', '' ); + await admin.createNewPost(); + await admin.editor.insertBlock( { name: 'wp-parsely/recommendations' } ); - await page.waitForSelector( '.parsely-recommendations-error' ); - const text = await page.$eval( '.parsely-recommendations-error', ( element: Element ) => element.textContent ); - expect( text ).toMatch( 'A Parse.ly Site ID must be set in site options to use this endpoint' ); + await expect( page.getByText( + 'To use this Block, a Parse.ly Site ID must be set in the plugin\'s options', + { exact: true } + ) ).toBeVisible(); } ); /** * Verifies that the block will display an error when the API is not accessible. + * + * @since 3.17.0 Migrated to Playwright. */ - it( 'Should display an error when the Parse.ly API is not accessible', async () => { - await setSiteKeys( VALID_SITE_ID, '' ); - await createNewPost(); - await page.setOfflineMode( true ); - await insertBlock( 'Parse.ly' ); + test( 'Should display an error when the Parse.ly API is not accessible', async ( { admin } ) => { + const page = admin.page; + const context = admin.context; - await page.waitForSelector( '.parsely-recommendations-error' ); - const text = await page.$eval( '.parsely-recommendations-error', ( element: Element ) => element.textContent ); + await setSiteKeys( page, VALID_SITE_ID, '' ); + await admin.createNewPost(); + await context.setOffline( true ); + await admin.editor.insertBlock( { name: 'wp-parsely/recommendations' } ); - expect( text ).toMatch( 'The Parse.ly Recommendations API is not accessible. You may be offline.' ); + await expect( page.getByText( + 'The Parse.ly Recommendations API is not accessible. You may be offline.', + { exact: true } + ) ).toBeVisible(); - await page.setOfflineMode( false ); + context.setOffline( false ); } ); } ); diff --git a/tests/e2e/specs/blocks/recommendations/settings.spec.ts b/tests/e2e/specs/blocks/recommendations/settings.spec.ts index 9e8231bdf..82267646d 100644 --- a/tests/e2e/specs/blocks/recommendations/settings.spec.ts +++ b/tests/e2e/specs/blocks/recommendations/settings.spec.ts @@ -1,134 +1,156 @@ +/** + * External dependencies + */ +import { type Page } from '@playwright/test'; + /** * WordPress dependencies */ import { - createNewPost, - enablePageDialogAccept, - ensureSidebarOpened, - insertBlock, -} from '@wordpress/e2e-test-utils'; + expect, + test, +} from '@wordpress/e2e-test-utils-playwright'; /** * Internal dependencies */ import { VALID_SITE_ID, - arraysEqual, setSiteKeys, } from '../../../utils'; /** * Tests for the Recommendations Block's settings functionality. + * + * @since 3.17.0 Migrated to Playwright. */ -describe( 'Recommendations Block', () => { - /** - * Prevents browser from locking with dialogs, logs in to WordPress, - * and activates the Parse.ly plugin. - */ - beforeAll( async () => { - enablePageDialogAccept(); - } ); - +test.describe( 'Recommendations Block', () => { /** * Verifies that the Block works correctly when changing settings. + * + * @since 3.17.0 Migrated to Playwright. */ - it( 'Should update correctly when any options are changed', async () => { - await setSiteKeys( VALID_SITE_ID, '' ); - await createNewPost(); - await insertBlock( 'Parse.ly' ); + test( 'Should update correctly when any options are changed', async ( { admin } ) => { + const page = admin.page; + const editor = admin.editor; + const utils = new Utils( page ); + + // Insert the Block in a new post. + await setSiteKeys( page, VALID_SITE_ID, '' ); + await admin.createNewPost(); + await editor.insertBlock( { name: 'wp-parsely/recommendations' } ); // Verify Block default values. - await page.waitForSelector( '.parsely-recommendations-list' ); - expect( await getTitleText() ).toMatch( 'Related Content' ); - expect( await getResultCount() ).toBe( 3 ); - expect( await resultsContainImage() ).toBe( true ); + const listItems = page.locator( '.parsely-recommendations-list > li' ); + await expect( page.locator( '.parsely-recommendations-list-title' ) ) + .toHaveText( 'Related Content' ); + await expect( listItems ).toHaveCount( 3 ); + expect( page.locator( '.parsely-recommendations-image' ) ) + .toBeTruthy(); // Open sidebar to start changing settings. - await ensureSidebarOpened(); - const [ titleInput ] = await page.$x( "//label[contains(., 'Title')]/following-sibling::input" ); - const [ openLinksInNewTabLabel ] = await page.$x( "//label[contains(., 'Open Links in New Tab')]" ); - const [ showImagesLabel ] = await page.$x( "//label[contains(., 'Show Images')]" ); - const [ thumbnailImagesLabel ] = await page.$x( "//label[contains(., 'Thumbnail from Parse.ly')]" ); + await editor.openDocumentSettingsSidebar(); // Verify that changing "Title" works. - await titleInput.click( { clickCount: 3 } ); - await titleInput.type( 'Test' ); - expect( await getTitleText() ).toBe( 'Test' ); + const titleInput = page.getByLabel( 'Title', { exact: true } ); + await titleInput.fill( 'Test' ); + await expect( titleInput ).toHaveValue( 'Test' ); // Verify that changing "Maximum Results" works. - const [ maximumResultsLabel ] = await page.$x( "//label[contains(., 'Maximum Results')]" ); - await maximumResultsLabel.press( 'Tab' ); - await page.keyboard.type( '5' ); - await page.waitForFunction( - 'document.querySelectorAll(".parsely-recommendations-list > li").length === 5', - { polling: 'mutation', timeout: 3000 } - ); + await page.getByRole( 'slider', { name: 'Maximum Results' } ) + .fill( '5' ); + await expect( listItems ).toHaveCount( 5 ); // Verify that toggling "Open Links in New Tab" works. - const internalLinkTargets = await getLinkTargets(); + const internalLinkTargets = await utils.getLinkTargets(); internalLinkTargets.forEach( function( link ) { - expect( arraysEqual( link, [ '_self', '' ] ) ).toBe( true ); + expect( utils.arraysEqual( link, [ '_self', '' ] ) ).toBe( true ); } ); - await openLinksInNewTabLabel.click(); - const externalLinkTargets = await getLinkTargets(); + await page.getByLabel( 'Open Links in New Tab' ).click(); + const externalLinkTargets = await utils.getLinkTargets(); externalLinkTargets.forEach( function( link ) { - expect( arraysEqual( link, [ '_blank', 'noopener' ] ) ).toBe( true ); + expect( utils.arraysEqual( link, [ '_blank', 'noopener' ] ) ).toBe( true ); } ); // For images, verify that original and thumbnail "src" attributes are different. - const originalImagesUrls = await getResultImageUrls(); - await thumbnailImagesLabel.click(); - expect( arraysEqual( originalImagesUrls, await getResultImageUrls() ) ).toBe( false ); + const originalImagesUrls = await utils.getResultImageUrls(); + await page.getByLabel( 'Thumbnail from Parse.ly' ).click(); + const parselyImagesUrls = await utils.getResultImageUrls(); + expect( utils.arraysEqual( originalImagesUrls, parselyImagesUrls ) ).toBe( false ); // Verify that toggling "Show Images" works. - await showImagesLabel.click(); - expect( await resultsContainImage() ).toBe( false ); + await page.getByLabel( 'Show Images' ).click(); + await expect( page.locator( '.parsely-recommendations-image' ) ) + .toHaveCount( 0 ); } ); } ); /** - * Returns the Block's title text. + * Provides utility functions for the tests in this file. * - * @return {Promise} The Block's title text. + * @since 3.17.0 Migrated utility functions to Playwright. */ -async function getTitleText(): Promise { - return page.$eval( '.parsely-recommendations-list-title', ( element: Element ) => element.textContent ); -} +class Utils { + /** + * The Page object of the calling function. + * + * @since 3.17.0 + */ + readonly page: Page; -/** - * Returns the number of results displayed within the Block. - * - * @return {Promise} The number of results displayed within the Block. - */ -async function getResultCount(): Promise { - return page.$$eval( '.parsely-recommendations-list > li', ( element: Element[] ) => element.length ); -} + /** + * Constructor. + * + * @since 3.17.0 + * + * @param {Page} page The Page object of the calling function. + */ + constructor( page: Page ) { + this.page = page; + } -/** - * Returns whether the Block contains one or more images. - * - * @return {Promise} Whether the Block contains one or more images. - */ -async function resultsContainImage(): Promise { - return ( await page.$( '.parsely-recommendations-image' ) ) !== null; -} + /** + * Returns whether the passed arrays are equal. + * + * This function is meant to compare very simple arrays.Please don't use it to + * compare arrays that contain objects, or that are complex or large. + * + * @since 3.17.0 Moved from utils.ts. + * + * @param {Array} array1 + * @param {Array} array2 + * + * @return {boolean} Whether the passed arrays are equal. + */ + arraysEqual( array1: ( string | null )[], array2: ( string | null )[] ): boolean { + return JSON.stringify( array1 ) === JSON.stringify( array2 ); + } -/** - * Returns the "src" attribute of all images contained within the Block. - * - * @return {Promise>} The "src" attribute of all images contained within the Block. - */ -async function getResultImageUrls(): Promise<( string | null )[]> { - return page.$$eval( '.parsely-recommendations-image', ( imgs: Element[] ) => imgs.map( ( img: Element ) => img.getAttribute( 'src' ) ) ); -} + /** + * Returns the "src" attribute of all images contained within the Block. + * + * @since 3.17.0 Migrated to Playwright. + * + * @return {Promise>} The "src" attribute of all images contained within the Block. + */ + async getResultImageUrls(): Promise<( string | null )[]> { + return this.page.locator( '.parsely-recommendations-image' ) + .evaluateAll( ( images: Element[] ) => images.map( ( image: Element ) => + image.getAttribute( 'src' ) + ) ); + } -/** - * Returns the "target" and "rel" attribute of all links contained within the Block. - * - * @return {Promise>} The "target" and "rel" attributes of all links contained within the Block. - */ -async function getLinkTargets(): Promise { - return page.$$eval( '.parsely-recommendations-link', ( links: Element[] ) => links.map( - ( link: Element ): string[] => [ link.getAttribute( 'target' ) ?? '', link.getAttribute( 'rel' ) ?? '' ] ) - ); + /** + * Returns the "target" and "rel" attribute of all links contained within the Block. + * + * @since 3.17.0 Migrated to Playwright. + * + * @return {Promise>} The "target" and "rel" attributes of all links contained within the Block. + */ + async getLinkTargets(): Promise { + return this.page.locator( '.parsely-recommendations-link' ) + .evaluateAll( ( links: Element[] ) => links.map( ( link: Element ): string[] => + [ link.getAttribute( 'target' ) ?? '', link.getAttribute( 'rel' ) ?? '' ] + ) ); + } } diff --git a/tests/e2e/specs/browse-logo-button.spec.ts b/tests/e2e/specs/browse-logo-button.spec.ts index 13d41f254..ff6718672 100644 --- a/tests/e2e/specs/browse-logo-button.spec.ts +++ b/tests/e2e/specs/browse-logo-button.spec.ts @@ -1,100 +1,107 @@ /** * External dependencies */ -import { - enablePageDialogAccept, - visitAdminPage, -} from '@wordpress/e2e-test-utils'; import * as path from 'path'; -// General initializations. -const imageLocalPath: string = path.resolve( __dirname, '../../../.wordpress-org/icon-256x256.png' ); -const uploadedImagePattern = /\/wp-content\/uploads\/\d{4}\/\d{2}\/icon-256x256-?\d*\.png$/; -const filePathInput = '#media-single-image-logo input.file-path'; -const modalAttachment = 'li.attachment'; // Used in both modals. - -// Media library modal selectors. -const modalMediaLibrary = 'div.media-modal-content'; -const modalSelectFilesButton = '#media-single-image-logo button.browse'; -const modalConfirmButton = `${ modalMediaLibrary } button.media-button-select`; -const modalFileUploadInput = `${ modalMediaLibrary } input[type=file]`; - -// Edit attachment modal selectors. -const modalEditAttachment = 'div.media-modal div.edit-attachment-frame'; -const modalDeleteAttachmentLink = `${ modalEditAttachment } button.delete-attachment`; +/** + * WordPress dependencies + */ +import { + expect, + test, +} from '@wordpress/e2e-test-utils-playwright'; /** - * Browse button tests + * Tests the Settings page's Browse button behavior. + * + * @since 3.17.0 Migrated to Playwright. */ -describe( 'Browse for logo button', () => { +test.describe( 'Browse for logo button', () => { + // General initializations. + const uploadedImagePattern = /\/wp-content\/uploads\/\d{4}\/\d{2}\/icon-256x256-?\d*\.png$/; + const filePathInput = '#media-single-image-logo input.file-path'; + const modalAttachment = 'li.attachment'; + + // Media library modal selectors. + const modalMediaLibrary = 'div.media-modal-content'; + const modalConfirmButton = `${ modalMediaLibrary } button.media-button-select`; + const modalFileUploadInput = `${ modalMediaLibrary } input[type=file]`; + /** - * Remove the uploaded image. + * Deletes all uploaded images. + * + * Runs after all tests. + * + * @since 3.17.0 Migrated to Playwright. */ - afterAll( async () => { - // Go to Media Library and select the image. - await visitAdminPage( '/upload.php' ); - await page.waitForSelector( modalAttachment, { visible: true } ); - await page.click( modalAttachment ); - await page.waitForSelector( modalEditAttachment, { visible: true } ); - - enablePageDialogAccept(); // Confirm image deletion. - await page.click( modalDeleteAttachmentLink ); + test.afterAll( async ( { requestUtils } ) => { + await requestUtils.deleteAllMedia(); } ); /** - * Go to settings page and click the browse button. + * Clicks the Browse button in the Settings page, to show the Media Library. + * + * Runs before each test. + * + * @since 3.17.0 Migrated to Playwright. */ - beforeEach( async () => { - await visitAdminPage( '/options-general.php', '?page=parsely' ); + test.beforeEach( async ( { admin } ) => { + const modalSelectFilesButton = '#media-single-image-logo button.browse'; + + await admin.visitAdminPage( '/options-general.php?page=parsely' ); - // Click browse button and wait for Media Library to appear. - await page.click( modalSelectFilesButton ); - await page.waitForSelector( modalMediaLibrary, { visible: true } ); + await admin.page.click( modalSelectFilesButton ); } ); /** - * Test: Click the Browse button, upload new image, select it and confirm. + * Verifies that the image path gets set when a new image is uploaded and + * confirmed. + * + * @since 3.17.0 Migrated to Playwright. */ - it( 'Should set the file path when a new image is uploaded and confirmed', async () => { + test( 'Should set the file path when a new image is uploaded and confirmed', async ( { page } ) => { + const imageLocalPath: string = path.resolve( + __dirname, '../../../.wordpress-org/icon-256x256.png' + ); + // Upload an image file and confirm the dialog. - const fileInput = await page.$( modalFileUploadInput ); - await fileInput?.uploadFile( imageLocalPath ); - await page.waitForTimeout( 500 ); + await page.setInputFiles( modalFileUploadInput, imageLocalPath ); await page.click( modalConfirmButton ); // Verify that the image path has been updated. - await page.waitForTimeout( 500 ); - const filePath = await page.evaluate( ( element ) => element.value, await page.$( filePathInput ) ); - expect( filePath ).toMatch( uploadedImagePattern ); + await expect( page.locator( filePathInput ) ) + .toHaveValue( uploadedImagePattern ); } ); /** - * Test: Click the Browse button, select an existing image and confirm. + * Verifies that the image path gets set when an existing image is selected + * and confirmed. + * + * @since 3.17.0 Migrated to Playwright. */ - it( 'Should set the file path when an existing image is selected and confirmed', async () => { + test( 'Should set the file path when an existing image is selected and confirmed', async ( { page } ) => { // Select the existing and confirm the dialog. - await page.waitForSelector( modalAttachment, { visible: true } ); await page.click( modalAttachment ); await page.click( modalConfirmButton ); // Verify that the image path has been updated. - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const filePath = await page.$eval( filePathInput, ( input: any ) => input.value ); - expect( filePath ).toMatch( uploadedImagePattern ); + await expect( page.locator( filePathInput ) ) + .toHaveValue( uploadedImagePattern ); } ); /** - * Test: Click the Brows button, select an existing image and dismiss the modal. + * Verifies that the image path doesn't get set when the Media Library modal + * gets dismissed by the user. + * + * @since 3.17.0 Migrated to Playwright. */ - it( 'Should not set the file path when dismissing the modal', async () => { + test( 'Should not set the file path when dismissing the modal', async ( { page } ) => { // Select the existing image but cancel the dialog. - await page.waitForSelector( modalAttachment, { visible: true } ); await page.click( modalAttachment ); await page.keyboard.press( 'Escape' ); // Verify that the image path is empty. - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const filePath = await page.$eval( filePathInput, ( input: any ) => input.value ); - expect( filePath ).toMatch( '' ); + await expect( page.locator( filePathInput ) ) + .toHaveValue( '' ); } ); } ); diff --git a/tests/e2e/specs/content-helper/errors.spec.ts b/tests/e2e/specs/content-helper/errors.spec.ts index 8971617f9..fd80fa73d 100644 --- a/tests/e2e/specs/content-helper/errors.spec.ts +++ b/tests/e2e/specs/content-helper/errors.spec.ts @@ -1,3 +1,11 @@ +/** + * WordPress dependencies + */ +import { + expect, + test, +} from '@wordpress/e2e-test-utils-playwright'; + /** * Internal dependencies */ @@ -11,58 +19,73 @@ import { /** * Tests for the errors presented by the PCH Editor Sidebar Related Posts panel. + * + * @since 3.17.0 Migrated to Playwright. */ -describe( 'PCH Editor Sidebar Related Posts panel', () => { +test.describe( 'PCH Editor Sidebar Related Posts panel', () => { const contactMessage = 'Contact us about advanced plugin features and the Parse.ly dashboard.'; /** * Verifies that the panel will display an error when an invalid Site ID is * provided. + * + * @since 3.17.0 Migrated to Playwright. */ - it( 'Should display an error when an invalid Site ID is provided', async () => { - await setSiteKeys( INVALID_SITE_ID, VALID_API_SECRET ); + test( 'Should display an error when an invalid Site ID is provided', async ( { admin } ) => { + await setSiteKeys( admin.page, INVALID_SITE_ID, VALID_API_SECRET ); - expect( await getRelatedPostsMessage( '', '', 'author', 500, '.content-helper-error-message' ) ) - .toMatch( 'Error: Forbidden' ); + expect( await getRelatedPostsMessage( + admin, '', '', 'author', '.content-helper-error-message' + ) ).toMatch( 'Error: Forbidden' ); } ); /** * Verifies that the panel will display a "Contact Us" message when the Site * ID and API Secret are not provided. + * + * @since 3.17.0 Migrated to Playwright. */ - it( 'Should display a "Contact Us" message when the Site ID and API Secret are not provided', async () => { - await setSiteKeys( '', '' ); + test( 'Should display a "Contact Us" message when the Site ID and API Secret are not provided', async ( { admin } ) => { + await setSiteKeys( admin.page, '', '' ); - expect( await getRelatedPostsMessage() ).toMatch( contactMessage ); + expect( await getRelatedPostsMessage( admin ) ).toMatch( contactMessage ); } ); /** * Verifies that the panel will display a "Contact Us" message when only the * Site ID is provided. + * + * @since 3.17.0 Migrated to Playwright. */ - it( 'Should display a "Contact Us" message when only the Site ID is provided', async () => { - await setSiteKeys( VALID_SITE_ID, '' ); + test( 'Should display a "Contact Us" message when only the Site ID is provided', async ( { admin } ) => { + await setSiteKeys( admin.page, VALID_SITE_ID, '' ); - expect( await getRelatedPostsMessage() ).toMatch( contactMessage ); + expect( await getRelatedPostsMessage( admin ) ).toMatch( contactMessage ); } ); /** * Verifies that the panel will display a "Contact Us" message when only the * API Secret is provided. + * + * @since 3.17.0 Migrated to Playwright. */ - it( 'Should display a "Contact Us" message when only the API Secret is provided', async () => { - await setSiteKeys( '', VALID_API_SECRET ); + test( 'Should display a "Contact Us" message when only the API Secret is provided', async ( { admin } ) => { + await setSiteKeys( admin.page, '', VALID_API_SECRET ); - expect( await getRelatedPostsMessage() ).toMatch( contactMessage ); + expect( await getRelatedPostsMessage( admin ) ).toMatch( contactMessage ); } ); /** * Verifies that the panel will not display a "Contact Us" message when both * the Site ID and API Secret are provided. + * + * @since 3.17.0 Migrated to Playwright. */ - it( 'Should not display a "Contact Us" message when both the Site ID and API Secret are provided', async () => { - await setSiteKeys( VALID_SITE_ID, VALID_API_SECRET ); + test( 'Should not display a "Contact Us" message when both the Site ID and API Secret are provided', async ( { admin } ) => { + await setSiteKeys( admin.page, VALID_SITE_ID, VALID_API_SECRET ); - expect( await getRelatedPostsMessage( '', '', 'author', 500, '.related-posts-descr' ) ).not.toMatch( contactMessage ); + expect( await getRelatedPostsMessage( + admin, '', '', 'author', '.related-posts-descr' ) + ).not.toMatch( contactMessage ); } ); } ); diff --git a/tests/e2e/specs/content-helper/related-posts-panel-filters.spec.ts b/tests/e2e/specs/content-helper/related-posts-panel-filters.spec.ts index f38f841f7..c39410c42 100644 --- a/tests/e2e/specs/content-helper/related-posts-panel-filters.spec.ts +++ b/tests/e2e/specs/content-helper/related-posts-panel-filters.spec.ts @@ -2,8 +2,9 @@ * WordPress dependencies */ import { - enablePageDialogAccept, -} from '@wordpress/e2e-test-utils'; + expect, + test, +} from '@wordpress/e2e-test-utils-playwright'; /** * Internal dependencies @@ -13,46 +14,50 @@ import { VALID_SITE_ID, getRelatedPostsMessage, setSiteKeys, - setUserDisplayName, } from '../../utils'; /** * Tests for the PCH Editor Sidebar Related Post filters. + * + * @since 3.17.0 Migrated to Playwright. */ -describe( 'PCH Editor Sidebar Related Post panel filters', () => { +test.describe( 'PCH Editor Sidebar Related Post panel filters', () => { /** - * Prevents browser from locking with dialogs, logs in to WordPress, - * activates the Parse.ly plugin, and sets valid site keys. + * Sets a valid Site ID and API Secret. + * + * Runs before all tests. + * + * @since 3.17.0 Migrated to Playwright. */ - beforeAll( async () => { - enablePageDialogAccept(); - await setSiteKeys( VALID_SITE_ID, VALID_API_SECRET ); + test.beforeAll( async ( { browser } ) => { + const page = await browser.newPage(); + + await setSiteKeys( page, VALID_SITE_ID, VALID_API_SECRET ); } ); /** * Verifies that an attempt to fetch results is made when a Site ID and API * Secret are provided. + * + * @since 3.17.0 Migrated to Playwright. */ - it( 'Should attempt to fetch results when a Site ID and API Secret are provided', async () => { - await setUserDisplayName( 'admin', '' ); - - expect( await getRelatedPostsMessage( '', '', 'author', 500, '.related-posts-empty' ) ) - .toMatch( `No related posts found.` ); + test( 'Should attempt to fetch results when a Site ID and API Secret are provided', async ( { admin } ) => { + expect( await getRelatedPostsMessage( + admin, '', '', 'author', '.related-posts-empty' + ) ).toMatch( `No related posts found.` ); } ); /** * Verifies that the Related Posts panel will work correctly when a new * taxonomy is added from within the WordPress Post Editor. * - * Note: This test does not insert the taxonomy into the database before - * selecting it in the WordPress Post Editor. As such, a delay in - * intercepting the new value is expected, since it must first be stored - * into the database and then picked up by the Related Posts panel. + * @since 3.17.0 Migrated to Playwright. */ - it( 'Should work correctly when a taxonomy is added from within the WordPress Post Editor', async () => { + test( 'Should work correctly when a taxonomy is added from within the WordPress Post Editor', async ( { admin } ) => { const categoryName = 'Analytics That Matter'; - expect( await getRelatedPostsMessage( categoryName, '', 'section', 2000, '.related-posts-descr' ) ) - .toMatch( `Top related posts in the “${ categoryName }” section in the last 30 days.` ); + expect( await getRelatedPostsMessage( + admin, categoryName, '', 'section', '.related-posts-descr' + ) ).toMatch( `Top related posts in the “${ categoryName }” section in the last 30 days.` ); } ); } ); diff --git a/tests/e2e/specs/content-helper/top-bar-icon.spec.ts b/tests/e2e/specs/content-helper/top-bar-icon.spec.ts index 62c975c8c..327491e11 100644 --- a/tests/e2e/specs/content-helper/top-bar-icon.spec.ts +++ b/tests/e2e/specs/content-helper/top-bar-icon.spec.ts @@ -1,7 +1,11 @@ /** * WordPress dependencies */ -import { createNewPost } from '@wordpress/e2e-test-utils'; +import { + type Admin, + expect, + test, +} from '@wordpress/e2e-test-utils-playwright'; /** * Internal dependencies @@ -11,117 +15,180 @@ import { VALID_SITE_ID, setSidebarPanelExpanded, setSiteKeys, - toggleMoreMenu, } from '../../utils'; -// Selectors. -const pluginButton = 'button[aria-label="Parse.ly"]'; - /** * Tests for the PCH Editor Sidebar top bar icon. + * + * @since 3.17.0 Migrated to Playwright. */ -describe( 'PCH Editor Sidebar top bar icon in the WordPress Post Editor', () => { +test.describe( 'PCH Editor Sidebar top bar icon in the WordPress Post Editor', () => { const noRelatedPostsMessage = 'No related posts found.'; const emptyCredentialsMessage = 'Contact us about advanced plugin features and the Parse.ly dashboard.Existing Parse.ly customers can enable this feature by setting their Site ID and API Secret in wp-parsely options.'; /** * Verifies that the top bar icon gets displayed when the Site ID and API * Secret are not provided. + * + * @since 3.17.0 Migrated to Playwright. */ - it( 'Should be displayed when the Site ID and API Secret are not provided', async () => { - expect( await testContentHelperIcon( '', '' ) ) + test( 'Should be displayed when the Site ID and API Secret are not provided', async ( { admin } ) => { + const utils = new Utils( admin ); + + expect( await utils.testContentHelperIcon( '', '' ) ) .toMatch( emptyCredentialsMessage ); } ); /** * Verifies that the top bar icon gets displayed when only the Site ID is * provided. + * + * @since 3.17.0 Migrated to Playwright. */ - it( 'Should be displayed when only the Site ID is provided.', async () => { - expect( await testContentHelperIcon( VALID_SITE_ID, '' ) ) + test( 'Should be displayed when only the Site ID is provided.', async ( { admin } ) => { + const utils = new Utils( admin ); + + expect( await utils.testContentHelperIcon( VALID_SITE_ID, '' ) ) .toMatch( emptyCredentialsMessage ); } ); /** * Verifies that the top bar icon gets displayed when only the API Secret is * provided. + * + * @since 3.17.0 Migrated to Playwright. */ - it( 'Should be displayed when only the API Secret is provided', async () => { - expect( await testContentHelperIcon( '', VALID_API_SECRET ) ) + test( 'Should be displayed when only the API Secret is provided', async ( { admin } ) => { + const utils = new Utils( admin ); + + expect( await utils.testContentHelperIcon( '', VALID_API_SECRET ) ) .toMatch( emptyCredentialsMessage ); } ); /** * Verifies that the top bar icon gets displayed when both the Site ID and * API Secret are provided. + * + * @since 3.17.0 Migrated to Playwright. */ - it( 'Should be displayed when both the Site ID and API Secret are provided', async () => { - expect( await testContentHelperIcon( + test( 'Should be displayed when both the Site ID and API Secret are provided', async ( { admin } ) => { + const utils = new Utils( admin ); + + expect( await utils.testContentHelperIcon( VALID_SITE_ID, VALID_API_SECRET, '.related-posts-empty' - ) ) - .toMatch( noRelatedPostsMessage ); + ) ).toMatch( noRelatedPostsMessage ); } ); /** * Verifies that the top bar icon does not crash the WordPress Post Editor. * * More information: https://github.com/Parsely/wp-parsely/issues/962 + * + * @since 3.17.0 Migrated to Playwright. */ - it( 'Should not crash the editor', async () => { - await setSiteKeys( VALID_SITE_ID, VALID_API_SECRET ); - await createNewPost(); - - // Close sidebar if it is opened. - await page.waitForSelector( pluginButton, { visible: true } ); - const toggleSidebarButton = await page.$( - '.edit-post-header__settings [aria-label="Settings"][aria-expanded="true"]' + test( 'Should not crash the editor', async ( { admin } ) => { + const page = admin.page; + const utils = new Utils( admin ); + + await setSiteKeys( page, VALID_SITE_ID, VALID_API_SECRET ); + await admin.createNewPost(); + + // Close Settings sidebar if it is opened. + const toggleSidebarButton = page.getByRole( + 'button', { name: 'Settings', exact: true } ); - if ( toggleSidebarButton ) { + if ( 'true' === await toggleSidebarButton.getAttribute( 'aria-expanded' ) ) { await toggleSidebarButton.click(); } - // Ensure that the menu opens without crashing the Post Editor. - await toggleMoreMenu( 'open' ); - await page.waitForSelector( 'div.components-dropdown-menu__menu', { visible: true } ); - const text = await page.$eval( 'div.components-dropdown-menu__menu', ( element: Element ) => element.textContent ); - expect( await text ).toMatch( 'Parse.ly' ); + // Ensure that the Options menu opens without crashing the Post Editor. + await utils.toggleMoreMenu( 'open' ); + expect( await page.locator( 'div.components-dropdown-menu__menu' ).textContent() ) + .toMatch( 'Parse.ly' ); } ); } ); /** - * Tests the top bar icon by clicking on it and verifying that the PCH Editor - * Sidebar opens. + * Provides utility functions for the tests in this file. * - * @param {string} siteId The Site ID to use for the test. - * @param {string} apiSecret The API Secret to use for the test. - * @param {string} selector The selector from which to get the text content. - * - * @return {string} Text content found in the PCH Editor Sidebar. + * @since 3.17.0 Migrated utility functions to Playwright. */ -async function testContentHelperIcon( - siteId: string, apiSecret: string, selector = '.content-helper-error-message' -) { - const contentHelperMessageSelector = '.wp-parsely-content-helper div.components-panel__body.is-opened ' + selector; - - await setSiteKeys( siteId, apiSecret ); - await createNewPost(); - - // Click the top bar icon. - await page.waitForSelector( pluginButton ); - await page.click( pluginButton ); - - // Expand the Related Posts panel and get its text content. - setSidebarPanelExpanded( 'Related Posts', true ); - await page.waitForSelector( contentHelperMessageSelector ); - await page.waitForFunction( // Wait for the message to appear. - 'document.querySelector("' + contentHelperMessageSelector + '").innerText.length > 0', - { polling: 'mutation', timeout: 5000 } - ); - const text = await page.$eval( - contentHelperMessageSelector, - ( element: Element ): string => element.textContent ?? '' - ); - - return text; +class Utils { + /** + * The admin object of the calling function. + * + * @since 3.17.0 + */ + readonly admin: Admin; + + /** + * Constructor. + * + * @since 3.17.0 + * + * @param {Admin} admin The Admin object of the calling function. + */ + constructor( admin: Admin ) { + this.admin = admin; + } + + /** + * Tests the top bar icon by clicking on it and verifying that the PCH Editor + * Sidebar opens. + * + * @since 3.17.0 Migrated to Playwright. + * + * @param {string} siteId The Site ID to use for the test. + * @param {string} apiSecret The API Secret to use for the test. + * @param {string} selector The selector from which to get the text content. + * + * @return {Promise} Text content found in the PCH Editor Sidebar. + */ + async testContentHelperIcon( + siteId: string, apiSecret: string, selector: string = '.content-helper-error-message' + ): Promise { + const page = this.admin.page; + + await setSiteKeys( page, siteId, apiSecret ); + await this.admin.createNewPost(); + + // Click the top bar icon and // Expand the Related Posts panel. + await page.getByRole( 'button', { name: 'Parse.ly' } ).click(); + setSidebarPanelExpanded( page, 'Related Posts', true ); + + return await page.locator( + '.wp-parsely-content-helper div.components-panel__body.is-opened ' + selector + ).textContent() ?? ''; + } + + /** + * Toggles the More Menu. + * + * @since 3.16.1 + * @since 3.17.0 Moved from utils.ts and migrated to Playwright. + * + * @param {'open' | 'close' | undefined} waitFor Whether it should wait for the menu to open or close. + * If `undefined`, it won't wait for anything. + */ + async toggleMoreMenu( + waitFor: 'open' | 'close' | undefined = undefined + ): Promise { + const page = this.admin.page; + + const menuToggle = page.locator( 'button[aria-haspopup="true"][aria-label="Options"]' ); + const isOpen = await menuToggle.evaluate( ( el ) => el.getAttribute( 'aria-expanded' ) ); + + // If opening and it's already open then exit early. + if ( isOpen === 'true' && waitFor === 'open' ) { + return; + } + + // If closing and it's already closed then exit early. + if ( isOpen === 'false' && waitFor === 'close' ) { + return; + } + + await menuToggle.click(); + } } diff --git a/tests/e2e/specs/front-end-metadata.spec.ts b/tests/e2e/specs/front-end-metadata.spec.ts index 1f68a5f0c..3ed7ba014 100644 --- a/tests/e2e/specs/front-end-metadata.spec.ts +++ b/tests/e2e/specs/front-end-metadata.spec.ts @@ -2,9 +2,10 @@ * WordPress dependencies */ import { - createURL, - visitAdminPage, -} from '@wordpress/e2e-test-utils'; + type Admin, + expect, + test, +} from '@wordpress/e2e-test-utils-playwright'; /** * Internal dependencies @@ -12,102 +13,110 @@ import { import { VALID_SITE_ID, setSiteKeys, - setUserDisplayName, - waitForWpAdmin, } from '../utils'; -const setMetadataFormat = async ( format: string ) => { - await visitAdminPage( '/options-general.php', '?page=parsely' ); - - const selectedMetadataFormat = await page.$( `#meta_type_${ format }` ); - await selectedMetadataFormat?.click(); - - const submitButton = await page.$( `form[name="parsely"] #submit` ); - await submitButton?.click(); - - await waitForWpAdmin(); -}; - -async function setTrackLoggedInUsers( shouldTrack = false ) { - await visitAdminPage( '/options-general.php', '?page=parsely' ); - - const trackLoggedInUserRadioButton = await page.$( `#track_authenticated_users_${ shouldTrack }` ); - await trackLoggedInUserRadioButton?.click(); - - const submitButton = await page.$( `form[name="parsely"] #submit` ); - await submitButton?.click(); - - await waitForWpAdmin(); -} - -describe( 'Front end metadata insertion', () => { - beforeAll( async () => { - await setSiteKeys( VALID_SITE_ID, '' ); - await setTrackLoggedInUsers( true ); - - // Reset display name to compare metadata with default values. - await setUserDisplayName( 'admin', '' ); +/** + * Tests front-end metadata insertion functionality. + * + * @since 3.17.0 Migrated to Playwright. + */ +test.describe( 'Front end metadata insertion', () => { + /** + * Sets a valid Site ID and API Secret, and then activates tracking for + * logged-in users. + * + * Runs before all tests. + * + * @since 3.17.0 Migrated to Playwright. + */ + test.beforeAll( async ( { browser } ) => { + const page = await browser.newPage(); + + await setSiteKeys( page, VALID_SITE_ID, '' ); + + // Activate tracking for logged-in users. + await page.goto( '/wp-admin/options-general.php?page=parsely' ); + await page.getByLabel( 'Yes, track logged-in users.' ).click(); + await page.getByRole( 'button', { name: 'Save Changes' } ).click(); } ); - it( 'Should insert JSON-LD on homepage', async () => { - await setMetadataFormat( 'json_ld' ); + /** + * Verifies that JSON-LD metadata is correctly being inserted into the homepage. + * + * @since 3.17.0 Migrated to Playwright. + */ + test( 'Should insert JSON-LD on homepage', async ( { admin, page } ) => { + const utils = new Utils( admin ); + await utils.setMetadataFormat( 'json_ld' ); - await page.goto( createURL( '/' ) ); + await page.goto( '/' ); const content = await page.content(); expect( content ).toContain( '' ); - expect( content ).not.toContain( ' { - await setMetadataFormat( 'json_ld' ); - - await page.goto( createURL( '/', '?p=1' ) ); + /** + * Verifies that JSON-LD metadata is correctly being inserted into posts. + * + * @since 3.17.0 Migrated to Playwright. + */ + test( 'Should insert JSON-LD on post', async ( { page } ) => { + await page.goto( '/?p=1' ); const content = await page.content(); expect( content ).toContain( '` ); - expect( content ).toContain( `` ); + expect( content ).toContain( `` ); expect( content ).not.toContain( "` ); - expect( content ).toContain( `` ); + expect( content ).toContain( `` ); expect( content ).toContain( '` ); - expect( content ).toContain( `` ); + expect( content ).toContain( `` ); expect( content ).not.toContain( "` ); - expect( content ).toContain( `` ); + expect( content ).toContain( `` ); expect( content ).toContain( '