File: /var/www/hcv/wp-content/plugins/wordpress-seo/src/deprecated/src/actions/indexables-page-action.php
<?php
namespace Yoast\WP\SEO\Actions;
use Yoast\WP\SEO\Helpers\Indexables_Page_Helper;
use Yoast\WP\SEO\Helpers\Options_Helper;
use Yoast\WP\SEO\Helpers\Post_Type_Helper;
use Yoast\WP\SEO\Repositories\Indexable_Repository;
/**
* Get action for indexables.
*
* @deprecated 20.4
* @codeCoverageIgnore
*/
class Indexables_Page_Action {
/**
* The indexable repository.
*
* @var Indexable_Repository
*/
private $indexable_repository;
/**
* The post type helper.
*
* @var Post_Type_Helper
*/
private $post_type_helper;
/**
* The options helper.
*
* @var Options_Helper
*/
private $options_helper;
/**
* The indexables page helper.
*
* @var Indexables_Page_Helper
*/
private $indexables_page_helper;
/**
* Indexable_Action constructor.
*
* @deprecated 20.4
* @codeCoverageIgnore
*
* @param Indexable_Repository $indexable_repository The indexable repository.
* @param Post_Type_Helper $post_type_helper The post type helper.
* @param Options_Helper $options_helper The options helper.
* @param Indexables_Page_Helper $indexables_page_helper The indexables page helper.
*/
public function __construct(
Indexable_Repository $indexable_repository,
Post_Type_Helper $post_type_helper,
Options_Helper $options_helper,
Indexables_Page_Helper $indexables_page_helper
) {
\_deprecated_function( __METHOD__, 'Yoast SEO 20.4' );
$this->indexable_repository = $indexable_repository;
$this->post_type_helper = $post_type_helper;
$this->options_helper = $options_helper;
$this->indexables_page_helper = $indexables_page_helper;
}
/**
* Get public sub types that are relevant for the indexable page.
*
* @deprecated 20.4
* @codeCoverageIgnore
*
* @return array The subtypes.
*/
protected function get_sub_types() {
$object_sub_types = \array_values( $this->post_type_helper->get_public_post_types() );
$excluded_post_types = \apply_filters( 'wpseo_indexable_excluded_post_types', [ 'attachment' ] );
/**
* Filter: 'wpseo_indexable_included_post_types' - Allow developers to specify which post types will
* be shown in the indexables overview cards.
*
* @param array $included_post_types The currently included post types.
*/
$included_post_types = \apply_filters_deprecated( 'wpseo_indexable_included_post_types', [ [ 'post', 'page' ] ], 'Yoast SEO 20.4' );
$object_sub_types = \array_diff( $object_sub_types, $excluded_post_types );
$only_post_pages = \array_intersect( $object_sub_types, $included_post_types );
$wanted_sub_types = [];
foreach ( $only_post_pages as $sub_type ) {
if ( $this->post_type_helper->has_metabox( $sub_type ) ) {
$wanted_sub_types[] = $sub_type;
}
}
return $wanted_sub_types;
}
/**
* Creates a query that can find public indexables.
*
* @deprecated 20.4
* @codeCoverageIgnore
*
* @return ORM Returns an ORM instance that can be used to execute the query.
*/
protected function query() {
$sub_types = $this->get_sub_types();
if ( empty( $sub_types ) ) {
// If there are no subtypes to display, any query should return an empty result.
return $this->indexable_repository->query()->where_raw( '1 = 0' );
}
// Make sure that we consider the noindex of both each post but also for the global values.
$build_where = '(';
foreach ( $sub_types as $sub_type ) {
$is_default_noindex = $this->post_type_helper->is_indexable( $sub_type ) ? ' OR is_robots_noindex IS NULL' : '';
$build_where .= '( object_sub_type = \'' . $sub_type . '\' AND ( is_robots_noindex = FALSE' . $is_default_noindex . ' ) ) OR';
}
$build_where = \rtrim( $build_where, ' OR' );
$build_where .= ')';
return $this->indexable_repository->query()
->where_raw( '( post_status = \'publish\' OR post_status IS NULL )' )
->where_in( 'object_type', [ 'post' ] )
->where_raw( $build_where );
}
/**
* Gets the neccessary information to set up the indexables page.
*
* @deprecated 20.4
* @codeCoverageIgnore
*
* @param int $content_threshold The threshold to check against for enough content.
* @param int $analysis_threshold The threshold to check against for enough analyzed content.
*
* @return array The neccessary information to set up the indexables page.
*/
public function get_setup_info( $content_threshold, $analysis_threshold ) {
\_deprecated_function( __METHOD__, 'Yoast SEO 20.4' );
$features = [
'isSeoScoreEnabled' => $this->options_helper->get( 'keyword_analysis_active', true ),
'isReadabilityEnabled' => $this->options_helper->get( 'content_analysis_active', true ),
'isLinkCountEnabled' => $this->options_helper->get( 'enable_text_link_counter', true ),
];
$posts_with_seo_score = 0;
$posts_with_readability = 0;
$posts_without_keyphrase = [];
$all_posts = $this->query()->count();
if ( $all_posts < 1 ) {
$this->set_indexables_state( 'no-content' );
return [
'enabledFeatures' => $features,
'enoughContent' => false,
'enoughAnalysedContent' => false,
];
}
$posts_with_seo_score = $this->query()
->where_not_equal( 'primary_focus_keyword', 0 )
->count();
$posts_without_keyphrase = $this->query()
->where_null( 'primary_focus_keyword' )
->order_by_desc( 'incoming_link_count' )
->find_many();
$posts_with_readability = $this->query()
->where_not_equal( 'readability_score', 0 )
->count();
$analysed_content = ( \max( $posts_with_seo_score, $posts_with_readability ) / $all_posts );
$enough_content = $all_posts > $content_threshold;
$enough_analysed_content = $analysed_content > $analysis_threshold;
if ( ! $enough_content ) {
$this->set_indexables_state( 'not-enough-content' );
}
elseif ( ! $enough_analysed_content ) {
$this->set_indexables_state( 'not-enough-analysed-content' );
}
else {
$this->set_indexables_state( 'lists-shown' );
}
return [
'enabledFeatures' => $features,
'enoughContent' => $enough_content,
'enoughAnalysedContent' => $enough_analysed_content,
'postsWithoutKeyphrase' => \array_map(
static function ( $indexable ) {
$output = $indexable;
if ( $indexable->incoming_link_count === null ) {
$output->incoming_link_count = 0;
}
return $output;
},
$posts_without_keyphrase
),
];
}
/**
* Gets the posts with the smallest readability scores.
*
* @deprecated 20.4
* @codeCoverageIgnore
*
* @param int $limit The maximum amount of results to return.
*
* @return array The posts with the smallest readability scores as an array.
*/
public function get_least_readable( $limit ) {
\_deprecated_function( __METHOD__, 'Yoast SEO 20.4' );
$least_readability_ignore_list = $this->options_helper->get( 'least_readability_ignore_list', [] );
$ignore_list = empty( $least_readability_ignore_list ) ? [ -1 ] : $least_readability_ignore_list;
$least_readable = $this->query()
->select_many( 'id', 'object_id', 'object_sub_type', 'permalink', 'breadcrumb_title', 'readability_score' )
->where_not_in( 'id', $ignore_list )
->where_not_equal( 'readability_score', 0 )
->order_by_asc( 'readability_score' )
->limit( $limit )
->find_many();
return \array_map( [ $this->indexable_repository, 'ensure_permalink' ], $least_readable );
}
/**
* Gets the posts with the lowest seo scores.
*
* @deprecated 20.4
* @codeCoverageIgnore
*
* @param int $limit The maximum amount of results to return.
*
* @return array The posts with the lowest seo scores as an array.
*/
public function get_least_seo_score( $limit ) {
\_deprecated_function( __METHOD__, 'Yoast SEO 20.4' );
// Where_not_equal needs the set to check against not to be empty.
$least_seo_score_ignore_list = $this->options_helper->get( 'least_seo_score_ignore_list', [] );
$ignore_list = empty( $least_seo_score_ignore_list ) ? [ -1 ] : $least_seo_score_ignore_list;
$least_seo_score = $this->query()
->select_many( 'id', 'object_id', 'object_sub_type', 'permalink', 'breadcrumb_title', 'primary_focus_keyword', 'primary_focus_keyword_score' )
->where_not_in( 'id', $ignore_list )
->where_not_equal( 'primary_focus_keyword', 0 )
->order_by_asc( 'primary_focus_keyword_score' )
->limit( $limit )
->find_many();
return \array_map( [ $this->indexable_repository, 'ensure_permalink' ], $least_seo_score );
}
/**
* Gets the most linked posts.
*
* @deprecated 20.4
* @codeCoverageIgnore
*
* @param int $limit The maximum amount of results to return.
*
* @return array The most linked posts as an array.
*/
public function get_most_linked( $limit ) {
\_deprecated_function( __METHOD__, 'Yoast SEO 20.4' );
// Where_not_equal needs the set to check against not to be empty.
$most_linked_ignore_list = $this->options_helper->get( 'most_linked_ignore_list', [] );
$ignore_list = empty( $most_linked_ignore_list ) ? [ -1 ] : $most_linked_ignore_list;
$most_linked = $this->query()
->select_many( 'id', 'object_id', 'object_sub_type', 'permalink', 'breadcrumb_title', 'incoming_link_count', 'is_cornerstone' )
->where_gt( 'incoming_link_count', 0 )
->where_not_null( 'incoming_link_count' )
->where_not_in( 'id', $ignore_list )
->order_by_desc( 'incoming_link_count' )
->limit( $limit )
->find_many();
return \array_map( [ $this->indexable_repository, 'ensure_permalink' ], $most_linked );
}
/**
* Gets the least linked posts.
*
* @deprecated 20.4
* @codeCoverageIgnore
*
* @param int $limit The maximum amount of results to return.
*
* @return array The most linked posts as an array.
*/
public function get_least_linked( $limit ) {
\_deprecated_function( __METHOD__, 'Yoast SEO 20.4' );
// Where_not_equal needs the set to check against not to be empty.
$least_linked_ignore_list = $this->options_helper->get( 'least_linked_ignore_list', [] );
$ignore_list = empty( $least_linked_ignore_list ) ? [ -1 ] : $least_linked_ignore_list;
$least_linked = $this->query()
->select_many( 'id', 'object_id', 'object_sub_type', 'permalink', 'breadcrumb_title', 'incoming_link_count' )
->where_not_in( 'id', $ignore_list )
->order_by_asc( 'incoming_link_count' )
->limit( $limit )
->find_many();
$least_linked = \array_map( [ $this->indexable_repository, 'ensure_permalink' ], $least_linked );
return \array_map(
static function ( $indexable ) {
$output = $indexable;
if ( $indexable->incoming_link_count === null ) {
$output->incoming_link_count = 0;
}
return $output;
},
$least_linked
);
}
/**
* Stores an indexable in an ignore-list.
*
* @deprecated 20.4
* @codeCoverageIgnore
*
* @param string $ignore_list_name The name of the ignore-list.
* @param array $ignored_indexable_ids The IDs of the updated ignored indexables.
*
* @return bool Whether saving the ignore-list to the database succeeded.
*/
public function update_ignored_indexables( $ignore_list_name, $ignored_indexable_ids ) {
\_deprecated_function( __METHOD__, 'Yoast SEO 20.4' );
if ( ! $this->indexables_page_helper->is_valid_ignore_list_name( $ignore_list_name ) ) {
return false;
}
return $this->options_helper->set( $ignore_list_name, $ignored_indexable_ids );
}
/**
* Removes an indexable from its ignore-list.
*
* @deprecated 20.4
* @codeCoverageIgnore
*
* @param string $ignore_list_name The name of the ignore-list.
* @param int $indexable_id The ID of the indexable to store in the ignore-list.
*
* @return bool Whether saving the ignore-list to the database succeeded.
*/
public function remove_indexable_from_ignore_list( $ignore_list_name, $indexable_id ) {
\_deprecated_function( __METHOD__, 'Yoast SEO 20.4' );
if ( ! $this->indexables_page_helper->is_valid_ignore_list_name( $ignore_list_name ) ) {
return false;
}
$ignore_list = $this->options_helper->get( $ignore_list_name, [] );
$ignore_list = \array_values(
\array_filter(
$ignore_list,
static function( $indexable ) use ( $indexable_id ) {
return $indexable !== $indexable_id;
}
)
);
return $this->options_helper->set( $ignore_list_name, $ignore_list );
}
/**
* Removes all indexables from an ignore-list.
*
* @deprecated 20.4
* @codeCoverageIgnore
*
* @param string $ignore_list_name The name of the ignore-list.
*
* @return bool Whether saving the ignore-list to the database succeeded.
*/
public function remove_all_indexables_from_ignore_list( $ignore_list_name ) {
\_deprecated_function( __METHOD__, 'Yoast SEO 20.4' );
if ( ! $this->indexables_page_helper->is_valid_ignore_list_name( $ignore_list_name ) ) {
return false;
}
return $this->options_helper->set( $ignore_list_name, [] );
}
/**
* Gets the reading list state.
*
* @deprecated 20.4
* @codeCoverageIgnore
*
* @return array The state of each element in the reading list.
*/
public function get_reading_list() {
\_deprecated_function( __METHOD__, 'Yoast SEO 20.4' );
return $this->options_helper->get( 'indexables_page_reading_list', [ false, false, false, false, false ] );
}
/**
* Sets the reading list state.
*
* @deprecated 20.4
* @codeCoverageIgnore
*
* @param array $state The state to be saved.
*
* @return bool Whether saving the reading list state succeeded.
*/
public function set_reading_list( $state ) {
\_deprecated_function( __METHOD__, 'Yoast SEO 20.4' );
return $this->options_helper->set( 'indexables_page_reading_list', $state );
}
/**
* Sets the indexables overview state.
*
* @deprecated 20.4
* @codeCoverageIgnore
*
* @param string $state The state to be saved.
*
* @return bool Whether saving the indexables overview state succeeded.
*/
public function set_indexables_state( $state ) {
\_deprecated_function( __METHOD__, 'Yoast SEO 20.4' );
return $this->options_helper->set( 'indexables_overview_state', $state );
}
}