PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3
Jetpack – WP Security, Backup, Speed, & Growth v16.3
16.3 16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 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 All 508 releases
← All changes | modules/widgets/wordpress-post-widget/class.jetpack-display-posts-widget.php +282 -0 16.2-beta → 16.3 View file →
@@ -1,0 +1,282 @@
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 +}