sprintf( __( '%1$s Site Public', 'all-in-one-seo-pack' ), AIOSEO_PLUGIN_SHORT_NAME ), 'test' => [ $this, 'testCheckSitePublic' ], ]; $tests['direct']['aioseo_site_info'] = [ // Translators: 1 - The plugin short name ("AIOSEO"). 'label' => sprintf( __( '%1$s Site Info', 'all-in-one-seo-pack' ), AIOSEO_PLUGIN_SHORT_NAME ), 'test' => [ $this, 'testCheckSiteInfo' ], ]; $tests['direct']['aioseo_plugin_update'] = [ // Translators: 1 - The plugin short name ("AIOSEO"). 'label' => sprintf( __( '%1$s Plugin Update', 'all-in-one-seo-pack' ), AIOSEO_PLUGIN_SHORT_NAME ), 'test' => [ $this, 'testCheckPluginUpdate' ], ]; $tests['direct']['aioseo_schema_markup'] = [ // Translators: 1 - The plugin short name ("AIOSEO"). 'label' => sprintf( __( '%1$s Schema Markup', 'all-in-one-seo-pack' ), AIOSEO_PLUGIN_SHORT_NAME ), 'test' => [ $this, 'testCheckSchemaMarkup' ], ]; return $tests; } /** * Adds our site health debug info. * * @since 4.0.0 * * @param array $debugInfo The debug info. * @return array $debugInfo The debug info. */ public function addDebugInfo( $debugInfo ) { $fields = []; $noindexed = $this->noindexed(); if ( $noindexed ) { $fields['noindexed'] = $this->field( __( 'Noindexed content', 'all-in-one-seo-pack' ), implode( ', ', $noindexed ) ); } $nofollowed = $this->nofollowed(); if ( $nofollowed ) { $fields['nofollowed'] = $this->field( __( 'Nofollowed content', 'all-in-one-seo-pack' ), implode( ', ', $nofollowed ) ); } if ( ! count( $fields ) ) { return $debugInfo; } $debugInfo['aioseo'] = [ 'label' => __( 'SEO', 'all-in-one-seo-pack' ), 'description' => sprintf( // Translators: 1 - The plugin short name ("AIOSEO"). __( 'The fields below contain important SEO information from %1$s that may effect your site.', 'all-in-one-seo-pack' ), AIOSEO_PLUGIN_SHORT_NAME ), 'private' => false, 'show_count' => true, 'fields' => $fields, ]; return $debugInfo; } /** * Checks whether the site is public. * * @since 4.0.0 * * @return array The test result. */ public function testCheckSitePublic() { $test = 'aioseo_site_public'; if ( ! get_option( 'blog_public' ) ) { return $this->result( $test, 'critical', __( 'Your site does not appear in search results', 'all-in-one-seo-pack' ), __( 'Your site is set to private. This means WordPress asks search engines to exclude your website from search results.', 'all-in-one-seo-pack' ), $this->actionLink( admin_url( 'options-reading.php' ), __( 'Go to Settings > Reading', 'all-in-one-seo-pack' ) ) ); } return $this->result( $test, 'good', __( 'Your site appears in search results', 'all-in-one-seo-pack' ), __( 'Your site is set to public. Search engines will index your website and it will appear in search results.', 'all-in-one-seo-pack' ) ); } /** * Checks whether the site title and tagline are set. * * @since 4.0.0 * * @return array The test result. */ public function testCheckSiteInfo() { $siteTitle = get_bloginfo( 'name' ); $siteTagline = get_bloginfo( 'description' ); if ( ! $siteTitle || ! $siteTagline ) { return $this->result( 'aioseo_site_info', 'recommended', __( 'Your Site Title and/or Tagline are blank', 'all-in-one-seo-pack' ), sprintf( // Translators: 1 - The plugin short name ("AIOSEO"). __( 'Your Site Title and/or Tagline are blank. We recommend setting both of these values as %1$s requires these for various features, including our schema markup', 'all-in-one-seo-pack' ), AIOSEO_PLUGIN_SHORT_NAME ), $this->actionLink( admin_url( 'options-general.php' ), __( 'Go to Settings > General', 'all-in-one-seo-pack' ) ) ); } return $this->result( 'aioseo_site_info', 'good', __( 'Your Site Title and Tagline are set', 'all-in-one-seo-pack' ), sprintf( // Translators: 1 - The plugin short name ("AIOSEO"). __( 'Great! These are required for %1$s\'s schema markup and are often used as fallback values for various other features.', 'all-in-one-seo-pack' ), AIOSEO_PLUGIN_SHORT_NAME ) ); } /** * Checks whether the required settings for our schema markup are set. * * @since 4.0.0 * * @return array The test result. */ public function testCheckSchemaMarkup() { $menuPath = admin_url( 'admin.php?page=aioseo-search-appearance' ); if ( 'organization' === aioseo()->options->searchAppearance->global->schema->siteRepresents ) { if ( ! aioseo()->options->searchAppearance->global->schema->organizationName || ( ! aioseo()->options->searchAppearance->global->schema->organizationLogo && ! aioseo()->helpers->getSiteLogoUrl() ) ) { return $this->result( 'aioseo_schema_markup', 'recommended', __( 'Your Organization Name and/or Logo are blank', 'all-in-one-seo-pack' ), sprintf( // Translators: 1 - The plugin short name ("AIOSEO"). __( 'Your Organization Name and/or Logo are blank. These values are required for %1$s\'s Organization schema markup.', 'all-in-one-seo-pack' ), AIOSEO_PLUGIN_SHORT_NAME ), $this->actionLink( $menuPath, __( 'Go to Schema Settings', 'all-in-one-seo-pack' ) ) ); } return $this->result( 'aioseo_schema_markup', 'good', __( 'Your Organization Name and Logo are set', 'all-in-one-seo-pack' ), sprintf( // Translators: 1 - The plugin short name ("AIOSEO"). __( 'Awesome! These are required for %1$s\'s Organization schema markup.', 'all-in-one-seo-pack' ), AIOSEO_PLUGIN_SHORT_NAME ) ); } if ( ! aioseo()->options->searchAppearance->global->schema->person || ( 'manual' === aioseo()->options->searchAppearance->global->schema->person && ( ! aioseo()->options->searchAppearance->global->schema->personName || ! aioseo()->options->searchAppearance->global->schema->personLogo ) ) ) { return $this->result( 'aioseo_schema_markup', 'recommended', __( 'Your Person Name and/or Image are blank', 'all-in-one-seo-pack' ), sprintf( // Translators: 1 - The plugin short name ("AIOSEO"). __( 'Your Person Name and/or Image are blank. These values are required for %1$s\'s Person schema markup.', 'all-in-one-seo-pack' ), AIOSEO_PLUGIN_SHORT_NAME ), $this->actionLink( $menuPath, __( 'Go to Schema Settings', 'all-in-one-seo-pack' ) ) ); } return $this->result( 'aioseo_schema_markup', 'good', __( 'Your Person Name and Image are set', 'all-in-one-seo-pack' ), sprintf( // Translators: 1 - The plugin short name ("AIOSEO"). __( 'Awesome! These are required for %1$s\'s Person schema markup.', 'all-in-one-seo-pack' ), AIOSEO_PLUGIN_SHORT_NAME ) ); } /** * Checks whether the required settings for our schema markup are set. * * @since 4.0.0 * * @return array The test result. */ public function testCheckPluginUpdate() { $response = wp_remote_get( 'https://api.wordpress.org/plugins/info/1.0/all-in-one-seo-pack.json' ); $body = wp_remote_retrieve_body( $response ); if ( ! $body ) { // Something went wrong. return; } $pluginData = json_decode( $body ); $shouldUpdate = version_compare( AIOSEO_VERSION, $pluginData->version, '<' ); if ( $shouldUpdate ) { return $this->result( 'aioseo_plugin_update', 'critical', sprintf( // Translators: 1 - The plugin short name ("AIOSEO"). __( '%1$s needs to be updated', 'all-in-one-seo-pack' ), AIOSEO_PLUGIN_SHORT_NAME ), sprintf( // Translators: 1 - The plugin short name ("AIOSEO"). __( 'An update is available for %1$s. Upgrade to the latest version to receive all the latest features, bug fixes and security improvements.', 'all-in-one-seo-pack' ), AIOSEO_PLUGIN_SHORT_NAME ), $this->actionLink( admin_url( 'plugins.php' ), __( 'Go to Plugins', 'all-in-one-seo-pack' ) ) ); } return $this->result( 'aioseo_plugin_update', 'good', sprintf( // Translators: 1 - The plugin short name ("AIOSEO"). __( '%1$s is updated to the latest version', 'all-in-one-seo-pack' ), AIOSEO_PLUGIN_SHORT_NAME ), __( 'Fantastic! By updating to the latest version, you have access to all the latest features, bug fixes and security improvements.', 'all-in-one-seo-pack' ) ); } /** * Returns a list of noindexed content. * * @since 4.0.0 * * @return array $noindexed A list of noindexed content. */ protected function noindexed() { $globalDefault = aioseo()->options->searchAppearance->advanced->globalRobotsMeta->default; if ( ! $globalDefault && aioseo()->options->searchAppearance->advanced->globalRobotsMeta->noindex ) { return [ __( 'Your entire site is set to globally noindex content.', 'all-in-one-seo-pack' ) ]; } $noindexed = []; if ( ! $globalDefault && aioseo()->options->searchAppearance->advanced->globalRobotsMeta->noindexPaginated ) { $noindexed[] = __( 'Paginated Content', 'all-in-one-seo-pack' ); } $archives = [ 'author' => __( 'Author Archives', 'all-in-one-seo-pack' ), 'date' => __( 'Date Archives', 'all-in-one-seo-pack' ), 'search' => __( 'Search Page', 'all-in-one-seo-pack' ) ]; // Archives. foreach ( $archives as $name => $type ) { if ( ! aioseo()->options->searchAppearance->archives->{ $name }->advanced->robotsMeta->default && aioseo()->options->searchAppearance->archives->{ $name }->advanced->robotsMeta->noindex ) { $noindexed[] = $type; } } foreach ( aioseo()->helpers->getPublicPostTypes() as $postType ) { if ( aioseo()->dynamicOptions->searchAppearance->postTypes->has( $postType['name'] ) && ! aioseo()->dynamicOptions->searchAppearance->postTypes->{ $postType['name'] }->advanced->robotsMeta->default && aioseo()->dynamicOptions->searchAppearance->postTypes->{ $postType['name'] }->advanced->robotsMeta->noindex ) { $noindexed[] = $postType['label'] . ' (' . $postType['name'] . ')'; } } foreach ( aioseo()->helpers->getPublicTaxonomies() as $taxonomy ) { if ( aioseo()->dynamicOptions->searchAppearance->taxonomies->has( $taxonomy['name'] ) && ! aioseo()->dynamicOptions->searchAppearance->taxonomies->{ $taxonomy['name'] }->advanced->robotsMeta->default && aioseo()->dynamicOptions->searchAppearance->taxonomies->{ $taxonomy['name'] }->advanced->robotsMeta->noindex ) { $noindexed[] = $taxonomy['label'] . ' (' . $taxonomy['name'] . ')'; } } return $noindexed; } /** * Returns a list of nofollowed content. * * @since 4.0.0 * * @return array $nofollowed A list of nofollowed content. */ protected function nofollowed() { $globalDefault = aioseo()->options->searchAppearance->advanced->globalRobotsMeta->default; if ( ! $globalDefault && aioseo()->options->searchAppearance->advanced->globalRobotsMeta->nofollow ) { return [ __( 'Your entire site is set to globally nofollow content.', 'all-in-one-seo-pack' ) ]; } $nofollowed = []; if ( ! $globalDefault && aioseo()->options->searchAppearance->advanced->globalRobotsMeta->nofollowPaginated ) { $nofollowed[] = __( 'Paginated Content', 'all-in-one-seo-pack' ); } $archives = [ 'author' => __( 'Author Archives', 'all-in-one-seo-pack' ), 'date' => __( 'Date Archives', 'all-in-one-seo-pack' ), 'search' => __( 'Search Page', 'all-in-one-seo-pack' ) ]; // Archives. foreach ( $archives as $name => $type ) { if ( ! aioseo()->options->searchAppearance->archives->{ $name }->advanced->robotsMeta->default && aioseo()->options->searchAppearance->archives->{ $name }->advanced->robotsMeta->nofollow ) { $nofollowed[] = $type; } } foreach ( aioseo()->helpers->getPublicPostTypes() as $postType ) { if ( aioseo()->dynamicOptions->searchAppearance->postTypes->has( $postType['name'] ) && ! aioseo()->dynamicOptions->searchAppearance->postTypes->{ $postType['name'] }->advanced->robotsMeta->default && aioseo()->dynamicOptions->searchAppearance->postTypes->{ $postType['name'] }->advanced->robotsMeta->nofollow ) { $nofollowed[] = $postType['label'] . ' (' . $postType['name'] . ')'; } } foreach ( aioseo()->helpers->getPublicTaxonomies() as $taxonomy ) { if ( aioseo()->dynamicOptions->searchAppearance->taxonomies->has( $taxonomy['name'] ) && ! aioseo()->dynamicOptions->searchAppearance->taxonomies->{ $taxonomy['name'] }->advanced->robotsMeta->default && aioseo()->dynamicOptions->searchAppearance->taxonomies->{ $taxonomy['name'] }->advanced->robotsMeta->nofollow ) { $nofollowed[] = $taxonomy['label'] . ' (' . $taxonomy['name'] . ')'; } } return $nofollowed; } /** * Returns a debug info data field. * * @since 4.0.0 * * @param string $label The field label. * @param string $value The field value. * @param boolean $private Whether the field shouldn't be included if the debug info is copied. * @return array The debug info data field. */ private function field( $label, $value, $private = false ) { return [ 'label' => $label, 'value' => $value, 'private' => $private, ]; } /** * Returns the test result. * * @since 4.0.0 * * @param string $name The test name. * @param string $status The result status. * @param string $header The test header. * @param string $description The result description. * @param string $actions The result actions. * @return array The test result. */ protected function result( $name, $status, $header, $description, $actions = '' ) { $color = 'blue'; switch ( $status ) { case 'good': break; case 'recommended': $color = 'orange'; break; case 'critical': $color = 'red'; break; default: break; } return [ 'test' => $name, 'status' => $status, 'label' => $header, 'description' => $description, 'actions' => $actions, 'badge' => [ 'label' => AIOSEO_PLUGIN_SHORT_NAME, 'color' => $color, ], ]; } /** * Returns an action link. * * @since 4.0.0 * * @param string $path The path. * @param string $anchor The anchor text. * @return string The action link. */ protected function actionLink( $path, $anchor ) { return sprintf( '

%2$s

', $path, $anchor ); } }