|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/** |
|
4
|
|
|
* Provide entity-related services. |
|
5
|
|
|
* |
|
6
|
|
|
* @since 3.1.0 |
|
7
|
|
|
*/ |
|
8
|
|
|
class Wordlift_Entity_Service { |
|
9
|
|
|
|
|
10
|
|
|
/** |
|
11
|
|
|
* The Log service. |
|
12
|
|
|
* |
|
13
|
|
|
* @since 3.2.0 |
|
14
|
|
|
* @access private |
|
15
|
|
|
* @var \Wordlift_Log_Service $log_service The Log service. |
|
16
|
|
|
*/ |
|
17
|
|
|
private $log_service; |
|
18
|
|
|
|
|
19
|
|
|
/** |
|
20
|
|
|
* The UI service. |
|
21
|
|
|
* |
|
22
|
|
|
* @since 3.2.0 |
|
23
|
|
|
* @access private |
|
24
|
|
|
* @var \Wordlift_UI_Service $ui_service The UI service. |
|
25
|
|
|
*/ |
|
26
|
|
|
private $ui_service; |
|
27
|
|
|
|
|
28
|
|
|
/** |
|
29
|
|
|
* The entity post type name. |
|
30
|
|
|
* |
|
31
|
|
|
* @since 3.1.0 |
|
32
|
|
|
*/ |
|
33
|
|
|
const TYPE_NAME = 'entity'; |
|
34
|
|
|
|
|
35
|
|
|
/** |
|
36
|
|
|
* The alternative label meta key. |
|
37
|
|
|
* |
|
38
|
|
|
* @since 3.2.0 |
|
39
|
|
|
*/ |
|
40
|
|
|
const ALTERNATIVE_LABEL_META_KEY = '_wl_alt_label'; |
|
41
|
|
|
|
|
42
|
|
|
/** |
|
43
|
|
|
* The alternative label input template. |
|
44
|
|
|
* |
|
45
|
|
|
* @since 3.2.0 |
|
46
|
|
|
*/ |
|
47
|
|
|
// TODO: this should be moved to a class that deals with HTML code. |
|
48
|
|
|
const ALTERNATIVE_LABEL_INPUT_TEMPLATE = '<div class="wl-alternative-label"> |
|
49
|
|
|
<label class="screen-reader-text" id="wl-alternative-label-prompt-text" for="wl-alternative-label">Enter alternative label here</label> |
|
50
|
|
|
<input name="wl_alternative_label[]" size="30" value="%s" id="wl-alternative-label" type="text"> |
|
51
|
|
|
<button class="button wl-delete-button">%s</button> |
|
52
|
|
|
</div>'; |
|
53
|
|
|
|
|
54
|
|
|
/** |
|
55
|
|
|
* A singleton instance of the Entity service. |
|
56
|
|
|
* |
|
57
|
|
|
* @since 3.2.0 |
|
58
|
|
|
* @access private |
|
59
|
|
|
* @var \Wordlift_Entity_Service $instance A singleton instance of the Entity service. |
|
60
|
|
|
*/ |
|
61
|
|
|
private static $instance; |
|
62
|
|
|
|
|
63
|
|
|
/** |
|
64
|
|
|
* Create a Wordlift_Entity_Service instance. |
|
65
|
|
|
* |
|
66
|
|
|
* @since 3.2.0 |
|
67
|
|
|
* |
|
68
|
|
|
* @param \Wordlift_UI_Service $ui_service The UI service. |
|
69
|
|
|
*/ |
|
70
|
|
|
public function __construct( $ui_service ) { |
|
71
|
|
|
|
|
72
|
|
|
$this->log_service = Wordlift_Log_Service::get_logger( 'Wordlift_Entity_Service' ); |
|
73
|
|
|
|
|
74
|
|
|
// Set the UI service. |
|
75
|
|
|
$this->ui_service = $ui_service; |
|
76
|
|
|
|
|
77
|
|
|
// Set the singleton instance. |
|
78
|
|
|
self::$instance = $this; |
|
79
|
|
|
|
|
80
|
|
|
} |
|
81
|
|
|
|
|
82
|
|
|
/** |
|
83
|
|
|
* Get the singleton instance of the Entity service. |
|
84
|
|
|
* |
|
85
|
|
|
* @since 3.2.0 |
|
86
|
|
|
* @return \Wordlift_Entity_Service The singleton instance of the Entity service. |
|
87
|
|
|
*/ |
|
88
|
|
|
public static function get_instance() { |
|
89
|
|
|
|
|
90
|
|
|
return self::$instance; |
|
91
|
|
|
} |
|
92
|
|
|
|
|
93
|
|
|
/** |
|
94
|
|
|
* Get the entities related to the last 50 posts published on this blog (we're keeping a long function name due to |
|
95
|
|
|
* its specific function). |
|
96
|
|
|
* |
|
97
|
|
|
* @since 3.1.0 |
|
98
|
|
|
* |
|
99
|
|
|
* @return array An array of post IDs. |
|
100
|
|
|
*/ |
|
101
|
|
|
public function get_all_related_to_last_50_published_posts() { |
|
102
|
|
|
|
|
103
|
|
|
// Global timeline. Get entities from the latest posts. |
|
104
|
|
|
$latest_posts_ids = get_posts( array( |
|
105
|
|
|
'numberposts' => 50, |
|
106
|
|
|
'fields' => 'ids', //only get post IDs |
|
107
|
|
|
'post_type' => 'post', |
|
108
|
|
|
'post_status' => 'publish' |
|
109
|
|
|
) ); |
|
110
|
|
|
|
|
111
|
|
|
if ( empty( $latest_posts_ids ) ) { |
|
112
|
|
|
// There are no posts. |
|
113
|
|
|
return array(); |
|
114
|
|
|
} |
|
115
|
|
|
|
|
116
|
|
|
// Collect entities related to latest posts |
|
117
|
|
|
$entity_ids = array(); |
|
118
|
|
|
foreach ( $latest_posts_ids as $id ) { |
|
119
|
|
|
$entity_ids = array_merge( $entity_ids, wl_core_get_related_entity_ids( $id, array( |
|
120
|
|
|
'status' => 'publish' |
|
121
|
|
|
) ) ); |
|
122
|
|
|
} |
|
123
|
|
|
|
|
124
|
|
|
return $entity_ids; |
|
125
|
|
|
} |
|
126
|
|
|
|
|
127
|
|
|
/** |
|
128
|
|
|
* Determines whether a post is an entity or not. |
|
129
|
|
|
* |
|
130
|
|
|
* @since 3.1.0 |
|
131
|
|
|
* |
|
132
|
|
|
* @param int $post_id A post id. |
|
133
|
|
|
* |
|
134
|
|
|
* @return true if the post is an entity otherwise false. |
|
135
|
|
|
*/ |
|
136
|
|
|
public function is_entity( $post_id ) { |
|
137
|
|
|
|
|
138
|
|
|
return ( self::TYPE_NAME === get_post_type( $post_id ) ); |
|
139
|
|
|
} |
|
140
|
|
|
|
|
141
|
|
|
/** |
|
142
|
|
|
* Find entity posts by the entity URI. Entity as searched by their entity URI or same as. |
|
143
|
|
|
* |
|
144
|
|
|
* @since 3.2.0 |
|
145
|
|
|
* |
|
146
|
|
|
* @param string $uri The entity URI. |
|
147
|
|
|
* |
|
148
|
|
|
* @return WP_Post|null A WP_Post instance or null if not found. |
|
149
|
|
|
*/ |
|
150
|
|
View Code Duplication |
public function get_entity_post_by_uri( $uri ) { |
|
|
|
|
|
|
151
|
|
|
|
|
152
|
|
|
$query = new WP_Query( array( |
|
153
|
|
|
'posts_per_page' => 1, |
|
154
|
|
|
'post_status' => 'any', |
|
155
|
|
|
'post_type' => self::TYPE_NAME, |
|
156
|
|
|
'meta_query' => array( |
|
157
|
|
|
'relation' => 'OR', |
|
158
|
|
|
array( |
|
159
|
|
|
'key' => Wordlift_Schema_Service::FIELD_SAME_AS, |
|
160
|
|
|
'value' => $uri, |
|
161
|
|
|
'compare' => '=' |
|
162
|
|
|
), |
|
163
|
|
|
array( |
|
164
|
|
|
'key' => WL_ENTITY_URL_META_NAME, |
|
165
|
|
|
'value' => $uri, |
|
166
|
|
|
'compare' => '=' |
|
167
|
|
|
) |
|
168
|
|
|
) |
|
169
|
|
|
) |
|
170
|
|
|
); |
|
171
|
|
|
|
|
172
|
|
|
// Get the matching entity posts. |
|
173
|
|
|
$posts = $query->get_posts(); |
|
174
|
|
|
|
|
175
|
|
|
// Return null if no post is found. |
|
176
|
|
|
if ( 0 === count( $posts ) ) { |
|
177
|
|
|
return null; |
|
178
|
|
|
} |
|
179
|
|
|
|
|
180
|
|
|
// Return the found post. |
|
181
|
|
|
return $posts[0]; |
|
182
|
|
|
} |
|
183
|
|
|
|
|
184
|
|
|
/** |
|
185
|
|
|
* Fires once a post has been saved. |
|
186
|
|
|
* |
|
187
|
|
|
* @since 3.2.0 |
|
188
|
|
|
* |
|
189
|
|
|
* @param int $post_id Post ID. |
|
190
|
|
|
* @param WP_Post $post Post object. |
|
191
|
|
|
* @param bool $update Whether this is an existing post being updated or not. |
|
192
|
|
|
*/ |
|
193
|
|
|
public function save_post( $post_id, $post, $update ) { |
|
|
|
|
|
|
194
|
|
|
|
|
195
|
|
|
// If it's not an entity, return. |
|
196
|
|
|
if ( ! $this->is_entity( $post_id ) ) { |
|
197
|
|
|
return; |
|
198
|
|
|
} |
|
199
|
|
|
|
|
200
|
|
|
// Get the alt labels from the request (or empty array). |
|
201
|
|
|
$alt_labels = isset( $_REQUEST['wl_alternative_label'] ) ? $_REQUEST['wl_alternative_label'] : array(); |
|
202
|
|
|
|
|
203
|
|
|
// Set the alternative labels. |
|
204
|
|
|
$this->set_alternative_labels( $post_id, $alt_labels ); |
|
205
|
|
|
|
|
206
|
|
|
} |
|
207
|
|
|
|
|
208
|
|
|
/** |
|
209
|
|
|
* Set the alternative labels. |
|
210
|
|
|
* |
|
211
|
|
|
* @since 3.2.0 |
|
212
|
|
|
* |
|
213
|
|
|
* @param int $post_id The post id. |
|
214
|
|
|
* @param array $alt_labels An array of labels. |
|
215
|
|
|
*/ |
|
216
|
|
|
public function set_alternative_labels( $post_id, $alt_labels ) { |
|
217
|
|
|
|
|
218
|
|
|
// Force $alt_labels to be an array |
|
219
|
|
|
if( !is_array( $alt_labels ) ) { |
|
220
|
|
|
$alt_labels = array( $alt_labels ); |
|
221
|
|
|
} |
|
222
|
|
|
|
|
223
|
|
|
$this->log_service->debug( "Setting alternative labels [ post id :: $post_id ][ alt labels :: " . implode( ',', $alt_labels ) . " ]" ); |
|
224
|
|
|
|
|
225
|
|
|
// Delete all the existing alternate labels. |
|
226
|
|
|
delete_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY ); |
|
227
|
|
|
|
|
228
|
|
|
// Set the alternative labels. |
|
229
|
|
|
foreach ( $alt_labels as $alt_label ) { |
|
230
|
|
|
if ( ! empty( $alt_label ) ) { |
|
231
|
|
|
add_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY, $alt_label ); |
|
232
|
|
|
} |
|
233
|
|
|
} |
|
234
|
|
|
|
|
235
|
|
|
} |
|
236
|
|
|
|
|
237
|
|
|
/** |
|
238
|
|
|
* Retrieve the alternate labels. |
|
239
|
|
|
* |
|
240
|
|
|
* @since 3.2.0 |
|
241
|
|
|
* |
|
242
|
|
|
* @param int $post_id Post id. |
|
243
|
|
|
* |
|
244
|
|
|
* @return mixed An array of alternative labels. |
|
245
|
|
|
*/ |
|
246
|
|
|
public function get_alternative_labels( $post_id ) { |
|
247
|
|
|
|
|
248
|
|
|
return get_post_meta( $post_id, self::ALTERNATIVE_LABEL_META_KEY ); |
|
249
|
|
|
} |
|
250
|
|
|
|
|
251
|
|
|
/** |
|
252
|
|
|
* Fires before the permalink field in the edit form (this event is available in WP from 4.1.0). |
|
253
|
|
|
* |
|
254
|
|
|
* @since 3.2.0 |
|
255
|
|
|
* |
|
256
|
|
|
* @param WP_Post $post Post object. |
|
257
|
|
|
*/ |
|
258
|
|
|
public function edit_form_before_permalink( $post ) { |
|
259
|
|
|
|
|
260
|
|
|
// If it's not an entity, return. |
|
261
|
|
|
if ( ! $this->is_entity( $post->ID ) ) { |
|
262
|
|
|
return; |
|
263
|
|
|
} |
|
264
|
|
|
|
|
265
|
|
|
// Print the input template. |
|
266
|
|
|
$this->ui_service->print_template( 'wl-tmpl-alternative-label-input', $this->get_alternative_label_input() ); |
|
267
|
|
|
|
|
268
|
|
|
// Print all the currently set alternative labels. |
|
269
|
|
|
foreach ( $this->get_alternative_labels( $post->ID ) as $alt_label ) { |
|
270
|
|
|
|
|
271
|
|
|
echo $this->get_alternative_label_input( $alt_label ); |
|
272
|
|
|
|
|
273
|
|
|
}; |
|
274
|
|
|
|
|
275
|
|
|
// Print the button. |
|
276
|
|
|
$this->ui_service->print_button( 'wl-add-alternative-labels-button', __( 'Add more titles', 'wordlift' ) ); |
|
277
|
|
|
|
|
278
|
|
|
} |
|
279
|
|
|
|
|
280
|
|
|
/** |
|
281
|
|
|
* Get the alternative label input HTML code. |
|
282
|
|
|
* |
|
283
|
|
|
* @since 3.2.0 |
|
284
|
|
|
* |
|
285
|
|
|
* @param string $value The input value. |
|
286
|
|
|
* |
|
287
|
|
|
* @return string The input HTML code. |
|
288
|
|
|
*/ |
|
289
|
|
|
private function get_alternative_label_input( $value = '' ) { |
|
290
|
|
|
|
|
291
|
|
|
return sprintf( self::ALTERNATIVE_LABEL_INPUT_TEMPLATE, esc_attr( $value ), __( 'Delete', 'wordlift' ) ); |
|
292
|
|
|
} |
|
293
|
|
|
} |
|
294
|
|
|
|
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.