PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / trunk
Yoast SEO – Advanced SEO with real-time guidance and built-in AI vtrunk
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 / actions / indexing / post-link-indexing-action.php

post-link-indexing-action.php in Yoast SEO – Advanced SEO with real-time guidance and built-in AI trunk, at src/actions/indexing/post-link-indexing-action.php

153 lines 4.0 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\Actions\Indexing;
4
5 use Yoast\WP\Lib\Model;
6 use Yoast\WP\SEO\Helpers\Post_Type_Helper;
7
8 /**
9 * Reindexing action for post link indexables.
10 */
11 class Post_Link_Indexing_Action extends Abstract_Link_Indexing_Action {
12
13 /**
14 * The transient name.
15 *
16 * @var string
17 */
18 public const UNINDEXED_COUNT_TRANSIENT = 'wpseo_unindexed_post_link_count';
19
20 /**
21 * The transient cache key for limited counts.
22 *
23 * @var string
24 */
25 public const UNINDEXED_LIMITED_COUNT_TRANSIENT = self::UNINDEXED_COUNT_TRANSIENT . '_limited';
26
27 /**
28 * The post type helper.
29 *
30 * @var Post_Type_Helper
31 */
32 protected $post_type_helper;
33
34 /**
35 * Sets the required helper.
36 *
37 * @required
38 *
39 * @param Post_Type_Helper $post_type_helper The post type helper.
40 *
41 * @return void
42 */
43 public function set_helper( Post_Type_Helper $post_type_helper ) {
44 $this->post_type_helper = $post_type_helper;
45 }
46
47 /**
48 * Returns objects to be indexed.
49 *
50 * @return array Objects to be indexed.
51 */
52 protected function get_objects() {
53 $query = $this->get_select_query( $this->get_limit() );
54
55 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Function get_select_query returns a prepared query.
56 $posts = $this->wpdb->get_results( $query );
57
58 return \array_map(
59 static function ( $post ) {
60 return (object) [
61 'id' => (int) $post->ID,
62 'type' => 'post',
63 'content' => $post->post_content,
64 ];
65 },
66 $posts,
67 );
68 }
69
70 /**
71 * Builds a query for counting the number of unindexed post links.
72 *
73 * @return string The prepared query string.
74 */
75 protected function get_count_query() {
76 $public_post_types = $this->post_type_helper->get_indexable_post_types();
77 $indexable_table = Model::get_table_name( 'Indexable' );
78 $links_table = Model::get_table_name( 'SEO_Links' );
79
80 // Warning: If this query is changed, makes sure to update the query in get_select_query as well.
81 return $this->wpdb->prepare(
82 "SELECT COUNT(P.ID)
83 FROM {$this->wpdb->posts} AS P
84 WHERE P.post_status = 'publish'
85 AND P.post_type IN (" . \implode( ', ', \array_fill( 0, \count( $public_post_types ), '%s' ) ) . ')
86 AND (
87 NOT EXISTS (
88 SELECT 1 FROM ' . $indexable_table . " AS I
89 WHERE I.object_id = P.ID
90 AND I.link_count IS NOT NULL
91 AND I.object_type = 'post'
92 )
93 OR EXISTS (
94 SELECT 1 FROM $links_table AS L
95 WHERE L.post_id = P.ID
96 AND L.target_indexable_id IS NULL
97 AND L.type = 'internal'
98 AND L.target_post_id IS NOT NULL
99 AND L.target_post_id != 0
100 )
101 )",
102 $public_post_types,
103 );
104 }
105
106 /**
107 * Builds a query for selecting the ID's of unindexed post links.
108 *
109 * @param int|false $limit The maximum number of post link IDs to return.
110 *
111 * @return string The prepared query string.
112 */
113 protected function get_select_query( $limit = false ) {
114 $public_post_types = $this->post_type_helper->get_indexable_post_types();
115 $indexable_table = Model::get_table_name( 'Indexable' );
116 $links_table = Model::get_table_name( 'SEO_Links' );
117 $replacements = $public_post_types;
118
119 $limit_query = '';
120 if ( $limit ) {
121 $limit_query = 'LIMIT %d';
122 $replacements[] = $limit;
123 }
124
125 // Warning: If this query is changed, makes sure to update the query in get_count_query as well.
126 return $this->wpdb->prepare(
127 "
128 SELECT P.ID, P.post_content
129 FROM {$this->wpdb->posts} AS P
130 WHERE P.post_status = 'publish'
131 AND P.post_type IN (" . \implode( ', ', \array_fill( 0, \count( $public_post_types ), '%s' ) ) . ')
132 AND (
133 NOT EXISTS (
134 SELECT 1 FROM ' . $indexable_table . " AS I
135 WHERE I.object_id = P.ID
136 AND I.link_count IS NOT NULL
137 AND I.object_type = 'post'
138 )
139 OR EXISTS (
140 SELECT 1 FROM $links_table AS L
141 WHERE L.post_id = P.ID
142 AND L.target_indexable_id IS NULL
143 AND L.type = 'internal'
144 AND L.target_post_id IS NOT NULL
145 AND L.target_post_id != 0
146 )
147 )
148 $limit_query",
149 $replacements,
150 );
151 }
152 }
153