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 +164 -50 10.10.2 → 11.9 View file →
@@ -1,4 +1,4 @@
1 1 <?php
2 2 /**
3 3 * @version 1.0
4 4 * @package Booking Calendar
@@ -58,8 +58,9 @@
58 58 add_filter( 'plugin_action_links', array( $this, 'plugin_links' ), 10, 2 );
59 59 // Warning message in plugin info.
60 60 add_filter( 'plugin_row_meta', array( $this, 'plugin_row_meta' ), 10, 4 );
61 61
62 + // TODO: 2025-06-06 - required to be commented, if we use the Pro version as separate plugin.
62 63 $this->check_if_need_to_update(); // Check upgrade, if was no activation process
63 64 }
64 65
65 66
@@ -105,9 +106,9 @@
105 106 $is_delete_if_deactive = get_bk_option( $this->init_option['option-is_delete_if_deactive'] ); // check
106 107
107 108 if ($is_delete_if_deactive == 'On') { ?>
108 109 <div class="plugin-update-tr">
109 - <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
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
110 111 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
111 112 echo $this->init_option['message-delete_data']; ?></div>
112 113 </div>
113 114 <?php
@@ -112,8 +113,16 @@
112 113 </div>
113 114 <?php
114 115 }
115 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 +
116 125 /*
117 126 [$plugin_meta] => Array
118 127 (
119 128 [0] => Version 2.8.35
@@ -153,9 +162,10 @@
153 162
154 163 $this_plugin = plugin_basename( WPBC_FILE );
155 164
156 165 if ( $file == $this_plugin ) {
157 -
166 +
167 +
158 168 array_unshift( $links, $this->init_option['link_settings'] );
159 169
160 170 //array_unshift( $links, $this->init_option['link_whats_new'] );
161 171 array_unshift( $links, $this->init_option['link_faq'] );
@@ -160,19 +170,26 @@
160 170 //array_unshift( $links, $this->init_option['link_whats_new'] );
161 171 array_unshift( $links, $this->init_option['link_faq'] );
162 172
163 173
164 - $links = array_merge( $links, array(
165 - '<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="'
166 - . esc_url( wpbc_get_settings_url() . '&wpbc_setup_wizard=reset&_wpnonce=' . wp_create_nonce( 'wpbc_settings_url_nonce' ) )
167 - //. esc_url( admin_url( add_query_arg( array( 'page' => 'wpbc-about' ), 'index.php' ) ) )
168 - . '">' . esc_attr__( 'Start Setup Wizard', 'booking' ) . '</a>'
169 - )
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 + )
170 180 );
171 181
172 182
173 183 if ( ! class_exists( 'wpdev_bk_personal' ) ) {
174 - 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 + }
175 192 } else {
176 193 if ( ! class_exists( 'wpdev_bk_multiuser' ) ) {
177 194 array_unshift( $links, $this->init_option['link_upgrade'] );
178 195 }
@@ -210,67 +227,163 @@
210 227
211 228 } else {
212 229
213 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.
214 - $is_make_activation = $this->is_update_from_lower_to_high_version();
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();
215 233
216 234 }
217 235
218 - // Add hook for initial activation.
219 - if ( $is_make_activation ) {
220 - add_action( 'plugins_loaded', array( $this, 'wpbc_activate_initial' ), 1030 );
221 - }
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 + }
222 240 }
223 241 }
224 242
225 243
226 244 /**
227 - * Upgrade during bulk upgrade of plugins
228 - *
229 - * @param type $return_val
230 - * @param type $hook_extra
231 - *
232 - * @return type
233 - */
234 - public function wpbc_install_in_bulk_upgrade( $return_val, $hook_extra ) {
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 ) {
235 258
236 259 if ( is_wp_error( $return_val ) ) {
237 260 return $return_val;
238 261 }
239 262
240 - if ( isset( $hook_extra ) ) {
241 - if ( isset( $hook_extra['plugin'] ) ) {
242 - $file_name = basename( WPBC_FILE );
243 - $pos = strpos( $hook_extra['plugin'], trim( $file_name ) );
244 - if ( false !== $pos ) {
245 - $this->wpbc_activate();
246 - }
247 - }
248 - }
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 + }
249 273
250 274 return $return_val;
251 275 }
252 276
253 277
254 - /**
255 - * User clicked on "Activate" link at Plugins Menu.
256 - *
257 - * @return type
258 - */
259 - public function wpbc_activate_initial() {
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 + }
260 385
261 - // Activate the plugin.
262 - $this->wpbc_activate();
263 -
264 - // Bail if this demo or activating from network, or bulk.
265 - if ( is_network_admin() || isset( $_GET['activate-multi'] ) || wpbc_is_this_demo() ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.NonceVerification.Missing
266 - return;
267 - }
268 -
269 - // Add the transient to redirect - Showing Welcome screen.
270 - set_transient( $this->init_option['transient-wpbc_activation_redirect'], true, 30 );
271 - }
272 -
273 386 // -----------------------------------------------------------------------------------------------------------------
274 387
275 388 /**
276 389 * Run Activate
@@ -293,8 +406,9 @@
293 406 /**
294 407 * Run Deactivate
295 408 */
296 409 public function wpbc_deactivate() {
410 + wpbc_set_plugin_deactivation_state( true );
297 411
298 412 WPBC_Action_Scheduler_Compatibility::raise_memory_limit();
299 413 WPBC_Action_Scheduler_Compatibility::raise_time_limit( 300 );
300 414
@@ -309,5 +423,5 @@
309 423 delete_bk_option( $this->init_option['option-activation_process'] );
310 424 }
311 425 }
312 426
313 -}
427 +}