Completed
Push — add/rate-limiting ( b475df...82b58f )
by
unknown
50:37 queued 41:16
created

Jetpack_Sync_Server::receive()   C

Complexity

Conditions 7
Paths 8

Size

Total Lines 71
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 7
eloc 20
c 2
b 0
f 1
nc 8
nop 2
dl 0
loc 71
rs 6.7968

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
require_once dirname( __FILE__ ) . '/class.jetpack-sync-deflate-codec.php';
4
5
/**
6
 * Simple version of a Jetpack Sync Server - just receives arrays of events and
7
 * issues them locally with the 'jetpack_sync_remote_action' action.
8
 */
9
class Jetpack_Sync_Server {
10
	private $codec;
11
	const MAX_TIME_PER_REQUEST_IN_SECONDS = 15;
12
	const BLOG_LOCK_TRANSIENT_PREFIX = 'jetpack_sync_request_lock_';
13
	const BLOG_LOCK_TRANSIENT_EXPIRY = 60;
14
15
	// this is necessary because you can't use "new" when you declare instance properties >:(
16
	function __construct() {
17
		$this->codec            = new Jetpack_Sync_Deflate_Codec();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned correctly; expected 1 space but found 12 spaces

This check looks for improperly formatted assignments.

Every assignment must have exactly one space before and one space after the equals operator.

To illustrate:

$a = "a";
$ab = "ab";
$abc = "abc";

will have no issues, while

$a   = "a";
$ab  = "ab";
$abc = "abc";

will report issues in lines 1 and 2.

Loading history...
18
	}
19
20
	function set_codec( iJetpack_Sync_Codec $codec ) {
21
		$this->codec = $codec;
22
	}
23
24
	function attempt_request_lock( $blog_id, $expiry = self::BLOG_LOCK_TRANSIENT_EXPIRY ) {
25
		$transient_name = $this->get_concurrent_request_transient_name( $blog_id );
26
		$locked_time = get_transient( $transient_name );
27
		if ( $locked_time ) {
28
			return false;
29
		}
30
		// for some reason set_transient isn't returning TRUE like it's supposed to...
31
		set_transient( $transient_name, microtime( true ), $expiry );
32
		return true;
33
	}
34
35
	private function get_concurrent_request_transient_name( $blog_id ) {
36
		return self::BLOG_LOCK_TRANSIENT_PREFIX.$blog_id;
37
	}
38
39
	function remove_request_lock( $blog_id ) {
40
		delete_transient( $this->get_concurrent_request_transient_name( $blog_id ) );
41
	}
42
43
	function receive( $data, $token = null ) {
44
		$start_time = microtime( true );
45
		if ( ! is_array( $data ) ) {
46
			return new WP_Error( 'action_decoder_error', 'Events must be an array' );
47
		}
48
49
		if ( $token && ! $this->attempt_request_lock( $token->blog_id ) ) {
50
			/**
51
			 * Fires when the server receives two concurrent requests from the same blog
52
			 *
53
			 * @since 4.1
54
			 *
55
			 * @param token The token object of the misbehaving site
56
			 */
57
			do_action( "jetpack_sync_multi_request_fail", $token );
58
			return new WP_Error( 'concurrent_request_error', 'There is another request running for the same blog ID' );
59
		}
60
61
		$events = wp_unslash( array_map( array( $this->codec, 'decode' ), $data ) );
62
		$events_processed = array();
63
64
		/**
65
		 * Fires when an array of actions are received from a remote Jetpack site
66
		 *
67
		 * @since 4.1
68
		 *
69
		 * @param array Array of actions received from the remote site
70
		 */
71
		do_action( "jetpack_sync_remote_actions", $events, $token );
72
73
		foreach ( $events as $key => $event ) {
74
			list( $action_name, $args, $user_id, $timestamp ) = $event;
75
76
			/**
77
			 * Fires when an action is received from a remote Jetpack site
78
			 *
79
			 * @since 4.1
80
			 *
81
			 * @param string $action_name The name of the action executed on the remote site
82
			 * @param array $args The arguments passed to the action
83
			 * @param int $user_id The external_user_id who did the action
84
			 * @param double $timestamp Timestamp (in seconds) when the action occurred
85
			 * @param array $token The auth token used to invoke the API
86
			 */
87
			do_action( 'jetpack_sync_remote_action', $action_name, $args, $user_id, $timestamp, $token );
88
89
			/**
90
			 * Fires when an action is received from a remote Jetpack site
91
			 *
92
			 * @since 4.1
93
			 *
94
			 * @param array $args The arguments passed to the action
95
			 * @param int $user_id The external_user_id who did the action
96
			 * @param double $timestamp Timestamp (in seconds) when the action occurred
97
			 * @param array $token The auth token used to invoke the API
98
			 */
99
			do_action( 'jetpack_sync_' . $action_name, $args, $user_id, $timestamp, $token );
100
101
			$events_processed[] = $key;
102
103
			if ( microtime( true ) - $start_time > self::MAX_TIME_PER_REQUEST_IN_SECONDS ) {
104
				break;
105
			}
106
		}
107
108
		if ( $token ) {
109
			$this->remove_request_lock( $token->blog_id );
110
		}
111
112
		return $events_processed;
113
	}
114
}