PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 19.0
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v19.0
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 / src / integrations / admin / link-count-columns-integration.php

link-count-columns-integration.php in Yoast SEO – Advanced SEO with real-time guidance and built-in AI 19.0, at src/integrations/admin/link-count-columns-integration.php

253 lines 7.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Yoast\WP\SEO\Integrations\Admin;
4
5 use WP_Query;
6 use wpdb;
7 use Yoast\WP\Lib\Model;
8 use Yoast\WP\SEO\Actions\Indexing\Post_Link_Indexing_Action;
9 use Yoast\WP\SEO\Conditionals\Admin\Posts_Overview_Or_Ajax_Conditional;
10 use Yoast\WP\SEO\Conditionals\Admin_Conditional;
11 use Yoast\WP\SEO\Conditionals\Should_Index_Links_Conditional;
12 use Yoast\WP\SEO\Helpers\Post_Type_Helper;
13 use Yoast\WP\SEO\Integrations\Integration_Interface;
14
15 /**
16 * Link_Count_Columns_Integration class.
17 */
18 class Link_Count_Columns_Integration implements Integration_Interface {
19
20 /**
21 * Partial column name.
22 *
23 * @var string
24 */
25 const COLUMN_LINKED = 'linked';
26
27 /**
28 * Partial column name.
29 *
30 * @var string
31 */
32 const COLUMN_LINKS = 'links';
33
34 /**
35 * The post type helper.
36 *
37 * @var Post_Type_Helper
38 */
39 protected $post_type_helper;
40
41 /**
42 * The database object.
43 *
44 * @var wpdb
45 */
46 protected $wpdb;
47
48 /**
49 * The post link builder.
50 *
51 * @var Post_Link_Indexing_Action
52 */
53 protected $post_link_indexing_action;
54
55 /**
56 * The admin columns cache.
57 *
58 * @var Admin_Columns_Cache_Integration
59 */
60 protected $admin_columns_cache;
61
62 /**
63 * {@inheritDoc}
64 */
65 public static function get_conditionals() {
66 return [
67 Admin_Conditional::class,
68 Posts_Overview_Or_Ajax_Conditional::class,
69 Should_Index_Links_Conditional::class,
70 ];
71 }
72
73 /**
74 * Link_Count_Columns_Integration constructor
75 *
76 * @param Post_Type_Helper $post_type_helper The post type helper.
77 * @param wpdb $wpdb The wpdb object.
78 * @param Post_Link_Indexing_Action $post_link_indexing_action The post link indexing action.
79 * @param Admin_Columns_Cache_Integration $admin_columns_cache The admin columns cache.
80 */
81 public function __construct(
82 Post_Type_Helper $post_type_helper,
83 wpdb $wpdb,
84 Post_Link_Indexing_Action $post_link_indexing_action,
85 Admin_Columns_Cache_Integration $admin_columns_cache
86 ) {
87 $this->post_type_helper = $post_type_helper;
88 $this->wpdb = $wpdb;
89 $this->post_link_indexing_action = $post_link_indexing_action;
90 $this->admin_columns_cache = $admin_columns_cache;
91 }
92
93 /**
94 * {@inheritDoc}
95 */
96 public function register_hooks() {
97 \add_filter( 'posts_clauses', [ $this, 'order_by_links' ], 1, 2 );
98 \add_filter( 'posts_clauses', [ $this, 'order_by_linked' ], 1, 2 );
99
100 \add_filter( 'admin_init', [ $this, 'register_init_hooks' ] );
101
102 // Adds a filter to exclude the attachments from the link count.
103 \add_filter( 'wpseo_link_count_post_types', [ 'WPSEO_Post_Type', 'filter_attachment_post_type' ] );
104 }
105
106 /**
107 * Register hooks that need to be registered after `init` due to all post types not yet being registered.
108 */
109 public function register_init_hooks() {
110 $public_post_types = \apply_filters( 'wpseo_link_count_post_types', $this->post_type_helper->get_accessible_post_types() );
111
112 if ( ! \is_array( $public_post_types ) || empty( $public_post_types ) ) {
113 return;
114 }
115
116 foreach ( $public_post_types as $post_type ) {
117 \add_filter( 'manage_' . $post_type . '_posts_columns', [ $this, 'add_post_columns' ] );
118 \add_action( 'manage_' . $post_type . '_posts_custom_column', [ $this, 'column_content' ], 10, 2 );
119 \add_filter( 'manage_edit-' . $post_type . '_sortable_columns', [ $this, 'column_sort' ] );
120 }
121 }
122
123 /**
124 * Adds the columns for the post overview.
125 *
126 * @param array $columns Array with columns.
127 *
128 * @return array The extended array with columns.
129 */
130 public function add_post_columns( $columns ) {
131 if ( ! \is_array( $columns ) ) {
132 return $columns;
133 }
134
135 $columns[ 'wpseo-' . self::COLUMN_LINKS ] = \sprintf(
136 '<span class="yoast-linked-to yoast-column-header-has-tooltip" data-tooltip-text="%1$s"><span class="screen-reader-text">%2$s</span></span>',
137 \esc_attr__( 'Number of outgoing internal links in this post. See "Yoast Columns" text in the help tab for more info.', 'wordpress-seo' ),
138 \esc_html__( 'Outgoing internal links', 'wordpress-seo' )
139 );
140
141 if ( $this->post_link_indexing_action->get_total_unindexed() === 0 ) {
142 $columns[ 'wpseo-' . self::COLUMN_LINKED ] = \sprintf(
143 '<span class="yoast-linked-from yoast-column-header-has-tooltip" data-tooltip-text="%1$s"><span class="screen-reader-text">%2$s</span></span>',
144 \esc_attr__( 'Number of internal links linking to this post. See "Yoast Columns" text in the help tab for more info.', 'wordpress-seo' ),
145 \esc_html__( 'Received internal links', 'wordpress-seo' )
146 );
147 }
148
149 return $columns;
150 }
151
152 /**
153 * Modifies the query pieces to allow ordering column by links to post.
154 *
155 * @param array $pieces Array of Query pieces.
156 * @param WP_Query $query The Query on which to apply.
157 *
158 * @return array
159 */
160 public function order_by_linked( $pieces, $query ) {
161 if ( $query->get( 'orderby' ) !== 'wpseo-' . self::COLUMN_LINKED ) {
162 return $pieces;
163 }
164
165 return $this->build_sort_query_pieces( $pieces, $query, 'incoming_link_count' );
166 }
167
168 /**
169 * Modifies the query pieces to allow ordering column by links to post.
170 *
171 * @param array $pieces Array of Query pieces.
172 * @param WP_Query $query The Query on which to apply.
173 *
174 * @return array
175 */
176 public function order_by_links( $pieces, $query ) {
177 if ( $query->get( 'orderby' ) !== 'wpseo-' . self::COLUMN_LINKS ) {
178 return $pieces;
179 }
180
181 return $this->build_sort_query_pieces( $pieces, $query, 'link_count' );
182 }
183
184 /**
185 * Builds the pieces for a sorting query.
186 *
187 * @param array $pieces Array of Query pieces.
188 * @param WP_Query $query The Query on which to apply.
189 * @param string $field The field in the table to JOIN on.
190 *
191 * @return array Modified Query pieces.
192 */
193 protected function build_sort_query_pieces( $pieces, $query, $field ) {
194 // We only want our code to run in the main WP query.
195 if ( ! $query->is_main_query() ) {
196 return $pieces;
197 }
198
199 // Get the order query variable - ASC or DESC.
200 $order = \strtoupper( $query->get( 'order' ) );
201
202 // Make sure the order setting qualifies. If not, set default as ASC.
203 if ( ! \in_array( $order, [ 'ASC', 'DESC' ], true ) ) {
204 $order = 'ASC';
205 }
206
207 $table = Model::get_table_name( 'Indexable' );
208
209 $pieces['join'] .= " LEFT JOIN $table AS yoast_indexable ON yoast_indexable.object_id = {$this->wpdb->posts}.ID AND yoast_indexable.object_type = 'post' ";
210 $pieces['orderby'] = "yoast_indexable.$field $order, FIELD( {$this->wpdb->posts}.post_status, 'publish' ) $order, {$pieces['orderby']}";
211
212 return $pieces;
213 }
214
215 /**
216 * Displays the column content for the given column.
217 *
218 * @param string $column_name Column to display the content for.
219 * @param int $post_id Post to display the column content for.
220 */
221 public function column_content( $column_name, $post_id ) {
222 $indexable = $this->admin_columns_cache->get_indexable( $post_id );
223 // Nothing to output if we don't have the value.
224 if ( $indexable === false ) {
225 return;
226 }
227
228 switch ( $column_name ) {
229 case 'wpseo-' . self::COLUMN_LINKS:
230 echo (int) $indexable->link_count;
231 return;
232 case 'wpseo-' . self::COLUMN_LINKED:
233 if ( \get_post_status( $post_id ) === 'publish' ) {
234 echo (int) $indexable->incoming_link_count;
235 }
236 }
237 }
238
239 /**
240 * Sets the sortable columns.
241 *
242 * @param array $columns Array with sortable columns.
243 *
244 * @return array The extended array with sortable columns.
245 */
246 public function column_sort( array $columns ) {
247 $columns[ 'wpseo-' . self::COLUMN_LINKS ] = 'wpseo-' . self::COLUMN_LINKS;
248 $columns[ 'wpseo-' . self::COLUMN_LINKED ] = 'wpseo-' . self::COLUMN_LINKED;
249
250 return $columns;
251 }
252 }
253