class-premium-link-suggestions-service.php
3.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
<?php
/**
* @package WPSEO\Premium
*/
/**
* Handles the actual requests to the prominent words endpoints.
*/
class WPSEO_Premium_Link_Suggestions_Service {
const CACHE_PREFIX = 'wpseo_link_suggestions_';
/**
* @param WP_REST_Request $request The request object.
* @return WP_REST_Response The response for the query of link suggestions.
*/
public function query( WP_REST_Request $request ) {
$prominent_words = $request->get_param( 'prominent_words' );
return new WP_REST_Response( $this->get_suggestions( $prominent_words ) );
}
/**
* Makes a list of suggestions based on the passed prominent words.
*
* @param int[] $prominent_words The prominent words to base the link suggestion on.
* @return string[] Links for the post that are suggested.
*/
public function get_suggestions( $prominent_words ) {
$posts = array();
foreach ( $prominent_words as $prominent_word ) {
$posts_query = $this->retrieve_posts( $prominent_word );
$posts = $this->count( $posts_query, $posts );
}
usort( $posts, array( $this, 'compare_post_count' ) );
$suggestions = array_map( array( $this, 'get_post_object' ), $posts );
set_transient( $this->get_cache_key( $prominent_words ), $suggestions, WEEK_IN_SECONDS );
return $suggestions;
}
/**
* Returns the tax query to retrieve posts of a prominent word.
*
* @param {int} $term_id The ID of the prominent word to get posts for.
* @return {array} The tax query for the prominent word.
*/
public function get_tax_query( $term_id ) {
return array(
array(
'taxonomy' => WPSEO_Premium_Prominent_Words_Registration::TERM_NAME,
'field' => 'term_id',
'terms' => $term_id,
),
);
}
/**
* Creates the cache key for the list of prominent words.
*
* @param int[] $prominent_words The prominent words to cache the link suggestions for.
* @return string The cache key with which to save cache the link suggestions in the transients.
*/
public function get_cache_key( $prominent_words ) {
sort( $prominent_words );
return self::CACHE_PREFIX . md5( implode( ',', $prominent_words ) );
}
/**
* Retrieves posts that are connected to a specific prominent word.
*
* @param {int} $prominent_word_id ID of the prominent word to get posts for.
* @return WP_Query The query to retrieve the posts for the prominent word.
*/
private function retrieve_posts( $prominent_word_id ) {
$query_args = array(
'tax_query' => $this->get_tax_query( $prominent_word_id ),
);
$posts_query = new WP_Query( $query_args );
return $posts_query;
}
/**
* Increments post counts in $posts for posts that are present in the query.
*
* @param WP_Query $posts_query A query for posts in a specific prominent word.
* @param array $posts A list of currently counted posts.
*
* @return array A new list of counted posts.
*/
private function count( $posts_query, $posts ) {
foreach ( $posts_query->posts as $post ) {
if ( array_key_exists( $post->ID, $posts ) ) {
$posts[ $post->ID ]['count'] += 1;
}
else {
$posts[ $post->ID ] = array(
'count' => 1,
'post' => $post,
);
}
}
return $posts;
}
/**
* Compares post counts for use in usort.
*
* @param array $postA An associative array with a post object and a post count.
* @param array $postB An associative array with a post object and a post count.
* @return {int} -1 if $a has a higher count, 0 if $a and $b have an identical count, 1 if $b has a higher count.
*/
private function compare_post_count( $postA, $postB ) {
return ( $postB['count'] - $postA['count'] );
}
/**
* Prepares an item for our response.
*
* @param WP_Post $post The post to prepare.
* @return array The link to put in the link suggestions
*/
private function get_post_object( $post ) {
$post = $post['post'];
$title = trim( $post->post_title );
if ( empty( $title ) ) {
$title = __( '(no title)', 'wordpress-seo-premium' );
}
return array(
'id' => $post->ID,
'title' => $title,
'link' => get_permalink( $post ),
);
}
}