Completed
Push — master ( 69dad6...fb86a2 )
by David
05:07
created

Wordlift_Batch_Analysis_Service::request()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 47
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 20
nc 4
nop 0
dl 0
loc 47
rs 8.6845
c 0
b 0
f 0
1
<?php
2
/**
3
 * Services: Batch Analysis Service.
4
 *
5
 * The Batch Analysis service allows to queue analysis operations given a list
6
 * of URLs.
7
 *
8
 * The Batch Analysis service should also allow to queue all the posts/pages
9
 * that do not contain any annotation (example annotation:
10
 * <span id="urn:enhancement-{uuid}"
11
 *       class="textannotation disambiguated wl-{class} [wl-[no-]link]"
12
 *       itemid="{itemid-url}">{label}</span>
13
 *
14
 * We must identify the batch analysis status according to 3 stages:
15
 *  1. BATCH_ANALYSIS_SUBMIT, i.e. a post/page has been submitted for batch
16
 *      analysis.
17
 *  2. BATCH_ANALYSIS_REQUEST, i.e. a post/page batch analysis has been
18
 *      requested to the remote service.
19
 *  3. BATCH_ANALYSIS_SUCCESS / BATCH_ANALYSIS_ERROR: the outcome of the batch
20
 *      analysis.
21
 *
22
 * For each state we record the date time, this is especially useful since the
23
 * remote service doesn't provide a state management, therefore we need to
24
 * define a timeout on the client side.
25
 *
26
 * Upon reception of the results we need to check whether there are some
27
 * potential warning due to interpolation issues, i.e.
28
 *
29
 *  `\w<span id="urn:enhancement-` or `\s</span>` or `</span>\w`
30
 *
31
 * and in such a case, set a warning BATCH_ANALYSIS_WARNING in order to provide
32
 * a list of posts/pages that need manual review and allow the editor to clear
33
 * the warning flag.
34
 *
35
 * All the time-consuming operations must be executed asynchronously.
36
 *
37
 * Since setting the post meta for a large number of posts may be time consuming
38
 * in PHP, we can use prepared queries.
39
 *
40
 * @since      3.14.0
41
 * @package    Wordlift
42
 * @subpackage Wordlift/includes
43
 */
44
45
/**
46
 * Define the {@link Wordlift_Batch_Analysis_Service} class.
47
 *
48
 * @since      3.14.0
49
 * @package    Wordlift
50
 * @subpackage Wordlift/includes
51
 */
52
class Wordlift_Batch_Analysis_Service {
53
54
	/**
55
	 * The list of states for the Batch Analysis:
56
	 *  - STATE_META_KEY: the batch analysis state meta key,
57
	 *  - STATE_SUBMIT: a post/page has been submitted for analysis,
58
	 *  - STATE_REQUEST: the plugin requested an analysis for the submitted
59
	 *      post/page,
60
	 *  - STATE_SUCCESS: the analysis has completed successfully,
61
	 *  - STATE_ERROR: the analysis returned an error.
62
	 *
63
	 * @since 3.14.2
64
	 */
65
	const STATE_META_KEY = '_wl_batch_analysis_state';
66
	const STATE_SUBMIT = 0;
67
	const STATE_REQUEST = 1;
68
	//### COMPLETE states.
69
	const STATE_SUCCESS = 2;
70
	const STATE_ERROR = 2;
71
72
	/**
73
	 * The submit timestamp meta key. A post may have more than one timestamp.
74
	 *
75
	 * @since 3.14.2
76
	 */
77
	const SUBMIT_TIMESTAMP_META_KEY = '_wl_batch_analysis_submit_timestamp';
78
79
	/**
80
	 * The request timestamp meta key. A post may have more than one timestamp.
81
	 *
82
	 * @since 3.14.2
83
	 */
84
	const REQUEST_TIMESTAMP_META_KEY = '_wl_batch_analysis_request_timestamp';
85
86
	/**
87
	 * The complete (success or error) timestamp meta key. A post may have more
88
	 * than one timestamp.
89
	 *
90
	 * @since 3.14.2
91
	 */
92
	const COMPLETE_TIMESTAMP_META_KEY = '_wl_batch_analysis_complete_timestamp';
93
94
	/**
95
	 * The link setting meta key. A post may have more than one setting.
96
	 *
97
	 * @since 3.14.2
98
	 */
99
	const LINK_META_KEY = '_wl_batch_analysis_link';
100
101
	/**
102
	 * The warning timestamp meta key. A post has only zero/one value.
103
	 *
104
	 * @since 3.14.2
105
	 */
106
	const WARNING_META_KEY = '_wl_batch_analysis_warning';
107
108
	/**
109
	 * Option name.
110
	 *
111
	 * @since  3.14.0
112
	 */
113
	const OPTION_NAME = 'wl_analyze_batch';
114
115
	/**
116
	 * Name of waiting to be processed queue array inside the option.
117
	 *
118
	 * @since  3.14.0
119
	 */
120
	const ANALYZE_QUEUE = 'queue';
121
122
	/**
123
	 * Name of waiting for response queue array inside the option.
124
	 *
125
	 * @since  3.14.0
126
	 */
127
	const RESPONSE_QUEUE = 'processing';
128
129
	/**
130
	 * The {@link Wordlift} plugin instance.
131
	 *
132
	 * @since  3.14.0
133
	 * @access private
134
	 * @var \Wordlift $plugin The {@link Wordlift} plugin instance.
135
	 */
136
	private $plugin;
137
138
	/**
139
	 * The {@link Wordlift_Configuration_Service} instance.
140
	 *
141
	 * @since  3.14.0
142
	 * @access private
143
	 * @var \Wordlift_Configuration_Service $configuration_service The {@link Wordlift_Configuration_Service} instance.
144
	 */
145
	private $configuration_service;
146
147
	/**
148
	 * A {@link Wordlift_Log_Service} instance.
149
	 *
150
	 * @since  3.14.2
151
	 * @access private
152
	 * @var \Wordlift_Log_Service $log A {@link Wordlift_Log_Service} instance.
153
	 */
154
	private $log;
155
156
	/**
157
	 * The {@link Class_Wordlift_Batch_Analys_Service} instance.
158
	 *
159
	 * @since 3.14.0
160
	 *
161
	 * @param \Wordlift                       $plugin                The {@link Wordlift} plugin instance.
162
	 * @param \Wordlift_Configuration_Service $configuration_service The {@link Wordlift_Configuration_Service} instance.
163
	 */
164
	public function __construct( $plugin, $configuration_service ) {
165
166
		$this->plugin                = $plugin;
167
		$this->configuration_service = $configuration_service;
168
		$this->log                   = Wordlift_Log_Service::get_logger( 'Wordlift_Batch_Analysis_Service' );
169
170
		add_action( 'wp_async_wl_batch_analysis_request', array(
171
			$this,
172
			'request',
173
		) );
174
		add_action( 'wp_async_wl_batch_analysis_complete', array(
175
			$this,
176
			'complete',
177
		) );
178
179
	}
180
181
	/**
182
	 * Get the base SQL statement to submit a post for Batch Analysis.
183
	 *
184
	 * Functions may use this base SQL and add their own filters.
185
	 *
186
	 * @since 3.14.2
187
	 *
188
	 * @param string $link The link setting ('yes'/'no').
189
	 *
190
	 * @return string The base SQL.
191
	 */
192
	private function get_sql( $link ) {
193
		global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
194
195
		// Prepare the statement:
196
		//  1. Insert into `postmeta` the meta keys and values:
197
		//    a) state meta, with value of SUBMIT (0),
198
		//    b) submit timestamp, with value of UTC timestamp,
199
		//    c) link meta, with the provided value.
200
		//  2. Join the current state value, can be used for filters by other
201
		//     functions.
202
		//  3. Filter by `post`/`page` types.
203
		//  4. Filter by `publish` status.
204
		return $wpdb->prepare(
205
			"
206
			INSERT INTO $wpdb->postmeta ( post_id, meta_key, meta_value )
207
			SELECT p.ID, metas.*
208
			FROM (
209
				SELECT %s, 0 FROM dual
210
				UNION
211
				SELECT %s, UTC_TIMESTAMP() FROM dual
212
				UNION
213
				SELECT %s, %s FROM dual
214
			) metas, $wpdb->posts p
215
			LEFT JOIN $wpdb->postmeta batch_analysis_state
216
				ON batch_analysis_state.post_id = p.ID
217
					AND batch_analysis_state.meta_key = %s
218
			WHERE p.post_type IN ('post', 'page')
219
				AND p.post_status = 'publish'
220
			",
221
			self::STATE_META_KEY,
222
			self::SUBMIT_TIMESTAMP_META_KEY,
223
			self::LINK_META_KEY,
224
			$link,
225
			self::STATE_META_KEY
226
		);
227
	}
228
229
	/**
230
	 * Submit for analysis all the posts/pages which do not have annotations
231
	 * and haven't been analyzed before.
232
	 *
233
	 * @since 3.14.2
234
	 *
235
	 * @param string $link The link setting.
236
	 *
237
	 * @return false|int The number of submitted {@link WP_Post}s or false on
238
	 *                   error.
239
	 */
240
	public function submit_auto_selected_posts( $link ) {
241
		global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
242
243
		// Submit the posts/pages and return the number of affected results.
244
		// We're using a SQL query here because we could have potentially
245
		// thousands of rows.
246
		$count = $wpdb->query( $wpdb->prepare(
247
			$this->get_sql( $link ) .
248
			"
249
				AND batch_analysis_state.meta_value IS NULL
250
				AND p.post_content NOT REGEXP %s;
251
			",
252
			'<[a-z]+ id="urn:enhancement-[^"]+" class="[^"]+" itemid="[^"]+">'
253
		) );
254
255
		// Request Batch Analysis (the operation is handled asynchronously).
256
		do_action( 'wl_batch_analysis_request' );
257
258
		// Divide the count by 3 to get the number of posts/pages queued.
259
		return $count / 3;
260
	}
261
262
	/**
263
	 * Submit the provided list of {@link WP_Post}s' ids for Batch Analysis.
264
	 *
265
	 * @since 3.14.2
266
	 *
267
	 * @param int|array $post_ids A single {@link WP_Post}'s id or an array of
268
	 *                            {@link WP_Post}s' ids.
269
	 * @param string    $link     The link setting.
270
	 *
271
	 * @return int The number of submitted {@link WP_Post}s or false on error.
272
	 */
273
	public function submit( $post_ids, $link ) {
274
		global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
275
276
		// Submit the posts/pages and return the number of affected results.
277
		// We're using a SQL query here because we could have potentially
278
		// thousands of rows.
279
		$count = $wpdb->query(
280
			$this->get_sql( $link ) .
281
			' AND p.ID IN ( ' . implode( ',', wp_parse_id_list( $post_ids ) ) . ' )'
282
		);
283
284
		// Request Batch Analysis (the operation is handled asynchronously).
285
		do_action( 'wl_batch_analysis_request' );
286
287
		// Divide the count by 3 to get the number of posts/pages queued.
288
		return $count / 3;
289
	}
290
291
	/**
292
	 * Cancel the Batch Analysis request for the specified {@link WP_Post}s.
293
	 *
294
	 * @since 3.14.2
295
	 *
296
	 * @param int|array $post_ids A single {@link WP_Post}'s id or an array of
297
	 *                            {@link WP_Post}s' ids.
298
	 *
299
	 * @return false|int The number of cancelled {@link WP_Post}s or false on
300
	 *                   error.
301
	 */
302
	public function cancel( $post_ids ) {
303
		global $wpdb;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
304
305
		return $wpdb->query( $wpdb->prepare(
306
			"
307
			DELETE FROM $wpdb->postmeta
308
			WHERE meta_key = %s
309
				AND meta_value = %s
310
				AND post_id IN ( " . implode( ',', wp_parse_id_list( $post_ids ) ) . " )
311
			",
312
			self::STATE_META_KEY,
313
			self::STATE_REQUEST
314
		) );
315
316
	}
317
318
	/**
319
	 * Request the batch analysis for submitted posts.
320
	 *
321
	 * @since 3.14.2
322
	 */
323
	public function request() {
324
325
		$this->log->debug( "Requesting analysis..." );
326
327
		// By default 5 posts of any post type are returned.
328
		$posts = get_posts( array(
329
			'fields'     => 'ids',
330
			'meta_key'   => self::STATE_META_KEY,
331
			'meta_value' => self::STATE_SUBMIT,
332
			'orderby'    => 'ID',
333
		) );
334
335
		// Bail out if there are no submitted posts.
336
		if ( empty( $posts ) ) {
337
			$this->log->debug( 'No posts to submit found, checking for completed requests...' );
338
339
			do_action( 'wl_batch_analysis_complete' );
340
341
			return;
342
		}
343
344
		// Send a request for each post.
345
		foreach ( $posts as $id ) {
346
			$this->log->debug( "Requesting analysis for post $id..." );
347
348
			// Change the state to `REQUEST`.
349
			$this->set_state( $id, self::STATE_REQUEST );
350
351
			// Send the actual request to the remote service.
352
			$result = $this->do_request( $id );
353
354
			$this->log->debug( "Analysis requested for post $id." );
355
356
			// Set an error if we received an error.
357
			if ( is_wp_error( $result ) ) {
358
				$this->log->error( "Analysis request for post $id returned {$result->get_error_message()}." );
359
360
				$this->set_state( $id, self::STATE_ERROR );
361
			}
362
363
		}
364
365
		// Call the `wl_batch_analysis_request` action again. This is going
366
		// to be handled by the async task.
367
		do_action( 'wl_batch_analysis_request' );
368
369
	}
370
371
	/**
372
	 * Get the results for the Batch Analysis.
373
	 *
374
	 * @since 3.14.2
375
	 */
376
	public function complete() {
377
378
		$this->log->debug( "Requesting results..." );
379
380
		// By default 5 posts of any post type are returned.
381
		$posts = get_posts( array(
382
			'fields'     => 'ids',
383
			'meta_key'   => self::STATE_META_KEY,
384
			'meta_value' => self::STATE_REQUEST,
385
			'orderby'    => 'ID',
386
		) );
387
388
		// Bail out if there are no submitted posts.
389
		if ( empty( $posts ) ) {
390
			$this->log->debug( 'No posts in request state found.' );
391
392
			return;
393
		}
394
395
		// Send a request for each post.
396
		foreach ( $posts as $id ) {
397
			$this->log->debug( "Requesting results for post $id..." );
398
399
			// Send the actual request to the remote service.
400
			$response = $this->do_complete( $id );
401
402
			$this->log->debug( "Results requested for post $id." );
403
404
			// Set an error if we received an error.
405
			if ( ! is_wp_error( $response ) && isset( $response['body'] ) ) {
406
407
				$this->log->debug( "Results received for post $id." );
408
409
				// Save the returned content as new revision.
410
				$json = json_decode( $response['body'] );
411
412
				// Continue if the content isn't set.
413
				if ( ! isset( $json->content ) || empty( $json->content ) ) {
414
					continue;
415
				}
416
417
				$this->set_warning_based_on_content( $id, $json->content );
418
419
				$content = wp_slash( $json->content );
420
421
				wp_update_post( array(
422
					'ID'           => $id,
423
					'post_content' => $content,
424
				) );
425
426
				// Update the status.
427
				$this->set_state( $id, self::STATE_SUCCESS );
428
429
				$this->log->debug( "Post $id updated with batch analysis results." );
430
431
				continue;
432
			}
433
434
			// @todo: implement a kind of timeout that sets an error if the
435
			// results haven't been received after a long time.
436
437
		}
438
439
		// Call the `wl_batch_analysis_request` action again. This is going
440
		// to be handled by the async task.
441
		do_action( 'wl_batch_analysis_complete' );
442
443
	}
444
445
	/**
446
	 * Set a warning flag on the {@link WP_Post} if its content has suspicious
447
	 * interpolations.
448
	 *
449
	 * @since 3.14.2
450
	 *
451
	 * @param int    $post_id The {@link WP_Post}'s id.
452
	 * @param string $content The {@link WP_Post}'s content.
453
	 *
454
	 * @return string The content (for chaining operations).
455
	 */
456
	private function set_warning_based_on_content( $post_id, $content ) {
457
458
		$matches = array();
459
460
		// Check for suspicious interpolations.
461
		$warning = 0 < preg_match_all( '/\w<[a-z]+ id="urn:enhancement-[^"]+" class="[^"]+" itemid="[^"]+">/', $content, $matches )
462
		           || 0 < preg_match_all( '/<[a-z]+ id="urn:enhancement-[^"]+" class="[^"]+" itemid="[^"]+">\s/', $content, $matches );
463
464
		// Set the warning flag accordingly.
465
		$this->set_warning( $post_id, $warning );
466
467
		return $content;
468
	}
469
470
	/**
471
	 * Clear the warning flag for the specified {@link WP_Post}s.
472
	 *
473
	 * @since 3.14.2
474
	 *
475
	 * @param int|array $post_ids A single {@link WP_Post}'s id or an array of
476
	 *                            {@link WP_Post}s' ids.
477
	 */
478
	public function clear_warning( $post_ids ) {
479
480
		foreach ( (array) $post_ids as $post_id ) {
481
			delete_post_meta( $post_id, self::WARNING_META_KEY );
482
		}
483
484
	}
485
486
	/**
487
	 * Set the warning flag for the specified {@link WP_Post}.
488
	 *
489
	 * @since 3.14.2
490
	 *
491
	 * @param int  $post_id The {@link WP_Post}'s id.
492
	 * @param bool $value   The flag's value.
493
	 *
494
	 * @return int|bool Meta ID if the key didn't exist, true on successful update,
495
	 *                  false on failure.
496
	 */
497
	private function set_warning( $post_id, $value ) {
498
499
		return update_post_meta( $post_id, self::WARNING_META_KEY, ( true === $value ? 'yes' : 'no' ) );
500
	}
501
502
	/**
503
	 * Get the post/page batch analysis state.
504
	 *
505
	 * @since 3.14.2
506
	 *
507
	 * @param int $post_id The {@link WP_Post}'s id.
508
	 *
509
	 * @return int|string The post state or an empty string if not set.
510
	 */
511
	public function get_state( $post_id ) {
512
513
		return get_post_meta( $post_id, self::STATE_META_KEY, true );
514
	}
515
516
	/**
517
	 * Set the post/page batch analysis state.
518
	 *
519
	 * @since 3.14.2
520
	 *
521
	 * @param int $post_id The {@link WP_Post}'s id.
522
	 * @param int $value   The new state.
523
	 *
524
	 * @return int|bool Meta ID if the key didn't exist, true on successful update,
525
	 *                  false on failure.
526
	 */
527
	public function set_state( $post_id, $value ) {
528
529
		// Update the state.
530
		$result = update_post_meta( $post_id, self::STATE_META_KEY, $value );
531
532
		// Update timestamps as required.
533
		switch ( $value ) {
534
535
			//### REQUEST state.
536
			case self::STATE_REQUEST:
537
				add_post_meta( $post_id, self::REQUEST_TIMESTAMP_META_KEY, current_time( 'mysql', true ) );
538
				break;
539
540
			//### SUCCESS/ERROR state.
541
			case self::STATE_SUCCESS:
542
			case self::STATE_ERROR:
543
				add_post_meta( $post_id, self::COMPLETE_TIMESTAMP_META_KEY, current_time( 'mysql', true ) );
544
				break;
545
		}
546
547
		// Finally return the result.
548
		return $result;
549
	}
550
551
	/**
552
	 * Get the link setting for a {@link WP_Post}.
553
	 *
554
	 * If there are multiple link settings, only the last one is returned.
555
	 *
556
	 * @since 3.14.2
557
	 *
558
	 * @param int $post_id The {@link WP_Post}'s id.
559
	 *
560
	 * @return string The link setting or `default` if not set.
561
	 */
562
	public function get_link( $post_id ) {
563
564
		$values = get_post_meta( $post_id, self::LINK_META_KEY );
565
566
		return end( $values ) ?: 'default';
567
	}
568
569
	/**
570
	 * Get the array of post IDS waiting in the queue to start processing.
571
	 *
572
	 * @since 3.14.0
573
	 *
574
	 * @return array The waiting to be processed post ids queue.
575
	 */
576 View Code Duplication
	public function waiting_for_analysis() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
577
578
		return get_posts( array(
579
			'posts_per_page' => - 1,
580
			'fields'         => 'ids',
581
			'post_status'    => 'any',
582
			'meta_key'       => self::STATE_META_KEY,
583
			'meta_value'     => self::STATE_SUBMIT,
584
			'orderby'        => 'ID',
585
		) );
586
	}
587
588
	/**
589
	 * Get the array of post IDS waiting for response.
590
	 *
591
	 * @deprecated
592
	 * @since 3.14.0
593
	 *
594
	 * @return array The waiting for response post ids queue.
595
	 */
596 View Code Duplication
	public function waiting_for_response() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
597
598
		return get_posts( array(
599
			'posts_per_page' => - 1,
600
			'fields'         => 'ids',
601
			'post_status'    => 'any',
602
			'meta_key'       => self::STATE_META_KEY,
603
			'meta_value'     => self::STATE_REQUEST,
604
			'orderby'        => 'ID',
605
		) );
606
	}
607
608
	/**
609
	 * Request the analysis for the specified {@link WP_Post}.
610
	 *
611
	 * @since 3.14.2
612
	 *
613
	 * @param int $post_id The {@link WP_Post}'s id.
614
	 *
615
	 * @return WP_Error|array The response or WP_Error on failure.
616
	 */
617
	private function do_request( $post_id ) {
618
619
		// Get the post.
620
		$post = get_post( $post_id );
621
622
		// Bail out if the post isn't found.
623
		if ( null === $post ) {
624
			$this->log->warn( "Post $post_id not found." );
625
626
			return new WP_Error( 0, "Cannot find post $post_id." );
627
		}
628
629
		// Get the link setting.
630
		$link = $this->get_link( $post_id );
631
632
		$this->log->debug( "Sending analysis request for post $post_id [ link :: $link ]..." );
633
634
		// Get the batch analysis URL.
635
		$url = $this->configuration_service->get_batch_analysis_url();
636
637
		// Prepare the POST parameters.
638
		$param = array(
639
			'id'              => $post->ID,
640
			'key'             => $this->configuration_service->get_key(),
641
			'content'         => $post->post_content,
642
			'contentLanguage' => $this->configuration_service->get_language_code(),
643
			'version'         => $this->plugin->get_version(),
644
			'links'           => $link,
645
			'scope'           => 'local',
646
		);
647
648
		// Get the HTTP options.
649
		$args = array_merge_recursive( unserialize( WL_REDLINK_API_HTTP_OPTIONS ), array(
650
			'method'      => 'POST',
651
			'headers'     => array(
652
				'Accept'       => 'application/json',
653
				'Content-type' => 'application/json; charset=UTF-8',
654
			),
655
			// we need to downgrade the HTTP version in this case since chunked encoding is dumping numbers in the response.
656
			'httpversion' => '1.0',
657
			'body'        => wp_json_encode( $param ),
658
		) );
659
660
		$this->log->debug( "Posting analysis request for post $post_id to $url..." );
661
662
		// Post the parameter.
663
		return wp_remote_post( $url, $args );
664
	}
665
666
	/**
667
	 * Get the Batch Analysis results for the specified {@link WP_Post}.
668
	 *
669
	 * @since 3.14.2
670
	 *
671
	 * @param int $post_id The {@link WP_Post}'s id.
672
	 *
673
	 * @return WP_Error|array The response or WP_Error on failure.
674
	 */
675
	private function do_complete( $post_id ) {
676
677
		$post = get_post( $post_id );
678
679
		if ( null === $post ) {
680
			// Post was possibly deleted, just bailout.
681
			return new WP_Error( 0, "Post $post_id not found." );
682
		}
683
684
		$url = $this->configuration_service->get_batch_analysis_url();
685
		$key = $this->configuration_service->get_key();
686
		$url = $url . '/' . $post->ID . '?key=' . $key;
687
688
		return wp_remote_get( $url, unserialize( WL_REDLINK_API_HTTP_OPTIONS ) );
689
	}
690
691
	/**
692
	 * Get the {@link WP_Post}s' ids flagged with warnings.
693
	 *
694
	 * @since 3.14.2
695
	 *
696
	 * @return array An array of {@link WP_Post}s' ids.
697
	 */
698 View Code Duplication
	public function get_warnings() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
699
700
		return get_posts( array(
701
			'fields'      => 'ids',
702
			'numberposts' => - 1,
703
			'post_status' => 'any',
704
			'meta_key'    => self::WARNING_META_KEY,
705
			'meta_value'  => 'yes',
706
		) );
707
	}
708
709
}
710