PluginProbe ʕ •ᴥ•ʔ
WooCommerce Square / 3.8.1
WooCommerce Square v3.8.1
5.4.2 5.4.1 5.4.0 trunk 1.0.25 1.0.26 1.0.27 1.0.28 1.0.29 1.0.30 1.0.31 1.0.32 1.0.33 1.0.34 1.0.35 1.0.36 1.0.37 1.0.38 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 2.4.0 2.4.1 2.5.0 2.5.1 2.5.2 2.5.3 2.6.0 2.7.0 2.8.0 2.9.0 2.9.1 3.0.0 3.0.1 3.0.2 3.0.3 3.1.0 3.2.0 3.3.0 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.6.1 3.7.0 3.7.1 3.8.0 3.8.1 3.8.2 3.8.3 3.9.0 4.0.0 4.1.0 4.2.0 4.2.1 4.2.2 4.2.3 4.3.0 4.3.1 4.3.2 4.4.0 4.4.1 4.4.2 4.5.0 4.5.1 4.5.2 4.6.0 4.6.1 4.6.2 4.6.3 4.6.4 4.7.0 4.7.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.1 4.8.2 4.8.3 4.8.4 4.8.5 4.8.6 4.8.7 4.8.8 4.9.0 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 4.9.6 4.9.7 4.9.8 4.9.9 5.0.0 5.0.1 5.1.0 5.1.1 5.1.2 5.2.0 5.3.0 5.3.1 5.3.2 5.3.3
woocommerce-square / includes / Framework / Lifecycle.php
woocommerce-square / includes / Framework Last commit date
Addresses 3 years ago Api 3 years ago Compatibility 3 years ago PaymentGateway 3 years ago Utilities 3 years ago Admin_Message_Handler.php 3 years ago Admin_Notice_Handler.php 3 years ago Lifecycle.php 3 years ago Plugin.php 3 years ago Plugin_Compatibility.php 3 years ago Plugin_Dependencies.php 3 years ago Square_Helper.php 4 years ago
Lifecycle.php
572 lines
1 <?php
2 /**
3 * WooCommerce Plugin Framework
4 *
5 * This source file is subject to the GNU General Public License v3.0
6 * that is bundled with this package in the file license.txt.
7 * It is also available through the world-wide-web at this URL:
8 * http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0 or later
9 * If you did not receive a copy of the license and are unable to
10 * obtain it through the world-wide-web, please send an email
11 * to license@skyverge.com so we can send you a copy immediately.
12 *
13 * @since 3.0.0
14 * @author WooCommerce / SkyVerge
15 * @copyright Copyright (c) 2021-2022, WooCommerce.
16 * @copyright Copyright (c) 2013-2019, SkyVerge, Inc.
17 * @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0 or later
18 *
19 * Modified by WooCommerce on 15 December 2021.
20 */
21
22 namespace WooCommerce\Square\Framework;
23
24 use WooCommerce;
25
26 defined( 'ABSPATH' ) or exit;
27
28 /**
29 * Plugin lifecycle handler.
30 *
31 * Registers and displays milestone notice prompts and eventually the plugin
32 * install, upgrade, activation, and deactivation routines.
33 *
34 * @since 3.0.0
35 */
36 class Lifecycle {
37
38
39 /** @var array the version numbers that have an upgrade routine */
40 protected $upgrade_versions = array();
41
42 /** @var string minimum milestone version */
43 private $milestone_version;
44
45 /** @var Plugin plugin instance */
46 private $plugin;
47
48
49 /**
50 * Constructs the class.
51 *
52 * @since 3.0.0
53 *
54 * @param Plugin $plugin plugin instance
55 */
56 public function __construct( WooCommerce\Square\Framework\Plugin $plugin ) {
57
58 $this->plugin = $plugin;
59
60 $this->add_hooks();
61 }
62
63
64 /**
65 * Adds the action & filter hooks.
66 *
67 * @since 3.0.0
68 */
69 protected function add_hooks() {
70
71 // handle activation
72 add_action( 'admin_init', array( $this, 'handle_activation' ) );
73
74 // handle deactivation
75 add_action( 'deactivate_' . $this->get_plugin()->get_plugin_file(), array( $this, 'handle_deactivation' ) );
76
77 if ( is_admin() && ! wp_doing_ajax() ) {
78
79 // initialize the plugin lifecycle
80 add_action( 'wp_loaded', array( $this, 'init' ) );
81
82 // add the admin notices
83 add_action( 'init', array( $this, 'add_admin_notices' ) );
84 }
85
86 // catch any milestones triggered by action
87 add_action( 'wc_square_milestone_reached', array( $this, 'trigger_milestone' ), 10, 3 );
88 }
89
90
91 /**
92 * Initializes the plugin lifecycle.
93 *
94 * @since 3.0.0
95 */
96 public function init() {
97
98 // potentially handle a new activation
99 $this->handle_activation();
100
101 $installed_version = $this->get_installed_version();
102 $plugin_version = $this->get_plugin()->get_version();
103
104 // installed version lower than plugin version?
105 if ( version_compare( $installed_version, $plugin_version, '<' ) ) {
106
107 if ( ! $installed_version ) {
108
109 $this->install();
110
111 // store the upgrade event regardless if there was a routine for it
112 $this->store_event( 'install' );
113
114 /**
115 * Fires after the plugin has been installed.
116 *
117 * @since 3.0.0
118 */
119 do_action( 'wc_square_installed' );
120
121 } else {
122
123 $this->upgrade( $installed_version );
124
125 // store the upgrade event regardless if there was a routine for it
126 $this->add_upgrade_event( $installed_version );
127
128 // if the plugin never had any previous milestones, consider them all reached so their notices aren't displayed
129 if ( ! $this->get_milestone_version() ) {
130 $this->set_milestone_version( $plugin_version );
131 }
132
133 /**
134 * Fires after the plugin has been updated.
135 *
136 * @since 3.0.0
137 *
138 * @param string $installed_version previously installed version
139 */
140 do_action( 'wc_square_updated', $installed_version );
141 }
142
143 // new version number
144 $this->set_installed_version( $plugin_version );
145 }
146 }
147
148
149 /**
150 * Triggers plugin activation.
151 *
152 * We don't use register_activation_hook() as that can't be called inside
153 * the 'plugins_loaded' action. Instead, we rely on setting to track the
154 * plugin's activation status.
155 *
156 * @internal
157 *
158 * @link https://developer.wordpress.org/reference/functions/register_activation_hook/#comment-2100
159 *
160 * @since 3.0.0
161 */
162 public function handle_activation() {
163
164 if ( ! get_option( 'wc_square_is_active', false ) ) {
165
166 /**
167 * Fires when the plugin is activated.
168 *
169 * @since 3.0.0
170 */
171 do_action( 'wc_square_activated' );
172
173 update_option( 'wc_square_is_active', 'yes' );
174 }
175 }
176
177
178 /**
179 * Triggers plugin deactivation.
180 *
181 * @internal
182 *
183 * @since 3.0.0
184 */
185 public function handle_deactivation() {
186
187 /**
188 * Fires when the plugin is deactivated.
189 *
190 * @since 3.0.0
191 */
192 do_action( 'wc_square_deactivated' );
193
194 delete_option( 'wc_square_is_active' );
195 }
196
197 /**
198 * Helper method to install default settings for a plugin.
199 *
200 * @since 3.0.0
201 *
202 * @param array $settings settings in format required by WC_Admin_Settings
203 */
204 public function install_default_settings( array $settings ) {
205
206 foreach ( $settings as $setting ) {
207
208 if ( isset( $setting['id'], $setting['default'] ) ) {
209 update_option( $setting['id'], $setting['default'] );
210 }
211 }
212 }
213
214 /**
215 * Performs any upgrade tasks based on the provided installed version.
216 *
217 * @since 3.0.0
218 *
219 * @param string $installed_version installed version
220 */
221 protected function upgrade( $installed_version ) {
222
223 foreach ( $this->upgrade_versions as $upgrade_version ) {
224
225 $upgrade_method = 'upgrade_to_' . str_replace( array( '.', '-' ), '_', $upgrade_version );
226
227 if ( version_compare( $installed_version, $upgrade_version, '<' ) && is_callable( array( $this, $upgrade_method ) ) ) {
228
229 $this->get_plugin()->log( sprintf( "Starting upgrade to v%s", $upgrade_version ) );
230
231 $this->$upgrade_method( $installed_version );
232
233 $this->get_plugin()->log( sprintf( "Upgrade to v%s complete.", $upgrade_version ) );
234 }
235 }
236 }
237
238
239 /**
240 * Adds any lifecycle admin notices.
241 *
242 * @since 3.0.0
243 */
244 public function add_admin_notices() {
245
246 // display any milestone notices
247 foreach ( $this->get_milestone_messages() as $id => $message ) {
248
249 // bail if this notice was already dismissed
250 if ( ! $this->get_plugin()->get_admin_notice_handler()->should_display_notice( $id ) ) {
251 continue;
252 }
253
254 /**
255 * Filters a milestone notice message.
256 *
257 * @since 3.0.0
258 *
259 * @param string $message message text to be used for the milestone notice
260 * @param string $id milestone ID
261 */
262 $message = apply_filters( 'wc_square_milestone_message', $this->generate_milestone_notice_message( $message ), $id );
263
264 if ( $message ) {
265
266 $this->get_plugin()->get_admin_notice_handler()->add_admin_notice( $message, $id, array(
267 'always_show_on_settings' => false,
268 ) );
269
270 // only display one notice at a time
271 break;
272 }
273 }
274 }
275
276
277 /** Milestone Methods *****************************************************/
278
279
280 /**
281 * Triggers a milestone.
282 *
283 * This will only be triggered if the install's "milestone version" is lower
284 * than $since. Plugins can specify $since as the version at which a
285 * milestone's feature was added. This prevents existing installs from
286 * triggering notices for milestones that have long passed, like a payment
287 * gateway's first successful payment. Omitting $since will assume the
288 * milestone has always existed and should only trigger for fresh installs.
289 *
290 * @since 3.0.0
291 *
292 * @param string $id milestone ID
293 * @param string $message message to display to the user
294 * @param string $since the version since this milestone has existed in the plugin
295 * @return bool
296 */
297 public function trigger_milestone( $id, $message, $since = '1.0.0' ) {
298
299 // if the plugin was had milestones before this milestone was added, don't trigger it
300 if ( version_compare( $this->get_milestone_version(), $since, '>' ) ) {
301 return false;
302 }
303
304 return $this->register_milestone_message( $id, $message );
305 }
306
307
308 /**
309 * Generates a milestone notice message.
310 *
311 * @since 3.0.0
312 *
313 * @param string $custom_message custom text that notes what milestone was completed.
314 * @return string
315 */
316 protected function generate_milestone_notice_message( $custom_message ) {
317
318 $message = '';
319
320 if ( $this->get_plugin()->get_reviews_url() ) {
321
322 // to be prepended at random to each milestone notice
323 $exclamations = array(
324 __( 'Awesome', 'woocommerce-square' ),
325 __( 'Fantastic', 'woocommerce-square' ),
326 __( 'Cowabunga', 'woocommerce-square' ),
327 __( 'Congratulations', 'woocommerce-square' ),
328 __( 'Hot dog', 'woocommerce-square' ),
329 );
330
331 $message = $exclamations[ array_rand( $exclamations ) ] . ', ' . esc_html( $custom_message ) . ' ';
332
333 $message .= sprintf(
334 /* translators: Placeholders: %1$s - plugin name, %2$s - <a> tag, %3$s - </a> tag, %4$s - <a> tag, %5$s - </a> tag */
335 __( 'Are you having a great experience with %1$s so far? Please consider %2$sleaving a review%3$s! If things aren\'t going quite as expected, we\'re happy to help -- please %4$sreach out to our support team%5$s.', 'woocommerce-square' ),
336 '<strong>' . esc_html( $this->get_plugin()->get_plugin_name() ) . '</strong>',
337 '<a href="' . esc_url( $this->get_plugin()->get_reviews_url() ) . '">', '</a>',
338 '<a href="' . esc_url( $this->get_plugin()->get_support_url() ) . '">', '</a>'
339 );
340 }
341
342 return $message;
343 }
344
345
346 /**
347 * Registers a milestone message to be displayed in the admin.
348 *
349 * @since 3.0.0
350 * @see Lifecycle::generate_milestone_notice_message()
351 *
352 * @param string $id milestone ID
353 * @param string $message message to display to the user
354 * @return bool whether the message was successfully registered
355 */
356 public function register_milestone_message( $id, $message ) {
357
358 $milestone_messages = $this->get_milestone_messages();
359 $dismissed_notices = array_keys( $this->get_plugin()->get_admin_notice_handler()->get_dismissed_notices() );
360
361 // get the total number of dismissed milestone messages
362 $dismissed_milestone_messages = array_intersect( array_keys( $milestone_messages ), $dismissed_notices );
363
364 // if the user has dismissed more than three milestone messages already, don't add any more
365 if ( count( $dismissed_milestone_messages ) > 3 ) {
366 return false;
367 }
368
369 $milestone_messages[ $id ] = $message;
370
371 return update_option( 'wc_square_milestone_messages', $milestone_messages );
372 }
373
374
375 /** Event history methods *****************************************************************************************/
376
377
378 /**
379 * Adds an upgrade lifecycle event.
380 *
381 * @since 3.0.0
382 *
383 * @param string $from_version version upgrading from
384 * @param array $data extra data to add
385 * @return false|int
386 */
387 public function add_upgrade_event( $from_version, array $data = array() ) {
388
389 $data = array_merge( array(
390 'from_version' => $from_version,
391 ), $data );
392
393 return $this->store_event( 'upgrade', $data );
394 }
395
396 /**
397 * Stores a lifecycle event.
398 *
399 * This can be used to log installs, upgrades, etc...
400 *
401 * Uses a direct database query to avoid cache issues.
402 *
403 * @since 3.0.0
404 *
405 * @param string $name lifecycle event name
406 * @param array $data any extra data to store
407 * @return false|int
408 */
409 public function store_event( $name, array $data = array() ) {
410 global $wpdb;
411
412 $history = $this->get_event_history();
413
414 $event = array(
415 'name' => wc_clean( $name ),
416 'time' => (int) current_time( 'timestamp' ),
417 'version' => wc_clean( $this->get_plugin()->get_version() ),
418 );
419
420 if ( ! empty( $data ) ) {
421 $event['data'] = wc_clean( $data );
422 }
423
424 array_unshift( $history, $event );
425
426 // limit to the last 30 events
427 $history = array_slice( $history, 0, 29 );
428
429 return $wpdb->replace(
430 $wpdb->options,
431 array(
432 'option_name' => $this->get_event_history_option_name(),
433 'option_value' => wp_json_encode( $history ),
434 'autoload' => 'no',
435 ),
436 array(
437 '%s',
438 '%s',
439 )
440 );
441 }
442
443
444 /**
445 * Gets the lifecycle event history.
446 *
447 * The last 30 events are stored, with the latest first.
448 *
449 * @since 3.0.0
450 *
451 * @return array
452 */
453 public function get_event_history() {
454 global $wpdb;
455
456 $history = array();
457
458 $results = $wpdb->get_var( $wpdb->prepare( "
459 SELECT option_value
460 FROM {$wpdb->options}
461 WHERE option_name = %s
462 ", $this->get_event_history_option_name() ) );
463
464 if ( $results ) {
465 $history = json_decode( $results, true );
466 }
467
468 return is_array( $history ) ? $history : array();
469 }
470
471
472 /**
473 * Gets the event history option name.
474 *
475 * @since 3.0.0
476 *
477 * @return string
478 */
479 protected function get_event_history_option_name() {
480
481 return 'wc_square_lifecycle_events';
482 }
483
484
485 /** Utility Methods *******************************************************/
486
487
488 /**
489 * Gets the registered milestone messages.
490 *
491 * @since 3.0.0
492 *
493 * @return array
494 */
495 protected function get_milestone_messages() {
496
497 return get_option( 'wc_square_milestone_messages', array() );
498 }
499
500
501 /**
502 * Sets the milestone version.
503 *
504 * @since 3.0.0
505 *
506 * @param string $version plugin version
507 * @return bool
508 */
509 public function set_milestone_version( $version ) {
510
511 $this->milestone_version = $version;
512
513 return update_option( 'wc_square_milestone_version', $version );
514 }
515
516
517 /**
518 * Gets the milestone version.
519 *
520 * @since 3.0.0
521 *
522 * @return string
523 */
524 public function get_milestone_version() {
525
526 if ( ! $this->milestone_version ) {
527 $this->milestone_version = get_option( 'wc_square_milestone_version', '' );
528 }
529
530 return $this->milestone_version;
531 }
532
533
534 /**
535 * Gets the currently installed plugin version.
536 *
537 * @since 3.0.0
538 *
539 * @return string
540 */
541 protected function get_installed_version() {
542
543 return get_option( $this->get_plugin()->get_plugin_version_name() );
544 }
545
546
547 /**
548 * Sets the installed plugin version.
549 *
550 * @since 3.0.0
551 *
552 * @param string $version version to set
553 */
554 protected function set_installed_version( $version ) {
555
556 update_option( $this->get_plugin()->get_plugin_version_name(), $version );
557 }
558
559
560 /**
561 * Gets the plugin instance.
562 *
563 * @since 3.0.0
564 *
565 * @return Plugin
566 */
567 protected function get_plugin() {
568
569 return $this->plugin;
570 }
571 }
572