Completed
Push — unify/wordpress-post-widget ( 9319c3 )
by
unknown
09:34
created

deactivate_cron_static()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * Display a list of recent posts from a WordPress.com or Jetpack-enabled blog.
5
 */
6
7
class Jetpack_Display_Posts_Widget extends Jetpack_Display_Posts_Widget__Base {
8
	/**
9
	 * @var string Widget options key prefix.
10
	 */
11
	public $widget_options_key_prefix = 'display_posts_site_data_';
12
13
	/**
14
	 * @var string The name of the cron that will update widget data.
15
	 */
16
	public static $cron_name = 'jetpack_display_posts_widget_cron_update';
17
18
19
	// FETCH
20
21
	/**
22
	 * @param string $url  The URL to fetch
23
	 * @param array  $args Optional. Request arguments.
24
	 *
25
	 * @return array|WP_Error
26
	 */
27
	public function wpcom_json_api_get( $url, $args = array() ) {
28
		return wp_remote_get( $url, $args );
29
        }
30
31
	/**
32
	 * @param array $response
0 ignored issues
show
Documentation introduced by
There is no parameter named $response. Did you maybe mean $service_response?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
33
	 *
34
	 * @return array|WP_Error
35
	 */
36
	public function wpcom_json_api_parse( $service_response ) {
37
		/**
38
		 * Validate HTTP response code.
39
		 */
40
		if ( 200 !== wp_remote_retrieve_response_code( $service_response ) ) {
41
			return new WP_Error(
42
				'http_error',
43
				__( 'An error occurred fetching the remote data.', 'jetpack' ),
44
				wp_remote_retrieve_response_message( $service_response )
45
			);
46
		}
47
48
49
		/**
50
		 * Extract service response body from the request.
51
		 */
52
53
		$service_response_body = wp_remote_retrieve_body( $service_response );
54
55
56
		/**
57
		 * No body has been set in the response. This should be pretty bad.
58
		 */
59
		if ( ! $service_response_body ) {
60
			return new WP_Error(
61
				'no_body',
62
				__( 'Invalid remote response.', 'jetpack' ),
63
				'No body in response.'
64
			);
65
		}
66
67
		/**
68
		 * Parse the JSON response from the API. Convert to associative array.
69
		 */
70
		$parsed_data = json_decode( $service_response_body );
71
72
		/**
73
		 * If there is a problem with parsing the posts return an empty array.
74
		 */
75
		if ( is_null( $parsed_data ) ) {
76
			return new WP_Error(
77
				'no_body',
78
				__( 'Invalid remote response.', 'jetpack' ),
79
				'Invalid JSON from remote.'
80
			);
81
		}
82
83
		/**
84
		 * No errors found, return parsed data.
85
		 */
86
		return $parsed_data;
87
	}
88
89
90
	// DATA STORE
91
92
	/**
93
	 * Gets blog data from the cache.
94
	 *
95
	 * @param string $site
96
	 *
97
	 * @return array|WP_Error
98
	 */
99
	public function get_blog_data( $site ) {
100
		// load from cache, if nothing return an error
101
		$site_hash = $this->get_site_hash( $site );
102
103
		$cached_data = $this->wp_get_option( $this->widget_options_key_prefix . $site_hash );
104
105
		/**
106
		 * If the cache is empty, return an empty_cache error.
107
		 */
108
		if ( false === $cached_data ) {
109
			return new WP_Error(
110
				'empty_cache',
111
				__( 'Information about this blog is currently being retrieved.', 'jetpack' )
112
			);
113
		}
114
115
		return $cached_data;
116
117
	}
118
119
	/**
120
	 * Update a widget instance.
121
	 *
122
	 * @param string $site The site to fetch the latest data for.
123
	 */
124
	public function update_instance( $site ) {
125
126
		/**
127
		 * Fetch current information for a site.
128
		 */
129
		$site_hash = $this->get_site_hash( $site );
130
131
		$option_key = $this->widget_options_key_prefix . $site_hash;
132
133
		$instance_data = $this->wp_get_option( $option_key );
134
135
		/**
136
		 * Fetch blog data and save it in $instance_data.
137
		 */
138
		$new_data = $this->fetch_blog_data( $site, $instance_data );
139
140
		/**
141
		 * If the option doesn't exist yet - create a new option
142
		 */
143
		if ( false === $instance_data ) {
144
			$this->wp_add_option( $option_key, $new_data );
145
		}
146
		else {
147
			$this->wp_update_option( $option_key, $new_data );
148
		}
149
	}
150
151
152
	// WIDGET API
153
154
	public function update( $new_instance, $old_instance ) {
155
		$instance = parent::update( $new_instance, $old_instance );
156
157
		/**
158
		 * Forcefully activate the update cron when saving widget instance.
159
		 *
160
		 * So we can be sure that it will be running later.
161
		 */
162
		$this->activate_cron();
163
164
		return $instance;
165
	}
166
167
168
	// CRON
169
170
	/**
171
	 * Activates widget update cron task.
172
	 */
173
	public static function activate_cron() {
174
		if ( ! wp_next_scheduled( self::$cron_name ) ) {
175
			wp_schedule_event( time(), 'minutes_10', self::$cron_name );
176
		}
177
	}
178
179
	/**
180
	 * Deactivates widget update cron task.
181
	 *
182
	 * This is a wrapper over the static method as it provides some syntactic sugar.
183
	 */
184
	public function deactivate_cron() {
185
		self::deactivate_cron_static();
186
	}
187
188
	/**
189
	 * Deactivates widget update cron task.
190
	 */
191
	public static function deactivate_cron_static() {
192
		$next_scheduled_time = wp_next_scheduled( self::$cron_name );
193
		wp_unschedule_event( $next_scheduled_time, self::$cron_name );
194
	}
195
196
	/**
197
	 * Checks if the update cron should be running and returns appropriate result.
198
	 *
199
	 * @return bool If the cron should be running or not.
200
	 */
201
	public function should_cron_be_running() {
202
		/**
203
		 * The cron doesn't need to run empty loops.
204
		 */
205
		$widget_instances = $this->get_instances_sites();
206
207
		if ( empty( $widget_instances ) || ! is_array( $widget_instances ) ) {
208
			return false;
209
		}
210
211
		if ( ! defined( 'IS_WPCOM' ) || ! IS_WPCOM ) {
212
			/**
213
			 * If Jetpack is not active or in development mode, we don't want to update widget data.
214
			 */
215
			if ( ! Jetpack::is_active() && ! Jetpack::is_development_mode() ) {
216
				return false;
217
			}
218
219
			/**
220
			 * If Extra Sidebar Widgets module is not active, we don't need to update widget data.
221
			 */
222
			if ( ! Jetpack::is_module_active( 'widgets' ) ) {
223
				return false;
224
			}
225
		}
226
227
		/**
228
		 * If none of the above checks failed, then we definitely want to update widget data.
229
		 */
230
		return true;
231
	}
232
233
	/**
234
	 * Main cron code. Updates all instances of the widget.
235
	 *
236
	 * @return bool
237
	 */
238
	public function cron_task() {
239
240
		/**
241
		 * If the cron should not be running, disable it.
242
		 */
243
		if ( false === $this->should_cron_be_running() ) {
244
			return true;
245
		}
246
247
		$instances_to_update = $this->get_instances_sites();
248
249
		/**
250
		 * If no instances are found to be updated - stop.
251
		 */
252
		if ( empty( $instances_to_update ) || ! is_array( $instances_to_update ) ) {
253
			return true;
254
		}
255
256
		foreach ( $instances_to_update as $site_url ) {
257
			$this->update_instance( $site_url );
258
		}
259
260
		return true;
261
	}
262
263
	/**
264
	 * Get a list of unique sites from all instances of the widget.
265
	 *
266
	 * @return array|bool
267
	 */
268
	public function get_instances_sites() {
269
270
		$widget_settings = $this->wp_get_option( 'widget_jetpack_display_posts_widget' );
271
272
		/**
273
		 * If the widget still hasn't been added anywhere, the config will not be present.
274
		 *
275
		 * In such case we don't want to continue execution.
276
		 */
277
		if ( false === $widget_settings || ! is_array( $widget_settings ) ) {
278
			return false;
279
		}
280
281
		$urls = array();
282
283
		foreach ( $widget_settings as $widget_instance_data ) {
284
			if ( isset( $widget_instance_data['url'] ) && ! empty( $widget_instance_data['url'] ) ) {
285
				$urls[] = $widget_instance_data['url'];
286
			}
287
		}
288
289
		/**
290
		 * Make sure only unique URLs are returned.
291
		 */
292
		$urls = array_unique( $urls );
293
294
		return $urls;
295
296
	}
297
298
299
	// MOCKABLES
300
301
	/**
302
	 * This is just to make method mocks in the unit tests easier.
303
	 *
304
	 * @param string $param Option key to get
305
	 *
306
	 * @return mixed
307
	 *
308
	 * @codeCoverageIgnore
309
	 */
310
	public function wp_get_option( $param ) {
311
		return get_option( $param );
312
	}
313
314
	/**
315
	 * This is just to make method mocks in the unit tests easier.
316
	 *
317
	 * @param string $option_name  Option name to be added
318
	 * @param mixed  $option_value Option value
319
	 *
320
	 * @return mixed
321
	 *
322
	 * @codeCoverageIgnore
323
	 */
324
	public function wp_add_option( $option_name, $option_value ) {
325
		return add_option( $option_name, $option_value );
326
	}
327
328
	/**
329
	 * This is just to make method mocks in the unit tests easier.
330
	 *
331
	 * @param string $option_name  Option name to be updated
332
	 * @param mixed  $option_value Option value
333
	 *
334
	 * @return mixed
335
	 *
336
	 * @codeCoverageIgnore
337
	 */
338
	public function wp_update_option( $option_name, $option_value ) {
339
		return update_option( $option_name, $option_value );
340
	}
341
}
342