PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 27.6
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v27.6
28.5 28.4 28.3 28.2 28.1 28.0 27.9 27.8 27.7 27.6 27.5 trunk 18.0 18.1 18.2 18.3 18.4 18.4.1 18.5 18.5.1 18.6 18.7 18.8 18.9 19.0 All 129 releases
wordpress-seo / admin / filters / class-abstract-post-filter.php

class-abstract-post-filter.php in Yoast SEO – Advanced SEO with real-time guidance and built-in AI 27.6, at admin/filters/class-abstract-post-filter.php

204 lines 5.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * WPSEO plugin file.
4 *
5 * @package WPSEO\Admin\Filters
6 */
7
8 /**
9 * Class WPSEO_Abstract_Post_Filter.
10 */
11 abstract class WPSEO_Abstract_Post_Filter implements WPSEO_WordPress_Integration {
12
13 /**
14 * The filter's query argument.
15 *
16 * @var string
17 */
18 public const FILTER_QUERY_ARG = 'yoast_filter';
19
20 /**
21 * Modify the query based on the FILTER_QUERY_ARG variable in $_GET.
22 *
23 * @param string $where Query variables.
24 *
25 * @return string The modified query.
26 */
27 abstract public function filter_posts( $where );
28
29 /**
30 * Returns the query value this filter uses.
31 *
32 * @return string The query value this filter uses.
33 */
34 abstract public function get_query_val();
35
36 /**
37 * Returns the total number of posts that match this filter.
38 *
39 * @return int The total number of posts that match this filter.
40 */
41 abstract protected function get_post_total();
42
43 /**
44 * Returns the label for this filter.
45 *
46 * @return string The label for this filter.
47 */
48 abstract protected function get_label();
49
50 /**
51 * Registers the hooks.
52 *
53 * @return void
54 */
55 public function register_hooks() {
56 add_action( 'admin_init', [ $this, 'add_filter_links' ], 11 );
57
58 add_filter( 'posts_where', [ $this, 'filter_posts' ] );
59
60 if ( $this->is_filter_active() ) {
61 add_action( 'restrict_manage_posts', [ $this, 'render_hidden_input' ] );
62 }
63
64 if ( $this->is_filter_active() ) {
65 add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_explanation_assets' ] );
66 }
67 }
68
69 /**
70 * Adds the filter links to the view_edit screens to give the user a filter link.
71 *
72 * @return void
73 */
74 public function add_filter_links() {
75 foreach ( $this->get_post_types() as $post_type ) {
76 add_filter( 'views_edit-' . $post_type, [ $this, 'add_filter_link' ] );
77 }
78 }
79
80 /**
81 * Enqueues the necessary assets to display a filter explanation.
82 *
83 * @return void
84 */
85 public function enqueue_explanation_assets() {
86 $explanation = $this->get_explanation();
87
88 if ( $explanation === null ) {
89 return;
90 }
91
92 $asset_manager = new WPSEO_Admin_Asset_Manager();
93 $asset_manager->enqueue_script( 'filter-explanation' );
94 $asset_manager->enqueue_style( 'filter-explanation' );
95 $asset_manager->localize_script(
96 'filter-explanation',
97 'yoastFilterExplanation',
98 [ 'text' => $explanation ],
99 );
100 }
101
102 /**
103 * Adds a filter link to the views.
104 *
105 * @param array<string, string> $views Array with the views.
106 *
107 * @return array<string, string> Array of views including the added view.
108 */
109 public function add_filter_link( $views ) {
110 $views[ 'yoast_' . $this->get_query_val() ] = sprintf(
111 '<a href="%1$s"%2$s>%3$s</a> (%4$s)',
112 esc_url( $this->get_filter_url() ),
113 ( $this->is_filter_active() ) ? ' class="current" aria-current="page"' : '',
114 $this->get_label(),
115 $this->get_post_total(),
116 );
117
118 return $views;
119 }
120
121 /**
122 * Returns a text explaining this filter. Null if no explanation is necessary.
123 *
124 * @return string|null The explanation or null.
125 */
126 protected function get_explanation() {
127 return null;
128 }
129
130 /**
131 * Renders a hidden input to preserve this filter's state when using sub-filters.
132 *
133 * @return void
134 */
135 public function render_hidden_input() {
136 echo '<input type="hidden" name="' . esc_attr( self::FILTER_QUERY_ARG ) . '" value="' . esc_attr( $this->get_query_val() ) . '">';
137 }
138
139 /**
140 * Returns an url to edit.php with post_type and this filter as the query arguments.
141 *
142 * @return string The url to activate this filter.
143 */
144 protected function get_filter_url() {
145 $query_args = [
146 self::FILTER_QUERY_ARG => $this->get_query_val(),
147 'post_type' => $this->get_current_post_type(),
148 ];
149
150 return add_query_arg( $query_args, 'edit.php' );
151 }
152
153 /**
154 * Returns true when the filter is active.
155 *
156 * @return bool Whether the filter is active.
157 */
158 protected function is_filter_active() {
159 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information.
160 if ( isset( $_GET[ self::FILTER_QUERY_ARG ] ) && is_string( $_GET[ self::FILTER_QUERY_ARG ] ) ) {
161 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information.
162 return sanitize_text_field( wp_unslash( $_GET[ self::FILTER_QUERY_ARG ] ) ) === $this->get_query_val();
163 }
164 return false;
165 }
166
167 /**
168 * Returns the current post type.
169 *
170 * @return string The current post type.
171 */
172 protected function get_current_post_type() {
173 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information.
174 if ( isset( $_GET['post_type'] ) && is_string( $_GET['post_type'] ) ) {
175 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information.
176 $post_type = sanitize_text_field( wp_unslash( $_GET['post_type'] ) );
177 if ( ! empty( $post_type ) ) {
178 return $post_type;
179 }
180 }
181 return 'post';
182 }
183
184 /**
185 * Returns the post types to which this filter should be added.
186 *
187 * @return array The post types to which this filter should be added.
188 */
189 protected function get_post_types() {
190 return WPSEO_Post_Type::get_accessible_post_types();
191 }
192
193 /**
194 * Checks if the post type is supported.
195 *
196 * @param string $post_type Post type to check against.
197 *
198 * @return bool True when it is supported.
199 */
200 protected function is_supported_post_type( $post_type ) {
201 return in_array( $post_type, $this->get_post_types(), true );
202 }
203 }
204