├── src ├── Data │ ├── .gitkeep │ ├── Connection │ │ └── .gitkeep │ └── Loader │ │ └── .gitkeep ├── Type │ ├── .gitkeep │ ├── WPObject │ │ ├── JsonLd.php │ │ ├── OpenGraph │ │ │ ├── Video.php │ │ │ ├── SlackEnhancedData.php │ │ │ ├── TwitterApp.php │ │ │ ├── Facebook.php │ │ │ ├── Image.php │ │ │ ├── Product.php │ │ │ └── Article.php │ │ ├── Breadcrumbs.php │ │ ├── Settings.php │ │ ├── Settings │ │ │ ├── Meta │ │ │ │ ├── DateArchiveMeta.php │ │ │ │ ├── LocalMeta.php │ │ │ │ ├── SocialMeta.php │ │ │ │ ├── AuthorArchiveMeta.php │ │ │ │ ├── HomepageMeta.php │ │ │ │ └── GlobalMeta.php │ │ │ ├── General │ │ │ │ ├── Webmaster.php │ │ │ │ ├── FrontendSeoScore.php │ │ │ │ ├── Links.php │ │ │ │ └── BreadcrumbsConfig.php │ │ │ ├── Sitemap │ │ │ │ ├── Author.php │ │ │ │ ├── General.php │ │ │ │ ├── Taxonomy.php │ │ │ │ └── ContentType.php │ │ │ ├── General.php │ │ │ └── Sitemap.php │ │ ├── SeoScore.php │ │ └── AdvancedRobotsMeta.php │ ├── Enum │ │ ├── KnowledgeGraphTypeEnum.php │ │ ├── RobotsMetaValueEnum.php │ │ ├── SeoScoreTemplateTypeEnum.php │ │ ├── OpenGraphProductAvailabilityEnum.php │ │ ├── ArticleTypeEnum.php │ │ ├── OpenGraphLocaleEnum.php │ │ ├── BulkEditingTypeEnum.php │ │ ├── ImagePreviewSizeEnum.php │ │ ├── SeoRatingEnum.php │ │ ├── SeoScorePositionEnum.php │ │ ├── TwitterCardTypeEnum.php │ │ └── SnippetTypeEnum.php │ └── WPInterface │ │ ├── MetaSettingWithArchive.php │ │ ├── MetaSettingWithRobots.php │ │ └── ContentNodeSeo.php ├── Utils │ ├── .gitkeep │ ├── Utils.php │ └── RMUtils.php ├── Connection │ └── .gitkeep ├── Mutation │ └── .gitkeep ├── Extensions │ ├── Extensions.php │ └── WPGraphQLWooCommerce │ │ ├── WPGraphQLWooCommerce.php │ │ └── Type │ │ └── WPObject │ │ └── SeoObjects.php ├── Modules │ └── Redirection │ │ ├── Fields │ │ ├── GeneralSettings.php │ │ └── RootQuery.php │ │ ├── Type │ │ ├── Enum │ │ │ ├── RedirectionTypeEnum.php │ │ │ ├── RedirectionComparisonTypeEnum.php │ │ │ ├── RedirectionStatusEnum.php │ │ │ ├── RedirectionBehaviorEnum.php │ │ │ └── RedirectionConnectionOrderByEnum.php │ │ ├── Input │ │ │ └── RedirectionConnectionOrderbyInput.php │ │ └── WPObject │ │ │ ├── RedirectionSource.php │ │ │ ├── RedirectionSettings.php │ │ │ └── Redirection.php │ │ ├── Data │ │ ├── Loader │ │ │ └── RedirectionsLoader.php │ │ ├── Cursor │ │ │ └── RedirectionCursor.php │ │ └── Connection │ │ │ └── RedirectionConnectionResolver.php │ │ ├── Connection │ │ └── RedirectionConnection.php │ │ ├── TypeRegistry.php │ │ └── CoreSchemaFilters.php ├── Fields │ └── RootQuery.php ├── CoreSchemaFilters.php ├── Admin │ └── Settings │ │ └── Settings.php ├── Autoloader.php └── Main.php ├── assets ├── header.png └── built-with.png ├── .wordpress-org ├── banner-772x250.png ├── icon-128x128.png ├── icon-256x256.png └── banner-1544x500.png ├── .coveralls.yml ├── vendor ├── composer │ ├── autoload_namespaces.php │ ├── autoload_psr4.php │ ├── autoload_files.php │ ├── platform_check.php │ ├── LICENSE │ ├── installed.php │ ├── autoload_real.php │ └── installed.json └── autoload.php ├── vendor-prefixed ├── composer │ ├── autoload_namespaces.php │ ├── autoload_files.php │ ├── autoload_psr4.php │ ├── platform_check.php │ ├── LICENSE │ ├── autoload_real.php │ └── installed.json ├── axepress │ └── wp-graphql-plugin-boilerplate │ │ └── src │ │ ├── Interfaces │ │ ├── GraphQLType.php │ │ ├── Registrable.php │ │ ├── TypeWithInterfaces.php │ │ ├── TypeWithInputFields.php │ │ ├── TypeWithFields.php │ │ └── TypeWithConnections.php │ │ ├── Helper │ │ ├── Helper.php │ │ └── Compat.php │ │ ├── Traits │ │ ├── TypeNameTrait.php │ │ └── TypeResolverTrait.php │ │ └── Abstracts │ │ ├── FieldsType.php │ │ ├── InputType.php │ │ ├── EnumType.php │ │ ├── Type.php │ │ ├── UnionType.php │ │ ├── InterfaceType.php │ │ ├── ObjectType.php │ │ ├── ConnectionType.php │ │ └── MutationType.php └── autoload.php ├── activation.php ├── readme.txt ├── docker-compose.yml ├── deactivation.php ├── access-functions.php └── codeception.dist.yml /src/Data/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/Type/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/Utils/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/Connection/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/Mutation/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/Data/Connection/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/Data/Loader/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxeWP/wp-graphql-rank-math/HEAD/assets/header.png -------------------------------------------------------------------------------- /assets/built-with.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxeWP/wp-graphql-rank-math/HEAD/assets/built-with.png -------------------------------------------------------------------------------- /.wordpress-org/banner-772x250.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxeWP/wp-graphql-rank-math/HEAD/.wordpress-org/banner-772x250.png -------------------------------------------------------------------------------- /.wordpress-org/icon-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxeWP/wp-graphql-rank-math/HEAD/.wordpress-org/icon-128x128.png -------------------------------------------------------------------------------- /.wordpress-org/icon-256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxeWP/wp-graphql-rank-math/HEAD/.wordpress-org/icon-256x256.png -------------------------------------------------------------------------------- /.wordpress-org/banner-1544x500.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxeWP/wp-graphql-rank-math/HEAD/.wordpress-org/banner-1544x500.png -------------------------------------------------------------------------------- /.coveralls.yml: -------------------------------------------------------------------------------- 1 | service_name: php-coveralls 2 | coverage_clover: tests/_output/coverage.xml 3 | json_path: tests/_output/coveralls-upload.json 4 | -------------------------------------------------------------------------------- /vendor/composer/autoload_namespaces.php: -------------------------------------------------------------------------------- 1 | array($baseDir . '/src'), 10 | ); 11 | -------------------------------------------------------------------------------- /vendor/composer/autoload_files.php: -------------------------------------------------------------------------------- 1 | $baseDir . '/access-functions.php', 10 | ); 11 | -------------------------------------------------------------------------------- /vendor-prefixed/composer/autoload_files.php: -------------------------------------------------------------------------------- 1 | $baseDir . '/access-functions.php', 10 | ); 11 | -------------------------------------------------------------------------------- /vendor-prefixed/composer/autoload_psr4.php: -------------------------------------------------------------------------------- 1 | array($baseDir . '/src'), 10 | 'AxeWP\\GraphQL\\' => array($vendorDir . '/axepress/wp-graphql-plugin-boilerplate/src'), 11 | ); 12 | -------------------------------------------------------------------------------- /activation.php: -------------------------------------------------------------------------------- 1 | Click here for full changelog. 21 | -------------------------------------------------------------------------------- /vendor-prefixed/axepress/wp-graphql-plugin-boilerplate/src/Interfaces/TypeWithInterfaces.php: -------------------------------------------------------------------------------- 1 | [ 38 | 'type' => 'String', 39 | 'description' => static fn () => __( 'The raw JSON+LD output', 'wp-graphql-rank-math' ), 40 | ], 41 | ]; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /vendor-prefixed/axepress/wp-graphql-plugin-boilerplate/src/Interfaces/TypeWithInputFields.php: -------------------------------------------------------------------------------- 1 | >, 17 | * description: callable(): string, 18 | * defaultValue?:string 19 | * } 20 | */ 21 | interface TypeWithInputFields extends GraphQLType 22 | { 23 | /** 24 | * Gets the input fields for the type. 25 | * 26 | * @return array 27 | */ 28 | public static function get_fields(): array; 29 | } 30 | } -------------------------------------------------------------------------------- /vendor/composer/platform_check.php: -------------------------------------------------------------------------------- 1 | = 70400)) { 8 | $issues[] = 'Your Composer dependencies require a PHP version ">= 7.4.0". You are running ' . PHP_VERSION . '.'; 9 | } 10 | 11 | if ($issues) { 12 | if (!headers_sent()) { 13 | header('HTTP/1.1 500 Internal Server Error'); 14 | } 15 | if (!ini_get('display_errors')) { 16 | if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { 17 | fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); 18 | } elseif (!headers_sent()) { 19 | echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; 20 | } 21 | } 22 | trigger_error( 23 | 'Composer detected issues in your platform: ' . implode(' ', $issues), 24 | E_USER_ERROR 25 | ); 26 | } 27 | -------------------------------------------------------------------------------- /vendor-prefixed/composer/platform_check.php: -------------------------------------------------------------------------------- 1 | = 70400)) { 8 | $issues[] = 'Your Composer dependencies require a PHP version ">= 7.4.0". You are running ' . PHP_VERSION . '.'; 9 | } 10 | 11 | if ($issues) { 12 | if (!headers_sent()) { 13 | header('HTTP/1.1 500 Internal Server Error'); 14 | } 15 | if (!ini_get('display_errors')) { 16 | if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { 17 | fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); 18 | } elseif (!headers_sent()) { 19 | echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; 20 | } 21 | } 22 | trigger_error( 23 | 'Composer detected issues in your platform: ' . implode(' ', $issues), 24 | E_USER_ERROR 25 | ); 26 | } 27 | -------------------------------------------------------------------------------- /src/Modules/Redirection/Fields/GeneralSettings.php: -------------------------------------------------------------------------------- 1 | [ 35 | 'type' => RedirectionSettings::get_type_name(), 36 | 'description' => static fn () => __( 'RankMath SEO redirection settings', 'wp-graphql-rank-math' ), 37 | ], 38 | ]; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /vendor-prefixed/composer/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) Nils Adermann, Jordi Boggiano 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /vendor/composer/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Copyright (c) Nils Adermann, Jordi Boggiano 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is furnished 9 | to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | 22 | -------------------------------------------------------------------------------- /src/Fields/RootQuery.php: -------------------------------------------------------------------------------- 1 | [ 42 | 'type' => Settings::get_type_name(), 43 | 'description' => static fn () => __( 'RankMath SEO site settings', 'wp-graphql-rank-math' ), 44 | 'resolve' => static fn () => new ModelSettings(), 45 | ], 46 | ]; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Type/Enum/KnowledgeGraphTypeEnum.php: -------------------------------------------------------------------------------- 1 | [ 38 | 'description' => static fn () => __( 'Person.', 'wp-graphql-rank-math' ), 39 | 'value' => 'person', 40 | ], 41 | 'COMPANY' => [ 42 | 'description' => static fn () => __( 'Company.', 'wp-graphql-rank-math' ), 43 | 'value' => 'company', 44 | ], 45 | ]; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Type/Enum/RobotsMetaValueEnum.php: -------------------------------------------------------------------------------- 1 | $description ) { 41 | $values[ strtoupper( $name ) ] = [ 42 | 'description' => static fn () => wp_strip_all_tags( $description ), 43 | 'value' => $name, 44 | ]; 45 | } 46 | 47 | return $values; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Type/Enum/SeoScoreTemplateTypeEnum.php: -------------------------------------------------------------------------------- 1 | [ 38 | 'description' => static fn () => __( 'Circle template', 'wp-graphql-rank-math' ), 39 | 'value' => 'circle', 40 | ], 41 | 'SQUARE' => [ 42 | 'description' => static fn () => __( 'Square template', 'wp-graphql-rank-math' ), 43 | 'value' => 'square', 44 | ], 45 | ]; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Type/WPObject/OpenGraph/Video.php: -------------------------------------------------------------------------------- 1 | [ 38 | 'type' => 'String', 39 | 'description' => static fn () => __( 'The URL of the video.', 'wp-graphql-rank-math' ), 40 | ], 41 | 'duration' => [ 42 | 'type' => 'String', 43 | 'description' => static fn () => __( 'The duration of the video.', 'wp-graphql-rank-math' ), 44 | ], 45 | ]; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Type/Enum/OpenGraphProductAvailabilityEnum.php: -------------------------------------------------------------------------------- 1 | [ 38 | 'description' => static fn () => __( 'The product is in stock', 'wp-graphql-rank-math' ), 39 | 'value' => 'instock', 40 | ], 41 | 'OUT_OF_STOCK' => [ 42 | 'description' => static fn () => __( 'The product is out of stock', 'wp-graphql-rank-math' ), 43 | 'value' => '', 44 | ], 45 | ]; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Type/WPObject/OpenGraph/SlackEnhancedData.php: -------------------------------------------------------------------------------- 1 | [ 38 | 'type' => 'String', 39 | 'description' => static fn () => __( 'The Enhanced Data label', 'wp-graphql-rank-math' ), 40 | ], 41 | 'data' => [ 42 | 'type' => 'String', 43 | 'description' => static fn () => __( 'The Enhanced Data', 'wp-graphql-rank-math' ), 44 | ], 45 | ]; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.3' 2 | 3 | services: 4 | app: 5 | depends_on: 6 | - app_db 7 | image: wp-graphql-rankmath:latest-wp${WP_VERSION-6.3}-php${PHP_VERSION-8.2} 8 | volumes: 9 | - '.:/var/www/html/wp-content/plugins/wp-graphql-rank-math' 10 | - './.log/app:/var/log/apache2' 11 | env_file: 12 | - .env 13 | environment: 14 | WP_URL: http://localhost:8091 15 | USING_XDEBUG: ${USING_XDEBUG:-} 16 | ports: 17 | - '8091:80' 18 | networks: 19 | local: 20 | 21 | app_db: 22 | image: mariadb:10 23 | environment: 24 | MYSQL_ROOT_PASSWORD: root 25 | MYSQL_DATABASE: wordpress 26 | MYSQL_USER: wordpress 27 | MYSQL_PASSWORD: wordpress 28 | ports: 29 | - '3306' 30 | networks: 31 | testing: 32 | local: 33 | 34 | testing: 35 | depends_on: 36 | - app_db 37 | image: wp-graphql-rankmath-testing:latest-wp${WP_VERSION-6.3}-php${PHP_VERSION-8.2} 38 | volumes: 39 | - '.:/var/www/html/wp-content/plugins/wp-graphql-rank-math' 40 | - './.log/testing:/var/log/apache2' 41 | env_file: 42 | - .env 43 | environment: 44 | SUITES: ${SUITES:-} 45 | networks: 46 | testing: 47 | 48 | networks: 49 | local: 50 | testing: 51 | -------------------------------------------------------------------------------- /src/Type/WPInterface/MetaSettingWithArchive.php: -------------------------------------------------------------------------------- 1 | [ 38 | 'type' => 'String', 39 | 'description' => static fn () => __( 'Default title tag for archive page.', 'wp-graphql-rank-math' ), 40 | ], 41 | 'archiveDescription' => [ 42 | 'type' => 'String', 43 | 'description' => static fn () => __( 'Description for archive pages.', 'wp-graphql-rank-math' ), 44 | ], 45 | ]; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Type/Enum/ArticleTypeEnum.php: -------------------------------------------------------------------------------- 1 | [ 38 | 'description' => static fn () => __( 'Article.', 'wp-graphql-rank-math' ), 39 | 'value' => 'Article', 40 | ], 41 | 'BLOG_POST' => [ 42 | 'description' => static fn () => __( 'Blog post.', 'wp-graphql-rank-math' ), 43 | 'value' => 'BlogPosting', 44 | ], 45 | 'NEWS_ARTICLE' => [ 46 | 'description' => static fn () => __( 'News article.', 'wp-graphql-rank-math' ), 47 | 'value' => 'NewsArticle', 48 | ], 49 | ]; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Type/Enum/OpenGraphLocaleEnum.php: -------------------------------------------------------------------------------- 1 | static fn () => sprintf( __( '%s.', 'wp-graphql-rank-math' ), $locale ), 46 | 'value' => $locale, 47 | ]; 48 | } 49 | 50 | return $values; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Modules/Redirection/Type/Enum/RedirectionTypeEnum.php: -------------------------------------------------------------------------------- 1 | $description ) { 43 | $values[ WPEnumType::get_safe_name( 'REDIRECT_' . (string) $value ) ] = [ 44 | 'description' => static fn () => $description, 45 | 'value' => $value, 46 | ]; 47 | } 48 | 49 | return $values; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Type/Enum/BulkEditingTypeEnum.php: -------------------------------------------------------------------------------- 1 | [ 38 | 'description' => static fn () => __( 'Disabled.', 'wp-graphql-rank-math' ), 39 | 'value' => '0', 40 | ], 41 | 'ENABLED' => [ 42 | 'description' => static fn () => __( 'Enabled.', 'wp-graphql-rank-math' ), 43 | 'value' => 'editing', 44 | ], 45 | 'READ_ONLY' => [ 46 | 'description' => static fn () => __( 'Read only.', 'wp-graphql-rank-math' ), 47 | 'value' => 'readonly', 48 | ], 49 | ]; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /vendor/composer/installed.php: -------------------------------------------------------------------------------- 1 | array( 3 | 'name' => 'axepress/wp-graphql-rank-math', 4 | 'pretty_version' => 'dev-develop', 5 | 'version' => 'dev-develop', 6 | 'reference' => '4ed02ae44ecdf072a0467273d60861de2c44ec4a', 7 | 'type' => 'wordpress-plugin', 8 | 'install_path' => __DIR__ . '/../../', 9 | 'aliases' => array(), 10 | 'dev' => false, 11 | ), 12 | 'versions' => array( 13 | 'axepress/wp-graphql-plugin-boilerplate' => array( 14 | 'pretty_version' => '0.1.1', 15 | 'version' => '0.1.1.0', 16 | 'reference' => '09495b61346453baabdf4c71a38ada3cfc91c3a7', 17 | 'type' => 'library', 18 | 'install_path' => __DIR__ . '/../axepress/wp-graphql-plugin-boilerplate', 19 | 'aliases' => array(), 20 | 'dev_requirement' => false, 21 | ), 22 | 'axepress/wp-graphql-rank-math' => array( 23 | 'pretty_version' => 'dev-develop', 24 | 'version' => 'dev-develop', 25 | 'reference' => '4ed02ae44ecdf072a0467273d60861de2c44ec4a', 26 | 'type' => 'wordpress-plugin', 27 | 'install_path' => __DIR__ . '/../../', 28 | 'aliases' => array(), 29 | 'dev_requirement' => false, 30 | ), 31 | ), 32 | ); 33 | -------------------------------------------------------------------------------- /src/Modules/Redirection/Type/Enum/RedirectionComparisonTypeEnum.php: -------------------------------------------------------------------------------- 1 | $description ) { 43 | $values[ WPEnumType::get_safe_name( $value ) ] = [ 44 | 'description' => static fn () => $description, 45 | 'value' => $value, 46 | ]; 47 | } 48 | 49 | return $values; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Type/Enum/ImagePreviewSizeEnum.php: -------------------------------------------------------------------------------- 1 | [ 38 | 'description' => static fn () => __( 'Large', 'wp-graphql-rank-math' ), 39 | 'value' => 'large', 40 | ], 41 | 'STANDARD' => [ 42 | 'description' => static fn () => __( 'Standard.', 'wp-graphql-rank-math' ), 43 | 'value' => 'standard', 44 | ], 45 | 'NONE' => [ 46 | 'description' => static fn () => __( 'Prevents search engines from following links on the pages', 'wp-graphql-rank-math' ), 47 | 'value' => 'none', 48 | ], 49 | ]; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Type/WPObject/OpenGraph/TwitterApp.php: -------------------------------------------------------------------------------- 1 | [ 38 | 'type' => 'String', 39 | 'description' => static fn () => __( 'The name of the Twitter app.', 'wp-graphql-rank-math' ), 40 | ], 41 | 'id' => [ 42 | 'type' => 'ID', 43 | 'description' => static fn () => __( 'The App ID .', 'wp-graphql-rank-math' ), 44 | ], 45 | 'url' => [ 46 | 'type' => 'String', 47 | 'description' => static fn () => __( 'Your app\’s custom URL scheme.', 'wp-graphql-rank-math' ), 48 | ], 49 | ]; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Modules/Redirection/Type/Enum/RedirectionStatusEnum.php: -------------------------------------------------------------------------------- 1 | [ 39 | 'description' => static fn () => __( 'Active.', 'wp-graphql-rank-math' ), 40 | 'value' => 'active', 41 | ], 42 | 'INACTIVE' => [ 43 | 'description' => static fn () => __( 'Inactive.', 'wp-graphql-rank-math' ), 44 | 'value' => 'inactive', 45 | ], 46 | 'TRASH' => [ 47 | 'description' => static fn () => __( 'Trashed.', 'wp-graphql-rank-math' ), 48 | 'value' => 'trash', 49 | ], 50 | ]; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Type/WPObject/Breadcrumbs.php: -------------------------------------------------------------------------------- 1 | [ 38 | 'type' => 'String', 39 | 'description' => static fn () => __( 'The text for the given breadcrumb', 'wp-graphql-rank-math' ), 40 | ], 41 | 'url' => [ 42 | 'type' => 'String', 43 | 'description' => static fn () => __( 'The url for the given breadcrumb', 'wp-graphql-rank-math' ), 44 | ], 45 | 'isHidden' => [ 46 | 'type' => 'Boolean', 47 | 'description' => static fn () => __( 'Whether the given breadcrumb is hidden from the schema', 'wp-graphql-rank-math' ), 48 | ], 49 | ]; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Modules/Redirection/Type/Enum/RedirectionBehaviorEnum.php: -------------------------------------------------------------------------------- 1 | [ 38 | 'description' => static fn () => __( 'Redirect to default 404.', 'wp-graphql-rank-math' ), 39 | 'value' => 'default', 40 | ], 41 | 'HOMEPAGE' => [ 42 | 'description' => static fn () => __( 'Redirect to Home page.', 'wp-graphql-rank-math' ), 43 | 'value' => 'homepage', 44 | ], 45 | 'CUSTOM' => [ 46 | 'description' => static fn () => __( 'Redirect to custom URL.', 'wp-graphql-rank-math' ), 47 | 'value' => 'custom', 48 | ], 49 | ]; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Extensions/WPGraphQLWooCommerce/WPGraphQLWooCommerce.php: -------------------------------------------------------------------------------- 1 | [ 38 | 'description' => static fn () => __( 'Unknown score.', 'wp-graphql-rank-math' ), 39 | 'value' => 'unknown', 40 | ], 41 | 'BAD' => [ 42 | 'description' => static fn () => __( 'Bad ( < 50 ) score', 'wp-graphql-rank-math' ), 43 | 'value' => 'bad', 44 | ], 45 | 'GOOD' => [ 46 | 'description' => static fn () => __( 'Good (50-79) score', 'wp-graphql-rank-math' ), 47 | 'value' => 'good', 48 | ], 49 | 'GREAT' => [ 50 | 'description' => static fn () => __( 'Great ( > 80 ) score', 'wp-graphql-rank-math' ), 51 | 'value' => 'great', 52 | ], 53 | ]; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /vendor-prefixed/axepress/wp-graphql-plugin-boilerplate/src/Helper/Helper.php: -------------------------------------------------------------------------------- 1 | [ 40 | 'type' => AdvancedRobotsMeta::get_type_name(), 41 | 'description' => static fn () => __( 'Advanced robots meta tag settings.', 'wp-graphql-rank-math' ), 42 | ], 43 | 'robotsMeta' => [ 44 | 'type' => [ 'list_of' => RobotsMetaValueEnum::get_type_name() ], 45 | 'description' => static fn () => __( 'Custom values for robots meta tag.', 'wp-graphql-rank-math' ), 46 | ], 47 | ]; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/CoreSchemaFilters.php: -------------------------------------------------------------------------------- 1 | [ 40 | 'type' => RedirectionConnectionOrderByEnum::get_type_name(), 41 | 'description' => static fn () => __( 'The field to order the results by.', 'wp-graphql-rank-math' ), 42 | ], 43 | 'order' => [ 44 | 'type' => 'OrderEnum', 45 | 'description' => static fn () => __( 'The ordering direction.', 'wp-graphql-rank-math' ), 46 | ], 47 | ]; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Type/Enum/SeoScorePositionEnum.php: -------------------------------------------------------------------------------- 1 | [ 38 | 'description' => static fn () => __( 'Below content', 'wp-graphql-rank-math' ), 39 | 'value' => 'bottom', 40 | ], 41 | 'TOP' => [ 42 | 'description' => static fn () => __( 'Above content', 'wp-graphql-rank-math' ), 43 | 'value' => 'top', 44 | ], 45 | 'BOTH' => [ 46 | 'description' => static fn () => __( 'Above & below content', 'wp-graphql-rank-math' ), 47 | 'value' => 'both', 48 | ], 49 | 'CUSTOM' => [ 50 | 'description' => static fn () => __( 'Custom (use shortcode)', 'wp-graphql-rank-math' ), 51 | 'value' => 'custom', 52 | ], 53 | ]; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Type/WPObject/Settings.php: -------------------------------------------------------------------------------- 1 | [ 41 | 'type' => General::get_type_name(), 42 | 'description' => static fn () => __( 'General settings.', 'wp-graphql-rank-math' ), 43 | ], 44 | 'meta' => [ 45 | 'type' => Meta::get_type_name(), 46 | 'description' => static fn () => __( 'Meta settings.', 'wp-graphql-rank-math' ), 47 | ], 48 | 'sitemap' => [ 49 | 'type' => Sitemap::get_type_name(), 50 | 'description' => static fn () => __( 'Sitemap settings.', 'wp-graphql-rank-math' ), 51 | ], 52 | ]; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /vendor-prefixed/axepress/wp-graphql-plugin-boilerplate/src/Interfaces/TypeWithFields.php: -------------------------------------------------------------------------------- 1 | >, 19 | * description:callable(): string, 20 | * defaultValue?:mixed 21 | * } 22 | * 23 | * @phpstan-type FieldConfig array{ 24 | * type:string|array>, 25 | * description:callable(): string, 26 | * args?:array, 27 | * resolve?:callable, 28 | * deprecationReason?:callable(): string, 29 | * } 30 | * 31 | * phpcs:enable SlevomatCodingStandard.Namespaces.FullyQualifiedClassNameInAnnotation 32 | */ 33 | interface TypeWithFields extends GraphQLType 34 | { 35 | /** 36 | * Gets the fields for the type. 37 | * 38 | * @return array 39 | */ 40 | public static function get_fields(): array; 41 | } 42 | } -------------------------------------------------------------------------------- /deactivation.php: -------------------------------------------------------------------------------- 1 | get_settings_fields(); 50 | 51 | // Loop over the registered settings fields and delete the options. 52 | if ( ! empty( $fields ) && is_array( $fields ) ) { 53 | foreach ( $fields as $group => $fields ) { 54 | delete_option( $group ); 55 | } 56 | } 57 | 58 | do_action( 'graphql_seo_delete_data' ); 59 | } 60 | -------------------------------------------------------------------------------- /src/Type/Enum/TwitterCardTypeEnum.php: -------------------------------------------------------------------------------- 1 | [ 38 | 'description' => static fn () => __( 'Summary Card.', 'wp-graphql-rank-math' ), 39 | 'value' => 'summary_card', 40 | ], 41 | 'SUMMARY_LARGE_IMAGE' => [ 42 | 'description' => static fn () => __( 'Summary Card with Large Image.', 'wp-graphql-rank-math' ), 43 | 'value' => 'summary_large_image', 44 | ], 45 | 'APP' => [ 46 | 'description' => static fn () => __( 'The twitter App card', 'wp-graphql-rank-math' ), 47 | 'value' => 'app', 48 | ], 49 | 'PLAYER' => [ 50 | 'description' => static fn () => __( 'The twitter Player card', 'wp-graphql-rank-math' ), 51 | 'value' => 'player', 52 | ], 53 | ]; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Type/WPObject/Settings/Meta/DateArchiveMeta.php: -------------------------------------------------------------------------------- 1 | [ 51 | 'type' => 'Boolean', 52 | 'description' => static fn () => __( 'Whether archives are enabled.', 'wp-graphql-rank-math' ), 53 | ], 54 | ]; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /vendor-prefixed/axepress/wp-graphql-plugin-boilerplate/src/Interfaces/TypeWithConnections.php: -------------------------------------------------------------------------------- 1 | >, 19 | * description: callable(): string, 20 | * defaultValue?: mixed 21 | * } 22 | * 23 | * @phpstan-type ConnectionConfig array{ 24 | * toType: string, 25 | * description: callable():string, 26 | * args?: array, 27 | * connectionInterfaces?: string[], 28 | * oneToOne?: bool, 29 | * resolve?: callable 30 | * } 31 | * 32 | * phpcs:enable SlevomatCodingStandard.Namespaces.FullyQualifiedClassNameInAnnotation 33 | */ 34 | interface TypeWithConnections extends GraphQLType 35 | { 36 | /** 37 | * Gets the properties for the type. 38 | * 39 | * @return array 40 | */ 41 | public static function get_connections(): array; 42 | } 43 | } -------------------------------------------------------------------------------- /src/Type/Enum/SnippetTypeEnum.php: -------------------------------------------------------------------------------- 1 | [ 41 | 'description' => static fn () => __( 'Local Business', 'wp-graphql-rank-math' ), 42 | 'value' => 'LocalBusiness', 43 | ], 44 | ]; 45 | 46 | foreach ( $types as $name => $description ) { 47 | $values[ strtoupper( $name ) ] = [ 48 | 'description' => static fn () => $description, 49 | 'value' => $name, 50 | ]; 51 | } 52 | 53 | if ( class_exists( 'WooCommerce' ) || class_exists( 'Easy_Digital_Downloads' ) ) { 54 | $values['PRODUCT'] = [ 55 | 'description' => static fn () => __( 'Product.', 'wp-graphql-rank-math' ), 56 | 'value' => 'product', 57 | ]; 58 | } 59 | 60 | return $values; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/Type/WPObject/SeoScore.php: -------------------------------------------------------------------------------- 1 | [ 39 | 'type' => 'String', 40 | 'description' => static fn () => __( 'The html output for the Frontend SEO badge', 'wp-graphql-rank-math' ), 41 | ], 42 | 'hasFrontendScore' => [ 43 | 'type' => 'Boolean', 44 | 'description' => static fn () => __( 'Whether the SEO score should be displayed on the frontend', 'wp-graphql-rank-math' ), 45 | ], 46 | 'score' => [ 47 | 'type' => 'Integer', 48 | 'description' => static fn () => __( 'The SEO score', 'wp-graphql-rank-math' ), 49 | ], 50 | 'rating' => [ 51 | 'type' => SeoRatingEnum::get_type_name(), 52 | 'description' => static fn () => __( 'The SEO score', 'wp-graphql-rank-math' ), 53 | ], 54 | ]; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Modules/Redirection/Type/WPObject/RedirectionSource.php: -------------------------------------------------------------------------------- 1 | [ 40 | 'type' => 'String', 41 | 'description' => static fn () => __( 'The ignore flag to use when matching the pattern.', 'wp-graphql-rank-math' ), 42 | ], 43 | 'pattern' => [ 44 | 'type' => 'String', 45 | 'description' => static fn () => __( 'The pattern to match.', 'wp-graphql-rank-math' ), 46 | ], 47 | 'comparison' => [ 48 | 'type' => RedirectionComparisonTypeEnum::get_type_name(), 49 | 'description' => static fn () => __( 'The comparison type to use when matching the pattern.', 'wp-graphql-rank-math' ), 50 | ], 51 | ]; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /vendor-prefixed/axepress/wp-graphql-plugin-boilerplate/src/Traits/TypeNameTrait.php: -------------------------------------------------------------------------------- 1 | [ 38 | 'type' => 'ID', 39 | 'description' => static fn () => __( 'The Facebook app ID associated with this resource', 'wp-graphql-rank-math' ), 40 | 'resolve' => static fn ( $source ): ?string => ! empty( $source['app_id'] ) ? (string) $source['app_id'] : null, 41 | ], 42 | 'admins' => [ 43 | 'type' => [ 'list_of' => 'String' ], 44 | 'description' => static fn () => __( 'The Facebook admins associated with this resource', 'wp-graphql-rank-math' ), 45 | 'resolve' => static function ( $source ): ?array { 46 | $value = ! empty( $source['admins'] ) ? $source['admins'] : null; 47 | 48 | if ( empty( $value ) ) { 49 | return null; 50 | } 51 | 52 | if ( ! is_array( $value ) ) { 53 | $value = [ (string) $value ]; 54 | } 55 | 56 | // Ensure all tags are strings. 57 | $value = array_map( 'strval', $value ); 58 | 59 | return $value; 60 | }, 61 | ], 62 | ]; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /vendor-prefixed/axepress/wp-graphql-plugin-boilerplate/src/Traits/TypeResolverTrait.php: -------------------------------------------------------------------------------- 1 | get_type($type_name); 38 | }; 39 | } 40 | /** 41 | * Gets the name of the GraphQL type to that the interface/union resolves to. 42 | * 43 | * @param mixed $value The value from the resolver of the parent field. 44 | */ 45 | abstract public static function get_resolved_type_name($value): ?string; 46 | } 47 | } -------------------------------------------------------------------------------- /vendor-prefixed/axepress/wp-graphql-plugin-boilerplate/src/Abstracts/FieldsType.php: -------------------------------------------------------------------------------- 1 | 2.3.0 is required. */ 42 | $config = ['fields' => static::get_fields()]; 43 | $config = Compat::resolve_graphql_config($config); 44 | register_graphql_fields(static::get_type_name(), $config['fields'] ?? []); 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /src/Type/WPObject/OpenGraph/Image.php: -------------------------------------------------------------------------------- 1 | [ 38 | 'type' => 'String', 39 | 'description' => static fn () => __( 'URL for the image.', 'wp-graphql-rank-math' ), 40 | ], 41 | 'secureUrl' => [ 42 | 'type' => 'String', 43 | 'description' => static fn () => __( 'The https:// URL for the image.', 'wp-graphql-rank-math' ), 44 | 'resolve' => static fn ( $source ): ?string => ! empty( $source['secure_url'] ) ? (string) $source['secure_url'] : null, 45 | ], 46 | 'type' => [ 47 | 'type' => 'String', // @todo 48 | 'description' => static fn () => __( 'MIME type of the image. ', 'wp-graphql-rank-math' ), 49 | ], 50 | 'width' => [ 51 | 'type' => 'Float', 52 | 'description' => static fn () => __( 'Width of image in pixels.', 'wp-graphql-rank-math' ), 53 | ], 54 | 'height' => [ 55 | 'type' => 'Float', 56 | 'description' => static fn () => __( 'Height of image in pixels. ', 'wp-graphql-rank-math' ), 57 | ], 58 | 59 | ]; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/Modules/Redirection/Fields/RootQuery.php: -------------------------------------------------------------------------------- 1 | [ 47 | 'type' => Redirection::get_type_name(), 48 | 'args' => [ 49 | 'id' => [ 50 | 'type' => 'ID', 51 | 'description' => static fn () => __( 'The ID of the redirection. Accepts either a global or database ID.', 'wp-graphql-rank-math' ), 52 | ], 53 | ], 54 | 'description' => static fn () => __( 'RankMath SEO redirection', 'wp-graphql-rank-math' ), 55 | 'resolve' => static function ( $source, array $args, AppContext $context ) { 56 | $database_id = Utils::get_database_id_from_id( $args['id'] ); 57 | 58 | return ! empty( $database_id ) ? $context->get_loader( RedirectionsLoader::$name )->load( $database_id ) : null; 59 | }, 60 | ], 61 | ]; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /vendor/composer/autoload_real.php: -------------------------------------------------------------------------------- 1 | register(true); 35 | 36 | $filesToLoad = \Composer\Autoload\ComposerStaticInit52c774cabe83db5bf865195d7b3794c8::$files; 37 | $requireFile = \Closure::bind(static function ($fileIdentifier, $file) { 38 | if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { 39 | $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; 40 | 41 | require $file; 42 | } 43 | }, null, null); 44 | foreach ($filesToLoad as $fileIdentifier => $file) { 45 | $requireFile($fileIdentifier, $file); 46 | } 47 | 48 | return $loader; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Modules/Redirection/Data/Loader/RedirectionsLoader.php: -------------------------------------------------------------------------------- 1 | where( 'id', 'IN', $keys )->get( ARRAY_A ); 48 | 49 | $loaded = []; 50 | 51 | foreach ( $keys as $key ) { 52 | $index = array_search( $key, array_column( $redirections, 'id' ) ); // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict -- @todo remove this once we can investigate the strict type. 53 | if ( ! isset( $redirections[ $index ] ) ) { 54 | throw new UserError( 55 | sprintf( 56 | // translators: %s is the redirection ID. 57 | esc_html__( 'Redirection with ID "%s" does not exist.', 'wp-graphql-rank-math' ), 58 | esc_html( (string) $key ) 59 | ), 60 | ); 61 | } 62 | 63 | $loaded[ $key ] = $redirections[ $index ]; 64 | } 65 | 66 | return $loaded; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/Type/WPObject/Settings/Meta/LocalMeta.php: -------------------------------------------------------------------------------- 1 | [ 40 | 'type' => KnowledgeGraphTypeEnum::get_type_name(), 41 | 'description' => static fn () => __( 'Whether the site represents a person or an organization.', 'wp-graphql-rank-math' ), 42 | ], 43 | 'name' => [ 44 | 'type' => 'String', 45 | 'description' => static fn () => __( 'Your name or company name to be used in Google\'s Knowledge Graph', 'wp-graphql-rank-math' ), 46 | ], 47 | 'logo' => [ 48 | 'type' => 'MediaItem', 49 | 'description' => static fn () => __( 'The logo to be used in the Google\'s Knowledge Graph.', 'wp-graphql-rank-math' ), 50 | 'resolve' => static function ( $source, array $args, AppContext $context ) { 51 | return ! empty( $source['logoId'] ) ? $context->get_loader( 'post' )->load_deferred( $source['logoId'] ) : null; 52 | }, 53 | ], 54 | 'url' => [ 55 | 'type' => 'String', 56 | 'description' => static fn () => __( 'URL of the item.', 'wp-graphql-rank-math' ), 57 | ], 58 | ]; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Admin/Settings/Settings.php: -------------------------------------------------------------------------------- 1 | register_fields( 57 | self::$section_name, 58 | [ 59 | [ 60 | 'name' => 'delete_data_on_deactivate', 61 | 'label' => __( 'Delete Data on Deactivation', 'wp-graphql-rank-math' ), 62 | 'desc' => __( 'Delete settings and any other data stored by WPGraphQL for Rank Math upon de-activation of the plugin. Un-checking this will keep data after the plugin is de-activated.', 'wp-graphql-rank-math' ), 63 | 'type' => 'checkbox', 64 | 'default' => 'on', 65 | ], 66 | ] 67 | ); 68 | 69 | $settings_api->admin_init(); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /access-functions.php: -------------------------------------------------------------------------------- 1 | [ 39 | 'type' => 'String', 40 | 'description' => static fn () => __( 'The brand of the product.', 'wp-graphql-rank-math' ), 41 | ], 42 | 'price' => [ 43 | 'type' => 'Float', 44 | 'description' => static fn () => __( 'The price of the object', 'wp-graphql-rank-math' ), 45 | 'resolve' => static function ( $source ): ?float { 46 | return ! empty( $source['price']['amount'] ) ? (float) $source['price']['amount'] : null; 47 | }, 48 | ], 49 | 'currency' => [ 50 | 'type' => 'String', 51 | 'description' => static fn () => __( 'The currency of the object price.', 'wp-graphql-rank-math' ), 52 | 'resolve' => static function ( $source ): ?string { 53 | return ! empty( $source['price']['currency'] ) ? (string) $source['price']['currency'] : null; 54 | }, 55 | ], 56 | 'availability' => [ 57 | 'type' => OpenGraphProductAvailabilityEnum::get_type_name(), 58 | 'description' => static fn () => __( 'The currency of the object price.', 'wp-graphql-rank-math' ), 59 | ], 60 | 61 | ]; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/Type/WPObject/Settings/General/Webmaster.php: -------------------------------------------------------------------------------- 1 | [ 38 | 'type' => 'String', 39 | 'description' => static fn () => __( 'The Baidu Webmaster Tools verification HTML code or ID.', 'wp-graphql-rank-math' ), 40 | ], 41 | 'bing' => [ 42 | 'type' => 'String', 43 | 'description' => static fn () => __( 'The Bing Webmaster Tools verification HTML code or ID.', 'wp-graphql-rank-math' ), 44 | ], 45 | 'google' => [ 46 | 'type' => 'String', 47 | 'description' => static fn () => __( 'The Google Search Console verification HTML code or ID.', 'wp-graphql-rank-math' ), 48 | ], 49 | 'norton' => [ 50 | 'type' => 'String', 51 | 'description' => static fn () => __( 'The Norton Safe Web verification HTML code or ID.', 'wp-graphql-rank-math' ), 52 | ], 53 | 'pinterest' => [ 54 | 'type' => 'String', 55 | 'description' => static fn () => __( 'The Pinterest verification HTML code or ID.', 'wp-graphql-rank-math' ), 56 | ], 57 | 'yandex' => [ 58 | 'type' => 'String', 59 | 'description' => static fn () => __( 'The Yandex verification HTML code or ID.', 'wp-graphql-rank-math' ), 60 | ], 61 | ]; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /vendor-prefixed/axepress/wp-graphql-plugin-boilerplate/src/Abstracts/InputType.php: -------------------------------------------------------------------------------- 1 | , 25 | * } 26 | * 27 | * @extends \WPGraphQL\RankMath\Vendor\AxeWP\GraphQL\Abstracts\Type 28 | * 29 | * phpcs:enable SlevomatCodingStandard.Namespaces.FullyQualifiedClassNameInAnnotation 30 | */ 31 | abstract class InputType extends Type implements TypeWithInputFields 32 | { 33 | /** 34 | * {@inheritDoc} 35 | */ 36 | public static function register(): void 37 | { 38 | /** @todo remove when WPGraphQL > 2.3.0 is required. */ 39 | $config = Compat::resolve_graphql_config(static::get_type_config()); 40 | register_graphql_input_type(static::get_type_name(), $config); 41 | } 42 | /** 43 | * {@inheritDoc} 44 | * 45 | * @return InputTypeConfig 46 | */ 47 | protected static function get_type_config(): array 48 | { 49 | $config = parent::get_type_config(); 50 | $config['fields'] = static::get_fields(); 51 | return $config; 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /vendor-prefixed/composer/autoload_real.php: -------------------------------------------------------------------------------- 1 | setClassMapAuthoritative(true); 35 | $loader->register(true); 36 | 37 | $filesToLoad = \WPGraphQL\RankMath\Vendor\Composer\Autoload\ComposerStaticInitbf31fcfbd71f02b8733e2b41ad240ef3::$files; 38 | $requireFile = \Closure::bind(static function ($fileIdentifier, $file) { 39 | if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { 40 | $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; 41 | 42 | require $file; 43 | } 44 | }, null, null); 45 | foreach ($filesToLoad as $fileIdentifier => $file) { 46 | $requireFile($fileIdentifier, $file); 47 | } 48 | 49 | return $loader; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Type/WPObject/Settings/General/FrontendSeoScore.php: -------------------------------------------------------------------------------- 1 | [ 40 | 'type' => [ 'list_of' => 'ContentTypeEnum' ], 41 | 'description' => static fn () => __( 'The list of post types which should display the calculated SEO score.', 'wp-graphql-rank-math' ), 42 | ], 43 | 'template' => [ 44 | 'type' => SeoScoreTemplateTypeEnum::get_type_name(), 45 | 'description' => static fn () => __( 'The list of post types which should display the calculated SEO score.', 'wp-graphql-rank-math' ), 46 | ], 47 | 'position' => [ 48 | 'type' => SeoScorePositionEnum::get_type_name(), 49 | 'description' => static fn () => __( 'Where the SEO score badges should be displayed automatically, or if the `[rank_math_seo_score]` shortcode is used instead.', 'wp-graphql-rank-math' ), 50 | ], 51 | 'hasRankMathBacklink' => [ 52 | 'type' => 'Boolean', 53 | 'description' => static fn () => __( 'Whether to insert a backlink to RankMath.com to show your support, if you are showing the SEO scores on the front end.', 'wp-graphql-rank-math' ), 54 | ], 55 | ]; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Type/WPObject/Settings/Meta/SocialMeta.php: -------------------------------------------------------------------------------- 1 | [ 38 | 'type' => 'String', 39 | 'description' => static fn () => __( 'The complete Facebook page URL.', 'wp-graphql-rank-math' ), 40 | ], 41 | 'facebookAuthorUrl' => [ 42 | 'type' => 'String', 43 | 'description' => static fn () => __( 'The personal Facebook profile URL used to show authorship when articles are shared on Facebook.', 'wp-graphql-rank-math' ), 44 | ], 45 | 'facebookAdminId' => [ 46 | 'type' => [ 'list_of' => 'Int' ], 47 | 'description' => static fn () => __( 'A list of numeric Facebook admin User Ids.', 'wp-graphql-rank-math' ), 48 | ], 49 | 'facebookAppId' => [ 50 | 'type' => 'Int', 51 | 'description' => static fn () => __( 'The facebook Facebook app ID.', 'wp-graphql-rank-math' ), 52 | ], 53 | 'twitterAuthorName' => [ 54 | 'type' => 'String', 55 | 'description' => static fn () => __( 'Twitter Username of the auther used in the `twitter:creater` tag.', 'wp-graphql-rank-math' ), 56 | ], 57 | 'additionalProfiles' => [ 58 | 'type' => [ 'list_of' => 'String' ], 59 | 'description' => static fn () => __( 'Additional social profile URLs to add to the sameAs property for the Organization Schema.', 'wp-graphql-rank-math' ), 60 | ], 61 | ]; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/Modules/Redirection/Type/WPObject/RedirectionSettings.php: -------------------------------------------------------------------------------- 1 | [ 41 | 'type' => RedirectionBehaviorEnum::get_type_name(), 42 | 'description' => static fn () => __( 'The fallback redirection behavior', 'wp-graphql-rank-math' ), 43 | ], 44 | 'fallbackCustomUrl' => [ 45 | 'type' => 'String', 46 | 'description' => static fn () => __( 'The custom redirection URL to use as a fallback. Only set if `fallbackBehavior` is `CUSTOM`.', 'wp-graphql-rank-math' ), 47 | ], 48 | 'hasAutoPostRedirect' => [ 49 | 'type' => 'Boolean', 50 | 'description' => static fn () => __( 'Whether the auto post redirection is enabled.', 'wp-graphql-rank-math' ), 51 | ], 52 | 'hasDebug' => [ 53 | 'type' => 'Boolean', 54 | 'description' => static fn () => __( 'Whether the redirection Debug console is enabled.', 'wp-graphql-rank-math' ), 55 | ], 56 | 'redirectionType' => [ 57 | 'type' => RedirectionTypeEnum::get_type_name(), 58 | 'description' => static fn () => __( 'The redirection type.', 'wp-graphql-rank-math' ), 59 | ], 60 | ]; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /vendor-prefixed/axepress/wp-graphql-plugin-boilerplate/src/Abstracts/EnumType.php: -------------------------------------------------------------------------------- 1 | , 28 | * } 29 | * 30 | * @extends \WPGraphQL\RankMath\Vendor\AxeWP\GraphQL\Abstracts\Type 31 | * 32 | * phpcs:enable SlevomatCodingStandard.Namespaces.FullyQualifiedClassNameInAnnotation 33 | */ 34 | abstract class EnumType extends Type 35 | { 36 | /** 37 | * Gets the Enum values configuration array. 38 | * 39 | * @return array 40 | */ 41 | abstract public static function get_values(): array; 42 | /** 43 | * {@inheritDoc} 44 | */ 45 | public static function register(): void 46 | { 47 | /** @todo remove when WPGraphQL > 2.3.0 is required. */ 48 | $config = Compat::resolve_graphql_config(static::get_type_config()); 49 | register_graphql_enum_type(static::get_type_name(), $config); 50 | } 51 | /** 52 | * {@inheritDoc} 53 | * 54 | * @return EnumTypeConfig 55 | */ 56 | protected static function get_type_config(): array 57 | { 58 | $config = parent::get_type_config(); 59 | $config['values'] = static::get_values(); 60 | return $config; 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /vendor-prefixed/axepress/wp-graphql-plugin-boilerplate/src/Abstracts/Type.php: -------------------------------------------------------------------------------- 1 | static fn(): string => static::get_description(), 'eagerlyLoadType' => static::should_load_eagerly()]; 51 | } 52 | /** 53 | * Whether the type should be loaded eagerly by WPGraphQL. Defaults to false. 54 | * 55 | * Eager load should only be necessary for types that are not referenced directly (e.g. in Unions, Interfaces ). 56 | */ 57 | public static function should_load_eagerly(): bool 58 | { 59 | return false; 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /src/Type/WPObject/AdvancedRobotsMeta.php: -------------------------------------------------------------------------------- 1 | [ 39 | 'type' => 'Boolean', 40 | 'description' => static fn () => __( 'Whether to specify a maximum text length of a snippet of your page', 'wp-graphql-rank-math' ), 41 | ], 42 | 'snippetLength' => [ 43 | 'type' => 'Int', 44 | 'description' => static fn () => __( 'The maximum text length (in characters) of the snippet. -1 for no limit.', 'wp-graphql-rank-math' ), 45 | ], 46 | 'hasVideoPreview' => [ 47 | 'type' => 'Boolean', 48 | 'description' => static fn () => __( 'Whether to specify a maximum duration of an animated video preview.', 'wp-graphql-rank-math' ), 49 | ], 50 | 'videoDuration' => [ 51 | 'type' => 'Int', 52 | 'description' => static fn () => __( 'The maximum duration (seconds characters) of the snippet. -1 for no limit.', 'wp-graphql-rank-math' ), 53 | ], 54 | 'hasImagePreview' => [ 55 | 'type' => 'Boolean', 56 | 'description' => static fn () => __( 'Whether to specify a maximum size of image preview to be shown for images on the page.', 'wp-graphql-rank-math' ), 57 | ], 58 | 'imagePreviewSize' => [ 59 | 'type' => ImagePreviewSizeEnum::get_type_name(), 60 | 'description' => static fn () => __( 'The maximum size of image preview to be shown for images.', 'wp-graphql-rank-math' ), 61 | ], 62 | ]; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/Modules/Redirection/Type/Enum/RedirectionConnectionOrderByEnum.php: -------------------------------------------------------------------------------- 1 | [ 39 | 'description' => static fn () => __( 'Order by the database ID.', 'wp-graphql-rank-math' ), 40 | 'value' => 'id', 41 | ], 42 | 'DATE_CREATED' => [ 43 | 'description' => static fn () => __( 'Order by the date created.', 'wp-graphql-rank-math' ), 44 | 'value' => 'created', 45 | ], 46 | 'DATE_LAST_ACCESSED' => [ 47 | 'description' => static fn () => __( 'Order by the date last accessed.', 'wp-graphql-rank-math' ), 48 | 'value' => 'last_accessed', 49 | ], 50 | 'DATE_UPDATED' => [ 51 | 'description' => static fn () => __( 'Order by the date created.', 'wp-graphql-rank-math' ), 52 | 'value' => 'created', 53 | ], 54 | 'HITS' => [ 55 | 'description' => static fn () => __( 'Order by the number of hits.', 'wp-graphql-rank-math' ), 56 | 'value' => 'hits', 57 | ], 58 | 'REDIRECT_TO_URL' => [ 59 | 'description' => static fn () => __( 'Order by the Redirect To URL', 'wp-graphql-rank-math' ), 60 | 'value' => 'url_to', 61 | ], 62 | 'TYPE' => [ 63 | 'description' => static fn () => __( 'Order by the redirection type (HTTP status code).', 'wp-graphql-rank-math' ), 64 | 'value' => 'header_code', 65 | ], 66 | ]; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/Type/WPInterface/ContentNodeSeo.php: -------------------------------------------------------------------------------- 1 | [ 55 | 'type' => 'Boolean', 56 | 'description' => static fn () => __( 'Whether the item is considered pillar (cornerstone) content', 'wp-graphql-rank-math' ), 57 | ], 58 | 'seoScore' => [ 59 | 'type' => SeoScore::get_type_name(), 60 | 'description' => static fn () => __( 'The SEO score', 'wp-graphql-rank-math' ), 61 | ], 62 | ]; 63 | } 64 | 65 | /** 66 | * {@inheritDoc} 67 | */ 68 | public static function get_interfaces(): array { 69 | return [ Seo::get_type_name() ]; 70 | } 71 | 72 | /** 73 | * {@inheritDoc} 74 | * 75 | * @param \WPGraphQL\Model\Model $value The model. 76 | */ 77 | public static function get_resolved_type_name( $value ): ?string { 78 | $type_name = null; 79 | 80 | if ( isset( $value->post_type ) ) { 81 | $type_name = 'RankMath' . graphql_format_type_name( $value->post_type . 'ObjectSeo' ); 82 | } 83 | 84 | return $type_name; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /vendor-prefixed/axepress/wp-graphql-plugin-boilerplate/src/Abstracts/UnionType.php: -------------------------------------------------------------------------------- 1 | 27 | * 28 | * phpcs:enable SlevomatCodingStandard.Namespaces.FullyQualifiedClassNameInAnnotation 29 | */ 30 | abstract class UnionType extends Type 31 | { 32 | use TypeResolverTrait; 33 | /** 34 | * Gets the array of possible GraphQL types that can be resolved to. 35 | * 36 | * @return string[] 37 | */ 38 | abstract public static function get_possible_types(): array; 39 | /** 40 | * {@inheritDoc} 41 | */ 42 | public static function register(): void 43 | { 44 | /** @todo remove when WPGraphQL > 2.3.0 is required. */ 45 | $config = Compat::resolve_graphql_config(static::get_type_config()); 46 | register_graphql_union_type(static::get_type_name(), $config); 47 | } 48 | /** 49 | * {@inheritDoc} 50 | * 51 | * @return UnionTypeConfig 52 | */ 53 | protected static function get_type_config(): array 54 | { 55 | $config = parent::get_type_config(); 56 | $config['typeNames'] = static::get_possible_types(); 57 | $config['resolveType'] = static::get_type_resolver(); 58 | return $config; 59 | } 60 | /** 61 | * {@inheritDoc} 62 | */ 63 | public static function should_load_eagerly(): bool 64 | { 65 | return true; 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /src/Type/WPObject/Settings/Sitemap/Author.php: -------------------------------------------------------------------------------- 1 | [ 33 | 'toType' => 'User', 34 | 'description' => static fn () => __( 'The connected authors whose URLs are included in the sitemap', 'wp-graphql-rank-math' ), 35 | 'resolve' => static function ( $source, $args, $context, $info ) { 36 | $resolver = new UserConnectionResolver( $source, $args, $context, $info ); 37 | 38 | if ( ! empty( $source->excludedRoles ) ) { 39 | $resolver->set_query_arg( 'role__not_in', $source->excludedRoles ); 40 | } 41 | 42 | if ( ! empty( $source->excludedUserDatabaseIds ) ) { 43 | $resolver->set_query_arg( 'exclude', $source->excludedUserDatabaseIds ); 44 | } 45 | 46 | return $resolver->get_connection(); 47 | }, 48 | ], 49 | ]; 50 | } 51 | 52 | /** 53 | * {@inheritDoc} 54 | */ 55 | public static function get_description(): string { 56 | return __( 'The RankMath SEO Sitemap general settings.', 'wp-graphql-rank-math' ); 57 | } 58 | 59 | /** 60 | * {@inheritDoc} 61 | */ 62 | public static function get_fields(): array { 63 | return [ 64 | 'excludedRoles' => [ 65 | 'type' => [ 'list_of' => 'UserRoleEnum' ], 66 | 'description' => static fn () => __( 'List of user roles excluded from the sitemap.', 'wp-graphql-rank-math' ), 67 | ], 68 | 'excludedUserDatabaseIds' => [ 69 | 'type' => [ 'list_of' => 'Int' ], 70 | 'description' => static fn () => __( 'List of user IDs excluded from the sitemap.', 'wp-graphql-rank-math' ), 71 | ], 72 | 'sitemapUrl' => [ 73 | 'type' => 'String', 74 | 'description' => static fn () => __( 'The sitemap URL.', 'wp-graphql-rank-math' ), 75 | ], 76 | ]; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/Type/WPObject/Settings/Sitemap/General.php: -------------------------------------------------------------------------------- 1 | [ 38 | 'type' => 'Boolean', 39 | 'deprecationReason' => static fn () => __( 'This feature is no longer supported by Google, and has been removed from RankMath v1.0.211+.', 'wp-graphql-rank-math' ), 40 | 'description' => static fn () => __( 'Whether to notify search engines when the sitemap is updated.', 'wp-graphql-rank-math' ), 41 | ], 42 | 'excludedPostDatabaseIds' => [ 43 | 'type' => [ 'list_of' => 'Int' ], 44 | 'description' => static fn () => __( 'A list of post IDs excluded from the sitemap. This option **applies** to all posts types including posts, pages, and custom post types.', 'wp-graphql-rank-math' ), 45 | ], 46 | 'excludedTermDatabaseIds' => [ 47 | 'type' => [ 'list_of' => 'Int' ], 48 | 'description' => static fn () => __( 'A list of term IDs excluded from the sitemap. This option **applies** to all taxonomies.', 'wp-graphql-rank-math' ), 49 | ], 50 | 'hasFeaturedImage' => [ 51 | 'type' => 'Boolean', 52 | 'description' => static fn () => __( 'Whether the Featured Image is included in sitemaps too, even if it does not appear directly in the post content.', 'wp-graphql-rank-math' ), 53 | ], 54 | 'hasImages' => [ 55 | 'type' => 'Boolean', 56 | 'description' => static fn () => __( 'Whether reference to images from the post content is included in sitemaps.', 'wp-graphql-rank-math' ), 57 | ], 58 | 'linksPerSitemap' => [ 59 | 'type' => 'Int', 60 | 'description' => static fn () => __( 'Max number of links on each sitemap page.', 'wp-graphql-rank-math' ), 61 | ], 62 | ]; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/Type/WPObject/Settings/Meta/AuthorArchiveMeta.php: -------------------------------------------------------------------------------- 1 | [ 51 | 'type' => 'String', 52 | 'description' => static fn () => __( 'Change the `/author/` part in author archive URLs.', 'wp-graphql-rank-math' ), 53 | ], 54 | 'hasArchives' => [ 55 | 'type' => 'Boolean', 56 | 'description' => static fn () => __( 'Whether author archives are enabled.', 'wp-graphql-rank-math' ), 57 | ], 58 | 'hasCustomRobotsMeta' => [ 59 | 'type' => 'Boolean', 60 | 'description' => static fn () => __( 'Whether custom robots meta for author page are set. Otherwise the default meta will be used, as set in the Global Meta tab.', 'wp-graphql-rank-math' ), 61 | ], 62 | 'hasSlackEnhancedSharing' => [ 63 | 'type' => 'Boolean', 64 | 'description' => static fn () => __( 'Whether to show additional information (name & total number of posts) when an author archive is shared on Slack.', 'wp-graphql-rank-math' ), 65 | ], 66 | 'hasSeoControls' => [ 67 | 'type' => 'Boolean', 68 | 'description' => static fn () => __( 'Whether the SEO Controls meta box for user profile pages is enabled.', 'wp-graphql-rank-math' ), 69 | ], 70 | ]; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /vendor-prefixed/axepress/wp-graphql-plugin-boilerplate/src/Abstracts/InterfaceType.php: -------------------------------------------------------------------------------- 1 | , 25 | * resolveType?: callable, 26 | * interfaces?: string[], 27 | * } 28 | * 29 | * @extends \WPGraphQL\RankMath\Vendor\AxeWP\GraphQL\Abstracts\Type 30 | * 31 | * phpcs:enable SlevomatCodingStandard.Namespaces.FullyQualifiedClassNameInAnnotation 32 | */ 33 | abstract class InterfaceType extends Type implements TypeWithFields 34 | { 35 | /** 36 | * {@inheritDoc} 37 | */ 38 | public static function register(): void 39 | { 40 | /** @todo remove when WPGraphQL > 2.3.0 is required. */ 41 | $config = Compat::resolve_graphql_config(static::get_type_config()); 42 | register_graphql_interface_type(static::get_type_name(), $config); 43 | } 44 | /** 45 | * {@inheritDoc} 46 | */ 47 | protected static function get_type_config(): array 48 | { 49 | $config = parent::get_type_config(); 50 | $config['fields'] = static::get_fields(); 51 | if (method_exists(static::class, 'get_type_resolver')) { 52 | $config['resolveType'] = static::get_type_resolver(); 53 | } 54 | if (method_exists(static::class, 'get_interfaces')) { 55 | $config['interfaces'] = static::get_interfaces(); 56 | } 57 | return $config; 58 | } 59 | /** 60 | * {@inheritDoc} 61 | */ 62 | public static function should_load_eagerly(): bool 63 | { 64 | return true; 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /vendor-prefixed/axepress/wp-graphql-plugin-boilerplate/src/Abstracts/ObjectType.php: -------------------------------------------------------------------------------- 1 | , 26 | * connections?: array, 27 | * resolveType?: callable, 28 | * interfaces?: string[], 29 | * } 30 | * 31 | * @extends \WPGraphQL\RankMath\Vendor\AxeWP\GraphQL\Abstracts\Type 32 | * 33 | * phpcs:enable SlevomatCodingStandard.Namespaces.FullyQualifiedClassNameInAnnotation 34 | */ 35 | abstract class ObjectType extends Type implements TypeWithFields 36 | { 37 | /** 38 | * {@inheritDoc} 39 | */ 40 | public static function register(): void 41 | { 42 | /** @todo remove when WPGraphQL > 2.3.0 is required. */ 43 | $config = Compat::resolve_graphql_config(static::get_type_config()); 44 | register_graphql_object_type(static::get_type_name(), $config); 45 | } 46 | /** 47 | * {@inheritDoc} 48 | * 49 | * @return ObjectTypeConfig 50 | */ 51 | protected static function get_type_config(): array 52 | { 53 | $config = parent::get_type_config(); 54 | $config['fields'] = static::get_fields(); 55 | if (method_exists(static::class, 'get_connections')) { 56 | $config['connections'] = static::get_connections(); 57 | } 58 | if (method_exists(static::class, 'get_interfaces')) { 59 | $config['interfaces'] = static::get_interfaces(); 60 | } 61 | return $config; 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /src/Modules/Redirection/Connection/RedirectionConnection.php: -------------------------------------------------------------------------------- 1 | 'RootQuery', 39 | 'fromFieldName' => 'redirections', 40 | 'connectionArgs' => self::get_connection_args(), 41 | 'description' => static fn () => __( 'A RankMath SEO redirection object.', 'wp-graphql-rank-math' ), 42 | 'resolve' => static function ( $source, array $args, AppContext $context, ResolveInfo $info ) { 43 | $resolver = new RedirectionConnectionResolver( $source, $args, $context, $info ); 44 | 45 | return $resolver->get_connection(); 46 | }, 47 | ] 48 | ); 49 | // @todo Remove when WPGraphQL < 2.3.0 is dropped. 50 | $config = Compat::resolve_graphql_config( $config ); 51 | 52 | register_graphql_connection( $config ); 53 | } 54 | 55 | /** 56 | * {@inheritDoc} 57 | */ 58 | public static function connection_args(): array { 59 | return [ 60 | 'search' => [ 61 | 'type' => 'String', 62 | 'description' => static fn () => __( 'Search the status, redirection url, or sources for the provided value.', 'wp-graphql-rank-math' ), 63 | ], 64 | 'status' => [ 65 | 'type' => [ 'list_of' => RedirectionStatusEnum::get_type_name() ], 66 | 'description' => static fn () => __( 'Filter the redirections by their status.', 'wp-graphql-rank-math' ), 67 | ], 68 | 'orderby' => [ 69 | 'type' => RedirectionConnectionOrderbyInput::get_type_name(), 70 | 'description' => static fn () => __( 'Order the results by a specific field.', 'wp-graphql-rank-math' ), 71 | ], 72 | ]; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/Utils/Utils.php: -------------------------------------------------------------------------------- 1 | $length ) { 35 | $excerpt .= $append; 36 | } 37 | 38 | return $excerpt; 39 | } 40 | 41 | /** 42 | * Checks if a given url is relative. 43 | * 44 | * @param string $url the url to check. 45 | */ 46 | public static function is_url_relative( string $url ): bool { 47 | return ( 0 !== strpos( $url, 'http' ) && 0 !== strpos( $url, '//' ) ); 48 | } 49 | 50 | /** 51 | * Appends the base url to the provided path. 52 | * 53 | * @param string $path . 54 | */ 55 | public static function base_url( string $path = '' ): string { 56 | $blog_id = is_multisite() ? get_current_blog_id() : null; 57 | 58 | $base_url = get_home_url( $blog_id, $path ); 59 | 60 | return user_trailingslashit( $base_url ); 61 | } 62 | 63 | /** 64 | * Overloads the field type of an existing GraphQL field. 65 | * 66 | * This is necessary because register_graphql_field() doesn't have a way to check inheritance. 67 | * 68 | * @see https://github.com/wp-graphql/wp-graphql/issues/3096 69 | * 70 | * @param string $object_type The WPGraphQL object type name where the field is located. 71 | * @param string $field_name The field name to overload. 72 | * @param string $new_type_name The new GraphQL type name to use. 73 | */ 74 | public static function overload_graphql_field_type( string $object_type, string $field_name, string $new_type_name ): void { 75 | add_filter( 76 | 'graphql_' . $object_type . '_fields', 77 | static function ( array $fields ) use ( $field_name, $new_type_name ) { 78 | if ( isset( $fields[ $field_name ] ) ) { 79 | $fields[ $field_name ]['type'] = $new_type_name; 80 | } 81 | 82 | return $fields; 83 | }, 84 | 10, 85 | 1 86 | ); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/Type/WPObject/OpenGraph/Article.php: -------------------------------------------------------------------------------- 1 | [ 38 | 'type' => 'String', 39 | 'description' => static fn () => __( 'The date modified.', 'wp-graphql-rank-math' ), 40 | 'resolve' => static fn ( $source ): ?string => ! empty( $source['modified_time'] ) ? (string) $source['modified_time'] : null, 41 | ], 42 | 'publishedTime' => [ 43 | 'type' => 'String', 44 | 'description' => static fn () => __( 'The date published.', 'wp-graphql-rank-math' ), 45 | 'resolve' => static fn ( $source ): ?string => ! empty( $source['published_time'] ) ? (string) $source['published_time'] : null, 46 | ], 47 | 'publisher' => [ 48 | 'type' => 'String', 49 | 'description' => static fn () => __( 'The publisher', 'wp-graphql-rank-math' ), 50 | ], 51 | 'author' => [ 52 | 'type' => 'String', 53 | 'description' => static fn () => __( 'The author.', 'wp-graphql-rank-math' ), 54 | ], 55 | 'tags' => [ 56 | 'type' => [ 'list_of' => 'String' ], 57 | 'description' => static fn () => __( 'The article tags.', 'wp-graphql-rank-math' ), 58 | 'resolve' => static function ( $source ): ?array { 59 | $value = ! empty( $source['tag'] ) ? $source['tag'] : null; 60 | 61 | if ( empty( $value ) ) { 62 | return null; 63 | } 64 | 65 | if ( ! is_array( $value ) ) { 66 | $value = [ (string) $value ]; 67 | } 68 | 69 | // Ensure all tags are strings. 70 | $value = array_map( 'strval', $value ); 71 | 72 | return $value; 73 | }, 74 | ], 75 | 'section' => [ 76 | 'type' => 'String', 77 | 'description' => static fn () => __( 'The article category.', 'wp-graphql-rank-math' ), 78 | 'resolve' => static fn ( $source ): ?string => ! empty( $source['section'] ) ? (string) $source['section'] : null, 79 | ], 80 | ]; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/Autoloader.php: -------------------------------------------------------------------------------- 1 | 83 |
84 |

85 | 86 |

87 |
88 | [ 42 | 'type' => BreadcrumbsConfig::get_type_name(), 43 | 'description' => static fn () => __( 'Breadcrumbs settings.', 'wp-graphql-rank-math' ), 44 | ], 45 | 'hasBreadcrumbs' => [ 46 | 'type' => 'Boolean', 47 | 'description' => static fn () => __( 'Whether RankMath breadcrumbs are enabled.', 'wp-graphql-rank-math' ), 48 | ], 49 | 'links' => [ 50 | 'type' => Links::get_type_name(), 51 | 'description' => static fn () => __( 'Link settings.', 'wp-graphql-rank-math' ), 52 | ], 53 | 'webmaster' => [ 54 | 'type' => Webmaster::get_type_name(), 55 | 'description' => static fn () => __( 'Webmaster Tools settings.', 'wp-graphql-rank-math' ), 56 | ], 57 | 'hasFrontendSeoScore' => [ 58 | 'type' => 'Boolean', 59 | 'description' => static fn () => __( 'Whether to display the calculated SEO Score as a badge on the frontend. It can be disabled for specific posts in the post editor.', 'wp-graphql-rank-math' ), 60 | ], 61 | 'frontendSeoScore' => [ 62 | 'type' => FrontendSeoScore::get_type_name(), 63 | 'description' => static fn () => __( 'Frontend SEO score settings.', 'wp-graphql-rank-math' ), 64 | ], 65 | 'rssBeforeContent' => [ 66 | 'type' => 'String', 67 | 'description' => static fn () => __( 'The content to add before each post in your site feeds', 'wp-graphql-rank-math' ), 68 | ], 69 | 'rssAfterContent' => [ 70 | 'type' => 'String', 71 | 'description' => static fn () => __( 'The content to add after each post in your site feeds', 'wp-graphql-rank-math' ), 72 | ], 73 | ]; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /vendor/composer/installed.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | { 4 | "name": "axepress/wp-graphql-plugin-boilerplate", 5 | "version": "0.1.1", 6 | "version_normalized": "0.1.1.0", 7 | "source": { 8 | "type": "git", 9 | "url": "https://github.com/AxeWP/wp-graphql-plugin-boilerplate.git", 10 | "reference": "09495b61346453baabdf4c71a38ada3cfc91c3a7" 11 | }, 12 | "dist": { 13 | "type": "zip", 14 | "url": "https://api.github.com/repos/AxeWP/wp-graphql-plugin-boilerplate/zipball/09495b61346453baabdf4c71a38ada3cfc91c3a7", 15 | "reference": "09495b61346453baabdf4c71a38ada3cfc91c3a7", 16 | "shasum": "" 17 | }, 18 | "require": { 19 | "php": ">=7.4" 20 | }, 21 | "require-dev": { 22 | "axepress/wp-graphql-cs": "^2.0.0", 23 | "axepress/wp-graphql-stubs": "^2.3.0", 24 | "phpcompatibility/php-compatibility": "dev-develop as 9.9.9", 25 | "phpstan/extension-installer": "^1.1", 26 | "phpstan/phpstan": "^2.0", 27 | "phpstan/phpstan-deprecation-rules": "^2.0.1", 28 | "szepeviktor/phpstan-wordpress": "^2.0", 29 | "wp-cli/wp-cli-bundle": "^2.8.1" 30 | }, 31 | "time": "2025-06-07T02:03:50+00:00", 32 | "type": "library", 33 | "installation-source": "dist", 34 | "autoload": { 35 | "psr-4": { 36 | "AxeWP\\GraphQL\\": "src/" 37 | } 38 | }, 39 | "notification-url": "https://packagist.org/downloads/", 40 | "license": [ 41 | "GPL-3.0-or-later" 42 | ], 43 | "authors": [ 44 | { 45 | "name": "AxePress Development", 46 | "homepage": "https://axepress.dev" 47 | }, 48 | { 49 | "name": "David Levine", 50 | "role": "Developer" 51 | } 52 | ], 53 | "description": "Boilerplate for creating WPGraphQL extensions", 54 | "support": { 55 | "issues": "https://github.com/AxeWP/wp-graphql-plugin-boilerplate/issues", 56 | "source": "https://github.com/AxeWP/wp-graphql-plugin-boilerplate/tree/0.1.1" 57 | }, 58 | "funding": [ 59 | { 60 | "url": "https://github.com/AxeWp", 61 | "type": "github" 62 | } 63 | ], 64 | "install-path": "../../vendor-prefixed/axepress/wp-graphql-plugin-boilerplate/" 65 | } 66 | ], 67 | "dev": false, 68 | "dev-package-names": [] 69 | } 70 | -------------------------------------------------------------------------------- /src/Type/WPObject/Settings/Sitemap/Taxonomy.php: -------------------------------------------------------------------------------- 1 | [ 34 | 'toType' => 'TermNode', 35 | 'description' => static fn () => __( 'The connected terms whose URLs are included in the sitemap', 'wp-graphql-rank-math' ), 36 | 'resolve' => static function ( $source, $args, $context, $info ) { 37 | if ( empty( $source['isInSitemap'] ) ) { 38 | return null; 39 | } 40 | 41 | $resolver = new TermObjectConnectionResolver( $source, $args, $context, $info, $source['type'] ); 42 | 43 | $excluded_term_ids = Helper::get_settings( 'sitemap.exclude_terms' ); 44 | $excluded_term_ids = ! empty( $excluded_term_ids ) ? array_map( 'absint', explode( ',', $excluded_term_ids ) ) : null; 45 | 46 | if ( ! empty( $excluded_term_ids ) ) { 47 | $resolver->set_query_arg( 'exclude', $excluded_term_ids ); 48 | } 49 | 50 | return $resolver->get_connection(); 51 | }, 52 | ], 53 | ]; 54 | } 55 | 56 | /** 57 | * {@inheritDoc} 58 | */ 59 | public static function get_description(): string { 60 | return __( 'The RankMath SEO Sitemap general settings.', 'wp-graphql-rank-math' ); 61 | } 62 | 63 | /** 64 | * {@inheritDoc} 65 | */ 66 | public static function get_fields(): array { 67 | return [ 68 | 'hasEmptyTerms' => [ 69 | 'type' => 'Boolean', 70 | 'description' => static fn () => __( 'Whether to archive pages of terms that have no posts associated.', 'wp-graphql-rank-math' ), 71 | ], 72 | 'isInSitemap' => [ 73 | 'type' => 'Boolean', 74 | 'description' => static fn () => __( 'Whether the content type is included in the sitemap.', 'wp-graphql-rank-math' ), 75 | ], 76 | 'sitemapUrl' => [ 77 | 'type' => 'String', 78 | 'description' => static fn () => __( 'The sitemap URL.', 'wp-graphql-rank-math' ), 79 | ], 80 | 'type' => [ 81 | 'type' => 'TaxonomyEnum', 82 | 'description' => static fn () => __( 'The taxonomy type.', 'wp-graphql-rank-math' ), 83 | ], 84 | ]; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /vendor-prefixed/composer/installed.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | { 4 | "name": "axepress/wp-graphql-plugin-boilerplate", 5 | "version": "0.1.1", 6 | "version_normalized": "0.1.1.0", 7 | "source": { 8 | "type": "git", 9 | "url": "https://github.com/AxeWP/wp-graphql-plugin-boilerplate.git", 10 | "reference": "09495b61346453baabdf4c71a38ada3cfc91c3a7" 11 | }, 12 | "dist": { 13 | "type": "zip", 14 | "url": "https://api.github.com/repos/AxeWP/wp-graphql-plugin-boilerplate/zipball/09495b61346453baabdf4c71a38ada3cfc91c3a7", 15 | "reference": "09495b61346453baabdf4c71a38ada3cfc91c3a7", 16 | "shasum": "" 17 | }, 18 | "require": { 19 | "php": ">=7.4" 20 | }, 21 | "require-dev": { 22 | "axepress/wp-graphql-cs": "^2.0.0", 23 | "axepress/wp-graphql-stubs": "^2.3.0", 24 | "phpcompatibility/php-compatibility": "dev-develop as 9.9.9", 25 | "phpstan/extension-installer": "^1.1", 26 | "phpstan/phpstan": "^2.0", 27 | "phpstan/phpstan-deprecation-rules": "^2.0.1", 28 | "szepeviktor/phpstan-wordpress": "^2.0", 29 | "wp-cli/wp-cli-bundle": "^2.8.1" 30 | }, 31 | "time": "2025-06-07T02:03:50+00:00", 32 | "type": "library", 33 | "installation-source": "dist", 34 | "autoload": { 35 | "psr-4": { 36 | "AxeWP\\GraphQL\\": "src/" 37 | } 38 | }, 39 | "notification-url": "https://packagist.org/downloads/", 40 | "license": [ 41 | "GPL-3.0-or-later" 42 | ], 43 | "authors": [ 44 | { 45 | "name": "AxePress Development", 46 | "homepage": "https://axepress.dev" 47 | }, 48 | { 49 | "name": "David Levine", 50 | "role": "Developer" 51 | } 52 | ], 53 | "description": "Boilerplate for creating WPGraphQL extensions", 54 | "support": { 55 | "issues": "https://github.com/AxeWP/wp-graphql-plugin-boilerplate/issues", 56 | "source": "https://github.com/AxeWP/wp-graphql-plugin-boilerplate/tree/0.1.1" 57 | }, 58 | "funding": [ 59 | { 60 | "url": "https://github.com/AxeWp", 61 | "type": "github" 62 | } 63 | ], 64 | "install-path": "../../vendor-prefixed/axepress/wp-graphql-plugin-boilerplate/" 65 | } 66 | ], 67 | "dev": false, 68 | "dev-package-names": [] 69 | } 70 | -------------------------------------------------------------------------------- /src/Type/WPObject/Settings/Meta/HomepageMeta.php: -------------------------------------------------------------------------------- 1 | Reading > Your homepage displays is set to `Your latest posts`.', 'wp-graphql-rank-math' ); 33 | } 34 | 35 | /** 36 | * {@inheritDoc} 37 | */ 38 | public static function get_interfaces(): array { 39 | return [ 40 | MetaSettingWithRobots::get_type_name(), 41 | ]; 42 | } 43 | 44 | /** 45 | * {@inheritDoc} 46 | */ 47 | public static function get_fields(): array { 48 | return [ 49 | 'title' => [ 50 | 'type' => 'String', 51 | 'description' => static fn () => __( 'Title tag.', 'wp-graphql-rank-math' ), 52 | ], 53 | 'description' => [ 54 | 'type' => 'String', 55 | 'description' => static fn () => __( 'Meta description.', 'wp-graphql-rank-math' ), 56 | ], 57 | 'hasCustomRobotsMeta' => [ 58 | 'type' => 'Boolean', 59 | 'description' => static fn () => __( 'Whether custom robots meta for author page are set. Otherwise the default meta will be used, as set in the Global Meta tab.', 'wp-graphql-rank-math' ), 60 | ], 61 | 'socialTitle' => [ 62 | 'type' => 'String', 63 | 'description' => static fn () => __( 'Title when shared on Facebook, Twitter and other social networks.', 'wp-graphql-rank-math' ), 64 | ], 65 | 'socialDescription' => [ 66 | 'type' => 'String', 67 | 'description' => static fn () => __( 'Description when shared on Facebook, Twitter and other social networks.', 'wp-graphql-rank-math' ), 68 | ], 69 | 'socialImage' => [ 70 | 'type' => 'MediaItem', 71 | 'description' => static fn () => __( 'Image displayed when your homepage is shared on Facebook and other social networks.', 'wp-graphql-rank-math' ), 72 | 'resolve' => static function ( $source, array $args, AppContext $context ) { 73 | return ! empty( $source['socialImageId'] ) ? $context->get_loader( 'post' )->load_deferred( $source['socialImageId'] ) : null; 74 | }, 75 | ], 76 | ]; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/Main.php: -------------------------------------------------------------------------------- 1 | setup(); 39 | // @codeCoverageIgnoreEnd 40 | } 41 | 42 | /** 43 | * Fire off init action. 44 | * 45 | * @param self $instance the instance of the plugin class. 46 | */ 47 | do_action( 'graphql_seo_init', self::$instance ); 48 | 49 | return self::$instance; 50 | } 51 | 52 | /** 53 | * Sets up the schema. 54 | * 55 | * @codeCoverageIgnore 56 | */ 57 | private function setup(): void { 58 | // // Setup boilerplate hook prefix. 59 | Helper::set_hook_prefix( 'graphql_seo' ); 60 | 61 | // Force enable RankMath headless support. 62 | $enabled = RMHelper::get_settings( 'general.headless_support' ); 63 | 64 | if ( empty( $enabled ) ) { 65 | $options = get_option( 'rank-math-options-general', [] ); 66 | $options['headless_support'] = 'on'; 67 | update_option( 'rank-math-options-general', $options ); 68 | } 69 | 70 | // Setup plugin. 71 | Extensions::init(); 72 | CoreSchemaFilters::init(); 73 | Settings::init(); 74 | TypeRegistry::init(); 75 | } 76 | 77 | /** 78 | * Throw error on object clone. 79 | * The whole idea of the singleton design pattern is that there is a single object 80 | * therefore, we don't want the object to be cloned. 81 | * 82 | * @codeCoverageIgnore 83 | * 84 | * @return void 85 | */ 86 | public function __clone() { 87 | // Cloning instances of the class is forbidden. 88 | _doing_it_wrong( __FUNCTION__, esc_html__( 'The plugin Main class should not be cloned.', 'wp-graphql-rank-math' ), '0.0.1' ); 89 | } 90 | 91 | /** 92 | * Disable unserializing of the class. 93 | * 94 | * @codeCoverageIgnore 95 | */ 96 | public function __wakeup(): void { 97 | // De-serializing instances of the class is forbidden. 98 | _doing_it_wrong( __FUNCTION__, esc_html__( 'De-serializing instances of the plugin Main class is not allowed.', 'wp-graphql-rank-math' ), '0.0.1' ); 99 | } 100 | } 101 | endif; 102 | -------------------------------------------------------------------------------- /src/Type/WPObject/Settings/Sitemap/ContentType.php: -------------------------------------------------------------------------------- 1 | [ 34 | 'toType' => 'ContentNode', 35 | 'description' => static fn () => __( 'The connected content nodes whose URLs are included in the sitemap', 'wp-graphql-rank-math' ), 36 | 'resolve' => static function ( $source, $args, $context, $info ) { 37 | if ( empty( $source['isInSitemap'] ) ) { 38 | return null; 39 | } 40 | 41 | $resolver = new PostObjectConnectionResolver( $source, $args, $context, $info, $source['type'] ); 42 | 43 | $excluded_post_ids = Helper::get_settings( 'sitemap.exclude_posts' ); 44 | $excluded_post_ids = ! empty( $excluded_post_ids ) ? array_map( 'absint', explode( ',', $excluded_post_ids ) ) : null; 45 | 46 | if ( ! empty( $excluded_post_ids ) ) { 47 | $resolver->set_query_arg( 'post__not_in', $excluded_post_ids ); 48 | } 49 | 50 | return $resolver->get_connection(); 51 | }, 52 | ], 53 | ]; 54 | } 55 | 56 | /** 57 | * {@inheritDoc} 58 | */ 59 | public static function get_description(): string { 60 | return __( 'The RankMath SEO Sitemap general settings.', 'wp-graphql-rank-math' ); 61 | } 62 | 63 | /** 64 | * {@inheritDoc} 65 | */ 66 | public static function get_fields(): array { 67 | return [ 68 | 'customImageMetaKeys' => [ 69 | 'type' => [ 'list_of' => 'String' ], 70 | 'description' => static fn () => __( 'List of custom field (post meta) names which contain image URLs to include them in the sitemaps.', 'wp-graphql-rank-math' ), 71 | ], 72 | 'isInSitemap' => [ 73 | 'type' => 'Boolean', 74 | 'description' => static fn () => __( 'Whether the content type is included in the sitemap.', 'wp-graphql-rank-math' ), 75 | ], 76 | 'sitemapUrl' => [ 77 | 'type' => 'String', 78 | 'description' => static fn () => __( 'The sitemap URL.', 'wp-graphql-rank-math' ), 79 | ], 80 | 'type' => [ 81 | 'type' => 'ContentTypeEnum', 82 | 'description' => static fn () => __( 'The content type.', 'wp-graphql-rank-math' ), 83 | ], 84 | 85 | ]; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/Type/WPObject/Settings/General/Links.php: -------------------------------------------------------------------------------- 1 | [ 38 | 'type' => 'String', 39 | 'description' => static fn () => __( 'The default redirection url for attachments without a parent post', 'wp-graphql-rank-math' ), 40 | ], 41 | 'hasCategoryBase' => [ 42 | 'type' => 'Boolean', 43 | 'description' => static fn () => __( 'Whether /category/ should be included in category archive URLs.', 'wp-graphql-rank-math' ), 44 | ], 45 | 'nofollowDomains' => [ 46 | 'type' => 'String', 47 | 'description' => static fn () => __( 'Only add `nofollow` attributes to links with the following target domains. If null, `nofollow` will be applied to all external domains.', 'wp-graphql-rank-math' ), 48 | ], 49 | 'nofollowExcludedDomains' => [ 50 | 'type' => 'String', 51 | 'description' => static fn () => __( '`nofollow` attributes will not be added to links with the following target domains.', 'wp-graphql-rank-math' ), 52 | ], 53 | 'shouldNofollowImageLinks' => [ 54 | 'type' => 'Boolean', 55 | 'description' => static fn () => __( 'Whether to automatically add the `rel="nofollow" attribute to links pointing to external image files.', 'wp-graphql-rank-math' ), 56 | ], 57 | 'shouldNofollowLinks' => [ 58 | 'type' => 'Boolean', 59 | 'description' => static fn () => __( 'Whether to automatically add the `rel="nofollow" attribute to external links appearing in your posts, pages, and other post types.', 'wp-graphql-rank-math' ), 60 | ], 61 | 'shouldOpenInNewWindow' => [ 62 | 'type' => 'Boolean', 63 | 'description' => static fn () => __( 'Whether to automatically add `target="_blank"` attribute for external links appearing in your posts, pages, and other post types to make them open in a new browser tab or window.', 'wp-graphql-rank-math' ), 64 | ], 65 | 'shouldRedirectAttachments' => [ 66 | 'type' => 'Boolean', 67 | 'description' => static fn () => __( 'Whether to redirect all attachment page URLs to the post they appear in.', 'wp-graphql-rank-math' ), 68 | ], 69 | ]; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /codeception.dist.yml: -------------------------------------------------------------------------------- 1 | namespace: Tests\WPGraphQL\RankMath 2 | paths: 3 | tests: '%TESTS_DIR%' 4 | output: '%TESTS_OUTPUT%' 5 | data: '%TESTS_DATA%' 6 | support: '%TESTS_SUPPORT%' 7 | envs: '%TESTS_ENVS%' 8 | params: 9 | - env 10 | - .env 11 | actor_suffix: Tester 12 | settings: 13 | colors: true 14 | memory_limit: 1024M 15 | coverage: 16 | enabled: true 17 | remote: false 18 | c3_url: '%WP_URL%/wp-content/plugins/wp-graphql-rank-math/wp-graphql-rank-math.php/' 19 | include: 20 | - src/* 21 | - access-functions.php 22 | exclude: 23 | - vendor/* 24 | show_only_summary: false 25 | extensions: 26 | enabled: 27 | - Codeception\Extension\RunFailed 28 | commands: 29 | - Codeception\Command\GenerateWPUnit 30 | - Codeception\Command\GenerateWPRestApi 31 | - Codeception\Command\GenerateWPRestController 32 | - Codeception\Command\GenerateWPRestPostTypeController 33 | - Codeception\Command\GenerateWPAjax 34 | - Codeception\Command\GenerateWPCanonical 35 | - Codeception\Command\GenerateWPXMLRPC 36 | modules: 37 | config: 38 | WPDb: 39 | dsn: 'mysql:host=%DB_HOST%;dbname=%DB_NAME%' 40 | user: '%DB_USER%' 41 | password: '%DB_PASSWORD%' 42 | dump: 'tests/_data/dump.sql' 43 | populate: true 44 | cleanup: true 45 | waitlock: 0 46 | url: '%WP_URL%' 47 | urlReplacement: true 48 | tablePrefix: '%WP_TABLE_PREFIX%' 49 | WPBrowser: 50 | url: '%WP_URL%' 51 | wpRootFolder: '%WP_ROOT_FOLDER%' 52 | adminUsername: '%ADMIN_USERNAME%' 53 | adminPassword: '%ADMIN_PASSWORD%' 54 | adminPath: '/wp-admin' 55 | cookies: false 56 | REST: 57 | depends: WPBrowser 58 | url: '%WP_URL%' 59 | WPFilesystem: 60 | wpRootFolder: '%WP_ROOT_FOLDER%' 61 | plugins: '/wp-content/plugins' 62 | mu-plugins: '/wp-content/mu-plugins' 63 | themes: '/wp-content/themes' 64 | uploads: '/wp-content/uploads' 65 | WPLoader: 66 | wpRootFolder: '%WP_ROOT_FOLDER%' 67 | dbName: '%DB_NAME%' 68 | dbHost: '%DB_HOST%' 69 | dbUser: '%DB_USER%' 70 | dbPassword: '%DB_PASSWORD%' 71 | tablePrefix: '%WP_TABLE_PREFIX%' 72 | domain: '%WP_DOMAIN%' 73 | adminEmail: '%ADMIN_EMAIL%' 74 | title: 'Test' 75 | plugins: 76 | - wp-graphql/wp-graphql.php 77 | - seo-by-rank-math/rank-math.php 78 | - wp-graphql-rank-math/wp-graphql-rank-math.php 79 | activatePlugins: 80 | - seo-by-rank-math/rank-math.php 81 | - wp-graphql/wp-graphql.php 82 | - wp-graphql-rank-math/wp-graphql-rank-math.php 83 | configFile: 'tests/_data/config.php' 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /src/Type/WPObject/Settings/Meta/GlobalMeta.php: -------------------------------------------------------------------------------- 1 | [ 51 | 'type' => 'MediaItem', 52 | 'description' => static fn () => __( 'When a featured image or an OpenGraph Image is not set for individual posts/pages/CPTs, this image will be used as a fallback thumbnail when your post is shared on Facebook.', 'wp-graphql-rank-math' ), 53 | 'resolve' => static function ( $source, array $args, AppContext $context ) { 54 | return ! empty( $source['openGraphImageId'] ) ? $context->get_loader( 'post' )->load_deferred( $source['openGraphImageId'] ) : null; 55 | }, 56 | ], 57 | 'separator' => [ 58 | 'type' => 'String', 59 | 'description' => static fn () => __( 'The separator character used in titles.', 'wp-graphql-rank-math' ), 60 | ], 61 | 'shouldCapitalizeTitles' => [ 62 | 'type' => 'Boolean', 63 | 'description' => static fn () => __( 'Whether to automatically capitalize the first character of each word in the titles.', 'wp-graphql-rank-math' ), 64 | ], 65 | 'shouldIndexEmptyTaxonomies' => [ 66 | 'type' => 'Boolean', 67 | 'description' => static fn () => __( 'Whether to index enpty Taxonomy archives', 'wp-graphql-rank-math' ), 68 | ], 69 | 'twitterCardType' => [ 70 | 'type' => TwitterCardTypeEnum::get_type_name(), 71 | 'description' => static fn () => __( 'Card type selected when creating a new post. This will also be applied for posts without a card type selected.', 'wp-graphql-rank-math' ), 72 | ], 73 | ]; 74 | 75 | if ( ! current_theme_supports( 'title-tag' ) ) { 76 | $fields['shouldRewriteTitle'] = [ 77 | 'type' => 'Boolean', 78 | 'description' => static fn () => __( 'Whether titles for page, post, category, search, and archive pages can be rewritten. Only visible in themes without title-tag support', 'wp-graphql-rank-math' ), 79 | ]; 80 | } 81 | 82 | return $fields; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/Type/WPObject/Settings/Sitemap.php: -------------------------------------------------------------------------------- 1 | [ 42 | 'type' => Author::get_type_name(), 43 | 'description' => static fn () => __( 'Author sitemap settings. Null if authors are not indexable.', 'wp-graphql-rank-math' ), 44 | ], 45 | 'contentTypes' => [ 46 | 'type' => [ 'list_of' => ContentType::get_type_name() ], 47 | 'args' => [ 48 | 'include' => [ 49 | 'type' => [ 'list_of' => 'ContentTypeEnum' ], 50 | 'description' => static fn () => __( 'Limit results to specific content types.', 'wp-graphql-rank-math' ), 51 | ], 52 | ], 53 | 'description' => static fn () => __( 'Content types included in the sitemap.', 'wp-graphql-rank-math' ), 54 | 'resolve' => static function ( $source, array $args ) { 55 | $content_types = $source['contentTypes']; 56 | 57 | if ( ! empty( $args['include'] ) ) { 58 | $content_types = array_intersect_key( $content_types, array_flip( $args['include'] ) ); 59 | } 60 | 61 | return ! empty( $content_types ) ? $content_types : null; 62 | }, 63 | ], 64 | 'general' => [ 65 | 'type' => General::get_type_name(), 66 | 'description' => static fn () => __( 'Sitemap general settings.', 'wp-graphql-rank-math' ), 67 | ], 68 | 'sitemapIndexUrl' => [ 69 | 'type' => 'String', 70 | 'description' => static fn () => __( 'The URL to the sitemap index.', 'wp-graphql-rank-math' ), 71 | ], 72 | 'taxonomies' => [ 73 | 'type' => [ 'list_of' => Taxonomy::get_type_name() ], 74 | 'args' => [ 75 | 'include' => [ 76 | 'type' => [ 'list_of' => 'TaxonomyEnum' ], 77 | 'description' => static fn () => __( 'Limit results to specific taxonomies.', 'wp-graphql-rank-math' ), 78 | ], 79 | ], 80 | 'description' => static fn () => __( 'Content types included in the sitemap.', 'wp-graphql-rank-math' ), 81 | 'resolve' => static function ( $source, array $args ) { 82 | $taxonomies = $source['taxonomies']; 83 | 84 | if ( ! empty( $args['include'] ) ) { 85 | $taxonomies = array_intersect_key( $taxonomies, array_flip( $args['include'] ) ); 86 | } 87 | 88 | return ! empty( $taxonomies ) ? $taxonomies : null; 89 | }, 90 | ], 91 | ]; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/Utils/RMUtils.php: -------------------------------------------------------------------------------- 1 | $args The arguments to filter the redirections with. 66 | * 67 | * @since 0.0.13 68 | * 69 | * @return array 70 | */ 71 | public static function get_redirections( array $args = [] ): array { 72 | return DB::get_redirections( $args ); 73 | } 74 | 75 | /** 76 | * Get a redirection by its ID. 77 | * 78 | * @see \RankMath\Redirections\DB\get_redirection_by_id() 79 | * 80 | * @param int $id ID of the record to search for. 81 | * @param string $status Status to filter with. 82 | * 83 | * @since 0.0.13 84 | * 85 | * @return bool|array 86 | */ 87 | public static function get_redirection_by_id( int $id, string $status = 'all' ) { 88 | return DB::get_redirection_by_id( $id, $status ); 89 | } 90 | 91 | /** 92 | * Gets a redirection directly from the database. 93 | * 94 | * This allows us to check for redirections without having to reset the existing DB::$table. 95 | * 96 | * @see https://support.rankmath.com/ticket/adding-where-clause-to-redirection-query-overwrites-existing-query 97 | * 98 | * @param int $id ID of the redirection to get. 99 | * 100 | * @since 0.0.13 101 | * 102 | * @return array|null 103 | */ 104 | public static function get_redirection_from_db( int $id ) { 105 | $result = wp_cache_get( 'rm_redirection_' . $id, 'rm_redirections' ); 106 | 107 | if ( false === $result ) { 108 | global $wpdb; 109 | 110 | $result = $wpdb->get_row( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery 111 | $wpdb->prepare( 112 | "SELECT * FROM {$wpdb->prefix}rank_math_redirections WHERE id = %d LIMIT 1", 113 | $id 114 | ), 115 | ARRAY_A 116 | ); 117 | 118 | wp_cache_set( 'rm_redirection_' . $id, $result, 'rm_redirections' ); 119 | } 120 | 121 | return ! empty( $result ) ? $result : null; 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /src/Modules/Redirection/Type/WPObject/Redirection.php: -------------------------------------------------------------------------------- 1 | [ 42 | 'type' => 'String', 43 | 'description' => static fn () => __( 'The date the redirection was created.', 'wp-graphql-rank-math' ), 44 | ], 45 | 'dateCreatedGmt' => [ 46 | 'type' => 'String', 47 | 'description' => static fn () => __( 'The GMT date the redirection was created.', 'wp-graphql-rank-math' ), 48 | ], 49 | 'dateModified' => [ 50 | 'type' => 'String', 51 | 'description' => static fn () => __( 'The date the redirection was last modified.', 'wp-graphql-rank-math' ), 52 | ], 53 | 'dateModifiedGmt' => [ 54 | 'type' => 'String', 55 | 'description' => static fn () => __( 'The GMT date the redirection was last modified.', 'wp-graphql-rank-math' ), 56 | ], 57 | 'dateLastAccessed' => [ 58 | 'type' => 'String', 59 | 'description' => static fn () => __( 'The date the redirection was last accessed.', 'wp-graphql-rank-math' ), 60 | ], 61 | 'dateLastAccessedGmt' => [ 62 | 'type' => 'String', 63 | 'description' => static fn () => __( 'The GMT date the redirection was last accessed.', 'wp-graphql-rank-math' ), 64 | ], 65 | 'hits' => [ 66 | 'type' => 'Int', 67 | 'description' => static fn () => __( 'The number of hits for this redirection.', 'wp-graphql-rank-math' ), 68 | ], 69 | 'redirectToUrl' => [ 70 | 'type' => 'String', 71 | 'description' => static fn () => __( 'The URL to redirect to.', 'wp-graphql-rank-math' ), 72 | ], 73 | 'sources' => [ 74 | 'type' => [ 'list_of' => RedirectionSource::get_type_name() ], 75 | 'description' => static fn () => __( 'The sources of the redirection.', 'wp-graphql-rank-math' ), 76 | ], 77 | 'status' => [ 78 | 'type' => RedirectionStatusEnum::get_type_name(), 79 | 'description' => static fn () => __( 'The status of the redirection.', 'wp-graphql-rank-math' ), 80 | ], 81 | 'type' => [ 82 | 'type' => RedirectionTypeEnum::get_type_name(), 83 | 'description' => static fn () => __( 'The redirection type (HTTP status code).', 'wp-graphql-rank-math' ), 84 | ], 85 | ]; 86 | } 87 | 88 | /** 89 | * {@inheritDoc} 90 | */ 91 | public static function get_interfaces(): array { 92 | return [ 93 | 'Node', 94 | 'DatabaseIdentifier', 95 | ]; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/Type/WPObject/Settings/General/BreadcrumbsConfig.php: -------------------------------------------------------------------------------- 1 | [ 38 | 'type' => 'String', 39 | 'description' => static fn () => __( 'Separator character or string that appears between breadcrumb items.', 'wp-graphql-rank-math' ), 40 | ], 41 | 'hasHome' => [ 42 | 'type' => 'Boolean', 43 | 'description' => static fn () => __( 'Whether to display the homepage breadcrumb in trail.', 'wp-graphql-rank-math' ), 44 | ], 45 | 'homeLabel' => [ 46 | 'type' => 'String', 47 | 'description' => static fn () => __( 'Label used for homepage link (first item) in breadcrumbs.', 'wp-graphql-rank-math' ), 48 | ], 49 | 'homeUrl' => [ 50 | 'type' => 'String', 51 | 'description' => static fn () => __( 'Link to use for homepage (first item) in breadcrumbs.', 'wp-graphql-rank-math' ), 52 | ], 53 | 'prefix' => [ 54 | 'type' => 'String', 55 | 'description' => static fn () => __( 'Prefix for the breadcrumb path.', 'wp-graphql-rank-math' ), 56 | ], 57 | 'archiveFormat' => [ 58 | 'type' => 'String', 59 | 'description' => static fn () => __( 'Format the label used for archive pages.', 'wp-graphql-rank-math' ), 60 | ], 61 | 'searchFormat' => [ 62 | 'type' => 'String', 63 | 'description' => static fn () => __( 'Format the label used for search results pages.', 'wp-graphql-rank-math' ), 64 | ], 65 | 'notFoundLabel' => [ 66 | 'type' => 'String', 67 | 'description' => static fn () => __( 'Label used for 404 error item in breadcrumbs.', 'wp-graphql-rank-math' ), 68 | ], 69 | 'hasPostTitle' => [ 70 | 'type' => 'Boolean', 71 | 'description' => static fn () => __( 'Whether the post title is visible in the breadcrumbs.', 'wp-graphql-rank-math' ), 72 | ], 73 | 'hasAncestorCategories' => [ 74 | 'type' => 'Boolean', 75 | 'description' => static fn () => __( 'Whether to show all ancestor categories, if a category is a child category.', 'wp-graphql-rank-math' ), 76 | ], 77 | 'hasTaxonomyName' => [ 78 | 'type' => 'Boolean', 79 | 'description' => static fn () => __( 'Whether the taxonomy name is visible in the breadcrumbs.', 'wp-graphql-rank-math' ), 80 | ], 81 | ]; 82 | 83 | if ( 'page' === get_option( 'show_on_front' ) && 0 < get_option( 'page_for_posts' ) ) { 84 | $fields['hasBlogPage'] = [ 85 | 'type' => 'Boolean', 86 | 'description' => static fn () => __( 'Whether the Blog page is visible in the breadcrumbs. Only relevant if you have a Posts page set.', 'wp-graphql-rank-math' ), 87 | ]; 88 | } 89 | 90 | return $fields; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /vendor-prefixed/axepress/wp-graphql-plugin-boilerplate/src/Abstracts/ConnectionType.php: -------------------------------------------------------------------------------- 1 | >, 22 | * description: callable():string, 23 | * defaultValue?: mixed 24 | * } 25 | * 26 | * @phpstan-type ConnectionFieldConfig array{ 27 | * type: string|array>, 28 | * description: callable():string, 29 | * args?: array, 30 | * resolve?: callable, 31 | * deprecationReason?: callable():string, 32 | * } 33 | * 34 | * @phpstan-type ConnectionConfig array{ 35 | * fromType: string, 36 | * fromFieldName: string, 37 | * resolve: callable, 38 | * oneToOne?: bool, 39 | * toType?: string, 40 | * connectionArgs?: array, 41 | * connectionFields?: array, 42 | * } 43 | * 44 | * phpcs:enable SlevomatCodingStandard.Namespaces.FullyQualifiedClassNameInAnnotation 45 | */ 46 | abstract class ConnectionType implements GraphQLType, Registrable 47 | { 48 | use TypeNameTrait; 49 | /** 50 | * {@inheritDoc} 51 | */ 52 | public static function init(): void 53 | { 54 | add_action('graphql_register_types', [static::class, 'register']); 55 | } 56 | /** 57 | * Defines all possible connection args for the GraphQL type. 58 | * 59 | * @return array 60 | */ 61 | abstract protected static function connection_args(): array; 62 | /** 63 | * Gets the $config array used to register the connection to the GraphQL type. 64 | * 65 | * @param ConnectionConfig $config The connection config array. 66 | * 67 | * @return ConnectionConfig 68 | */ 69 | protected static function get_connection_config($config): array 70 | { 71 | return array_merge(['toType' => static::get_type_name()], $config); 72 | } 73 | /** 74 | * Returns a filtered array of connection args. 75 | * 76 | * @param ?string[] $filter_by an array of specific connections to return. 77 | * 78 | * @return array 79 | */ 80 | final public static function get_connection_args(?array $filter_by = null): array 81 | { 82 | $connection_args = static::connection_args(); 83 | if (empty($filter_by)) { 84 | return $connection_args; 85 | } 86 | $filtered_args = []; 87 | foreach ($filter_by as $filter) { 88 | $filtered_args[$filter] = $connection_args[$filter]; 89 | } 90 | return $filtered_args; 91 | } 92 | } 93 | } -------------------------------------------------------------------------------- /vendor-prefixed/axepress/wp-graphql-plugin-boilerplate/src/Abstracts/MutationType.php: -------------------------------------------------------------------------------- 1 | >, 20 | * description:callable():string, 21 | * defaultValue?:string 22 | * } 23 | * 24 | * @phpstan-type MutationOutputFieldConfig array{ 25 | * type:string|array>, 26 | * description:callable():string, 27 | * args?:array>, 29 | * description:callable():string, 30 | * defaultValue?:mixed 31 | * }>, 32 | * resolve?:callable, 33 | * deprecationReason?:callable():string 34 | * } 35 | * 36 | * @phpstan-type MutationTypeConfig array{ 37 | * description:callable():string, 38 | * eagerlyLoadType:bool, 39 | * inputFields:array, 40 | * outputFields:array, 41 | * mutateAndGetPayload:callable, 42 | * } 43 | * 44 | * @extends \WPGraphQL\RankMath\Vendor\AxeWP\GraphQL\Abstracts\Type 45 | * 46 | * phpcs:disable SlevomatCodingStandard.Namespaces.FullyQualifiedClassNameInAnnotation 47 | */ 48 | abstract class MutationType extends Type 49 | { 50 | /** 51 | * Gets the input fields for the mutation. 52 | * 53 | * @return array 54 | */ 55 | abstract public static function get_input_fields(): array; 56 | /** 57 | * Gets the fields for the type. 58 | * 59 | * @return array 60 | */ 61 | abstract public static function get_output_fields(): array; 62 | /** 63 | * Defines the mutation data modification closure. 64 | */ 65 | abstract public static function mutate_and_get_payload(): callable; 66 | /** 67 | * Register mutations to the GraphQL Schema. 68 | */ 69 | public static function register(): void 70 | { 71 | /** @todo remove when WPGraphQL > 2.3.0 is required. */ 72 | $config = Compat::resolve_graphql_config(static::get_type_config()); 73 | register_graphql_mutation(static::get_type_name(), $config); 74 | } 75 | /** 76 | * {@inheritDoc} 77 | */ 78 | public static function get_description(): string 79 | { 80 | return ''; 81 | } 82 | /** 83 | * {@inheritDoc} 84 | * 85 | * @return MutationTypeConfig 86 | */ 87 | protected static function get_type_config(): array 88 | { 89 | $config = parent::get_type_config(); 90 | $config['inputFields'] = static::get_input_fields(); 91 | $config['outputFields'] = static::get_output_fields(); 92 | $config['mutateAndGetPayload'] = static::mutate_and_get_payload(); 93 | return $config; 94 | } 95 | } 96 | } -------------------------------------------------------------------------------- /src/Modules/Redirection/Data/Cursor/RedirectionCursor.php: -------------------------------------------------------------------------------- 1 | 43 | */ 44 | public $query_vars = []; 45 | 46 | /** 47 | * Constructor 48 | * 49 | * @param array $query_args The query args. 50 | * @param string $cursor The cursor. 51 | */ 52 | public function __construct( $query_args, $cursor = 'after' ) { 53 | $this->query_vars = $query_args; 54 | $this->cursor = $cursor; 55 | 56 | // Get the cursor offset if any. 57 | $offset_key = 'graphql_' . $cursor . '_cursor'; 58 | $offset = $this->get_query_var( $offset_key ); 59 | 60 | $this->cursor_offset = absint( $offset ); 61 | 62 | $this->cursor_node = $this->get_cursor_node(); 63 | } 64 | 65 | /** 66 | * Get the WP Object instance for the cursor. 67 | * 68 | * This is cached internally so it should not generate additionl queries. 69 | * 70 | * @return ?array 71 | */ 72 | public function get_cursor_node() { 73 | if ( ! $this->cursor_offset ) { 74 | return null; 75 | } 76 | 77 | // We don't want to reset the sql clauses. 78 | return RMUtils::get_redirection_from_db( $this->cursor_offset ); 79 | } 80 | 81 | /** 82 | * Get the direction pagination is going in. 83 | * 84 | * @return string 85 | */ 86 | public function get_cursor_compare() { 87 | return 'DESC' === $this->query_vars['order'] ? '<' : '>'; 88 | } 89 | 90 | /** 91 | * Ensure the cursor_offset is a positive integer and we have a valid object for our cursor node. 92 | * 93 | * @return bool 94 | */ 95 | protected function is_valid_offset_and_node() { 96 | if ( 97 | ! is_int( $this->cursor_offset ) || 98 | 0 >= $this->cursor_offset || 99 | ! $this->cursor_node 100 | ) { 101 | return false; 102 | } 103 | 104 | return true; 105 | } 106 | 107 | /** 108 | * Return the additional AND operators for the where statement 109 | * 110 | * @return array 111 | */ 112 | public function get_where() { 113 | // If we have a bad cursor, just return an empty array. 114 | if ( ! $this->is_valid_offset_and_node() ) { 115 | return []; 116 | } 117 | 118 | $orderby = $this->get_query_var( 'orderby' ); 119 | $compare = $this->get_cursor_compare(); 120 | $comparison_value = $this->cursor_node[ $orderby ]; 121 | 122 | if ( 'id' === $orderby ) { 123 | $comparison_value = (int) $comparison_value; 124 | } 125 | 126 | return [ 127 | 'column' => $orderby, 128 | 'operator' => $compare, 129 | 'value' => $comparison_value, 130 | ]; 131 | } 132 | 133 | /** 134 | * Get the query variable for the provided name. 135 | * 136 | * @param string $name . 137 | * 138 | * @return mixed|null 139 | */ 140 | public function get_query_var( string $name ) { 141 | return ! empty( $this->query_vars[ $name ] ) ? $this->query_vars[ $name ] : null; 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /vendor-prefixed/axepress/wp-graphql-plugin-boilerplate/src/Helper/Compat.php: -------------------------------------------------------------------------------- 1 | =')) { 31 | return $config; 32 | } 33 | /** 34 | * Recursively resolve nested configuration arrays. 35 | * Some keys contain arrays of configurations that might also contain lazy-loaded values. 36 | */ 37 | $nested_configs = ['args', 'connections', 'connectionArgs', 'connectionFields', 'edgeFields', 'fields', 'inputFields', 'outputFields', 'values']; 38 | foreach ($nested_configs as $nested_key) { 39 | // Skip if the key doesn't exist or isn't an array. 40 | if (!isset($config[$nested_key]) || !is_array($config[$nested_key])) { 41 | continue; 42 | } 43 | foreach ($config[$nested_key] as $key => $value) { 44 | // If the value is an array, it might be a nested config requiring resolution. 45 | if (is_array($value)) { 46 | $config[$nested_key][$key] = self::resolve_graphql_config($value); 47 | } 48 | } 49 | } 50 | /** 51 | * Resolve the keys that cant be lazy-loaded in < 2.3.0. 52 | * 53 | * Mock \WPGraphQL\TypeRegistry::get_introspection_keys(). 54 | * 55 | * @see https://github.com/wp-graphql/wp-graphql/blob/f0988f9d70c592ae34902e6cd0a0ecf91774608e/src/Registry/TypeRegistry.php#L823-L836 56 | */ 57 | $introspection_keys = ['description', 'deprecationReason']; 58 | // @phpstan-ignore function.alreadyNarrowedType (`WPGraphQL::is_introspection_query()` is only available in WPGraphQL 1.28.0+) 59 | $has_introspection_check = method_exists(\WPGraphQL::class, 'is_introspection_query'); 60 | $is_introspection_query = $has_introspection_check ? \WPGraphQL::is_introspection_query() : false; 61 | foreach ($introspection_keys as $introspection_key) { 62 | // Skip if the key doesn't need to be resolved. 63 | if (!isset($config[$introspection_key]) || !is_callable($config[$introspection_key])) { 64 | continue; 65 | } 66 | // If we 're _sure_ we are not introspecting, we can safely set the value to null. 67 | if ($has_introspection_check && !$is_introspection_query) { 68 | $config[$introspection_key] = null; 69 | continue; 70 | } 71 | $config[$introspection_key] = $config[$introspection_key](); 72 | } 73 | return $config; 74 | } 75 | } 76 | } -------------------------------------------------------------------------------- /src/Extensions/WPGraphQLWooCommerce/Type/WPObject/SeoObjects.php: -------------------------------------------------------------------------------- 1 | =' ) ) { 44 | $product_types = array_merge( 45 | $product_types, 46 | [ 47 | 'DownloadableProduct', 48 | 'InventoriedProduct', 49 | 'ProductUnion', 50 | 'ProductWithAttributes', 51 | 'ProductWithDimensions', 52 | 'ProductWithPricing', 53 | 'ProductWithVariations', 54 | 'ProductVariation', 55 | ] 56 | ); 57 | } 58 | 59 | foreach ( $product_types as $graphql_type_name ) { 60 | Utils::overload_graphql_field_type( $graphql_type_name, 'seo', 'RankMathProductObjectSeo' ); 61 | } 62 | 63 | /** 64 | * @todo: remove this when we don't need to support WooGraphQL< 0.21.1 65 | * @see https://github.com/AxeWP/wp-graphql-rank-math/pull/115#issuecomment-2660900767 66 | */ 67 | if ( defined( 'WPGRAPHQL_WOOCOMMERCE_VERSION' ) && version_compare( WPGRAPHQL_WOOCOMMERCE_VERSION, '0.21.1', '<' ) ) { 68 | self::register_product_variation_types(); 69 | } 70 | } 71 | 72 | /** 73 | * Registers the SEO types for product variations. 74 | * 75 | * @todo: remove this when we don't need to support WooGraphQL< 0.21.1 76 | * @see https://github.com/AxeWP/wp-graphql-rank-math/pull/115#issuecomment-2660900767 77 | */ 78 | private static function register_product_variation_types(): void { 79 | // Register the Product Variation SEO type and apply it to the Product Variation and children. 80 | $type_name_for_product_variation = 'RankMathProductVariationObjectSeo'; 81 | 82 | register_graphql_object_type( 83 | $type_name_for_product_variation, 84 | // @todo Remove when WPGraphQL < 2.3.0 is dropped. 85 | Compat::resolve_graphql_config( 86 | [ 87 | 'description' => static fn () => __( 'The product variation object SEO data', 'wp-graphql-rank-math' ), 88 | 'interfaces' => [ ContentNodeSeo::get_type_name() ], 89 | 'fields' => [], 90 | 'eagerlyLoadType' => true, 91 | ] 92 | ), 93 | ); 94 | 95 | $product_variations = array_merge( 96 | [ 97 | 'ProductVariation', 98 | ], 99 | WP_GraphQL_WooCommerce::get_enabled_product_variation_types(), 100 | ); 101 | 102 | foreach ( $product_variations as $product_variation ) { 103 | Utils::overload_graphql_field_type( $product_variation, 'seo', $type_name_for_product_variation ); 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/Modules/Redirection/TypeRegistry.php: -------------------------------------------------------------------------------- 1 | > 21 | */ 22 | class RedirectionConnectionResolver extends AbstractConnectionResolver { 23 | /** 24 | * {@inheritDoc} 25 | */ 26 | protected function loader_name(): string { 27 | return RedirectionsLoader::$name; 28 | } 29 | 30 | /** 31 | * {@inheritDoc} 32 | */ 33 | protected function prepare_query_args( array $args ): array { 34 | /** 35 | * Prepare for later use 36 | */ 37 | $last = ! empty( $args['last'] ) ? $args['last'] : null; 38 | 39 | $query_args = []; 40 | 41 | if ( ! empty( $args['where']['search'] ) ) { 42 | $query_args['search'] = $args['where']['search']; 43 | } 44 | 45 | $query_args['status'] = ! empty( $args['where']['status'] ) ? $args['where']['status'] : 'active'; 46 | 47 | if ( ! empty( $args['where']['orderby']['field'] ) ) { 48 | $query_args['orderby'] = $args['where']['orderby']['field']; 49 | } 50 | 51 | $query_args['order'] = ! empty( $args['where']['orderby']['order'] ) ? $args['where']['orderby']['order'] : 'DESC'; 52 | 53 | // If $last is set, we need to reverse the order. 54 | if ( ! empty( $last ) ) { 55 | $query_args['order'] = 'DESC' === $query_args['order'] ? 'ASC' : 'DESC'; 56 | } 57 | 58 | /** 59 | * Set limit the highest value of $first and $last, with a (filterable) max of 100 60 | */ 61 | $query_args['limit'] = $this->one_to_one ? 1 : $this->get_query_amount() + 1; 62 | 63 | /** 64 | * Set the before and after cursors. This will modify the query in CoreSchemaFilters::add_redirection_pagination_support() 65 | */ 66 | $query_args['graphql_cursor_compare'] = ! empty( $last ) ? '>' : '<'; 67 | 68 | if ( ! empty( $args['after'] ) ) { 69 | $query_args['graphql_after_cursor'] = $this->get_after_offset(); 70 | } 71 | 72 | if ( ! empty( $args['before'] ) ) { 73 | $query_args['graphql_before_cursor'] = $this->get_before_offset(); 74 | } 75 | 76 | return $query_args; 77 | } 78 | 79 | /** 80 | * {@inheritDoc} 81 | */ 82 | protected function query( array $query_args ) { 83 | $query = RMUtils::get_redirections( $query_args ); 84 | 85 | // Prime the cache for each of the queried redirections. 86 | $loader = $this->get_loader(); 87 | if ( isset( $query['redirections'] ) ) { 88 | foreach ( $query['redirections'] as $redirection ) { 89 | $loader->prime( $redirection['id'], $redirection ); 90 | } 91 | } 92 | 93 | return $query; 94 | } 95 | 96 | /** 97 | * {@inheritDoc} 98 | */ 99 | public function should_execute() { 100 | $query_args = $this->get_query_args(); 101 | 102 | if ( isset( $query_args['status'] ) && 'active' === $query_args['status'] ) { 103 | return true; 104 | } 105 | 106 | return RMUtils::has_cap( 'redirections' ); 107 | } 108 | 109 | /** 110 | * {@inheritDoc} 111 | */ 112 | public function is_valid_offset( $offset ) { 113 | return ! empty( RMUtils::get_redirection_by_id( $offset ) ); 114 | } 115 | 116 | /** 117 | * {@inheritDoc} 118 | */ 119 | public function get_ids_from_query() { 120 | $ids = []; 121 | $query = $this->get_query(); 122 | $queried = ! empty( $query['redirections'] ) ? $query['redirections'] : []; 123 | 124 | if ( empty( $queried ) ) { 125 | return $ids; 126 | } 127 | 128 | $ids = array_column( $queried, 'id' ); 129 | 130 | // If we're going backwards, we need to reverse the array. 131 | $args = $this->get_args(); 132 | if ( ! empty( $args['last'] ) ) { 133 | $ids = array_reverse( $ids ); 134 | } 135 | 136 | return $ids; 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /src/Modules/Redirection/CoreSchemaFilters.php: -------------------------------------------------------------------------------- 1 | $loaders Data loaders. 42 | * @param \WPGraphQL\AppContext $context App context. 43 | * 44 | * @return array 45 | */ 46 | public static function register_loaders( array $loaders, AppContext $context ): array { 47 | $loaders[ RedirectionsLoader::$name ] = new RedirectionsLoader( $context ); 48 | 49 | return $loaders; 50 | } 51 | 52 | /** 53 | * Adds pagination support to the redirections query. 54 | * 55 | * @param \MyThemeShop\Database\Query_Builder $table The redirections table. 56 | * @param array $args The query args passed to the query. 57 | */ 58 | public static function add_redirection_pagination_support( &$table, array $args ): void { 59 | // Return early if its not a GraphQL request. 60 | if ( true !== is_graphql_request() ) { 61 | return; 62 | } 63 | 64 | $where = []; 65 | 66 | // Get a copy of the table, not the reference. 67 | $current_table = clone $table; 68 | 69 | // Apply the after cursor to the query. 70 | if ( ! empty( $args['graphql_after_cursor'] ) ) { 71 | $after_cursor = new RedirectionCursor( $args, 'after' ); 72 | $where = $after_cursor->get_where(); 73 | 74 | // Modify the table to include the where. 75 | if ( ! empty( $where ) ) { 76 | $current_table->where( $where['column'], $where['operator'], $where['value'], 'AND' ); 77 | } 78 | } 79 | 80 | // Apply the before cursor to the query. 81 | if ( ! empty( $args['graphql_before_cursor'] ) ) { 82 | $before_cursor = new RedirectionCursor( $args, 'before' ); 83 | $where = $before_cursor->get_where(); 84 | 85 | // Modify the table to include the where. 86 | if ( ! empty( $where ) ) { 87 | $current_table->where( $where['column'], $where['operator'], $where['value'], 'AND' ); 88 | } 89 | } 90 | 91 | // // Add cursor stabilization 92 | $orderby_dir = isset( $args['graphql_cursor_compare'] ) && '>' === $args['graphql_cursor_compare'] ? 'ASC' : 'DESC'; 93 | $current_table->orderBy( 'id', $orderby_dir ); 94 | 95 | // Set the table back to the reference. 96 | $table = $current_table; 97 | } 98 | 99 | /** 100 | * Deduplicates clauses on the Rank Math table instance. 101 | * 102 | * These are caused when paginating, since the $table is a static instance. 103 | * 104 | * @param string[] $clauses The clauses to dedupe. 105 | * 106 | * @return string[] 107 | */ 108 | public static function dedupe_pagination_clauses( array $clauses ): array { 109 | // Return early if its not a GraphQL request. 110 | if ( true !== is_graphql_request() ) { 111 | return $clauses; 112 | } 113 | 114 | // Dedupe the clauses. 115 | return array_unique( $clauses ); 116 | } 117 | } 118 | --------------------------------------------------------------------------------