PluginProbe
Stream – Activity Log & Audit Trail / 2.0.2
Stream – Activity Log & Audit Trail v2.0.2
4.4.0 4.3.0 4.2.2 4.2.1 trunk 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.1 3.1.1 3.10.0 3.2.0 3.2.1 3.2.2 3.2.3 All 50 releases
stream / classes / class-wp-stream-api.php

class-wp-stream-api.php in Stream – Activity Log & Audit Trail 2.0.2, at classes/class-wp-stream-api.php

359 lines 8.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 class WP_Stream_API {
4
5 /**
6 * API Key key/identifier
7 */
8 const API_KEY_OPTION_KEY = 'wp_stream_site_api_key';
9
10 /**
11 * Site UUID key/identifier
12 */
13 const SITE_UUID_OPTION_KEY = 'wp_stream_site_uuid';
14
15 /**
16 * Site Retricted key/identifier
17 */
18 const RESTRICTED_OPTION_KEY = 'wp_stream_site_restricted';
19
20 /**
21 * The site's API Key
22 *
23 * @var string
24 */
25 public $api_key = false;
26
27 /**
28 * The site's unique identifier
29 *
30 * @var string
31 */
32 public $site_uuid = false;
33
34 /**
35 * The site's restriction status
36 *
37 * @var bool
38 */
39 public static $restricted = true;
40
41 /**
42 * The API URL
43 *
44 * @var string
45 */
46 public $api_url = 'https://api.wp-stream.com';
47
48 /**
49 * The API Version
50 *
51 * @var string
52 */
53 public $api_version = '0.0.2';
54
55 /**
56 * Error messages
57 *
58 * @var array
59 */
60 public $errors = array();
61
62 /**
63 * Total API calls made per page load
64 * Used for debugging and optimization
65 *
66 * @var array
67 */
68 public $count = 0;
69
70 /**
71 * Public constructor
72 *
73 * @return void
74 */
75 public function __construct() {
76 $this->api_key = get_option( self::API_KEY_OPTION_KEY, 0 );
77 $this->site_uuid = get_option( self::SITE_UUID_OPTION_KEY, 0 );
78 self::$restricted = get_option( self::RESTRICTED_OPTION_KEY, 1 );
79 }
80
81 /**
82 * Check if the current site is restricted
83 *
84 * @param bool Force the API to send a request to check the site's plan type
85 *
86 * @return bool
87 */
88 public static function is_restricted( $force_check = false ) {
89 if ( $force_check ) {
90 $site = WP_Stream::$api->get_site();
91
92 self::$restricted = ( ! isset( $site->plan->type ) || 'free' === $site->plan->type );
93 }
94
95 return self::$restricted;
96 }
97
98 /**
99 * Used to prioritise the streams transport which support non-blocking
100 *
101 * @filter http_api_transports
102 *
103 * @return bool
104 */
105 public static function http_api_transport_priority( $request_order, $args, $url ) {
106 if ( isset( $args['blocking'] ) && false === $args['blocking'] ) {
107 $request_order = array( 'streams', 'curl' );
108 }
109
110 return $request_order;
111 }
112
113 /**
114 * Get the details for a specific site.
115 *
116 * @param array Returns specified fields only.
117 * @param bool Allow API calls to be cached.
118 * @param int Set transient expiration in seconds.
119 *
120 * @return mixed
121 */
122 public function get_site( $fields = array(), $allow_cache = true, $expiration = 30 ) {
123 if ( ! $this->site_uuid ) {
124 return false;
125 }
126
127 $params = array();
128
129 if ( ! empty( $fields ) ) {
130 $params['fields'] = implode( ',', $fields );
131 }
132
133 $url = $this->request_url( sprintf( '/sites/%s', urlencode( $this->site_uuid ) ), $params );
134 $args = array( 'method' => 'GET' );
135 $site = $this->remote_request( $url, $args, $allow_cache, $expiration );
136
137 if ( $site && ! is_wp_error( $site ) ) {
138 $is_restricted = ( ! isset( $site->plan->type ) || 'free' === $site->plan->type ) ? 1 : 0;
139
140 if ( self::$restricted !== (bool) $is_restricted ) {
141 self::$restricted = $is_restricted;
142
143 update_option( self::RESTRICTED_OPTION_KEY, $is_restricted );
144 }
145 }
146
147 return $site;
148 }
149
150 /**
151 * Get a specific record.
152 *
153 * @param string A record ID.
154 * @param array Returns specified fields only.
155 * @param bool Allow API calls to be cached.
156 * @param int Set transient expiration in seconds.
157 *
158 * @return mixed
159 */
160 public function get_record( $record_id = false, $fields = array(), $allow_cache = true, $expiration = 30 ) {
161 if ( false === $record_id ) {
162 return false;
163 }
164
165 if ( ! $this->site_uuid ) {
166 return false;
167 }
168
169 $params = array();
170
171 if ( ! empty( $fields ) ) {
172 $params['fields'] = implode( ',', $fields );
173 }
174
175 $url = $this->request_url( sprintf( '/sites/%s/records/%s', urlencode( $this->site_uuid ), urlencode( $record_id ) ), $params );
176 $args = array( 'method' => 'GET' );
177
178 return $this->remote_request( $url, $args, $allow_cache, $expiration );
179 }
180
181 /**
182 * Get all records.
183 *
184 * @param array Returns specified fields only.
185 * @param bool Allow API calls to be cached.
186 * @param int Set transient expiration in seconds.
187 *
188 * @return mixed
189 */
190 public function get_records( $fields = array(), $allow_cache = true, $expiration = 30 ) {
191 if ( ! $this->site_uuid ) {
192 return false;
193 }
194
195 $params = array();
196
197 if ( ! empty( $fields ) ) {
198 $params['fields'] = implode( ',', $fields );
199 }
200
201 $url = $this->request_url( sprintf( '/sites/%s/records', urlencode( $this->site_uuid ) ), $params );
202 $args = array( 'method' => 'GET' );
203
204 return $this->remote_request( $url, $args, $allow_cache, $expiration );
205 }
206
207 /**
208 * Create new records.
209 *
210 * @param array $records
211 * @param bool $blocking
212 *
213 * @return mixed
214 */
215 public function new_records( $records, $blocking = false ) {
216 if ( ! $this->site_uuid ) {
217 return false;
218 }
219
220 $url = $this->request_url( sprintf( '/sites/%s/records', urlencode( $this->site_uuid ) ) );
221 $args = array( 'method' => 'POST', 'body' => json_encode( array( 'records' => $records ) ), 'blocking' => (bool) $blocking );
222
223 return $this->remote_request( $url, $args );
224 }
225
226 /**
227 * Search all records.
228 *
229 * @param array Elasticsearch's Query DSL query object.
230 * @param array Returns specified fields only.
231 * @param bool Allow API calls to be cached.
232 * @param int Set transient expiration in seconds.
233 *
234 * @return mixed
235 */
236 public function search( $query = array(), $fields = array(), $sites = array(), $search_type = '', $allow_cache = false, $expiration = 120 ) {
237 if ( ! $this->site_uuid ) {
238 return false;
239 }
240
241 $body = array();
242
243 $body['query'] = ! empty( $query ) ? $query : array();
244 $body['fields'] = ! empty( $fields ) ? $fields : array();
245 $body['sites'] = ! empty( $sites ) ? $sites : array( $this->site_uuid );
246 $body['search_type'] = ! empty( $search_type ) ? $search_type : '';
247
248 $url = $this->request_url( '/search' );
249 $args = array( 'method' => 'POST', 'body' => json_encode( (object) $body ) );
250
251 return $this->remote_request( $url, $args, $allow_cache, $expiration );
252 }
253
254 /**
255 * Helper function to create and escape a URL for an API request.
256 *
257 * @param string The endpoint path, with a starting slash.
258 * @param array The $_GET parameters.
259 *
260 * @return string A properly escaped URL.
261 */
262 public function request_url( $path, $params = array() ) {
263 return esc_url_raw(
264 add_query_arg(
265 $params,
266 untrailingslashit( $this->api_url ) . $path
267 )
268 );
269 }
270
271 /**
272 * Helper function to query the marketplace API via wp_remote_request.
273 *
274 * @param string The url to access.
275 * @param string The method of the request.
276 * @param array The headers sent during the request.
277 * @param bool Allow API calls to be cached.
278 * @param int Set transient expiration in seconds.
279 *
280 * @return object The results of the wp_remote_request request.
281 */
282 protected function remote_request( $url = '', $args = array(), $allow_cache = true, $expiration = 300 ) {
283 if ( empty( $url ) || empty( $this->api_key ) ) {
284 return false;
285 }
286
287 $defaults = array(
288 'headers' => array(),
289 'method' => 'GET',
290 'body' => '',
291 'sslverify' => true,
292 );
293
294 $this->count++;
295
296 $args = wp_parse_args( $args, $defaults );
297
298 $args['headers']['Stream-Site-API-Key'] = $this->api_key;
299 $args['headers']['Accept-Version'] = $this->api_version;
300 $args['headers']['Content-Type'] = 'application/json';
301
302 if ( WP_Stream::is_development_mode() ) {
303 $args['blocking'] = true;
304 }
305
306 add_filter( 'http_api_transports', array( __CLASS__, 'http_api_transport_priority' ), 10, 3 );
307
308 $transient = 'wp_stream_' . md5( $url );
309
310 if ( 'GET' === $args['method'] && $allow_cache ) {
311 if ( false === ( $request = get_transient( $transient ) ) ) {
312 $request = wp_remote_request( $url, $args );
313
314 set_transient( $transient, $request, $expiration );
315 }
316 } else {
317 $request = wp_remote_request( $url, $args );
318 }
319
320 remove_filter( 'http_api_transports', array( __CLASS__, 'http_api_transport_priority' ), 10 );
321
322 // Return early if the request is non blocking
323 if ( isset( $args['blocking'] ) && false === $args['blocking'] ) {
324 return true;
325 }
326
327 if ( ! is_wp_error( $request ) ) {
328 $data = apply_filters( 'wp_stream_api_request_data', json_decode( $request['body'] ), $url, $args );
329
330 // Loose comparison needed
331 if ( 200 == $request['response']['code'] || 201 == $request['response']['code'] ) {
332 return $data;
333 } else {
334 // Disconnect if unauthorized or no longer exists, loose comparison needed
335 if ( 403 == $request['response']['code'] || 410 == $request['response']['code'] ) {
336 WP_Stream_Admin::remove_api_authentication();
337 }
338
339 $this->errors['errors']['http_code'] = $request['response']['code'];
340 }
341
342 if ( isset( $data->error ) ) {
343 $this->errors['errors']['api_error'] = $data->error;
344 }
345 } else {
346 $this->errors['errors']['remote_request_error'] = $request->get_error_message();
347
348 WP_Stream::notice( sprintf( '<strong>%s</strong> %s.', __( 'Stream API Error.', 'stream' ), $this->errors['errors']['remote_request_error'] ) );
349 }
350
351 if ( ! empty( $this->errors ) ) {
352 delete_transient( $transient );
353 }
354
355 return false;
356 }
357
358 }
359