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