|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* Converters: Post to JSON-LD Converter. |
|
4
|
|
|
* |
|
5
|
|
|
* This file defines a converter from an entity {@link WP_Post} to a JSON-LD array. |
|
6
|
|
|
* |
|
7
|
|
|
* @since 3.10.0 |
|
8
|
|
|
* @package Wordlift |
|
9
|
|
|
*/ |
|
10
|
|
|
|
|
11
|
|
|
/** |
|
12
|
|
|
* Define the {@link Wordlift_Post_To_Jsonld_Converter} class. |
|
13
|
|
|
* |
|
14
|
|
|
* @since 3.10.0 |
|
15
|
|
|
*/ |
|
16
|
|
|
class Wordlift_Post_To_Jsonld_Converter extends Wordlift_Abstract_Post_To_Jsonld_Converter { |
|
17
|
|
|
|
|
18
|
|
|
/** |
|
19
|
|
|
* A {@link Wordlift_Configuration_Service} instance. |
|
20
|
|
|
* |
|
21
|
|
|
* @since 3.10.0 |
|
22
|
|
|
* @access private |
|
23
|
|
|
* @var \Wordlift_Configuration_Service $configuration_service A {@link Wordlift_Configuration_Service} instance. |
|
24
|
|
|
*/ |
|
25
|
|
|
private $configuration_service; |
|
26
|
|
|
|
|
27
|
|
|
/** |
|
28
|
|
|
* @var Wordlift_Entity_Post_To_Jsonld_Converter |
|
29
|
|
|
*/ |
|
30
|
|
|
private $entity_post_to_jsonld_converter; |
|
31
|
|
|
|
|
32
|
|
|
/** |
|
33
|
|
|
* A {@link Wordlift_Log_Service} instance. |
|
34
|
|
|
* |
|
35
|
|
|
* @since 3.10.0 |
|
36
|
|
|
* @access private |
|
37
|
|
|
* @var Wordlift_Log_Service $log A {@link Wordlift_Log_Service} instance. |
|
38
|
|
|
*/ |
|
39
|
|
|
private $log; |
|
40
|
|
|
|
|
41
|
|
|
/** |
|
42
|
|
|
* Wordlift_Post_To_Jsonld_Converter constructor. |
|
43
|
|
|
* |
|
44
|
|
|
* @since 3.10.0 |
|
45
|
|
|
* |
|
46
|
|
|
* @param \Wordlift_Entity_Type_Service $entity_type_service A {@link Wordlift_Entity_Type_Service} instance. |
|
47
|
|
|
* @param \Wordlift_Entity_Service $entity_service A {@link Wordlift_Entity_Service} instance. |
|
48
|
|
|
* @param \Wordlift_User_Service $user_service A {@link Wordlift_User_Service} instance. |
|
49
|
|
|
* @param \Wordlift_Attachment_Service $attachment_service A {@link Wordlift_Attachment_Service} instance. |
|
50
|
|
|
* @param \Wordlift_Configuration_Service $configuration_service A {@link Wordlift_Configuration_Service} instance. |
|
51
|
|
|
* @param \Wordlift_Entity_Post_To_Jsonld_Converter $entity_post_to_jsonld_converter |
|
52
|
|
|
*/ |
|
53
|
|
|
public function __construct( $entity_type_service, $entity_service, $user_service, $attachment_service, $configuration_service, $entity_post_to_jsonld_converter ) { |
|
54
|
|
|
parent::__construct( $entity_type_service, $entity_service, $user_service, $attachment_service ); |
|
55
|
|
|
|
|
56
|
|
|
$this->configuration_service = $configuration_service; |
|
57
|
|
|
$this->entity_post_to_jsonld_converter = $entity_post_to_jsonld_converter; |
|
58
|
|
|
|
|
59
|
|
|
// Set a reference to the logger. |
|
60
|
|
|
$this->log = Wordlift_Log_Service::get_logger( 'Wordlift_Post_To_Jsonld_Converter' ); |
|
61
|
|
|
} |
|
62
|
|
|
|
|
63
|
|
|
/** |
|
64
|
|
|
* Convert the provided {@link WP_Post} to a JSON-LD array. Any entity reference |
|
65
|
|
|
* found while processing the post is set in the $references array. |
|
66
|
|
|
* |
|
67
|
|
|
* @since 3.10.0 |
|
68
|
|
|
* |
|
69
|
|
|
* |
|
70
|
|
|
* @param int $post_id The post id. |
|
71
|
|
|
* @param array $references An array of entity references. |
|
72
|
|
|
* |
|
73
|
|
|
* @return array A JSON-LD array. |
|
74
|
|
|
*/ |
|
75
|
|
|
public function convert( $post_id, &$references = array() ) { |
|
76
|
|
|
|
|
77
|
|
|
// Get the post instance. |
|
78
|
|
|
if ( null === $post = get_post( $post_id ) ) { |
|
79
|
|
|
// Post not found. |
|
80
|
|
|
return null; |
|
81
|
|
|
} |
|
82
|
|
|
|
|
83
|
|
|
// Get the base JSON-LD and the list of entities referenced by this entity. |
|
84
|
|
|
$jsonld = parent::convert( $post_id, $references ); |
|
85
|
|
|
|
|
86
|
|
|
// Get the entity name. |
|
87
|
|
|
$jsonld['headline'] = $post->post_title; |
|
88
|
|
|
|
|
89
|
|
|
// Get the author. |
|
90
|
|
|
$jsonld['author'] = $this->get_author( $post->post_author ); |
|
91
|
|
|
|
|
92
|
|
|
// Set the published and modified dates. |
|
93
|
|
|
$jsonld['datePublished'] = get_post_time( 'Y-m-d\TH:i', true, $post, false ); |
|
94
|
|
|
$jsonld['dateModified'] = get_post_modified_time( 'Y-m-d\TH:i', true, $post, false ); |
|
95
|
|
|
|
|
96
|
|
|
// Set the publisher. |
|
97
|
|
|
$this->set_publisher( $jsonld ); |
|
98
|
|
|
|
|
99
|
|
|
// Process the references if any. |
|
100
|
|
|
if ( 0 < sizeof( $references ) ) { |
|
101
|
|
|
|
|
102
|
|
|
// Prepare the `about` and `mentions` array. |
|
|
|
|
|
|
103
|
|
|
$about = $mentions = array(); |
|
104
|
|
|
|
|
105
|
|
|
// If the entity is in the title, then it should be an `about`. |
|
106
|
|
|
foreach ( $references as $reference ) { |
|
107
|
|
|
|
|
108
|
|
|
// Get the entity labels. |
|
109
|
|
|
$labels = $this->entity_service->get_labels( $reference ); |
|
110
|
|
|
|
|
111
|
|
|
// Get the entity URI. |
|
112
|
|
|
$item = array( '@id' => $this->entity_service->get_uri( $reference ) ); |
|
113
|
|
|
|
|
114
|
|
|
// Check if the labels match any part of the title. |
|
115
|
|
|
$matches = 1 === preg_match( '/' . implode( '|', $labels ) . '/', $post->post_title ); |
|
116
|
|
|
|
|
117
|
|
|
// If the title matches, assign the entity to the about, otherwise to the mentions. |
|
118
|
|
|
if ( $matches ) { |
|
119
|
|
|
$about[] = $item; |
|
120
|
|
|
} else { |
|
121
|
|
|
$mentions[] = $item; |
|
122
|
|
|
} |
|
123
|
|
|
} |
|
124
|
|
|
|
|
125
|
|
|
// If we have abouts, assign them to the JSON-LD. |
|
126
|
|
|
if ( 0 < sizeof( $about ) ) { |
|
127
|
|
|
$jsonld['about'] = $about; |
|
128
|
|
|
} |
|
129
|
|
|
|
|
130
|
|
|
// If we have mentions, assign them to the JSON-LD. |
|
131
|
|
|
if ( 0 < sizeof( $mentions ) ) { |
|
132
|
|
|
$jsonld['mentions'] = $mentions; |
|
133
|
|
|
} |
|
134
|
|
|
|
|
135
|
|
|
} |
|
136
|
|
|
|
|
137
|
|
|
return $jsonld; |
|
138
|
|
|
} |
|
139
|
|
|
|
|
140
|
|
|
/** |
|
141
|
|
|
* Get the author's JSON-LD fragment. |
|
142
|
|
|
* |
|
143
|
|
|
* The JSON-LD fragment is generated using the {@link WP_User}'s data or |
|
144
|
|
|
* the referenced entity if configured for the {@link WP_User}. |
|
145
|
|
|
* |
|
146
|
|
|
* @since 3.14.0 |
|
147
|
|
|
* |
|
148
|
|
|
* @param int $author_id The author {@link WP_User}'s `id`. |
|
149
|
|
|
* |
|
150
|
|
|
* @return array A JSON-LD structure. |
|
151
|
|
|
*/ |
|
152
|
|
|
private function get_author( $author_id ) { |
|
153
|
|
|
|
|
154
|
|
|
// Get the entity bound to this user. |
|
155
|
|
|
$entity_id = $this->user_service->get_entity( $author_id ); |
|
156
|
|
|
|
|
157
|
|
|
// If there's no entity bound return a simple author structure. |
|
158
|
|
|
if ( empty( $entity_id ) ) { |
|
159
|
|
|
|
|
160
|
|
|
$author = get_the_author_meta( 'display_name', $author_id ); |
|
161
|
|
|
$author_uri = $this->user_service->get_uri( $author_id ); |
|
162
|
|
|
|
|
163
|
|
|
return array( |
|
164
|
|
|
'@type' => 'Person', |
|
165
|
|
|
'@id' => $author_uri, |
|
166
|
|
|
'name' => $author, |
|
167
|
|
|
); |
|
168
|
|
|
} |
|
169
|
|
|
|
|
170
|
|
|
// Return the JSON-LD for the referenced entity. |
|
171
|
|
|
return $this->entity_post_to_jsonld_converter->convert( $entity_id ); |
|
172
|
|
|
} |
|
173
|
|
|
|
|
174
|
|
|
/** |
|
175
|
|
|
* Enrich the provided params array with publisher data, if available. |
|
176
|
|
|
* |
|
177
|
|
|
* @since 3.10.0 |
|
178
|
|
|
* |
|
179
|
|
|
* @param array $params The parameters array. |
|
180
|
|
|
*/ |
|
181
|
|
|
private function set_publisher( &$params ) { |
|
182
|
|
|
|
|
183
|
|
|
// If the publisher id isn't set don't do anything. |
|
184
|
|
|
if ( null === $publisher_id = $this->configuration_service->get_publisher_id() ) { |
|
185
|
|
|
return; |
|
186
|
|
|
} |
|
187
|
|
|
|
|
188
|
|
|
// Get the post instance. |
|
189
|
|
|
if ( null === $post = get_post( $publisher_id ) ) { |
|
190
|
|
|
// Publisher not found. |
|
191
|
|
|
return; |
|
192
|
|
|
} |
|
193
|
|
|
|
|
194
|
|
|
// Get the item id |
|
195
|
|
|
$id = $this->entity_service->get_uri( $publisher_id ); |
|
196
|
|
|
|
|
197
|
|
|
// Get the type. |
|
198
|
|
|
$type = $this->entity_type_service->get( $publisher_id ); |
|
199
|
|
|
|
|
200
|
|
|
// Get the name. |
|
201
|
|
|
$name = $post->post_title; |
|
202
|
|
|
|
|
203
|
|
|
// Set the publisher data. |
|
204
|
|
|
$params['publisher'] = array( |
|
205
|
|
|
'@type' => $this->relative_to_context( $type['uri'] ), |
|
206
|
|
|
'@id' => $id, |
|
207
|
|
|
'name' => $name, |
|
208
|
|
|
); |
|
209
|
|
|
|
|
210
|
|
|
// Set the logo, only for http://schema.org/Organization as Person doesn't |
|
211
|
|
|
// support the logo property. |
|
212
|
|
|
// |
|
213
|
|
|
// See http://schema.org/logo |
|
214
|
|
|
if ( 'http://schema.org/Organization' !== $type['uri'] ) { |
|
215
|
|
|
return; |
|
216
|
|
|
} |
|
217
|
|
|
|
|
218
|
|
|
// Get the logo, WP < 4.4 way: only post ID accepted here. |
|
219
|
|
|
if ( '' === $thumbnail_id = get_post_thumbnail_id( $post->ID ) ) { |
|
220
|
|
|
return; |
|
221
|
|
|
} |
|
222
|
|
|
|
|
223
|
|
|
// Get the image URL. |
|
224
|
|
|
if ( false === $attachment = wp_get_attachment_image_src( $thumbnail_id, 'full' ) ) { |
|
225
|
|
|
return; |
|
226
|
|
|
} |
|
227
|
|
|
|
|
228
|
|
|
// Copy over some useful properties. |
|
229
|
|
|
// |
|
230
|
|
|
// See https://developers.google.com/search/docs/data-types/articles |
|
231
|
|
|
$params['publisher']['logo']['@type'] = 'ImageObject'; |
|
232
|
|
|
$params['publisher']['logo']['url'] = $attachment[0]; |
|
233
|
|
|
// If you specify a "width" or "height" value you should leave out |
|
234
|
|
|
// 'px'. For example: "width":"4608px" should be "width":"4608". |
|
|
|
|
|
|
235
|
|
|
// |
|
236
|
|
|
// See https://github.com/insideout10/wordlift-plugin/issues/451 |
|
237
|
|
|
$params['publisher']['logo']['width'] = $attachment[1]; |
|
238
|
|
|
$params['publisher']['logo']['height'] = $attachment[2]; |
|
239
|
|
|
|
|
240
|
|
|
} |
|
241
|
|
|
|
|
242
|
|
|
} |
|
243
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.