PluginProbe
Booking Calendar / 11.9
Booking Calendar v11.9
11.9 11.8.4 11.8.3 11.8.2 11.8.1 11.8 11.7 11.6.1 11.6 11.5 11.4.3 11.4.2 11.4.1 11.4 11.3 11.2.1 11.2 11.1 11.0 10.15.7 10.15.6 10.1.3 10.10 10.10.1 10.10.2 All 205 releases
← All changes | core/any/activation.php +278 -145 10.1.3 → 11.9 View file →
@@ -1,4 +1,4 @@
1 1 <?php
2 2 /**
3 3 * @version 1.0
4 4 * @package Booking Calendar
@@ -17,43 +17,53 @@
17 17 /**
18 18 * Activation | Deactivation Class
19 19 */
20 20 abstract class WPBC_Install {
21 -
22 - private $init_option;
23 -
24 - function __construct() {
25 -
26 - $default_init_option_names = array(
27 - 'option-version_num' => 'booking_version_num'
28 - , 'option-is_delete_if_deactive' => 'booking_is_delete_if_deactive'
29 - , 'option-activation_process' => 'booking_activation_process'
30 - , 'transient-wpbc_activation_redirect' => '_booking_activation_redirect'
31 - , 'message-delete_data' => '<strong>Warning!</strong> ' . 'All plugin data will be deleted when plugin had deactivated.' . '<br />'
32 - . sprintf( 'If you want to save your plugin data, please uncheck the %s"Delete plugin data"%s at the', '<strong>', '</strong>')
33 - , 'link_settings' => '<a href="">Settings</a>'
34 - , 'link_whats_new' => '<a href="">Whats New</a>'
35 - );
36 -
37 - $init_option = $this->get_init_option_names();
38 -
39 - $this->init_option = wp_parse_args( $init_option, $default_init_option_names );
40 21
41 -
42 - register_activation_hook( WPBC_FILE, array( $this, 'wpbc_activate_initial' ) ); // WordPress > Plugins > "Activate" link.
43 -
44 - register_deactivation_hook( WPBC_FILE, array( $this, 'wpbc_deactivate' ) ); // WordPress > Plugins > "Deactivate" link.
45 -
46 - add_filter('upgrader_post_install', array( $this, 'wpbc_install_in_bulk_upgrade' ), 10, 2 ); // Upgrade during bulk upgrade of plugins
47 -
48 - // Settings link at the plugin page
49 - add_filter('plugin_action_links', array( $this, 'plugin_links'), 10, 2 );
50 - // Warning message in plugin info
51 - add_filter('plugin_row_meta', array( $this, 'plugin_row_meta'), 10, 4 );
52 -
53 - $this->check_if_need_to_update(); // Check upgrade, if was no activation process
54 - }
22 + /**
23 + * Init option
24 + *
25 + * @var array
26 + */
27 + private $init_option;
55 28
29 + /**
30 + * Constructor
31 + */
32 + public function __construct() {
33 +
34 + $default_init_option_names = array(
35 + 'option-version_num' => 'booking_version_num',
36 + 'option-is_delete_if_deactive' => 'booking_is_delete_if_deactive',
37 + 'option-activation_process' => 'booking_activation_process',
38 + 'transient-wpbc_activation_redirect' => '_booking_activation_redirect',
39 + 'message-delete_data' => '<strong>Warning!</strong> All plugin data will be deleted when plugin had deactivated.<br />' . sprintf( 'If you want to save your plugin data, please uncheck the %s"Delete plugin data"%s at the', '<strong>', '</strong>' ),
40 + 'link_settings' => '<a href="">Settings</a>',
41 + 'link_whats_new' => '<a href="">Whats New</a>',
42 + );
43 +
44 + $init_option = $this->get_init_option_names();
45 +
46 + $this->init_option = wp_parse_args( $init_option, $default_init_option_names );
47 +
48 + // WordPress > Plugins > "Activate" link.
49 + register_activation_hook( WPBC_FILE, array( $this, 'wpbc_activate_initial' ) );
50 +
51 + // WordPress > Plugins > "Deactivate" link.
52 + register_deactivation_hook( WPBC_FILE, array( $this, 'wpbc_deactivate' ) );
53 +
54 + // Upgrade during bulk upgrade of plugins.
55 + add_filter( 'upgrader_post_install', array( $this, 'wpbc_install_in_bulk_upgrade' ), 10, 2 );
56 +
57 + // Settings link at the plugin page.
58 + add_filter( 'plugin_action_links', array( $this, 'plugin_links' ), 10, 2 );
59 + // Warning message in plugin info.
60 + add_filter( 'plugin_row_meta', array( $this, 'plugin_row_meta' ), 10, 4 );
61 +
62 + // TODO: 2025-06-06 - required to be commented, if we use the Pro version as separate plugin.
63 + $this->check_if_need_to_update(); // Check upgrade, if was no activation process
64 + }
65 +
56 66
57 67 /**
58 68 * Must be overloaded in child CLASS
59 69 *
@@ -82,11 +92,9 @@
82 92 */
83 93 abstract function is_update_from_lower_to_high_version();
84 94
85 95
86 - ////////////////////////////////////////////////////////////////////////////
87 -
88 -
96 + // -----------------------------------------------------------------------------------------------------------------
89 97 // <editor-fold defaultstate="collapsed" desc=" Update info of plugin at the plugins section ">
90 98
91 99 /** Update info of plugin at the plugins section */
92 100 function plugin_row_meta( $plugin_meta, $plugin_file, $plugin_data, $context ) {
@@ -98,14 +106,23 @@
98 106 $is_delete_if_deactive = get_bk_option( $this->init_option['option-is_delete_if_deactive'] ); // check
99 107
100 108 if ($is_delete_if_deactive == 'On') { ?>
101 109 <div class="plugin-update-tr">
102 - <div class="update-message notice inline notice-warning notice-altNO" style="font-size: 1em;line-height: 2em;margin:0 5px 10px;border-left: 3px solid #dd7000;"><?php
103 - echo $this->init_option['message-delete_data']; ?></div>
104 - </div>
110 + <div class="update-message notice inline notice-error" style="line-height: 2.2em;border-left: 3px solid #cc1818;margin-left: 0;color: #cc1818;background: #fff6f4;"><?php
111 + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
112 + echo $this->init_option['message-delete_data']; ?></div>
113 + </div>
105 114 <?php
106 115 }
107 116
117 + $version = wpbc_get_plugin_version_title();
118 +
119 + if ( 'Free' !== $version ) {
120 + $plugin_meta[0] .= ' | ' . __( 'Version type', 'booking' ) . ': <strong>Free + ' . ucfirst( $version ) . '</strong>';
121 + } else {
122 + $plugin_meta[0] .= ' | ' . __( 'Version type', 'booking' ) . ': <strong>' . ucfirst( $version ) . '</strong>';
123 + }
124 +
108 125 /*
109 126 [$plugin_meta] => Array
110 127 (
111 128 [0] => Version 2.8.35
@@ -145,15 +162,34 @@
145 162
146 163 $this_plugin = plugin_basename( WPBC_FILE );
147 164
148 165 if ( $file == $this_plugin ) {
149 -
166 +
167 +
150 168 array_unshift( $links, $this->init_option['link_settings'] );
151 169
152 170 //array_unshift( $links, $this->init_option['link_whats_new'] );
153 171 array_unshift( $links, $this->init_option['link_faq'] );
172 +
173 +
174 + $links = array_merge( $links, array(
175 + '<a class="wpbc_plugins_links__start_tour" title="' . esc_attr( sprintf( __('We\'ll guide you through the steps to set up WP Booking Calendar on your site.','booking'), '<strong>WP Booking Calendar</strong>' ) ) . '" href="'
176 + . esc_url( wpbc_get_setup_wizard_page_url() )
177 + //. esc_url( admin_url( add_query_arg( array( 'page' => 'wpbc-about' ), 'index.php' ) ) )
178 + . '">' . esc_attr__( 'Start Setup Wizard', 'booking' ) . '</a>'
179 + )
180 + );
181 +
182 +
154 183 if ( ! class_exists( 'wpdev_bk_personal' ) ) {
155 - array_unshift( $links, $this->init_option['link_up'] );
184 + if ( wpbc_is_updated_paid_to_free() ) {
185 + array_unshift(
186 + $links,
187 + '<a style="font-weight:600;" class="wpbc_plugins_links__start_tour" title="' . esc_attr( __( 'Request Update', 'booking' ) ) . '" href="' . esc_url( 'https://wpbookingcalendar.com/request-update/' ) . '">' . esc_attr__( 'Request Pro Version', 'booking' ) . '</a>'
188 + );
189 + } else {
190 + array_unshift( $links, $this->init_option['link_up'] );
191 + }
156 192 } else {
157 193 if ( ! class_exists( 'wpdev_bk_multiuser' ) ) {
158 194 array_unshift( $links, $this->init_option['link_upgrade'] );
159 195 }
@@ -163,132 +199,229 @@
163 199 return $links;
164 200 }
165 201
166 202 // </editor-fold>
167 -
168 -
169 - ////////////////////////////////////////////////////////////////////////////
170 -
171 -
172 - // Check about ability to upgrade, if was no activation process
173 - private function check_if_need_to_update() {
174 -
175 - if( is_admin() ) {
176 203
177 - $wpbc_version_num = get_option( $this->init_option['option-version_num'] );
178 204
179 - if ($wpbc_version_num === false )
180 - $wpbc_version_num = '0';
205 + // -----------------------------------------------------------------------------------------------------------------
181 206
182 - $is_make_activation = false;
183 -
184 - if ( version_compare( WP_BK_VERSION_NUM, $wpbc_version_num) > 0 ) {
207 + /**
208 + * Check about ability to upgrade, if was no activation process
209 + *
210 + * @return void
211 + */
212 + private function check_if_need_to_update() {
185 213
186 - $is_make_activation = true;
214 + if ( is_admin() ) {
187 215
188 - } else {
189 -
190 - // Check if we was update from free to paid or from lower to higher versions,
191 - // and do not make normal activation. In this case we need to make update.
192 - $is_make_activation = $this->is_update_from_lower_to_high_version();
193 -
194 - }
195 -
196 - // Add hook for initial activation.
197 - if ( $is_make_activation ) {
198 - add_action( 'plugins_loaded', array( $this, 'wpbc_activate_initial' ) , 1030 );
199 - }
200 - }
201 - }
202 -
203 -
204 - /**
205 - * Upgrade during bulk upgrade of plugins
206 - *
207 - * @param type $return
208 - * @param type $hook_extra
209 - * @return type
210 - */
211 - public function wpbc_install_in_bulk_upgrade( $return, $hook_extra ){
216 + $wpbc_version_num = get_option( $this->init_option['option-version_num'] );
212 217
213 - if ( is_wp_error( $return ) )
214 - return $return;
218 + if ( false === $wpbc_version_num ) {
219 + $wpbc_version_num = '0';
220 + }
215 221
216 - if ( isset( $hook_extra ) )
217 - if ( isset( $hook_extra['plugin'] ) ) {
218 - $file_name = basename( WPBC_FILE );
219 - $pos = strpos( $hook_extra['plugin'], trim( $file_name ) );
220 - if ( $pos !== false ) {
221 - $this->wpbc_activate();
222 - }
223 - }
224 - return $return;
225 - }
222 + $is_make_activation = false;
226 223
227 -
228 - /**
229 - * User clicked on "Activate" link at Plugins Menu.
230 - *
231 - * @return type
232 - */
233 - public function wpbc_activate_initial(){
224 + if ( version_compare( WP_BK_VERSION_NUM, $wpbc_version_num ) > 0 ) {
234 225
235 - // Activate the plugin
236 - $this->wpbc_activate();
226 + $is_make_activation = true;
237 227
238 - // Bail if this demo or activating from network, or bulk
239 - if ( is_network_admin() || isset( $_GET['activate-multi'] ) || wpbc_is_this_demo() )
240 - return;
228 + } else {
241 229
242 - // Add the transient to redirect - Showing Welcome screen
243 - set_transient( $this->init_option['transient-wpbc_activation_redirect'], true, 30 );
244 - }
230 + // Check if we was update from free to paid or from lower to higher versions, and do not make normal activation. In this case we need to make update.
231 + // TODO: 2025-11-23 - Commented, if we use the Pro version as separate plugin.
232 + // $is_make_activation = $this->is_update_from_lower_to_high_version();
245 233
246 -
247 - ////////////////////////////////////////////////////////////////////////////
248 -
249 -
250 - /** Run Activate */
251 - public function wpbc_activate() {
234 + }
252 235
253 - //FixIn: 8.4.7.24
254 - if ( function_exists( 'set_time_limit' ) ) {
255 - set_time_limit( 900 );
256 - }
257 -
258 - ini_set('memory_limit','256M'); //FixIn:6.1.1.15
259 - ini_set('max_execution_time', 300); //FixIn: 7.0.1.57
260 -
261 - update_bk_option( $this->init_option['option-activation_process'], 'On' );
236 + // Run the installed version's activation on the next request after files change.
237 + if ( $is_make_activation ) {
238 + add_action( 'init', array( $this, 'wpbc_activate_detected_update' ), 1030 );
239 + }
240 + }
241 + }
262 242
263 - make_bk_action( 'wpbc_activation' ); // S T A R T
264 243
265 - update_bk_option( $this->init_option['option-version_num'], WP_BK_VERSION_NUM );
244 + /**
245 + * Run activation work after WordPress successfully replaces this plugin.
246 + *
247 + * WordPress continues running the previously loaded PHP code during the
248 + * updater request. The completed-update context bridges that request to the
249 + * newly installed code so the next request can distinguish an interactive
250 + * Plugins-screen update from a non-interactive updater.
251 + *
252 + * @param bool|WP_Error $return_val Installation result.
253 + * @param array $hook_extra WordPress upgrader context.
254 + *
255 + * @return bool|WP_Error Unchanged installation result.
256 + */
257 + public function wpbc_install_in_bulk_upgrade( $return_val, $hook_extra ) {
266 258
267 - update_bk_option( $this->init_option['option-activation_process'], 'Off');
268 - }
259 + if ( is_wp_error( $return_val ) ) {
260 + return $return_val;
261 + }
269 262
263 + $updated_plugin = isset( $hook_extra['plugin'] ) && is_scalar( $hook_extra['plugin'] )
264 + ? plugin_basename( sanitize_text_field( (string) $hook_extra['plugin'] ) )
265 + : '';
266 + if ( plugin_basename( WPBC_FILE ) === $updated_plugin ) {
267 + $this->wpbc_activate();
268 +
269 + if ( class_exists( 'WPBC_Setup_Wizard_First_Install_State' ) ) {
270 + WPBC_Setup_Wizard_First_Install_State::record_completed_plugin_update( WPBC_FILE, WP_BK_VERSION_NUM );
271 + }
272 + }
270 273
271 - /** Run Deactivate */
272 - public function wpbc_deactivate() {
274 + return $return_val;
275 + }
273 276
274 - //FixIn: 8.4.7.24
275 - if ( function_exists( 'set_time_limit' ) ) {
276 - set_time_limit( 900 );
277 - }
278 277
279 - ini_set('memory_limit','256M'); //FixIn:6.1.1.15
280 - ini_set('max_execution_time', 300); //FixIn: 7.0.1.57
278 + /**
279 + * User clicked on "Activate" link at Plugins Menu.
280 + *
281 + * Genuine-install state is captured before activation creates canonical
282 + * tables and options. A dedicated versioned intent lets the following request
283 + * distinguish first-install onboarding from update/reactivation What's New,
284 + * while the released boolean redirect transient remains backward compatible.
285 + *
286 + * @return void
287 + */
288 + public function wpbc_activate_initial() {
289 + $is_initial_install = function_exists( 'wpbc_is_plugin_initial_install' )
290 + ? wpbc_is_plugin_initial_install()
291 + : false;
292 +
293 + // Activate the plugin.
294 + $this->wpbc_activate();
295 +
296 + $this->wpbc_schedule_activation_redirect( $is_initial_install, 'activation' );
297 + }
298 +
299 + /**
300 + * Run activation after the installed plugin version changes.
301 + *
302 + * A matching updater handoff suppresses navigation for automatic and other
303 + * non-interactive updates, while an interactive update opens What's New. When
304 + * no handoff exists, the files were replaced outside the standard upgrader
305 + * and retain the released one-time What's New behavior.
306 + *
307 + * @return void
308 + */
309 + public function wpbc_activate_detected_update() {
310 + $update_context = class_exists( 'WPBC_Setup_Wizard_First_Install_State' )
311 + ? WPBC_Setup_Wizard_First_Install_State::get_plugin_update_context( WPBC_FILE, WP_BK_VERSION_NUM )
312 + : false;
313 +
314 + $this->wpbc_activate();
315 +
316 + if ( class_exists( 'WPBC_Setup_Wizard_First_Install_State' ) ) {
317 + WPBC_Setup_Wizard_First_Install_State::clear_plugin_update_context( WPBC_FILE );
318 + }
319 +
320 + if (
321 + is_array( $update_context )
322 + && WPBC_Setup_Wizard_First_Install_State::UPDATE_SOURCE_SUPPRESSED === $update_context['source']
323 + ) {
324 + return;
325 + }
326 +
327 + $is_manual_update = is_array( $update_context )
328 + && WPBC_Setup_Wizard_First_Install_State::UPDATE_SOURCE_MANUAL === $update_context['source'];
329 + $redirect_user_id = $is_manual_update && isset( $update_context['user_id'] ) ? absint( $update_context['user_id'] ) : null;
330 +
331 + $this->wpbc_schedule_activation_redirect(
332 + false,
333 + $is_manual_update ? 'manual_update' : 'detected_file_update',
334 + $redirect_user_id,
335 + $is_manual_update ? WPBC_Setup_Wizard_First_Install_State::MANUAL_UPDATE_INTENT_TTL : 30,
336 + ! $is_manual_update
337 + );
338 + }
339 +
340 + /**
341 + * Schedule one allowed post-activation navigation intent.
342 + *
343 + * @param bool $is_initial_install Whether activation began from an empty installation.
344 + * @param string $source Activation or update source identifier.
345 + * @param int|null $user_id User who should receive the redirect, or null for the current user.
346 + * @param int $intent_ttl Structured redirect lifetime in seconds.
347 + * @param bool $write_legacy Whether to retain the released boolean redirect for older consumers.
348 + *
349 + * @return void
350 + */
351 + private function wpbc_schedule_activation_redirect( $is_initial_install, $source, $user_id = null, $intent_ttl = 30, $write_legacy = true ) {
352 + $is_restricted = class_exists( 'WPBC_Setup_Wizard_First_Install_State' )
353 + ? WPBC_Setup_Wizard_First_Install_State::is_automatic_onboarding_restricted()
354 + : (
355 + is_network_admin()
356 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only activation context detection.
357 + || isset( $_GET['activate-multi'] )
358 + || wpbc_is_this_demo()
359 + || ( defined( 'WPBC_IS_PLAYGROUND' ) && true === WPBC_IS_PLAYGROUND )
360 + || defined( 'IFRAME_REQUEST' )
361 + );
362 + if ( $is_restricted ) {
363 + return;
364 + }
365 +
366 + if ( class_exists( 'WPBC_Setup_Wizard_First_Install_State' ) ) {
367 + $redirect_intent = WPBC_Setup_Wizard_First_Install_State::create_activation_redirect_intent(
368 + $is_initial_install,
369 + WP_BK_VERSION_NUM,
370 + $source,
371 + $user_id
372 + );
373 + set_transient(
374 + WPBC_Setup_Wizard_First_Install_State::ACTIVATION_INTENT_TRANSIENT,
375 + $redirect_intent,
376 + absint( $intent_ttl )
377 + );
378 + }
379 +
380 + if ( $write_legacy ) {
381 + // Keep the released boolean payload for older paid editions and Welcome consumers.
382 + set_transient( $this->init_option['transient-wpbc_activation_redirect'], true, 30 );
383 + }
384 + }
281 385
282 - $is_delete_if_deactive = get_bk_option( $this->init_option['option-is_delete_if_deactive'] ); // check
386 + // -----------------------------------------------------------------------------------------------------------------
283 387
284 - if ( $is_delete_if_deactive == 'On' ) {
388 + /**
389 + * Run Activate
390 + */
391 + public function wpbc_activate() {
285 392
286 - make_bk_action( 'wpbc_deactivation' ); // F I N I S H
287 -
288 - delete_bk_option( $this->init_option['option-version_num'] );
289 -
290 - delete_bk_option( $this->init_option['option-activation_process'] );
291 - }
292 - }
393 + WPBC_Action_Scheduler_Compatibility::raise_memory_limit();
394 + WPBC_Action_Scheduler_Compatibility::raise_time_limit( 300 );
293 395
294 -}
396 + update_bk_option( $this->init_option['option-activation_process'], 'On' );
397 +
398 + make_bk_action( 'wpbc_activation' ); // S T A R T.
399 +
400 + update_bk_option( $this->init_option['option-version_num'], WP_BK_VERSION_NUM );
401 +
402 + update_bk_option( $this->init_option['option-activation_process'], 'Off' );
403 + }
404 +
405 +
406 + /**
407 + * Run Deactivate
408 + */
409 + public function wpbc_deactivate() {
410 + wpbc_set_plugin_deactivation_state( true );
411 +
412 + WPBC_Action_Scheduler_Compatibility::raise_memory_limit();
413 + WPBC_Action_Scheduler_Compatibility::raise_time_limit( 300 );
414 +
415 + $is_delete_if_deactive = get_bk_option( $this->init_option['option-is_delete_if_deactive'] ); // check.
416 +
417 + if ( 'On' === $is_delete_if_deactive ) {
418 +
419 + make_bk_action( 'wpbc_deactivation' ); // F I N I S H.
420 +
421 + delete_bk_option( $this->init_option['option-version_num'] );
422 +
423 + delete_bk_option( $this->init_option['option-activation_process'] );
424 + }
425 + }
426 +
427 +}