[ 'network-robots/(?P[\d]+|network)' => [ 'callback' => [ 'Network', 'fetchSiteRobots' ], 'access' => 'manage_network' ], 'schema/templates' => [ 'callback' => [ 'Schema', 'getTemplates' ], 'access' => 'aioseo_page_schema_settings' ], 'search-statistics/stats/seo-statistics' => [ 'callback' => [ 'SearchStatistics\SearchStatistics', 'getSeoStatistics' ], 'access' => 'aioseo_search_statistics_settings' ], 'search-statistics/stats/keywords' => [ 'callback' => [ 'SearchStatistics\SearchStatistics', 'getKeywords' ], 'access' => 'aioseo_search_statistics_settings' ], 'search-statistics/stats/content-rankings' => [ 'callback' => [ 'SearchStatistics\SearchStatistics', 'getContentRankings' ], 'access' => 'aioseo_search_statistics_settings' ], 'search-statistics/post-detail' => [ 'callback' => [ 'SearchStatistics\SearchStatistics', 'getPostDetail' ], 'access' => 'aioseo_search_statistics_settings' ], 'search-statistics/post-detail/seo-statistics' => [ 'callback' => [ 'SearchStatistics\SearchStatistics', 'getPostDetailSeoStatistics' ], 'access' => 'aioseo_search_statistics_settings' ], 'search-statistics/post-detail/keywords' => [ 'callback' => [ 'SearchStatistics\SearchStatistics', 'getPostDetailKeywords' ], 'access' => 'aioseo_search_statistics_settings' ], 'search-statistics/post-detail/focus-keyword' => [ 'callback' => [ 'SearchStatistics\SearchStatistics', 'getPostDetailFocusKeywordTrend' ], 'access' => 'aioseo_search_statistics_settings' ], 'search-statistics/pagespeed' => [ 'callback' => [ 'SearchStatistics\SearchStatistics', 'getPageSpeed' ], 'access' => 'aioseo_search_statistics_settings' ], 'search-statistics/seo-analysis' => [ 'callback' => [ 'SearchStatistics\SearchStatistics', 'getSeoAnalysis' ], 'access' => 'aioseo_search_statistics_settings' ], 'search-statistics/inspection-result' => [ 'callback' => [ 'SearchStatistics\SearchStatistics', 'getInspectionResult' ], 'access' => 'aioseo_search_statistics_settings' ], 'search-statistics/index-status/objects' => [ 'callback' => [ 'SearchStatistics\IndexStatus', 'fetchObjects' ], 'access' => 'aioseo_search_statistics_settings' ], 'search-statistics/index-status/overview' => [ 'callback' => [ 'SearchStatistics\IndexStatus', 'fetchOverview' ], 'access' => 'aioseo_search_statistics_settings' ], 'search-statistics/keyword-rank-tracker/groups' => [ 'callback' => [ 'SearchStatistics\KeywordRankTracker', 'fetchGroups' ], 'access' => 'aioseo_search_statistics_settings' ], 'search-statistics/keyword-rank-tracker/keywords' => [ 'callback' => [ 'SearchStatistics\KeywordRankTracker', 'fetchKeywords' ], 'access' => 'aioseo_search_statistics_settings' ], 'search-statistics/keyword-rank-tracker/related-keywords' => [ 'callback' => [ 'SearchStatistics\KeywordRankTracker', 'fetchRelatedKeywords' ], 'access' => 'aioseo_search_statistics_settings' ], 'seo-revisions/(?Ppost|term)/(?P[\d]+)' => [ 'callback' => [ 'SeoRevisions', 'getRevisions' ], 'access' => 'aioseo_page_seo_revisions_settings' ], 'seo-revisions/diff' => [ 'callback' => [ 'SeoRevisions', 'getRevisionsDiff' ], 'access' => 'aioseo_page_seo_revisions_settings' ], 'seo-analysis/issues' => [ 'callback' => [ 'SeoAnalysis', 'getIssues' ], 'access' => 'aioseo_seo_analysis_settings' ], 'seo-analysis/issues/(?P[\a-z]+)/(?P[\0-9z]+)' => [ 'callback' => [ 'SeoAnalysis', 'getIssuesByObject' ], 'access' => 'aioseo_seo_analysis_settings' ], 'seo-analysis/objects/(?P[\a-z]+)' => [ 'callback' => [ 'SeoAnalysis', 'getObjectsByIssueCode' ], 'access' => 'aioseo_seo_analysis_settings' ], 'seo-analysis/objects' => [ 'callback' => [ 'SeoAnalysis', 'getObjects' ], 'access' => 'aioseo_seo_analysis_settings' ], 'seo-analysis/objects-scan-percent' => [ 'callback' => [ 'SeoAnalysis', 'getObjectsScanPercent' ], 'access' => 'aioseo_seo_analysis_settings' ], // Redirects 'redirects/options' => [ 'callback' => [ 'Redirects', 'getOptions' ], 'access' => 'aioseo_redirects_settings' ], 'redirects/export/(?Papache|nginx)' => [ 'callback' => [ 'Redirects', 'exportServer' ], 'access' => 'aioseo_redirects_settings' ], 'redirects/export-logs/(?Predirect|404)' => [ 'callback' => [ 'Redirects', 'exportLogs' ], 'access' => 'aioseo_redirects_settings' ], 'redirects/server/test' => [ 'callback' => [ 'Redirects', 'serverTest' ], 'access' => 'aioseo_redirects_manage' ], 'redirects/(?Ppost|term)/(?P[\d]+)' => [ 'callback' => [ 'Redirects', 'getRedirects' ], 'access' => [ 'aioseo_redirects_manage', 'aioseo_page_redirects_manage' ] ], 'redirects/manual-redirects/(?P[a-zA-Z0-9]+)' => [ 'callback' => [ 'Redirects', 'getManualRedirects' ], 'access' => 'aioseo_redirects_manage' ] ], 'POST' => [ 'activate' => [ 'callback' => [ 'License', 'activateLicense' ], 'access' => 'aioseo_general_settings' ], 'deactivate' => [ 'callback' => [ 'License', 'deactivateLicense' ], 'access' => 'aioseo_general_settings' ], 'multisite' => [ 'callback' => [ 'License', 'multisite' ], 'access' => 'aioseo_general_settings' ], 'activated' => [ 'callback' => [ 'License', 'activated' ], 'access' => 'aioseo_general_settings' ], 'network-sites/(?Pall|activated|deactivated)' => [ 'callback' => [ 'Network', 'fetchSites' ], 'access' => 'manage_network' ], 'network-robots/(?P[\d]+|network)' => [ 'callback' => [ 'Network', 'saveNetworkRobots' ], 'access' => 'manage_network' ], 'notification/local-business-organization-reminder' => [ 'callback' => [ 'Notifications', 'localBusinessOrganizationReminder' ], 'access' => 'any' ], 'notification/news-publication-name-reminder' => [ 'callback' => [ 'Notifications', 'newsPublicationNameReminder' ], 'access' => 'any' ], 'notification/v3-migration-local-business-number-reminder' => [ 'callback' => [ 'Notifications', 'migrationLocalBusinessNumberReminder' ], 'access' => 'any' ], 'notification/v3-migration-local-business-country-reminder' => [ 'callback' => [ 'Notifications', 'migrationLocalBusinessCountryReminder' ], 'access' => 'any' ], 'notification/import-local-business-country-reminder' => [ 'callback' => [ 'Notifications', 'importLocalBusinessCountryReminder' ], 'access' => 'any' ], 'notification/import-local-business-type-reminder' => [ 'callback' => [ 'Notifications', 'importLocalBusinessTypeReminder' ], 'access' => 'any' ], 'notification/import-local-business-number-reminder' => [ 'callback' => [ 'Notifications', 'importLocalBusinessNumberReminder' ], 'access' => 'any' ], 'notification/import-local-business-fax-reminder' => [ 'callback' => [ 'Notifications', 'importLocalBusinessFaxReminder' ], 'access' => 'any' ], 'notification/import-local-business-currencies-reminder' => [ 'callback' => [ 'Notifications', 'importLocalBusinessCurrenciesReminder' ], 'access' => 'any' ], 'schema/templates' => [ 'callback' => [ 'Schema', 'addTemplate' ], 'access' => 'aioseo_page_schema_settings' ], 'schema/validator/output' => [ 'callback' => [ 'Schema', 'getValidatorOutput' ], 'access' => 'aioseo_page_schema_settings' ], 'search-statistics/stats/keywords/posts' => [ 'callback' => [ 'SearchStatistics\SearchStatistics', 'getPagesByKeywords' ], 'access' => 'aioseo_search_statistics_settings' ], 'search-statistics/keyword-rank-tracker/keywords' => [ 'callback' => [ 'SearchStatistics\KeywordRankTracker', 'insertKeywords' ], 'access' => 'aioseo_search_statistics_settings' ], 'search-statistics/keyword-rank-tracker/groups' => [ 'callback' => [ 'SearchStatistics\KeywordRankTracker', 'insertGroups' ], 'access' => 'aioseo_search_statistics_settings' ], 'search-statistics/keyword-rank-tracker/relationships' => [ 'callback' => [ 'SearchStatistics\KeywordRankTracker', 'updateRelationships' ], 'access' => 'aioseo_search_statistics_settings' ], 'search-statistics/keyword-rank-tracker/statistics' => [ 'callback' => [ 'SearchStatistics\KeywordRankTracker', 'fetchStatistics' ], 'access' => 'aioseo_search_statistics_settings' ], 'seo-revisions/(?P[\d]+)' => [ 'callback' => [ 'SeoRevisions', 'updateRevision' ], 'access' => 'aioseo_page_seo_revisions_settings' ], 'seo-revisions/restore/(?P[\d]+)' => [ 'callback' => [ 'SeoRevisions', 'restoreRevision' ], 'access' => 'aioseo_page_seo_revisions_settings' ], 'seo-analysis/issues/(?P[\d]+)/ignore' => [ 'callback' => [ 'SeoAnalysis', 'ignoreIssue' ], 'access' => 'aioseo_seo_analysis_settings' ], 'seo-analysis/objects/(?P[\d]+)/keywords' => [ 'callback' => [ 'SeoAnalysis', 'addFocusKeyword' ], 'access' => 'aioseo_seo_analysis_settings' ], // Redirects 'redirects/(?Penabled|disabled|all)' => [ 'callback' => [ 'Redirects', 'fetchRedirects' ], 'access' => [ 'aioseo_redirects_manage', 'aioseo_page_redirects_manage' ] ], 'redirects/(?Plogs|404)/(?Pall)' => [ 'callback' => [ 'Redirects', 'fetchLogs' ], 'access' => [ 'aioseo_redirects_manage', 'aioseo_page_redirects_manage' ] ], 'redirects/bulk/(?Penable|disable|reset-hits)' => [ 'callback' => [ 'Redirects', 'bulk' ], 'access' => [ 'aioseo_redirects_manage', 'aioseo_page_redirects_manage' ] ], 'redirects' => [ 'callback' => [ 'Redirects', 'create' ], 'access' => [ 'aioseo_redirects_manage', 'aioseo_page_redirects_manage' ] ], 'redirects/(?P[\d]+)' => [ 'callback' => [ 'Redirects', 'update' ], 'access' => [ 'aioseo_redirects_manage', 'aioseo_page_redirects_manage' ] ], 'redirects/posts' => [ 'callback' => [ 'Redirects', 'getPosts' ], 'access' => 'aioseo_redirects_manage' ], 'redirects/export/(?Phtaccess|nginx|json)' => [ 'callback' => [ 'Redirects', 'export' ], 'access' => 'aioseo_redirects_settings' ], 'redirects/import' => [ 'callback' => [ 'Redirects', 'import' ], 'access' => 'aioseo_redirects_settings' ], 'redirects/import-plugins' => [ 'callback' => [ 'Settings', 'importPlugins', 'AIOSEO\Plugin\Pro\Redirects\Api' ], 'access' => 'aioseo_redirects_settings' ], 'redirects/import-csv' => [ 'callback' => [ 'Redirects', 'importCsv' ], 'access' => 'aioseo_redirects_settings' ], 'redirects/(?P[\d]+/test)' => [ 'callback' => [ 'Redirects', 'test' ], 'access' => [ 'aioseo_redirects_manage', 'aioseo_page_redirects_manage' ] ] ], 'PUT' => [ 'schema/templates' => [ 'callback' => [ 'Schema', 'updateTemplate' ], 'access' => 'aioseo_page_schema_settings' ], 'search-statistics/keyword-rank-tracker/groups/(?P[\d]+)' => [ 'callback' => [ 'SearchStatistics\KeywordRankTracker', 'updateGroup' ], 'access' => 'aioseo_search_statistics_settings' ], 'search-statistics/keyword-rank-tracker/keywords/(?P[\d]+)' => [ 'callback' => [ 'SearchStatistics\KeywordRankTracker', 'updateKeyword' ], 'access' => 'aioseo_search_statistics_settings' ], ], 'DELETE' => [ 'schema/templates' => [ 'callback' => [ 'Schema', 'deleteTemplate' ], 'access' => 'aioseo_page_schema_settings' ], 'seo-revisions/(?P[\d]+)' => [ 'callback' => [ 'SeoRevisions', 'deleteRevision' ], 'access' => 'aioseo_page_seo_revisions_settings' ], 'search-statistics/keyword-rank-tracker/groups' => [ 'callback' => [ 'SearchStatistics\KeywordRankTracker', 'deleteGroups' ], 'access' => 'aioseo_search_statistics_settings' ], 'search-statistics/keyword-rank-tracker/keywords' => [ 'callback' => [ 'SearchStatistics\KeywordRankTracker', 'deleteKeywords' ], 'access' => 'aioseo_search_statistics_settings' ], // Redirects 'redirects/logs/(?Plogs|404)' => [ 'callback' => [ 'Redirects', 'deleteLog' ], 'access' => 'aioseo_redirects_manage' ], 'redirects/(?P[\d]+)' => [ 'callback' => [ 'Redirects', 'delete' ], 'access' => [ 'aioseo_redirects_manage', 'aioseo_page_redirects_manage' ] ], 'redirects/bulk' => [ 'callback' => [ 'Redirects', 'bulkDelete' ], 'access' => 'aioseo_redirects_manage' ] ] // phpcs:enable WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound, Generic.Files.LineLength.MaxExceeded ]; /** * Get all the routes to register. * * @since 4.0.0 * * @return array An array of routes. */ protected function getRoutes() { $routes = array_merge_recursive( parent::getRoutes(), $this->proRoutes ); $addonsRoutes = array_filter( aioseo()->addons->doAddonFunction( 'api', 'getRoutes' ) ); foreach ( $addonsRoutes as $addonRoute ) { $routes = array_replace_recursive( $addonRoute, $routes ); } return $routes; } /** * Pass any API class back to an addon to run a similar method. * * @since 4.1.0 * * @param \WP_REST_Request $request The original request. * @param \WP_REST_Response $response An optional response. * @param string $apiClass The class to call. * @param string $apiMethod The method to call on the class. * @return mixed Anything the addon needs to return. */ public static function addonsApi( $request, $response, $apiClass, $apiMethod ) { $loadedAddons = aioseo()->addons->getLoadedAddons(); if ( ! empty( $loadedAddons ) ) { foreach ( $loadedAddons as $addon ) { $class = new \ReflectionClass( $addon ); $addonClass = $class->getNamespaceName() . $apiClass; $classExists = class_exists( $addonClass ); $methodExists = method_exists( $addonClass, $apiMethod ); if ( $classExists && $methodExists ) { $response = call_user_func_array( [ $addonClass, $apiMethod ], [ $request, $response ] ); } } } return $response; } /** * Validates access from the routes array. * * @since 4.1.6 * * @param \WP_REST_Request $request The REST Request. * @return bool True if validated, false if not. */ public function validateAccess( $request ) { $routeData = $this->getRouteData( $request ); if ( empty( $routeData ) || empty( $routeData['access'] ) ) { return false; } // Admins always have access. if ( aioseo()->access->isAdmin() ) { return true; } switch ( $routeData['access'] ) { case 'any': // The user has access if he has any of our capabilities. $user = wp_get_current_user(); $aioseoCaps = aioseo()->access->getCapabilityList(); foreach ( $user->get_role_caps() as $capability => $enabled ) { if ( $enabled && in_array( $capability, $aioseoCaps, true ) ) { return true; } } return false; case 'options': // Check that user has access to any of the options pages. $user = wp_get_current_user(); $aioseoCaps = aioseo()->access->getCapabilityList(); // Remove all caps that start with aioseo_page_ $aioseoCaps = array_filter( $aioseoCaps, function( $capability ) { return strpos( $capability, 'aioseo_page_' ) !== 0; } ); foreach ( $user->get_role_caps() as $capability => $enabled ) { if ( $enabled && in_array( $capability, $aioseoCaps, true ) ) { return true; } } return false; default: // The user has access if he has any of the required capabilities. if ( ! is_array( $routeData['access'] ) ) { $routeData['access'] = [ $routeData['access'] ]; } foreach ( $routeData['access'] as $access ) { if ( current_user_can( $access ) ) { return true; } } return false; } } }