Completed
Push — fix/gulp-env ( ec4107...cf0b47 )
by
unknown
133:51 queued 124:05
created

Jetpack_Sync_Module_Full_Sync::start()   C

Complexity

Conditions 7
Paths 6

Size

Total Lines 51
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 8
Bugs 1 Features 1
Metric Value
cc 7
eloc 22
c 8
b 1
f 1
nc 6
nop 1
dl 0
loc 51
rs 6.9743

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
/**
4
 * This class does a full resync of the database by
5
 * enqueuing an outbound action for every single object
6
 * that we care about.
7
 *
8
 * This class, and its related class Jetpack_Sync_Module, contain a few non-obvious optimisations that should be explained:
9
 * - we fire an action called jetpack_full_sync_start so that WPCOM can erase the contents of the cached database
10
 * - for each object type, we page through the object IDs and enqueue them by firing some monitored actions
11
 * - we load the full objects for those IDs in chunks of Jetpack_Sync_Module::ARRAY_CHUNK_SIZE (to reduce the number of MySQL calls)
12
 * - we fire a trigger for the entire array which the Jetpack_Sync_Listener then serializes and queues.
13
 */
14
15
require_once 'class.jetpack-sync-wp-replicastore.php';
16
17
class Jetpack_Sync_Module_Full_Sync extends Jetpack_Sync_Module {
18
	const STATUS_OPTION = 'jetpack_full_sync_status';
19
	const FULL_SYNC_TIMEOUT = 3600;
20
21
	public function name() {
22
		return 'full-sync';
23
	}
24
25
	function init_listeners( $callable ) {
26
		// synthetic actions for full sync
27
		add_action( 'jetpack_full_sync_start', $callable );
28
		add_action( 'jetpack_full_sync_end', $callable );
29
	}
30
31
	function init_before_send() {
32
		// this is triggered after actions have been processed on the server
33
		add_action( 'jetpack_sync_processed_actions', array( $this, 'update_sent_progress_action' ) );
34
	}
35
36
	function start( $modules = null ) {
37
		if( ! $this->should_start_full_sync() ) {
38
			return false;
39
		}
40
41
		// ensure listener is loaded so we can guarantee full sync actions are enqueued
42
		require_once dirname( __FILE__ ) . '/class.jetpack-sync-listener.php';
43
		Jetpack_Sync_Listener::getInstance();
44
45
		/**
46
		 * Fires when a full sync begins. This action is serialized
47
		 * and sent to the server so that it knows a full sync is coming.
48
		 *
49
		 * @since 4.2.0
50
		 */
51
		do_action( 'jetpack_full_sync_start' );
52
		$this->set_status_queuing_started();
53
54
		foreach( Jetpack_Sync_Modules::get_modules() as $module ) {
55
			$module_name = $module->name();
56
			if ( is_array( $modules ) && ! in_array( $module_name, $modules ) ) {
57
				continue;
58
			}
59
60
			$items_enqueued = $module->enqueue_full_sync_actions();
61
			if ( $items_enqueued !== 0 ) {
62
				$status = $this->get_status();
63
64
				if ( ! isset( $status['queue'][ $module_name ] ) ) {
65
					$status['queue'][ $module_name ] = 0;	
66
				}
67
68
				$status['queue'][ $module_name ] += $items_enqueued;
69
			}
70
			$this->update_status( $status );
0 ignored issues
show
Bug introduced by
The variable $status does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
71
		}
72
73
		$this->set_status_queuing_finished();
74
75
		$store = new Jetpack_Sync_WP_Replicastore();
76
77
		/**
78
		 * Fires when a full sync ends. This action is serialized
79
		 * and sent to the server with checksums so that we can confirm the
80
		 * sync was successful.
81
		 *
82
		 * @since 4.2.0
83
		 */
84
		do_action( 'jetpack_full_sync_end', $store->checksum_all() );
85
		return true;
86
	}
87
88
	private function should_start_full_sync() {
89
		$status = $this->get_status();
90
		
91
		// We should try sync if we haven't started it yet or if we have finished it.
92
		if( is_null( $status['started'] ) || is_integer( $status['finished'] ) ) {
93
			return true;
94
		}
95
96
		// allow enqueing if last full sync was started more than FULL_SYNC_TIMEOUT seconds ago
97
		if ( intval( $status['started'] ) + self::FULL_SYNC_TIMEOUT < time() ) {
98
			return true;
99
		}
100
101
		return false;
102
	}
103
104
	function update_sent_progress_action( $actions ) {
105
		// quick way to map to first items with an array of arrays
106
		$actions_with_counts = array_count_values( array_map( 'reset', $actions ) );
107
108
		$status = $this->get_status();
109
		if ( is_null( $status['started'] ) || $status['finished'] ) {
110
			return;
111
		}
112
113
		if ( isset( $actions_with_counts[ 'jetpack_full_sync_start' ] ) ) {
114
			$status['sent_started'] = time();
115
		}
116
117
		foreach( Jetpack_Sync_Modules::get_modules() as $module ) {
118
			$module_name = $module->name();
119
			$module_actions = $module->get_full_sync_actions();
120
			foreach( $module_actions as $module_action ) {
121
				if ( isset( $actions_with_counts[ $module_action ] ) ) {
122
					if ( ! isset( $status[ 'sent' ][ $module_name ] ) ) {
123
						$status['sent'][ $module_name ] = 0;	
124
					}
125
					$status['sent'][ $module_name ] += $actions_with_counts[ $module_action ];	
126
				}
127
			}
128
		}
129
130
		if ( isset( $actions_with_counts[ 'jetpack_full_sync_end' ] ) ) {
131
			$status['finished'] = time();
132
		}
133
134
		$this->update_status( $status );
135
	}
136
137
	private function set_status_queuing_started() {
138
		$status = $this->initial_status;
139
		$status[ 'started' ] = time();
140
		$this->update_status( $status );
141
	}
142
143
	private function set_status_queuing_finished() {
144
		$this->update_status( array( 'queue_finished' => time() ) );
145
	}
146
147
	private $initial_status = array(
148
		'started' => null,
149
		'queue_finished' => null,
150
		'sent_started' => null,
151
		'finished' => null,
152
		'sent' => array(),
153
		'queue' => array(),
154
	);
155
156
	public function get_status() {
157
		return get_option( self::STATUS_OPTION, $this->initial_status );
158
	}
159
160
	public function update_status( $status ) {
161
		return update_option(
162
			self::STATUS_OPTION,
163
			array_merge( $this->get_status(), $status )
164
		);
165
	}
166
167
	public function clear_status() {
168
		delete_option( self::STATUS_OPTION );
169
	}
170
}
171