PageRenderTime 65ms CodeModel.GetById 13ms app.highlight 45ms RepoModel.GetById 1ms app.codeStats 0ms

/wp-content/plugins/wordpress-seo/admin/class-meta-columns.php

https://bitbucket.org/carloskikea/helpet
PHP | 754 lines | 385 code | 123 blank | 246 comment | 48 complexity | 8c0619ef9a582843a039b0b7b9a47a2f MD5 | raw file
  1<?php
  2/**
  3 * WPSEO plugin file.
  4 *
  5 * @package WPSEO\Admin
  6 */
  7
  8/**
  9 * Class WPSEO_Meta_Columns
 10 */
 11class WPSEO_Meta_Columns {
 12
 13	/**
 14	 * @var WPSEO_Metabox_Analysis_SEO
 15	 */
 16	private $analysis_seo;
 17
 18	/**
 19	 * @var WPSEO_Metabox_Analysis_Readability
 20	 */
 21	private $analysis_readability;
 22
 23	/**
 24	 * When page analysis is enabled, just initialize the hooks.
 25	 */
 26	public function __construct() {
 27		if ( apply_filters( 'wpseo_use_page_analysis', true ) === true ) {
 28			add_action( 'admin_init', array( $this, 'setup_hooks' ) );
 29		}
 30
 31		$this->analysis_seo         = new WPSEO_Metabox_Analysis_SEO();
 32		$this->analysis_readability = new WPSEO_Metabox_Analysis_Readability();
 33	}
 34
 35	/**
 36	 * Sets up up the hooks.
 37	 */
 38	public function setup_hooks() {
 39		$this->set_post_type_hooks();
 40
 41		if ( $this->analysis_seo->is_enabled() ) {
 42			add_action( 'restrict_manage_posts', array( $this, 'posts_filter_dropdown' ) );
 43		}
 44
 45		if ( $this->analysis_readability->is_enabled() ) {
 46			add_action( 'restrict_manage_posts', array( $this, 'posts_filter_dropdown_readability' ) );
 47		}
 48
 49		add_filter( 'request', array( $this, 'column_sort_orderby' ) );
 50	}
 51
 52	/**
 53	 * Adds the column headings for the SEO plugin for edit posts / pages overview.
 54	 *
 55	 * @param array $columns Already existing columns.
 56	 *
 57	 * @return array Array containing the column headings.
 58	 */
 59	public function column_heading( $columns ) {
 60		if ( $this->display_metabox() === false ) {
 61			return $columns;
 62		}
 63
 64		$added_columns = array();
 65
 66		if ( $this->analysis_seo->is_enabled() ) {
 67			$added_columns['wpseo-score'] = '<span class="yoast-tooltip yoast-tooltip-n yoast-tooltip-alt" data-label="' . esc_attr__( 'SEO score', 'wordpress-seo' ) . '"><span class="yoast-column-seo-score yoast-column-header-has-tooltip"><span class="screen-reader-text">' . __( 'SEO score', 'wordpress-seo' ) . '</span></span></span>';
 68		}
 69
 70		if ( $this->analysis_readability->is_enabled() ) {
 71			$added_columns['wpseo-score-readability'] = '<span class="yoast-tooltip yoast-tooltip-n yoast-tooltip-alt" data-label="' . esc_attr__( 'Readability score', 'wordpress-seo' ) . '"><span class="yoast-column-readability yoast-column-header-has-tooltip"><span class="screen-reader-text">' . __( 'Readability score', 'wordpress-seo' ) . '</span></span></span>';
 72		}
 73
 74		$added_columns['wpseo-title']    = __( 'SEO Title', 'wordpress-seo' );
 75		$added_columns['wpseo-metadesc'] = __( 'Meta Desc.', 'wordpress-seo' );
 76
 77		if ( $this->analysis_seo->is_enabled() ) {
 78			$added_columns['wpseo-focuskw'] = __( 'Focus KW', 'wordpress-seo' );
 79		}
 80
 81		return array_merge( $columns, $added_columns );
 82	}
 83
 84	/**
 85	 * Displays the column content for the given column.
 86	 *
 87	 * @param string $column_name Column to display the content for.
 88	 * @param int    $post_id     Post to display the column content for.
 89	 */
 90	public function column_content( $column_name, $post_id ) {
 91		if ( $this->display_metabox() === false ) {
 92			return;
 93		}
 94
 95		switch ( $column_name ) {
 96			case 'wpseo-score':
 97				echo $this->parse_column_score( $post_id );
 98				return;
 99
100			case 'wpseo-score-readability':
101				echo $this->parse_column_score_readability( $post_id );
102				return;
103
104			case 'wpseo-title':
105				$post  = get_post( $post_id, ARRAY_A );
106				$title = wpseo_replace_vars( $this->page_title( $post_id ), $post );
107				$title = apply_filters( 'wpseo_title', $title );
108
109				echo esc_html( $title );
110				return;
111
112			case 'wpseo-metadesc':
113				$post         = get_post( $post_id, ARRAY_A );
114				$metadesc_val = wpseo_replace_vars( WPSEO_Meta::get_value( 'metadesc', $post_id ), $post );
115				$metadesc_val = apply_filters( 'wpseo_metadesc', $metadesc_val );
116
117				if ( '' === $metadesc_val ) {
118					echo '<span aria-hidden="true">&#8212;</span><span class="screen-reader-text">',
119						esc_html__( 'Meta description not set.', 'wordpress-seo' ),
120						'</span>';
121					return;
122				}
123
124				echo esc_html( $metadesc_val );
125				return;
126
127			case 'wpseo-focuskw':
128				$focuskw_val = WPSEO_Meta::get_value( 'focuskw', $post_id );
129
130				if ( '' === $focuskw_val ) {
131					echo '<span aria-hidden="true">&#8212;</span><span class="screen-reader-text">',
132						esc_html__( 'Focus keyword not set.', 'wordpress-seo' ),
133						'</span>';
134					return;
135				}
136
137				echo esc_html( $focuskw_val );
138				return;
139		}
140	}
141
142	/**
143	 * Indicates which of the SEO columns are sortable.
144	 *
145	 * @param array $columns Appended with their orderby variable.
146	 *
147	 * @return array Array containing the sortable columns.
148	 */
149	public function column_sort( $columns ) {
150		if ( $this->display_metabox() === false ) {
151			return $columns;
152		}
153
154		$columns['wpseo-metadesc'] = 'wpseo-metadesc';
155
156		if ( $this->analysis_seo->is_enabled() ) {
157			$columns['wpseo-focuskw'] = 'wpseo-focuskw';
158		}
159
160		return $columns;
161	}
162
163	/**
164	 * Hides the SEO title, meta description and focus keyword columns if the user hasn't chosen which columns to hide.
165	 *
166	 * @param array|false $result The hidden columns.
167	 * @param string      $option The option name used to set which columns should be hidden.
168	 * @param WP_User     $user   The User.
169	 *
170	 * @return array      $result Array containing the columns to hide.
171	 */
172	public function column_hidden( $result, $option, $user ) {
173		global $wpdb;
174
175		if ( $user->has_prop( $wpdb->get_blog_prefix() . $option ) || $user->has_prop( $option ) ) {
176			return $result;
177		}
178
179		if ( ! is_array( $result ) ) {
180			$result = array();
181		}
182
183		array_push( $result, 'wpseo-title', 'wpseo-metadesc' );
184
185		if ( $this->analysis_seo->is_enabled() ) {
186			array_push( $result, 'wpseo-focuskw' );
187		}
188
189		return $result;
190	}
191
192	/**
193	 * Adds a dropdown that allows filtering on the posts SEO Quality.
194	 */
195	public function posts_filter_dropdown() {
196		if ( ! $this->can_display_filter() ) {
197			return;
198		}
199
200		$ranks = WPSEO_Rank::get_all_ranks();
201
202		echo '<label class="screen-reader-text" for="wpseo-filter">' . esc_html__( 'Filter by SEO Score', 'wordpress-seo' ) . '</label>';
203		echo '<select name="seo_filter" id="wpseo-filter">';
204
205		echo $this->generate_option( '', __( 'All SEO Scores', 'wordpress-seo' ) );
206
207		foreach ( $ranks as $rank ) {
208			$selected = selected( $this->get_current_seo_filter(), $rank->get_rank(), false );
209
210			echo $this->generate_option( $rank->get_rank(), $rank->get_drop_down_label(), $selected );
211		}
212
213		echo '</select>';
214	}
215
216	/**
217	 * Adds a dropdown that allows filtering on the posts Readability Quality.
218	 *
219	 * @return void
220	 */
221	public function posts_filter_dropdown_readability() {
222		if ( ! $this->can_display_filter() ) {
223			return;
224		}
225
226		$ranks = WPSEO_Rank::get_all_readability_ranks();
227
228		echo '<label class="screen-reader-text" for="wpseo-readability-filter">' . esc_html__( 'Filter by Readability Score', 'wordpress-seo' ) . '</label>';
229		echo '<select name="readability_filter" id="wpseo-readability-filter">';
230
231		echo $this->generate_option( '', __( 'All Readability Scores', 'wordpress-seo' ) );
232
233		foreach ( $ranks as $rank ) {
234			$selected = selected( $this->get_current_readability_filter(), $rank->get_rank(), false );
235
236			echo $this->generate_option( $rank->get_rank(), $rank->get_drop_down_readability_labels(), $selected );
237		}
238
239		echo '</select>';
240	}
241
242	/**
243	 * Generates an <option> element.
244	 *
245	 * @param string $value       The option's value.
246	 * @param string $label       The option's label.
247	 * @param string $selected    HTML selected attribute for an option.
248	 *
249	 * @return string The generated <option> element.
250	 */
251	protected function generate_option( $value, $label, $selected = '' ) {
252		return '<option ' . $selected . ' value="' . esc_attr( $value ) . '">' . esc_html( $label ) . '</option>';
253	}
254
255	/**
256	 * Determines the SEO score filter to be later used in the meta query, based on the passed SEO filter.
257	 *
258	 * @param string $seo_filter The SEO filter to use to determine what further filter to apply.
259	 *
260	 * @return array The SEO score filter.
261	 */
262	protected function determine_seo_filters( $seo_filter ) {
263		if ( $seo_filter === WPSEO_Rank::NO_FOCUS ) {
264			return $this->create_no_focus_keyword_filter();
265		}
266
267		if ( $seo_filter === WPSEO_Rank::NO_INDEX ) {
268			return $this->create_no_index_filter();
269		}
270
271		$rank = new WPSEO_Rank( $seo_filter );
272
273		return $this->create_seo_score_filter( $rank->get_starting_score(), $rank->get_end_score() );
274	}
275
276	/**
277	 * Determines the Readability score filter to the meta query, based on the passed Readability filter.
278	 *
279	 * @param string $readability_filter The Readability filter to use to determine what further filter to apply.
280	 *
281	 * @return array The Readability score filter.
282	 */
283	protected function determine_readability_filters( $readability_filter ) {
284		$rank = new WPSEO_Rank( $readability_filter );
285
286		return $this->create_readability_score_filter( $rank->get_starting_score(), $rank->get_end_score() );
287	}
288
289	/**
290	 * Creates a keyword filter for the meta query, based on the passed Keyword filter.
291	 *
292	 * @param string $keyword_filter The keyword filter to use.
293	 *
294	 * @return array The keyword filter.
295	 */
296	protected function get_keyword_filter( $keyword_filter ) {
297		return array(
298			'post_type' => get_query_var( 'post_type', 'post' ),
299			'key'       => WPSEO_Meta::$meta_prefix . 'focuskw',
300			'value'     => sanitize_text_field( $keyword_filter ),
301		);
302	}
303
304	/**
305	 * Determines whether the passed filter is considered to be valid.
306	 *
307	 * @param mixed $filter The filter to check against.
308	 *
309	 * @return bool Whether or not the filter is considered valid.
310	 */
311	protected function is_valid_filter( $filter ) {
312		return ! empty( $filter ) && is_string( $filter );
313	}
314
315	/**
316	 * Collects the filters and merges them into a single array.
317	 *
318	 * @return array Array containing all the applicable filters.
319	 */
320	protected function collect_filters() {
321		$active_filters = array();
322
323		$seo_filter             = $this->get_current_seo_filter();
324		$readability_filter     = $this->get_current_readability_filter();
325		$current_keyword_filter = $this->get_current_keyword_filter();
326
327		if ( $this->is_valid_filter( $seo_filter ) ) {
328			$active_filters = array_merge(
329				$active_filters,
330				$this->determine_seo_filters( $seo_filter )
331			);
332		}
333
334		if ( $this->is_valid_filter( $readability_filter ) ) {
335			$active_filters = array_merge(
336				$active_filters,
337				$this->determine_readability_filters( $readability_filter )
338			);
339		}
340
341		if ( $this->is_valid_filter( $current_keyword_filter ) ) {
342			$active_filters = array_merge(
343				$active_filters,
344				$this->get_keyword_filter( $current_keyword_filter )
345			);
346		}
347
348		return $active_filters;
349	}
350
351	/**
352	 * Modify the query based on the filters that are being passed.
353	 *
354	 * @param array $vars Query variables that need to be modified based on the filters.
355	 *
356	 * @return array Array containing the meta query to use for filtering the posts overview.
357	 */
358	public function column_sort_orderby( $vars ) {
359		$collected_filters = $this->collect_filters();
360
361		if ( isset( $vars['orderby'] ) ) {
362			$vars = array_merge( $vars, $this->filter_order_by( $vars['orderby'] ) );
363		}
364
365		return $this->build_filter_query( $vars, $collected_filters );
366	}
367
368	/**
369	 * Retrieves the meta robots query values to be used within the meta query.
370	 *
371	 * @return array Array containing the query parameters regarding meta robots.
372	 */
373	protected function get_meta_robots_query_values() {
374		return array(
375			'relation' => 'OR',
376			array(
377				'key'     => WPSEO_Meta::$meta_prefix . 'meta-robots-noindex',
378				'compare' => 'NOT EXISTS',
379			),
380			array(
381				'key'     => WPSEO_Meta::$meta_prefix . 'meta-robots-noindex',
382				'value'   => '1',
383				'compare' => '!=',
384			),
385		);
386	}
387
388	/**
389	 * Determines the score filters to be used. If more than one is passed, it created an AND statement for the query.
390	 *
391	 * @param array $score_filters Array containing the score filters.
392	 *
393	 * @return array Array containing the score filters that need to be applied to the meta query.
394	 */
395	protected function determine_score_filters( $score_filters ) {
396		if ( count( $score_filters ) > 1 ) {
397			return array_merge( array( 'relation' => 'AND' ), $score_filters );
398		}
399
400		return $score_filters;
401	}
402
403	/**
404	 * Retrieves the post type from the $_GET variable.
405	 *
406	 * @return string The current post type.
407	 */
408	public function get_current_post_type() {
409		return filter_input( INPUT_GET, 'post_type' );
410	}
411
412	/**
413	 * Retrieves the SEO filter from the $_GET variable.
414	 *
415	 * @return string The current post type.
416	 */
417	public function get_current_seo_filter() {
418		return filter_input( INPUT_GET, 'seo_filter' );
419	}
420
421	/**
422	 * Retrieves the Readability filter from the $_GET variable.
423	 *
424	 * @return string The current post type.
425	 */
426	public function get_current_readability_filter() {
427		return filter_input( INPUT_GET, 'readability_filter' );
428	}
429
430	/**
431	 * Retrieves the keyword filter from the $_GET variable.
432	 *
433	 * @return string The current post type.
434	 */
435	public function get_current_keyword_filter() {
436		return filter_input( INPUT_GET, 'seo_kw_filter' );
437	}
438
439	/**
440	 * Uses the vars to create a complete filter query that can later be executed to filter out posts.
441	 *
442	 * @param array $vars Array containing the variables that will be used in the meta query.
443	 * @param array $filters Array containing the filters that we need to apply in the meta query.
444	 *
445	 * @return array Array containing the complete filter query.
446	 */
447	protected function build_filter_query( $vars, $filters ) {
448		// If no filters were applied, just return everything.
449		if ( count( $filters ) === 0 ) {
450			return $vars;
451		}
452
453		$result               = array( 'meta_query' => array() );
454		$result['meta_query'] = array_merge( $result['meta_query'], array( $this->determine_score_filters( $filters ) ) );
455
456		$current_seo_filter = $this->get_current_seo_filter();
457
458		// This only applies for the SEO score filter because it can because the SEO score can be altered by the no-index option.
459		if ( $this->is_valid_filter( $current_seo_filter ) && ! in_array( $current_seo_filter, array( WPSEO_Rank::NO_INDEX, WPSEO_Rank::NO_FOCUS ), true ) ) {
460			$result['meta_query'] = array_merge( $result['meta_query'], array( $this->get_meta_robots_query_values() ) );
461		}
462
463		return array_merge( $vars, $result );
464	}
465
466	/**
467	 * Creates a Readability score filter.
468	 *
469	 * @param number $low The lower boundary of the score.
470	 * @param number $high The higher boundary of the score.
471	 *
472	 * @return array The Readability Score filter.
473	 */
474	protected function create_readability_score_filter( $low, $high ) {
475		return array(
476			array(
477				'key'     => WPSEO_Meta::$meta_prefix . 'content_score',
478				'value'   => array( $low, $high ),
479				'type'    => 'numeric',
480				'compare' => 'BETWEEN',
481			),
482		);
483	}
484
485	/**
486	 * Creates an SEO score filter.
487	 *
488	 * @param number $low The lower boundary of the score.
489	 * @param number $high The higher boundary of the score.
490	 *
491	 * @return array The SEO score filter.
492	 */
493	protected function create_seo_score_filter( $low, $high ) {
494		return array(
495			array(
496				'key'     => WPSEO_Meta::$meta_prefix . 'linkdex',
497				'value'   => array( $low, $high ),
498				'type'    => 'numeric',
499				'compare' => 'BETWEEN',
500			),
501		);
502	}
503
504	/**
505	 * Creates a filter to retrieve posts that were set to no-index.
506	 *
507	 * @return array Array containin the no-index filter.
508	 */
509	protected function create_no_index_filter() {
510		return array(
511			array(
512				'key'     => WPSEO_Meta::$meta_prefix . 'meta-robots-noindex',
513				'value'   => '1',
514				'compare' => '=',
515			),
516		);
517	}
518
519	/**
520	 * Creates a filter to retrieve posts that have no keyword set.
521	 *
522	 * @return array Array containing the no focus keyword filter.
523	 */
524	protected function create_no_focus_keyword_filter() {
525		return array(
526			array(
527				'key'     => WPSEO_Meta::$meta_prefix . 'meta-robots-noindex',
528				'value'   => 'needs-a-value-anyway',
529				'compare' => 'NOT EXISTS',
530			),
531			array(
532				'key'     => WPSEO_Meta::$meta_prefix . 'linkdex',
533				'value'   => 'needs-a-value-anyway',
534				'compare' => 'NOT EXISTS',
535			),
536		);
537	}
538
539	/**
540	 * Determines whether a particular post_id is of an indexable post type.
541	 *
542	 * @param string $post_id The post ID to check.
543	 *
544	 * @return bool Whether or not it is indexable.
545	 */
546	protected function is_indexable( $post_id ) {
547		if ( ! empty( $post_id ) && ! $this->uses_default_indexing( $post_id ) ) {
548			return WPSEO_Meta::get_value( 'meta-robots-noindex', $post_id ) === '2';
549		}
550
551		$post = get_post( $post_id );
552
553		if ( is_object( $post ) ) {
554			// If the option is false, this means we want to index it.
555			return WPSEO_Options::get( 'noindex-' . $post->post_type, false ) === false;
556		}
557
558		return true;
559	}
560
561	/**
562	 * Determines whether the given post ID uses the default indexing settings.
563	 *
564	 * @param integer $post_id The post ID to check.
565	 *
566	 * @return bool Whether or not the default indexing is being used for the post.
567	 */
568	protected function uses_default_indexing( $post_id ) {
569		return WPSEO_Meta::get_value( 'meta-robots-noindex', $post_id ) === '0';
570	}
571
572	/**
573	 * Returns filters when $order_by is matched in the if-statement.
574	 *
575	 * @param string $order_by The ID of the column by which to order the posts.
576	 *
577	 * @return array Array containing the order filters.
578	 */
579	private function filter_order_by( $order_by ) {
580		switch ( $order_by ) {
581			case 'wpseo-metadesc':
582				return array(
583					'meta_key' => WPSEO_Meta::$meta_prefix . 'metadesc',
584					'orderby'  => 'meta_value',
585				);
586
587			case 'wpseo-focuskw':
588				return array(
589					'meta_key' => WPSEO_Meta::$meta_prefix . 'focuskw',
590					'orderby'  => 'meta_value',
591				);
592		}
593
594		return array();
595	}
596
597	/**
598	 * Parses the score column.
599	 *
600	 * @param integer $post_id The ID of the post for which to show the score.
601	 *
602	 * @return string The HTML for the SEO score indicator.
603	 */
604	private function parse_column_score( $post_id ) {
605		if ( ! $this->is_indexable( $post_id ) ) {
606			$rank  = new WPSEO_Rank( WPSEO_Rank::NO_INDEX );
607			$title = __( 'Post is set to noindex.', 'wordpress-seo' );
608
609			WPSEO_Meta::set_value( 'linkdex', 0, $post_id );
610
611			return $this->render_score_indicator( $rank, $title );
612		}
613
614		if ( WPSEO_Meta::get_value( 'focuskw', $post_id ) === '' ) {
615			$rank  = new WPSEO_Rank( WPSEO_Rank::NO_FOCUS );
616			$title = __( 'Focus keyword not set.', 'wordpress-seo' );
617
618			return $this->render_score_indicator( $rank, $title );
619		}
620
621		$score = (int) WPSEO_Meta::get_value( 'linkdex', $post_id );
622		$rank  = WPSEO_Rank::from_numeric_score( $score );
623		$title = $rank->get_label();
624
625		return $this->render_score_indicator( $rank, $title );
626	}
627
628	/**
629	 * Parsing the readability score column.
630	 *
631	 * @param int $post_id The ID of the post for which to show the readability score.
632	 *
633	 * @return string The HTML for the readability score indicator.
634	 */
635	private function parse_column_score_readability( $post_id ) {
636		$score = (int) WPSEO_Meta::get_value( 'content_score', $post_id );
637		$rank  = WPSEO_Rank::from_numeric_score( $score );
638
639		return $this->render_score_indicator( $rank );
640	}
641
642	/**
643	 * Sets up the hooks for the post_types.
644	 */
645	private function set_post_type_hooks() {
646		$post_types = WPSEO_Post_Type::get_accessible_post_types();
647
648		if ( ! is_array( $post_types ) || $post_types === array() ) {
649			return;
650		}
651
652		foreach ( $post_types as $post_type ) {
653			if ( $this->display_metabox( $post_type ) === false ) {
654				continue;
655			}
656
657			add_filter( 'manage_' . $post_type . '_posts_columns', array( $this, 'column_heading' ), 10, 1 );
658			add_action( 'manage_' . $post_type . '_posts_custom_column', array( $this, 'column_content' ), 10, 2 );
659			add_action( 'manage_edit-' . $post_type . '_sortable_columns', array( $this, 'column_sort' ), 10, 2 );
660
661			/*
662			 * Use the `get_user_option_{$option}` filter to change the output of the get_user_option
663			 * function for the `manage{$screen}columnshidden` option, which is based on the current
664			 * admin screen. The admin screen we want to target is the `edit-{$post_type}` screen.
665			 */
666			$filter = sprintf( 'get_user_option_%s', sprintf( 'manage%scolumnshidden', 'edit-' . $post_type ) );
667
668			add_filter( $filter, array( $this, 'column_hidden' ), 10, 3 );
669		}
670
671		unset( $post_type );
672	}
673
674	/**
675	 * Wraps the WPSEO_Metabox check to determine whether the metabox should be displayed either by
676	 * choice of the admin or because the post type is not a public post type.
677	 *
678	 * @since 7.0
679	 *
680	 * @param string $post_type Optional. The post type to test, defaults to the current post post_type.
681	 *
682	 * @return bool Whether or not the meta box (and associated columns etc) should be hidden.
683	 */
684	private function display_metabox( $post_type = null ) {
685		$current_post_type = sanitize_text_field( $this->get_current_post_type() );
686
687		if ( ! isset( $post_type ) && ! empty( $current_post_type ) ) {
688			$post_type = $current_post_type;
689		}
690
691		return WPSEO_Utils::is_metabox_active( $post_type, 'post_type' );
692	}
693
694	/**
695	 * Retrieve the page title.
696	 *
697	 * @param int $post_id Post to retrieve the title for.
698	 *
699	 * @return string
700	 */
701	private function page_title( $post_id ) {
702		$fixed_title = WPSEO_Meta::get_value( 'title', $post_id );
703		if ( $fixed_title !== '' ) {
704			return $fixed_title;
705		}
706
707		$post = get_post( $post_id );
708
709		if ( is_object( $post ) && WPSEO_Options::get( 'title-' . $post->post_type, '' ) !== '' ) {
710			$title_template = WPSEO_Options::get( 'title-' . $post->post_type );
711			$title_template = str_replace( ' %%page%% ', ' ', $title_template );
712
713			return wpseo_replace_vars( $title_template, $post );
714		}
715
716		return wpseo_replace_vars( '%%title%%', $post );
717	}
718
719	/**
720	 * @param WPSEO_Rank $rank  The rank this indicator should have.
721	 * @param string     $title Optional. The title for this rank, defaults to the title of the rank.
722	 *
723	 * @return string The HTML for a score indicator.
724	 */
725	private function render_score_indicator( $rank, $title = '' ) {
726		if ( empty( $title ) ) {
727			$title = $rank->get_label();
728		}
729
730		return '<div aria-hidden="true" title="' . esc_attr( $title ) . '" class="wpseo-score-icon ' . esc_attr( $rank->get_css_class() ) . '"></div><span class="screen-reader-text">' . $title . '</span>';
731	}
732
733	/**
734	 * Determines whether or not filter dropdowns should be displayed.
735	 *
736	 * @return bool Whether or the current page can display the filter drop downs.
737	 */
738	public function can_display_filter() {
739		if ( $GLOBALS['pagenow'] === 'upload.php' ) {
740			return false;
741		}
742
743		if ( $this->display_metabox() === false ) {
744			return false;
745		}
746
747		$screen = get_current_screen();
748		if ( null === $screen ) {
749			return false;
750		}
751
752		return WPSEO_Post_Type::is_post_type_accessible( $screen->post_type );
753	}
754}