Completed
Push — develop ( 57bd93...14250f )
by David
04:13 queued 10s
created

Wordlift_Jsonld_Service::get()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 4
nop 0
dl 0
loc 15
rs 9.7666
c 0
b 0
f 0
1
<?php
2
/**
3
 * Define the Wordlift_Jsonld_Service class to support JSON-LD.
4
 *
5
 * @since   3.8.0
6
 * @package Wordlift
7
 */
8
9
/**
10
 * This class exports an entity using JSON-LD.
11
 *
12
 * @since 3.8.0
13
 */
14
class Wordlift_Jsonld_Service {
15
16
	/**
17
	 * A {@link Wordlift_Entity_Service} instance.
18
	 *
19
	 * @since  3.8.0
20
	 * @access private
21
	 * @var Wordlift_Entity_Service $entity_service A {@link Wordlift_Entity_Service} instance.
22
	 */
23
	private $entity_service;
24
25
	/**
26
	 * A {@link Wordlift_Post_Converter} instance.
27
	 *
28
	 * @since  3.8.0
29
	 * @access private
30
	 * @var \Wordlift_Post_Converter A {@link Wordlift_Post_Converter} instance.
31
	 */
32
	private $converter;
33
34
35
	/**
36
	 * A {@link Wordlift_Website_Jsonld_Converter} instance.
37
	 *
38
	 * @since  3.14.0
39
	 * @access private
40
	 * @var \Wordlift_Website_Jsonld_Converter A {@link Wordlift_Website_Jsonld_Converter} instance.
41
	 */
42
	private $website_converter;
43
44
	/**
45
	 * The singleton instance for the JSON-LD service.
46
	 *
47
	 * @since 3.15.1
48
	 *
49
	 * @var \Wordlift_Jsonld_Service $instance The singleton instance for the JSON-LD service.
50
	 */
51
	private static $instance;
52
53
	/**
54
	 * Create a JSON-LD service.
55
	 *
56
	 * @param \Wordlift_Entity_Service $entity_service A {@link Wordlift_Entity_Service} instance.
57
	 * @param \Wordlift_Post_Converter $converter A {@link Wordlift_Uri_To_Jsonld_Converter} instance.
58
	 * @param \Wordlift_Website_Jsonld_Converter $website_converter A {@link Wordlift_Website_Jsonld_Converter} instance.
59
	 *
60
	 * @since 3.8.0
61
	 *
62
	 */
63
	public function __construct( $entity_service, $converter, $website_converter ) {
64
65
		$this->entity_service    = $entity_service;
66
		$this->converter         = $converter;
67
		$this->website_converter = $website_converter;
68
69
		self::$instance = $this;
70
71
	}
72
73
	/**
74
	 * Get the singleton instance for the JSON-LD service.
75
	 *
76
	 * @return \Wordlift_Jsonld_Service The singleton instance for the JSON-LD service.
77
	 * @since 3.15.1
78
	 *
79
	 */
80
	public static function get_instance() {
81
82
		return self::$instance;
83
	}
84
85
	/**
86
	 * Process calls to the AJAX 'wl_jsonld' endpoint.
87
	 *
88
	 * @since 3.8.0
89
	 */
90
	public function get() {
91
		// Clear the buffer to be sure someone doesn't mess with our response.
92
		//
93
		// See https://github.com/insideout10/wordlift-plugin/issues/406.
94
		// See https://codex.wordpress.org/AJAX_in_Plugins.
95
		@ob_clean();
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
96
97
		// Get the parameter from the request.
98
		$is_homepage = isset( $_REQUEST['homepage'] );
99
		$post_id     = isset( $_REQUEST['id'] ) && is_numeric( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : null;
100
101
		// Send the generated JSON-LD.
102
		$this->send_jsonld( $this->get_jsonld( $is_homepage, $post_id ) );
103
104
	}
105
106
	/**
107
	 * A close of WP's own `wp_send_json` function which uses `application/ld+json` as content type.
108
	 *
109
	 * @param mixed $response Variable (usually an array or object) to encode as JSON,
110
	 *                           then print and die.
111
	 * @param int $status_code The HTTP status code to output.
112
	 *
113
	 * @since 3.18.5
114
	 *
115
	 */
116
	private function send_jsonld( $response, $status_code = null ) {
0 ignored issues
show
Unused Code introduced by
The parameter $status_code is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
117
		@header( 'Content-Type: application/ld+json; charset=' . get_option( 'blog_charset' ) );
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
118
		echo wp_json_encode( $response );
119
		if ( apply_filters( 'wp_doing_ajax', defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
120
			wp_die();
121
		} else {
122
			die;
123
		}
124
	}
125
126
	/**
127
	 * Get the JSON-LD.
128
	 *
129
	 * @param bool $is_homepage Whether the JSON-LD for the homepage is being requested.
130
	 * @param int|null $post_id The JSON-LD for the specified {@link WP_Post} id.
131
	 *
132
	 * @return array A JSON-LD structure.
133
	 * @since 3.15.1
134
	 *
135
	 */
136
	public function get_jsonld( $is_homepage = false, $post_id = null ) {
137
138
		// Tell NewRelic to ignore us, otherwise NewRelic customers might receive
139
		// e-mails with a low apdex score.
140
		//
141
		// See https://github.com/insideout10/wordlift-plugin/issues/521
142
		Wordlift_NewRelic_Adapter::ignore_apdex();
143
144
		// Switch to Website converter if is home page.
145
		if ( $is_homepage ) {
146
			/**
147
			 * Filter: 'wordlift_disable_website_json_ld' - Allow disabling of the json+ld output.
148
			 *
149
			 * @since  3.14.0
150
			 * @api    bool $display_search Whether or not to display json+ld search on the frontend.
151
			 */
152
			if ( apply_filters( 'wordlift_disable_website_json_ld', false ) ) {
153
				return array();
154
			}
155
156
			// Set a reference to the website_converter.
157
			$website_converter = $this->website_converter;
158
159
			// Send JSON-LD.
160
			return $website_converter->create_schema();
161
		}
162
163
		// If no id has been provided return an empty array.
164
		if ( ! isset( $post_id ) ) {
165
			return array();
166
		}
167
168
		// An array of references which is captured when converting an URI to a
169
		// json which we gather to further expand our json-ld.
170
		$references = array();
171
172
		// Set a reference to the entity_to_jsonld_converter to use in the closures.
173
		$entity_to_jsonld_converter = $this->converter;
174
175
		// Convert each URI to a JSON-LD array, while gathering referenced entities.
176
		// in the references array.
177
		$jsonld = array_merge(
178
			array( $entity_to_jsonld_converter->convert( $post_id, $references ) ),
179
			// Convert each URI in the references array to JSON-LD. We don't output
180
			// entities already output above (hence the array_diff).
181
			array_filter( array_map( function ( $item ) use ( $entity_to_jsonld_converter, $references ) {
182
183
				// "2nd level properties" may not output here, e.g. a post
184
				// mentioning an event, located in a place: the place is referenced
185
				// via the `@id` but no other properties are loaded.
186
				return $entity_to_jsonld_converter->convert( $item, $references );
187
			}, $references ) ) );
188
189
		// Finally send the JSON-LD.
190
		return $jsonld;
191
	}
192
193
	/**
194
	 * Write the JSON-LD in the head.
195
	 *
196
	 * This function isn't actually used, but may be used to quickly enable writing the JSON-LD synchronously to the
197
	 * document head, using the `wp_head` hook.
198
	 *
199
	 * @since 3.18.5
200
	 */
201
	public function wp_head() {
202
203
		// Determine whether this is the home page or whether we're displaying a single post.
204
		$is_homepage = is_home() || is_front_page();
205
		$post_id     = is_singular() ? get_the_ID() : null;
206
207
		$jsonld = json_encode( $this->get_jsonld( $is_homepage, $post_id ) );
208
		?>
209
        <script type="application/ld+json"><?php echo $jsonld; ?></script><?php
210
	}
211
212
}
213