|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* Services: Entity Uri Service |
|
4
|
|
|
* |
|
5
|
|
|
* Provides access to entities' URIs, i.e. URIs stored as `entity_url` (the main |
|
6
|
|
|
* entity item ID) or as `same_as`. |
|
7
|
|
|
* |
|
8
|
|
|
* @since 3.16.3 |
|
9
|
|
|
* @package Wordlift |
|
10
|
|
|
* @subpackage Wordlift/includes |
|
11
|
|
|
*/ |
|
12
|
|
|
|
|
13
|
|
|
/** |
|
14
|
|
|
* Define the {@link Wordlift_Entity_Uri_Service} class. |
|
15
|
|
|
* |
|
16
|
|
|
* @since 3.16.3 |
|
17
|
|
|
*/ |
|
18
|
|
|
class Wordlift_Entity_Uri_Service { |
|
19
|
|
|
|
|
20
|
|
|
/** |
|
21
|
|
|
* A {@link Wordlift_Log_Service} instance. |
|
22
|
|
|
* |
|
23
|
|
|
* @since 3.16.3 |
|
24
|
|
|
* @access private |
|
25
|
|
|
* @var \Wordlift_Log_Service $log A {@link Wordlift_Log_Service} instance. |
|
26
|
|
|
*/ |
|
27
|
|
|
private $log; |
|
28
|
|
|
|
|
29
|
|
|
/** |
|
30
|
|
|
* The {@link Wordlift_Configuration_Service} instance. |
|
31
|
|
|
* |
|
32
|
|
|
* @since 3.16.3 |
|
33
|
|
|
* @access private |
|
34
|
|
|
* @var \Wordlift_Configuration_Service $configuration_service The {@link Wordlift_Configuration_Service} instance. |
|
35
|
|
|
*/ |
|
36
|
|
|
private $configuration_service; |
|
37
|
|
|
|
|
38
|
|
|
/** |
|
39
|
|
|
* An array of URIs to post ID valid for the current request. |
|
40
|
|
|
* |
|
41
|
|
|
* @since 3.16.3 |
|
42
|
|
|
* @access private |
|
43
|
|
|
* @var array $uri_to_post An array of URIs to post ID valid for the current request. |
|
44
|
|
|
*/ |
|
45
|
|
|
protected $uri_to_post; |
|
46
|
|
|
|
|
47
|
|
|
/** |
|
48
|
|
|
* Create a {@link Wordlift_Entity_Uri_Service} instance. |
|
49
|
|
|
* |
|
50
|
|
|
* @since 3.16.3 |
|
51
|
|
|
* |
|
52
|
|
|
* @param \Wordlift_Configuration_Service $configuration_service The {@link Wordlift_Configuration_Service} instance. |
|
53
|
|
|
*/ |
|
54
|
|
|
public function __construct( $configuration_service ) { |
|
55
|
|
|
|
|
56
|
|
|
$this->log = Wordlift_Log_Service::get_logger( get_class() ); |
|
57
|
|
|
|
|
58
|
|
|
$this->configuration_service = $configuration_service; |
|
59
|
|
|
|
|
60
|
|
|
} |
|
61
|
|
|
|
|
62
|
|
|
/** |
|
63
|
|
|
* Preload the provided URIs in the local cache. |
|
64
|
|
|
* |
|
65
|
|
|
* This function will populate the local `$uri_to_post` array by running a |
|
66
|
|
|
* single query with all the URIs and returning the mappings in the array. |
|
67
|
|
|
* |
|
68
|
|
|
* @since 3.16.3 |
|
69
|
|
|
* |
|
70
|
|
|
* @param array $uris An array of URIs. |
|
71
|
|
|
*/ |
|
72
|
|
|
public function preload_uris( $uris ) { |
|
73
|
|
|
|
|
74
|
|
|
// Bail out if there are no URIs. |
|
75
|
|
|
if ( 0 === count( $uris ) ) { |
|
76
|
|
|
return; |
|
77
|
|
|
} |
|
78
|
|
|
|
|
79
|
|
|
$this->log->trace( 'Preloading ' . count( $uris ) . ' URI(s)...' ); |
|
80
|
|
|
|
|
81
|
|
|
$that = $this; |
|
82
|
|
|
$external_uris = array_filter( $uris, function ( $item ) use ( $that ) { |
|
83
|
|
|
return ! $that->is_internal( $item ); |
|
84
|
|
|
} ); |
|
85
|
|
|
|
|
86
|
|
|
$query_args = array( |
|
87
|
|
|
// See https://github.com/insideout10/wordlift-plugin/issues/654. |
|
88
|
|
|
'ignore_sticky_posts' => 1, |
|
89
|
|
|
'cache_results' => false, |
|
90
|
|
|
'numberposts' => - 1, |
|
91
|
|
|
'post_status' => 'any', |
|
92
|
|
|
'post_type' => Wordlift_Entity_Service::valid_entity_post_types(), |
|
93
|
|
|
'meta_query' => array( |
|
94
|
|
|
array( |
|
95
|
|
|
'key' => WL_ENTITY_URL_META_NAME, |
|
96
|
|
|
'value' => $uris, |
|
97
|
|
|
'compare' => 'IN', |
|
98
|
|
|
), |
|
99
|
|
|
), |
|
100
|
|
|
); |
|
101
|
|
|
|
|
102
|
|
|
// Only if the current uri is not an internal uri, entity search is |
|
103
|
|
|
// performed also looking at sameAs values. |
|
104
|
|
|
// |
|
105
|
|
|
// This solve issues like https://github.com/insideout10/wordlift-plugin/issues/237 |
|
106
|
|
View Code Duplication |
if ( 0 < count( $external_uris ) ) { |
|
|
|
|
|
|
107
|
|
|
|
|
108
|
|
|
$query_args['meta_query']['relation'] = 'OR'; |
|
109
|
|
|
$query_args['meta_query'][] = array( |
|
110
|
|
|
'key' => Wordlift_Schema_Service::FIELD_SAME_AS, |
|
111
|
|
|
'value' => $external_uris, |
|
112
|
|
|
'compare' => 'IN', |
|
113
|
|
|
); |
|
114
|
|
|
|
|
115
|
|
|
} |
|
116
|
|
|
|
|
117
|
|
|
// Get the posts. |
|
118
|
|
|
$posts = get_posts( $query_args ); |
|
119
|
|
|
|
|
120
|
|
|
// Populate the array. We reinitialize the array on purpose because |
|
121
|
|
|
// we don't want these data to long live. |
|
122
|
|
|
$this->uri_to_post = array_reduce( $posts, function ( $carry, $item ) use ( $that ) { |
|
|
|
|
|
|
123
|
|
|
$uris = get_post_meta( $item->ID, WL_ENTITY_URL_META_NAME ) |
|
124
|
|
|
+ get_post_meta( $item->ID, Wordlift_Schema_Service::FIELD_SAME_AS ); |
|
125
|
|
|
|
|
126
|
|
|
return $carry |
|
127
|
|
|
// Get the URI related to the post and fill them with the item id. |
|
128
|
|
|
+ array_fill_keys( $uris, $item ); |
|
129
|
|
|
}, array() ); |
|
130
|
|
|
|
|
131
|
|
|
// Add the not found URIs. |
|
132
|
|
|
$this->uri_to_post += array_fill_keys( $uris, null ); |
|
133
|
|
|
|
|
134
|
|
|
$this->log->debug( count( $this->uri_to_post ) . " URI(s) preloaded." ); |
|
135
|
|
|
|
|
136
|
|
|
} |
|
137
|
|
|
|
|
138
|
|
|
/** |
|
139
|
|
|
* Reset the URI to post local cache. |
|
140
|
|
|
* |
|
141
|
|
|
* @since 3.16.3 |
|
142
|
|
|
*/ |
|
143
|
|
|
public function reset_uris() { |
|
144
|
|
|
|
|
145
|
|
|
$this->uri_to_post = array(); |
|
146
|
|
|
|
|
147
|
|
|
} |
|
148
|
|
|
|
|
149
|
|
|
/** |
|
150
|
|
|
* Find entity posts by the entity URI. Entity as searched by their entity URI or same as. |
|
151
|
|
|
* |
|
152
|
|
|
* @since 3.2.0 |
|
153
|
|
|
* |
|
154
|
|
|
* @param string $uri The entity URI. |
|
155
|
|
|
* |
|
156
|
|
|
* @return WP_Post|null A WP_Post instance or null if not found. |
|
157
|
|
|
*/ |
|
158
|
|
|
public function get_entity( $uri ) { |
|
159
|
|
|
|
|
160
|
|
|
$this->log->trace( "Getting an entity post for URI $uri..." ); |
|
161
|
|
|
|
|
162
|
|
|
// Check if we've been provided with a value otherwise return null. |
|
163
|
|
|
if ( empty( $uri ) ) { |
|
164
|
|
|
return null; |
|
165
|
|
|
} |
|
166
|
|
|
|
|
167
|
|
|
$this->log->debug( "Querying post for $uri..." ); |
|
168
|
|
|
|
|
169
|
|
|
$query_args = array( |
|
170
|
|
|
// See https://github.com/insideout10/wordlift-plugin/issues/654. |
|
171
|
|
|
'ignore_sticky_posts' => 1, |
|
172
|
|
|
'posts_per_page' => 1, |
|
173
|
|
|
'post_status' => 'any', |
|
174
|
|
|
'post_type' => Wordlift_Entity_Service::valid_entity_post_types(), |
|
175
|
|
|
'meta_query' => array( |
|
176
|
|
|
array( |
|
177
|
|
|
'key' => WL_ENTITY_URL_META_NAME, |
|
178
|
|
|
'value' => $uri, |
|
179
|
|
|
'compare' => '=', |
|
180
|
|
|
), |
|
181
|
|
|
), |
|
182
|
|
|
); |
|
183
|
|
|
|
|
184
|
|
|
// Only if the current uri is not an internal uri, entity search is |
|
185
|
|
|
// performed also looking at sameAs values. |
|
186
|
|
|
// |
|
187
|
|
|
// This solve issues like https://github.com/insideout10/wordlift-plugin/issues/237 |
|
188
|
|
View Code Duplication |
if ( ! $this->is_internal( $uri ) ) { |
|
|
|
|
|
|
189
|
|
|
|
|
190
|
|
|
$query_args['meta_query']['relation'] = 'OR'; |
|
191
|
|
|
$query_args['meta_query'][] = array( |
|
192
|
|
|
'key' => Wordlift_Schema_Service::FIELD_SAME_AS, |
|
193
|
|
|
'value' => $uri, |
|
194
|
|
|
'compare' => '=', |
|
195
|
|
|
); |
|
196
|
|
|
} |
|
197
|
|
|
|
|
198
|
|
|
$posts = get_posts( $query_args ); |
|
199
|
|
|
|
|
200
|
|
|
// Return null if no post is found. |
|
201
|
|
|
if ( 0 === count( $posts ) ) { |
|
202
|
|
|
$this->log->warn( "No post for URI $uri." ); |
|
203
|
|
|
|
|
204
|
|
|
return null; |
|
205
|
|
|
} |
|
206
|
|
|
|
|
207
|
|
|
// Return the found post. |
|
208
|
|
|
return current( $posts ); |
|
209
|
|
|
} |
|
210
|
|
|
|
|
211
|
|
|
/** |
|
212
|
|
|
* Determines whether a given uri is an internal uri or not. |
|
213
|
|
|
* |
|
214
|
|
|
* @since 3.16.3 |
|
215
|
|
|
* |
|
216
|
|
|
* @param int $uri An uri. |
|
217
|
|
|
* |
|
218
|
|
|
* @return true if the uri internal to the current dataset otherwise false. |
|
219
|
|
|
*/ |
|
220
|
|
|
public function is_internal( $uri ) { |
|
221
|
|
|
|
|
222
|
|
|
return ( 0 === strrpos( $uri, $this->configuration_service->get_dataset_uri() ) ); |
|
223
|
|
|
} |
|
224
|
|
|
|
|
225
|
|
|
} |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.