PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-a.1
Jetpack – WP Security, Backup, Speed, & Growth v16.3-a.1
16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 13.9.2 14.0.1 14.1.1 All 503 releases
jetpack / modules / widgets / wordpress-post-widget / class.jetpack-display-posts-widget.php

class.jetpack-display-posts-widget.php in Jetpack – WP Security, Backup, Speed, & Growth 16.3-a.1, at modules/widgets/wordpress-post-widget/class.jetpack-display-posts-widget.php

283 lines 6.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2
3 use Automattic\Jetpack\Status;
4
5 if ( ! defined( 'ABSPATH' ) ) {
6 exit( 0 );
7 }
8
9 /**
10 * Display a list of recent posts from a WordPress.com or Jetpack-enabled blog.
11 */
12 class Jetpack_Display_Posts_Widget extends Jetpack_Display_Posts_Widget__Base {
13 /**
14 * Widget options key prefix.
15 *
16 * @var string
17 */
18 public $widget_options_key_prefix = 'display_posts_site_data_';
19
20 /**
21 * The name of the cron that will update widget data.
22 *
23 * @var string
24 */
25 public static $cron_name = 'jetpack_display_posts_widget_cron_update';
26
27 // DATA STORE.
28
29 /**
30 * Gets blog data from the cache.
31 *
32 * @param string $site Site.
33 *
34 * @return array|WP_Error
35 */
36 public function get_blog_data( $site ) {
37 // Load from cache, if nothing return an error.
38 $site_hash = $this->get_site_hash( $site );
39
40 $cached_data = $this->wp_get_option( $this->widget_options_key_prefix . $site_hash );
41
42 /**
43 * If the cache is empty, return an empty_cache error.
44 */
45 if ( false === $cached_data ) {
46 return new WP_Error(
47 'empty_cache',
48 __( 'Information about this blog is currently being retrieved.', 'jetpack' )
49 );
50 }
51
52 return $cached_data;
53 }
54
55 /**
56 * Update a widget instance.
57 *
58 * @param string $site The site to fetch the latest data for.
59 *
60 * @return array - the new data
61 */
62 public function update_instance( $site ) {
63
64 /**
65 * Fetch current information for a site.
66 */
67 $site_hash = $this->get_site_hash( $site );
68
69 $option_key = $this->widget_options_key_prefix . $site_hash;
70
71 $instance_data = $this->wp_get_option( $option_key );
72
73 /**
74 * Fetch blog data and save it in $instance_data.
75 */
76 $new_data = $this->fetch_blog_data( $site, $instance_data );
77
78 /**
79 * If the option doesn't exist yet - create a new option
80 */
81 if ( false === $instance_data ) {
82 $this->wp_add_option( $option_key, $new_data );
83 } else {
84 $this->wp_update_option( $option_key, $new_data );
85 }
86
87 return $new_data;
88 }
89
90 // WIDGET API.
91
92 /**
93 * Widget update function.
94 *
95 * @param array $new_instance New instance widget settings.
96 * @param array $old_instance Old instance widget settings.
97 */
98 public function update( $new_instance, $old_instance ) {
99 $instance = parent::update( $new_instance, $old_instance );
100
101 /**
102 * Forcefully activate the update cron when saving widget instance.
103 *
104 * So we can be sure that it will be running later.
105 */
106 $this->activate_cron();
107
108 return $instance;
109 }
110
111 // CRON.
112
113 /**
114 * Activates widget update cron task.
115 */
116 public static function activate_cron() {
117 if ( ! wp_next_scheduled( self::$cron_name ) ) {
118 wp_schedule_event( time(), 'minutes_10', self::$cron_name );
119 }
120 }
121
122 /**
123 * Deactivates widget update cron task.
124 *
125 * This is a wrapper over the static method as it provides some syntactic sugar.
126 */
127 public function deactivate_cron() {
128 self::deactivate_cron_static();
129 }
130
131 /**
132 * Deactivates widget update cron task.
133 */
134 public static function deactivate_cron_static() {
135 $next_scheduled_time = wp_next_scheduled( self::$cron_name );
136 wp_unschedule_event( $next_scheduled_time, self::$cron_name );
137 }
138
139 /**
140 * Checks if the update cron should be running and returns appropriate result.
141 *
142 * @return bool If the cron should be running or not.
143 */
144 public function should_cron_be_running() {
145 /**
146 * The cron doesn't need to run empty loops.
147 */
148 $widget_instances = $this->get_instances_sites();
149
150 if ( empty( $widget_instances ) || ! is_array( $widget_instances ) ) {
151 return false;
152 }
153
154 if ( ! defined( 'IS_WPCOM' ) || ! IS_WPCOM ) {
155 /**
156 * If Jetpack is not active or in offline mode, we don't want to update widget data.
157 */
158 if ( ! Jetpack::is_connection_ready() && ! ( new Status() )->is_offline_mode() ) {
159 return false;
160 }
161
162 /**
163 * If Extra Sidebar Widgets module is not active, we don't need to update widget data.
164 */
165 if ( ! Jetpack::is_module_active( 'widgets' ) ) {
166 return false;
167 }
168 }
169
170 /**
171 * If none of the above checks failed, then we definitely want to update widget data.
172 */
173 return true;
174 }
175
176 /**
177 * Main cron code. Updates all instances of the widget.
178 *
179 * @return bool
180 */
181 public function cron_task() {
182
183 /**
184 * If the cron should not be running, disable it.
185 */
186 if ( false === $this->should_cron_be_running() ) {
187 return true;
188 }
189
190 $instances_to_update = $this->get_instances_sites();
191
192 /**
193 * If no instances are found to be updated - stop.
194 */
195 if ( empty( $instances_to_update ) || ! is_array( $instances_to_update ) ) {
196 return true;
197 }
198
199 foreach ( $instances_to_update as $site_url ) {
200 $this->update_instance( $site_url );
201 }
202
203 return true;
204 }
205
206 /**
207 * Get a list of unique sites from all instances of the widget.
208 *
209 * @return array|bool
210 */
211 public function get_instances_sites() {
212
213 $widget_settings = $this->wp_get_option( 'widget_jetpack_display_posts_widget' );
214
215 /**
216 * If the widget still hasn't been added anywhere, the config will not be present.
217 *
218 * In such case we don't want to continue execution.
219 */
220 if ( false === $widget_settings || ! is_array( $widget_settings ) ) {
221 return false;
222 }
223
224 $urls = array();
225
226 foreach ( $widget_settings as $widget_instance_data ) {
227 if ( isset( $widget_instance_data['url'] ) && ! empty( $widget_instance_data['url'] ) ) {
228 $urls[] = $widget_instance_data['url'];
229 }
230 }
231
232 /**
233 * Make sure only unique URLs are returned.
234 */
235 $urls = array_unique( $urls );
236
237 return $urls;
238 }
239
240 // MOCKABLES.
241
242 /**
243 * This is just to make method mocks in the unit tests easier.
244 *
245 * @param string $param Option key to get.
246 *
247 * @return mixed
248 *
249 * @codeCoverageIgnore
250 */
251 public function wp_get_option( $param ) {
252 return get_option( $param );
253 }
254
255 /**
256 * This is just to make method mocks in the unit tests easier.
257 *
258 * @param string $option_name Option name to be added.
259 * @param mixed $option_value Option value.
260 *
261 * @return mixed
262 *
263 * @codeCoverageIgnore
264 */
265 public function wp_add_option( $option_name, $option_value ) {
266 return add_option( $option_name, $option_value );
267 }
268
269 /**
270 * This is just to make method mocks in the unit tests easier.
271 *
272 * @param string $option_name Option name to be updated.
273 * @param mixed $option_value Option value.
274 *
275 * @return mixed
276 *
277 * @codeCoverageIgnore
278 */
279 public function wp_update_option( $option_name, $option_value ) {
280 return update_option( $option_name, $option_value );
281 }
282 }
283