-
-
Notifications
You must be signed in to change notification settings - Fork 30
/
Copy pathclass-jsonld.php
140 lines (124 loc) · 4.43 KB
/
class-jsonld.php
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
<?php
namespace Webmention\Handler;
use DOMXPath;
use WP_Error;
use DateTimeImmutable;
use Webmention\Response;
/**
* Class for Webmention parsing using JSON-LD.
*/
class JSONLD extends Base {
/**
* Handler Slug to Uniquely Identify it.
*
* @var string
*/
protected $slug = 'jsonld';
/**
* Takes a response object and parses it.
*
* @param Webmention\Response $response Response Object.
* @param string $target_url The target URL
*
* @return WP_Error|true Return error or true if successful.
*/
public function parse( Response $response, $target_url ) {
$dom = $response->get_dom_document();
if ( is_wp_error( $dom ) ) {
return $dom;
}
$xpath = new DOMXPath( $dom );
$jsonld = array();
$content = '';
foreach ( $xpath->query( "//script[@type='application/ld+json']" ) as $script ) {
$content = $script->textContent; // phpcs:ignore
$jsonld[] = json_decode( $content, true );
}
$jsonld = array_filter( $jsonld );
if ( 1 === count( $jsonld ) && wp_is_numeric_array( $jsonld[0] ) ) {
$jsonld = $jsonld[0];
}
// Set raw data.
$this->webmention_item->add_raw( $jsonld );
$this->webmention_item->add_response_type( 'mention' );
$return = $this->add_properties( $jsonld );
return is_wp_error( $return ) ? $return : true;
}
/**
* Takes JSON-LD and generates a Webmention Item.
*
* @param array $jsonld Array of JSON-LD objects.
* @return WP_Error|true Return error or true if successful.
*/
public function add_properties( $jsonld ) {
foreach ( $jsonld as $json ) {
if ( ! $this->is_jsonld( $json ) ) {
continue;
}
if ( ! in_array( $json['@type'], array( 'WebPage', 'Article', 'NewsArticle', 'BlogPosting', 'SocialMediaPosting' ), true ) ) {
continue;
}
if ( isset( $json['datePublished'] ) ) {
$this->webmention_item->add_published( new DateTimeImmutable( $json['datePublished'] ) );
}
if ( isset( $json['dateModified'] ) ) {
$this->webmention_item->add_updated( new DateTimeImmutable( $json['dateModified'] ) );
}
if ( isset( $json['url'] ) ) {
$this->webmention_item->add_url( $json['url'] );
}
if ( isset( $json['headline'] ) ) {
$this->webmention_item->add_name( $json['headline'] );
} elseif ( isset( $json['name'] ) ) {
$this->webmention_item->add_name( $json['name'] );
}
if ( isset( $json['description'] ) ) {
$this->webmention_item->add_summary( $json['description'] );
} elseif ( isset( $json['articleBody'] ) ) {
$this->webmention_item->add_content( $json['articleBody'] );
}
if ( isset( $json['keywords'] ) ) {
$this->webmention_item->add_category( $json['keywords'] );
}
if ( isset( $json['image'] ) ) {
// For now extract only a single image because this is usually multiple sizes.
if ( wp_is_numeric_array( $json['image'] ) ) {
$json['image'] = end( $json['image'] );
}
if ( is_string( $json['image'] ) ) {
$this->webmention_item->add_photo( $json['image'] );
} elseif ( ! $this->is_jsonld( $json['image'] ) && $this->is_jsonld_type( $json['image'], 'ImageObject' ) ) {
$this->webmention_item->add_photo( $json['image']['url'] );
}
}
if ( isset( $json['author'] ) ) {
// For now extract only a single author as we only support one.
if ( wp_is_numeric_array( $json['author'] ) ) {
$json['author'] = end( $json['author'] );
}
if ( $this->is_jsonld( $json['author'] ) ) {
$author = array(
'type' => 'card',
'name' => isset( $json['author']['name'] ) ? $json['author']['name'] : null,
'photo' => isset( $json['author']['image']['url'] ) ? $json['author']['image']['url'] : null,
'url' => isset( $json['author']['url'] ) ? $json['author']['url'] : null,
'me' => isset( $json['author']['sameAs'] ) ? $json['author']['sameAs'] : null,
'email' => isset( $json['author']['email'] ) ? $json['author']['email'] : null,
);
$this->webmention_item->add_author( array_filter( $author ) );
}
}
if ( isset( $json['isPartOf']['name'] ) ) {
$this->webmention_item->add_site_name( $json['isPartOf']['name'] );
}
}
$this->webmention_item->add_meta( apply_filters( 'webmention_handler_jsonld_set_properties', array(), $this ) );
return true;
}
protected function is_jsonld( $jsonld ) {
return ( is_array( $jsonld ) && array_key_exists( '@type', $jsonld ) );
}
protected function is_jsonld_type( $jsonld, $type ) {
return ( array_key_exists( '@type', $jsonld ) && $type === $jsonld['@type'] );
}
}