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