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 | includes/publish/wpbc-create-pages.php +996 -225 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
@@ -9,8 +9,9 @@
9 9 * @link https://wpbookingcalendar.com/
10 10 * @email [email protected]
11 11 *
12 12 * @modified 2023-05-10
13 + * @file ../includes/publish/wpbc-create-pages.php
13 14 */
14 15
15 16 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
16 17
@@ -25,12 +26,17 @@
25 26 )
26 27 *
27 28 * @return false|int - ID of the page.
28 29 */
29 -function wpbc_create_page( $page_params = array() ){ //FixIn: 9.6.2.10
30 +function wpbc_create_page( $page_params = array() ){ // FixIn: 9.6.2.10.
30 31
32 + /* Live demos must never create WordPress content through Booking Calendar. */
33 + if ( wpbc_is_booking_form_publishing_restricted() ) {
34 + return false;
35 + }
36 +
31 37 global $wp_rewrite;
32 - if ( is_null( $wp_rewrite ) ) { //FixIn: 9.7.1.1
38 + if ( is_null( $wp_rewrite ) ) { // FixIn: 9.7.1.1.
33 39 return false;
34 40 }
35 41
36 42 // Create post object
@@ -60,9 +66,9 @@
60 66
61 67 $my_post = wp_parse_args( $page_params, $defaults );
62 68
63 69
64 - $post_id = wp_insert_post( $my_post ); // Insert the post into the database
70 + $post_id = wp_insert_post( $my_post, true ); // Insert the post into the database
65 71
66 72 if ( ( ! is_wp_error( $post_id ) ) && ( ! empty( $post_id ) ) ) {
67 73
68 74 // Success
@@ -68,24 +74,219 @@
68 74 // Success
69 75
70 76 // $post = get_post( $post_id );
71 77 // $post_url = get_permalink( $post_id );
78 + wpbc_try_assign_full_width_template( $post_id,
79 + array(
80 + 'excluded_title_parts' => array( 'wide image' ),
81 + 'excluded_classic_template_files' => array( 'elementor_header_footer' ),
82 + 'force_elementor_default_template' => true,
83 + ) );
72 84
73 85 } else {
74 - if ( is_wp_error( $post_id ) ) {
75 - // Error // __( 'Sorry, the post could not be created.' )
86 + $post_id = false;
87 + }
88 +
89 + return $post_id;
90 +}
91 +
92 +
93 +/**
94 + * Check whether a template label looks like a usable "Full Width" template.
95 + *
96 + * Excludes labels that contain unwanted fragments such as "wide image".
97 + *
98 + * @param string $template_label Human-readable template label.
99 + * @param array $excluded_fragments Lowercase fragments to exclude.
100 + *
101 + * @return bool
102 + */
103 +function wpbc_is_full_width_template_candidate( $template_label, $excluded_fragments = array() ) {
104 +
105 + $template_label = strtolower( wp_strip_all_tags( (string) $template_label ) );
106 +
107 + if (
108 + ( false === strpos( $template_label, 'full' ) ) ||
109 + ( false === strpos( $template_label, 'width' ) )
110 + ) {
111 + return false;
112 + }
113 +
114 + foreach ( $excluded_fragments as $excluded_fragment ) {
115 + $excluded_fragment = strtolower( (string) $excluded_fragment );
116 +
117 + if ( '' === $excluded_fragment ) {
118 + continue;
76 119 }
77 - if ( ! $post_id ) {
78 - // Error // __( 'Sorry, the post could not be created.' )
120 +
121 + if ( false !== strpos( $template_label, $excluded_fragment ) ) {
122 + return false;
79 123 }
80 - $post_id = false;
81 124 }
82 125
83 - return $post_id;
126 + return true;
84 127 }
85 128
86 129
87 130 /**
131 + * Attempt to assign a "Full Width" template to a page.
132 + *
133 + * Supports both classic page templates and block theme templates.
134 + * Can skip specific templates, such as Elementor "Elementor Full Width"
135 + * or templates containing "Wide Image".
136 + *
137 + * @param int $post_id Page ID.
138 + * @param array $args Optional arguments:
139 + * - excluded_title_parts array Fragments excluded from template labels.
140 + * - excluded_classic_template_files array Classic template file names to skip.
141 + * - force_elementor_default_template bool Whether to force Elementor "Theme/Default".
142 + *
143 + * @return bool True if a template was assigned, or Elementor default was forced as fallback.
144 + */
145 +function wpbc_try_assign_full_width_template( $post_id, $args = array() ) {
146 +
147 + if ( empty( $post_id ) || is_wp_error( $post_id ) ) {
148 + return false;
149 + }
150 +
151 + $post = get_post( $post_id );
152 +
153 + if ( ( ! $post ) || ( 'page' !== $post->post_type ) ) {
154 + return false;
155 + }
156 +
157 + $defaults = array(
158 + 'excluded_title_parts' => array( 'wide image' ),
159 + 'excluded_classic_template_files' => array( 'elementor_header_footer' ),
160 + 'force_elementor_default_template' => false,
161 + );
162 +
163 + $args = wp_parse_args( $args, $defaults );
164 +
165 + $excluded_title_parts = array_map( 'strtolower', (array) $args['excluded_title_parts'] );
166 + $excluded_classic_template_files = array_map( 'strtolower', (array) $args['excluded_classic_template_files'] );
167 +
168 + $is_elementor_full_width_skipped = false;
169 +
170 + // -------------------------------------------------------------------------
171 + // Classic themes: scan page templates.
172 + // get_page_templates() returns template file names keyed by template header.
173 + // -------------------------------------------------------------------------
174 + if ( function_exists( 'get_page_templates' ) ) {
175 +
176 + $classic_templates = get_page_templates( $post, 'page' );
177 +
178 + foreach ( $classic_templates as $template_name => $template_file ) {
179 +
180 + if ( ! wpbc_is_full_width_template_candidate( $template_name, $excluded_title_parts ) ) {
181 + continue;
182 + }
183 +
184 + $template_file_lc = strtolower( (string) $template_file );
185 +
186 + if ( in_array( $template_file_lc, $excluded_classic_template_files, true ) ) {
187 +
188 + if ( 'elementor_header_footer' === $template_file_lc ) {
189 + $is_elementor_full_width_skipped = true;
190 + }
191 +
192 + continue;
193 + }
194 +
195 + update_post_meta( $post_id, '_wp_page_template', $template_file );
196 +
197 + return true;
198 + }
199 + }
200 +
201 + // -------------------------------------------------------------------------
202 + // Block themes: scan block templates for pages.
203 + // -------------------------------------------------------------------------
204 + if ( function_exists( 'wp_is_block_theme' ) && wp_is_block_theme() && function_exists( 'get_block_templates' ) ) {
205 +
206 + $theme_slug = get_stylesheet();
207 + $templates = get_block_templates(
208 + array(
209 + 'post_type' => 'page',
210 + ),
211 + 'wp_template'
212 + );
213 +
214 + foreach ( $templates as $template ) {
215 +
216 + if ( empty( $template->title ) || empty( $template->slug ) ) {
217 + continue;
218 + }
219 +
220 + if ( $theme_slug !== $template->theme ) {
221 + continue;
222 + }
223 +
224 + if ( ! wpbc_is_full_width_template_candidate( $template->title, $excluded_title_parts ) ) {
225 + continue;
226 + }
227 +
228 + wp_update_post(
229 + array(
230 + 'ID' => $post_id,
231 + 'page_template' => $template->slug,
232 + )
233 + );
234 +
235 + return true;
236 + }
237 + }
238 +
239 + /*
240 + * If the only match we found was Elementor Full Width, optionally force
241 + * Elementor's default page template instead.
242 + */
243 + if ( $args['force_elementor_default_template'] && $is_elementor_full_width_skipped ) {
244 + return wpbc_set_elementor_default_page_template( $post_id );
245 + }
246 +
247 + return false;
248 +}
249 +
250 +
251 +/**
252 + * Set Elementor page layout to its default "Theme" template.
253 + *
254 + * This should be treated as a fallback for Elementor-managed pages.
255 + *
256 + * @param int $post_id Page ID.
257 + *
258 + * @return bool
259 + */
260 +function wpbc_set_elementor_default_page_template( $post_id ) {
261 +
262 + if ( empty( $post_id ) || is_wp_error( $post_id ) ) {
263 + return false;
264 + }
265 +
266 + // Make sure WordPress itself does not have a forced classic template.
267 + delete_post_meta( $post_id, '_wp_page_template' );
268 +
269 + // If Elementor is not active, nothing else to do.
270 + if ( ( ! defined( 'ELEMENTOR_VERSION' ) ) && ( ! did_action( 'elementor/loaded' ) ) ) {
271 + return true;
272 + }
273 +
274 + $elementor_page_settings = get_post_meta( $post_id, '_elementor_page_settings', true );
275 +
276 + if ( ! is_array( $elementor_page_settings ) ) {
277 + $elementor_page_settings = array();
278 + }
279 +
280 + $elementor_page_settings['default_page_template'] = 'default';
281 +
282 + update_post_meta( $post_id, '_elementor_page_settings', $elementor_page_settings );
283 +
284 + return true;
285 +}
286 +
287 +
288 +/**
88 289 * Is shortcode or some text exist in specific page
89 290 *
90 291 * @param string $relative_url relative URL of the page, if we have absolute url, then get it using: wpbc_make_link_relative( 'https://...' );
91 292 * @param string $shortcode_to_add shortcode to check '[booking'
@@ -107,9 +308,35 @@
107 308
108 309 return false;
109 310 }
110 311
312 +/**
313 + * Is shortcode or some text exist in specific page (got by ID)
314 + *
315 + * @param string $relative_url relative URL of the page, if we have absolute url, then get it using: wpbc_make_link_relative( 'https://...' );
316 + * @param string $shortcode_to_add shortcode to check '[booking'
317 + *
318 + * @return bool
319 + */
320 +function wpbc_is_shortcode_exist_in_page_with_id( $page_id, $shortcode_to_add ) {
111 321
322 + // FixIn: 10.12.3.1.
323 +
324 + if ( ! empty( $page_id ) ) {
325 +
326 + $post_obj = get_post( $page_id );
327 +
328 + if ( ! empty( $post_obj ) ) {
329 + if ( false !== strpos( $post_obj->post_content, $shortcode_to_add ) ) {
330 + return true;
331 + }
332 + }
333 + }
334 +
335 + return false;
336 +}
337 +
338 +
112 339 /**
113 340 * Add shortcode, if it does not exist yet, to the page
114 341 *
115 342 * @param string $relative_url relative URL of the page, if we have absolute url, then get it using: wpbc_make_link_relative( 'https://...' );
@@ -147,10 +374,10 @@
147 374 * Create new page or add to existing page the shortcode
148 375 *
149 376 * @param array $params
150 377 *
151 - * @return array success: [ 'result' => true, 'relative_url' => $relative_post_url, 'message' => __( 'Booking form shortcode embedded into the page.', 'booking' ) ]
152 - * failed: [ 'result' => false, 'message' => __( 'We can not embed booking form shortcode into the page.', 'booking' ) ]
378 + * @return array Success or failure response. Publishing restrictions return a
379 + * failure before WordPress page lookup or mutation.
153 380 *
154 381 * Example:
155 382 * $result_arr = wpbc_add_shortcode_into_page( array(
156 383 * 'shortcode' => '[booking resource_id=1]',
@@ -157,8 +384,15 @@
157 384 * 'post_title' => 'Booking Form'
158 385 * ) );
159 386 */
160 387 function wpbc_add_shortcode_into_page( $params = array() ) {
388 + /* Enforce the publishing policy at the canonical writer for every caller. */
389 + if ( wpbc_is_booking_form_publishing_restricted() ) {
390 + return array(
391 + 'result' => false,
392 + 'message' => __( 'In the demo versions this operation is not allowed.', 'booking' ),
393 + );
394 + }
161 395
162 396 $defaults = array(
163 397 'page_post_name' => '', // 'wpbc-booking',
164 398 'post_title' => esc_html( __( 'Booking Form', 'booking' ) ),
@@ -221,9 +455,10 @@
221 455 }
222 456
223 457 return array( 'result' => true,
224 458 'relative_url' => $relative_post_url,
225 - 'message' => __( 'A new page has been created.', 'booking' ) . ' ' . sprintf( __( 'The booking form shortcode %s has been embedded into the page %s', 'booking' )
459 + /* translators: 1: ... */
460 + 'message' => __( 'A new page has been created.', 'booking' ) . ' ' . sprintf( __( 'The booking form shortcode %1$s has been embedded into the page %2$s', 'booking' )
226 461 , "<code class='wpbc_inserted_shortcode_view'>{$params['shortcode']}</code>"
227 462 , "<a class='wpbc_open_page_as_new_tab' href='" . esc_url( $post_url ) . "'>{$post_title}</a>"
228 463 . " <a target='_blank' class='wpbc_open_page_as_new_tab tooltip_top wpbc-bi-arrow-up-right-square' href='" . esc_url( $post_url ) . "' title='" . esc_attr( __( 'Open in new window', 'booking' ) ) . "'></a>"
229 464 )
@@ -261,9 +496,10 @@
261 496
262 497 if ( $is_sh_added ) {
263 498 return array( 'result' => true,
264 499 'relative_url' => $relative_post_url,
265 - 'message' => sprintf( __( 'The booking form shortcode %s has been embedded into the page %s', 'booking' )
500 + /* translators: 1: ... */
501 + 'message' => sprintf( __( 'The booking form shortcode %1$s has been embedded into the page %2$s', 'booking' )
266 502 , "<code class='wpbc_inserted_shortcode_view'>{$params['shortcode']}</code>"
267 503 , "<a class='wpbc_open_page_as_new_tab' href='" . esc_url( $post_url ) . "'>{$post_title}</a>"
268 504 . " <a target='_blank' class='wpbc_open_page_as_new_tab tooltip_top wpbc-bi-arrow-up-right-square' href='" . esc_url( $post_url ) . "' title='" . esc_attr( __( 'Open in new window', 'booking' ) ) . "'></a>"
269 505
@@ -271,9 +507,10 @@
271 507 );
272 508
273 509 } else {
274 510 return array( 'result' => false,
275 - 'message' => sprintf( __( 'We are unable to embed the booking form shortcode %s into the page %s.', 'booking' )
511 + /* translators: 1: ... */
512 + 'message' => sprintf( __( 'We are unable to embed the booking form shortcode %1$s into the page %2$s.', 'booking' )
276 513 , "<code class='wpbc_inserted_shortcode_view'>{$params['shortcode']}</code>"
277 514 , "<a class='wpbc_open_page_as_new_tab' href='" . esc_url( $post_url ) . "'>{$post_title}</a>"
278 515 . " <a target='_blank' class='wpbc_open_page_as_new_tab tooltip_top wpbc-bi-arrow-up-right-square' href='" . esc_url( $post_url ) . "' title='" . esc_attr( __( 'Open in new window', 'booking' ) ) . "'></a>"
279 516 )
@@ -281,9 +518,10 @@
281 518 }
282 519 } else {
283 520
284 521 return array( 'result' => false,
285 - 'message' => sprintf( __( 'The Booking Calendar shortcode %s is already present on this page %s.', 'booking' )
522 + /* translators: 1: ... */
523 + 'message' => sprintf( __( 'The Booking Calendar shortcode %1$s is already present on this page %2$s.', 'booking' )
286 524 , "<code class='wpbc_inserted_shortcode_view'>{$params['shortcode']}</code>"
287 525 , "<a class='wpbc_open_page_as_new_tab' href='" . esc_url( $post_url ) . "'>{$post_title}</a>"
288 526 . " <a target='_blank' class='wpbc_open_page_as_new_tab tooltip_top wpbc-bi-arrow-up-right-square' href='" . esc_url( $post_url ) . "' title='" . esc_attr( __( 'Open in new window', 'booking' ) ) . "'></a>"
289 527 )
@@ -299,58 +537,670 @@
299 537 // ---------------------------------------------------------------------------------------------------------------------
300 538
301 539
302 540 /**
303 - * Create new starter page with booking form
541 + * Get starter booking form/page definitions created during plugin activation.
304 542 *
305 - * @param $default_options_to_add - array from function wpbc_get_default_options(), which passed only from 'wpbc_before_activation__add_options'. Here we skip this option.
543 + * @return array
544 + */
545 +function wpbc_get_activation_booking_form_page_configs() {
546 +
547 + return array(
548 + 'full_day_booking' => array(
549 + 'template_key' => 'dates_2_columns_hints_full_days', // 'dates_form_with_inline_hints', // FixIn: 11.8.1.1.
550 + 'form_slug' => 'full_day_booking',
551 + 'form_title' => esc_html__( 'Full Day Booking Form', 'booking' ),
552 + 'page_slug' => 'booking-calendar-full-day',
553 + 'legacy_page_slugs' => array( 'wp-booking-calendar-full-day' ),
554 + 'page_title' => esc_html__( 'Full Day Booking', 'booking' ),
555 + 'button_title' => esc_html__( 'Full day booking form', 'booking' ),
556 + ),
557 + 'time_slots_booking' => array(
558 + 'template_key' => 'time_slots_2_columns_hints',
559 + 'form_slug' => 'time_slots_booking',
560 + 'form_title' => esc_html__( 'Time Slots Booking Form', 'booking' ),
561 + 'page_slug' => 'booking-calendar-time-slots',
562 + 'legacy_page_slugs' => array( 'wp-booking-calendar-time-slots' ),
563 + 'page_title' => esc_html__( 'Time Slots Booking', 'booking' ),
564 + 'button_title' => esc_html__( 'Time slots booking form', 'booking' ),
565 + ),
566 + 'time_appointments_booking' => array(
567 + 'template_key' => 'time_appointments_3_steps_review_with_hints',
568 + 'form_slug' => 'time_appointments_booking',
569 + 'form_title' => esc_html__( 'Time Appointments Booking Form', 'booking' ),
570 + 'create_page' => false,
571 + ),
572 + 'appointment_services_booking' => array(
573 + 'template_key' => 'appointments_services_selection_summary',
574 + 'form_slug' => 'appointment_services_booking',
575 + 'form_title' => esc_html__( 'Appointment Services Booking Form', 'booking' ),
576 + 'create_page' => false,
577 + 'assign_to_default_appointment_service' => true,
578 + ),
579 + 'contact_form' => array(
580 + 'template_key' => 'contact_form_simple',
581 + 'form_slug' => 'contact_form',
582 + 'form_title' => esc_html__( 'Contact Form', 'booking' ),
583 + 'page_slug' => 'booking-calendar-contact',
584 + 'legacy_page_slugs' => array( 'wp-booking-calendar-contact' ),
585 + 'page_title' => esc_html__( 'Contact Form', 'booking' ),
586 + 'button_title' => esc_html__( 'Contact form', 'booking' ),
587 + ),
588 + );
589 +}
590 +
591 +
592 +/**
593 + * Get starter page definitions created during plugin activation.
306 594 *
595 + * Legacy starter pages keep using their dedicated custom booking forms. The
596 + * old Time Appointments form and the dedicated Appointment Service form are
597 + * form-only fixtures because the Appointment workflow has one canonical page.
598 + *
599 + * @return array Starter page definitions keyed by stable purpose.
600 + */
601 +function wpbc_get_activation_booking_page_configs() {
602 +
603 + $page_configs = wpbc_get_activation_booking_form_page_configs();
604 +
605 + foreach ( $page_configs as $page_key => $page_config ) {
606 + if ( isset( $page_config['create_page'] ) && false === (bool) $page_config['create_page'] ) {
607 + unset( $page_configs[ $page_key ] );
608 + continue;
609 + }
610 +
611 + $form_slug = '';
612 + if ( isset( $page_config['form_slug'] ) ) {
613 + $form_slug = sanitize_text_field( (string) $page_config['form_slug'] );
614 + }
615 +
616 + if ( '' === $form_slug ) {
617 + unset( $page_configs[ $page_key ] );
618 + continue;
619 + }
620 +
621 + $shortcode = "[booking resource_id=1 form_type='{$form_slug}']";
622 + $page_configs[ $page_key ]['shortcode'] = $shortcode;
623 + $page_configs[ $page_key ]['shortcode_checks'] = array(
624 + $shortcode,
625 + '[booking resource_id=1 form_type="' . $form_slug . '"]',
626 + );
627 + $page_configs[ $page_key ]['resource_id'] = 1;
628 + }
629 +
630 + $page_configs['appointment_booking'] = array(
631 + 'page_slug' => 'booking-calendar-appointment',
632 + 'legacy_page_slugs' => array( 'wpbc-appointment-booking' ),
633 + 'page_title' => esc_html__( 'Book an Appointment', 'booking' ),
634 + 'button_title' => esc_html__( 'Appointment booking form', 'booking' ),
635 + 'shortcode' => '[booking_appointment]',
636 + 'shortcode_checks' => array( '[booking_appointment]', '[booking_appointment ' ),
637 + 'resource_id' => 0,
638 + );
639 + $page_configs['resource_selector_booking'] = array(
640 + 'page_slug' => 'booking-calendar-resource-selection',
641 + 'legacy_page_slugs' => array(),
642 + 'page_title' => esc_html__( 'Resource Selection', 'booking' ),
643 + 'button_title' => esc_html__( 'Resource selection', 'booking' ),
644 + 'shortcode' => '[booking_resource_selector]',
645 + 'shortcode_checks' => array( '[booking_resource_selector]', '[booking_resource_selector ' ),
646 + 'resource_id' => 0,
647 + );
648 +
649 + return $page_configs;
650 +}
651 +
652 +
653 +/**
654 + * Get the Free Booking Received page definition used during initial activation.
655 + *
656 + * The legacy slug remains lookup-only so a clean reinstall can reuse a retained
657 + * page without making legacy URLs canonical for new installations.
658 + *
659 + * @return array Confirmation page definition with canonical and legacy slugs.
660 + */
661 +function wpbc_get_activation_confirmation_page_config() {
662 +
663 + return array(
664 + 'page_slug' => 'booking-calendar-confirmation',
665 + 'legacy_page_slugs' => array( 'wpbc-booking-received' ),
666 + );
667 +}
668 +
669 +
670 +/**
671 + * Get the Personal-edition customer page definitions used during activation.
672 + *
673 + * @return array Personal page definitions keyed by stable purpose.
674 + */
675 +function wpbc_get_activation_personal_page_configs() {
676 +
677 + return array(
678 + 'manage_booking' => array(
679 + 'page_slug' => 'booking-calendar-manage-booking',
680 + 'legacy_page_slugs' => array( 'wpbc-my-booking' ),
681 + 'page_title' => esc_html__( 'My Booking', 'booking' ),
682 + 'shortcode' => '[bookingedit]',
683 + 'option_name' => 'booking_url_bookings_edit_by_visitors',
684 + ),
685 + 'my_bookings' => array(
686 + 'page_slug' => 'booking-calendar-my-bookings',
687 + 'legacy_page_slugs' => array( 'wpbc-my-bookings-listing' ),
688 + 'page_title' => esc_html__( 'My Bookings Listing', 'booking' ),
689 + 'shortcode' => '[bookingcustomerlisting]',
690 + 'option_name' => 'booking_url_bookings_listing_by_customer',
691 + ),
692 + );
693 +}
694 +
695 +
696 +/**
697 + * Get the Business Small payment-result page definitions used during activation.
698 + *
699 + * @return array Payment-result definitions keyed by stable outcome.
700 + */
701 +function wpbc_get_activation_payment_page_configs() {
702 +
703 + return array(
704 + 'success' => array(
705 + 'page_slug' => 'booking-calendar-payment-success',
706 + 'legacy_page_slugs' => array( 'wpbc-booking-payment-successful' ),
707 + 'page_title' => esc_html__( 'Booking Payment Confirmation', 'booking' ),
708 + 'page_content' => esc_html__( 'Thank you for your booking. Your payment for the booking has been successfully received.', 'booking' )
709 + . "\r\n\r\n[booking_confirm]",
710 + 'required_shortcode' => '[booking_confirm]',
711 + 'default_url' => '/successful',
712 + 'option_names' => array(
713 + 'booking_stripe_v3_order_successful',
714 + 'booking_paypal_std_co_order_successful',
715 + 'booking_paypal_return_url',
716 + 'booking_authorizenet_order_successful',
717 + 'booking_sage_order_successful',
718 + 'booking_redsys_order_successful',
719 + 'booking_ideal_return_url',
720 + 'booking_ipay88_return_url',
721 + ),
722 + ),
723 + 'failed' => array(
724 + 'page_slug' => 'booking-calendar-payment-failed',
725 + 'legacy_page_slugs' => array( 'wpbc-booking-payment-failed' ),
726 + 'page_title' => esc_html__( 'Booking Payment Failed', 'booking' ),
727 + 'page_content' => esc_html__( 'Payment Unsuccessful. Please contact us for assistance.', 'booking' ),
728 + 'required_shortcode' => '',
729 + 'default_url' => '/failed',
730 + 'option_names' => array(
731 + 'booking_stripe_v3_order_failed',
732 + 'booking_paypal_std_co_order_failed',
733 + 'booking_paypal_cancel_return_url',
734 + 'booking_authorizenet_order_failed',
735 + 'booking_sage_order_failed',
736 + 'booking_redsys_order_failed',
737 + 'booking_ideal_cancel_return_url',
738 + 'booking_ipay88_cancel_return_url',
739 + ),
740 + ),
741 + );
742 +}
743 +
744 +
745 +/**
746 + * Check whether an activation payment URL still contains its replaceable default.
747 + *
748 + * Missing options and the released placeholder paths may be connected to a
749 + * newly eligible payment page. Every other value is treated as administrator
750 + * configuration and must remain unchanged.
751 + *
752 + * @param mixed $configured_url Saved payment return URL, or false when absent.
753 + * @param string $default_url Released relative placeholder URL.
754 + *
755 + * @return bool True when activation may store the eligible payment page URL.
756 + */
757 +function wpbc_should_update_activation_payment_url( $configured_url, $default_url ) {
758 +
759 + if ( false === $configured_url ) {
760 + return true;
761 + }
762 +
763 + return (string) $default_url === wpbc_make_link_relative( $configured_url );
764 +}
765 +
766 +
767 +/**
768 + * Find an existing activation-owned page by its canonical or legacy slug.
769 + *
770 + * Canonical slugs are checked first. Legacy aliases are used only to preserve
771 + * existing pages and prevent duplicates after a full plugin-data reset.
772 + *
773 + * @param string $page_slug Canonical page slug.
774 + * @param array $legacy_page_slugs Previously released page slugs.
775 + *
776 + * @return WP_Post|null Existing WordPress page, or null when no slug matches.
777 + */
778 +function wpbc_get_activation_page_by_slugs( $page_slug, $legacy_page_slugs = array() ) {
779 +
780 + $page_slugs = array_merge( array( $page_slug ), (array) $legacy_page_slugs );
781 + $page_slugs = array_unique( array_filter( array_map( 'sanitize_title', $page_slugs ) ) );
782 +
783 + foreach ( $page_slugs as $candidate_page_slug ) {
784 + $wp_post = get_page_by_path( $candidate_page_slug, OBJECT, 'page' );
785 +
786 + if ( $wp_post instanceof WP_Post ) {
787 + return $wp_post;
788 + }
789 + }
790 +
791 + return null;
792 +}
793 +
794 +
795 +/**
796 + * Get the first published activation page matching a canonical or legacy slug.
797 + *
798 + * This read-only lookup is separate from the activation writer lookup because
799 + * activation must recognize retained non-published pages to avoid duplicates,
800 + * while public-page navigation must never advertise an inaccessible draft or
801 + * trashed canonical page when a published legacy page is still available.
802 + *
803 + * @param string $page_slug Canonical activation page slug.
804 + * @param array $legacy_page_slugs Previously released lookup-only slugs.
805 + *
806 + * @return WP_Post|null Published page, or null when no public match exists.
807 + */
808 +function wpbc_get_published_activation_page_by_slugs( $page_slug, $legacy_page_slugs = array() ) {
809 +
810 + $page_slugs = array_merge( array( $page_slug ), (array) $legacy_page_slugs );
811 + $page_slugs = array_unique( array_filter( array_map( 'sanitize_title', $page_slugs ) ) );
812 +
813 + foreach ( $page_slugs as $candidate_page_slug ) {
814 + $wp_post = get_page_by_path( $candidate_page_slug, OBJECT, 'page' );
815 +
816 + if ( $wp_post instanceof WP_Post && 'publish' === $wp_post->post_status ) {
817 + return $wp_post;
818 + }
819 + }
820 +
821 + return null;
822 +}
823 +
824 +
825 +/**
826 + * Get a bundled BFB template record by template key.
827 + *
828 + * @param string $template_key Template key.
829 + *
830 + * @return array
831 + */
832 +function wpbc_get_bfb_template_record_by_key( $template_key ) {
833 +
834 + if (
835 + ! function_exists( 'wpbc_bfb_activation__get_templates_registry' ) ||
836 + ! function_exists( 'wpbc_bfb_activation__normalize_template_config' )
837 + ) {
838 + return array();
839 + }
840 +
841 + $template_key = sanitize_key( (string) $template_key );
842 + $templates = wpbc_bfb_activation__get_templates_registry();
843 +
844 + if ( empty( $templates ) || ! is_array( $templates ) ) {
845 + return array();
846 + }
847 +
848 + foreach ( $templates as $template_config ) {
849 +
850 + $template_config = wpbc_bfb_activation__normalize_template_config( $template_config );
851 +
852 + if ( $template_key === $template_config['template_key'] ) {
853 + return $template_config['record'];
854 + }
855 + }
856 +
857 + return array();
858 +}
859 +
860 +
861 +/**
862 + * Create starter custom booking forms from bundled BFB templates.
863 + *
864 + * @return bool
865 + */
866 +function wpbc_create_activation_custom_booking_forms() {
867 +
868 + if (
869 + ! function_exists( 'wpbc_is_table_exists' ) ||
870 + ! wpbc_is_table_exists( 'booking_form_structures' ) ||
871 + ! class_exists( 'WPBC_BFB_Form_Storage' )
872 + ) {
873 + return false;
874 + }
875 +
876 + $configs = wpbc_get_activation_booking_form_page_configs();
877 + if ( empty( $configs ) || ! is_array( $configs ) ) {
878 + return false;
879 + }
880 +
881 + $is_created = false;
882 +
883 + foreach ( $configs as $config ) {
884 +
885 + $form_slug = sanitize_text_field( (string) $config['form_slug'] );
886 + if ( '' === $form_slug ) {
887 + continue;
888 + }
889 +
890 + $existing_form = WPBC_BFB_Form_Storage::get_current_form_by_key( $form_slug, 0, 'published' );
891 + if ( ! empty( $existing_form ) ) {
892 + continue;
893 + }
894 +
895 + $template_record = wpbc_get_bfb_template_record_by_key( $config['template_key'] );
896 + if ( empty( $template_record ) ) {
897 + continue;
898 + }
899 +
900 + // The predefined Time Slots form must select one calendar day independently, // FixIn: 11.4.3.1
901 + // from the global/default Calendar Settings day-selection mode.
902 + if ( 'time_slots_booking' === $form_slug ) {
903 + $form_settings = array();
904 + if ( ! empty( $template_record['settings_json'] ) ) {
905 + $decoded_settings = json_decode( (string) $template_record['settings_json'], true );
906 + if ( is_array( $decoded_settings ) ) {
907 + $form_settings = $decoded_settings;
908 + }
909 + }
910 +
911 + if ( empty( $form_settings['options'] ) || ! is_array( $form_settings['options'] ) ) {
912 + $form_settings['options'] = array();
913 + }
914 +
915 + $form_settings['options']['booking_type_of_day_selections'] = 'single';
916 + $template_record['settings_json'] = function_exists( 'wpbc_form_config__encode_json' )
917 + ? wpbc_form_config__encode_json( $form_settings )
918 + : wp_json_encode( $form_settings );
919 + }
920 +
921 + $template_record['form_slug'] = $form_slug;
922 + $template_record['status'] = 'published';
923 + $template_record['scope'] = 'global';
924 + $template_record['owner_user_id'] = 0;
925 + $template_record['booking_resource_id'] = null;
926 + $template_record['is_default'] = 0;
927 + $template_record['title'] = $config['form_title'];
928 + $template_record['picture_url'] = isset( $template_record['picture_url'] ) ? (string) $template_record['picture_url'] : '';
929 + if ( function_exists( 'wpbc_bfb_resolve_picture_url' ) ) {
930 + $template_record['picture_url'] = wpbc_bfb_resolve_picture_url( $template_record['picture_url'] );
931 + }
932 +
933 + $booking_form_id = WPBC_BFB_Form_Storage::save_form( $template_record );
934 + if ( ! empty( $booking_form_id ) ) {
935 + $is_created = true;
936 + }
937 + }
938 +
939 + return $is_created;
940 +}
941 +
942 +
943 +/**
944 + * Return the ordered activation-page level for a Booking Calendar edition.
945 + *
946 + * The ordering is intentionally limited to product editions. Page groups use
947 + * these levels to determine whether a paid activation has crossed the edition
948 + * boundary that first makes those pages available.
949 + *
950 + * @param string $edition_id Booking Calendar edition identifier.
951 + *
952 + * @return int Edition level, or -1 when the identifier is not supported.
953 + */
954 +function wpbc_get_activation_page_edition_level( $edition_id ) {
955 +
956 + $edition_levels = array(
957 + 'free' => 0,
958 + 'personal' => 1,
959 + 'biz_s' => 2,
960 + 'biz_m' => 3,
961 + 'biz_l' => 4,
962 + 'multiuser' => 5,
963 + );
964 +
965 + $edition_id = (string) $edition_id;
966 +
967 + return isset( $edition_levels[ $edition_id ] ) ? $edition_levels[ $edition_id ] : -1;
968 +}
969 +
970 +
971 +/**
972 + * Check whether a paid-edition transition newly unlocks one page group.
973 + *
974 + * This pure comparison keeps Free-to-Pro, lower-to-higher, reactivation,
975 + * update, and downgrade behavior deterministic and independently testable.
976 + *
977 + * @param string $previous_edition_id Previously provisioned or detected edition.
978 + * @param string $current_edition_id Edition active during this activation.
979 + * @param string $required_edition_id First edition that owns the page group.
980 + *
981 + * @return bool True when this activation crosses the required edition boundary.
982 + */
983 +function wpbc_is_activation_page_edition_transition( $previous_edition_id, $current_edition_id, $required_edition_id ) {
984 +
985 + $previous_edition_level = wpbc_get_activation_page_edition_level( $previous_edition_id );
986 + $current_edition_level = wpbc_get_activation_page_edition_level( $current_edition_id );
987 + $required_edition_level = wpbc_get_activation_page_edition_level( $required_edition_id );
988 +
989 + if ( 0 > $previous_edition_level || 0 > $current_edition_level || 1 > $required_edition_level ) {
990 + return false;
991 + }
992 +
993 + return $previous_edition_level < $required_edition_level
994 + && $required_edition_level <= $current_edition_level;
995 +}
996 +
997 +
998 +/**
999 + * Check whether activation-owned WordPress pages may be provisioned.
1000 + *
1001 + * Free-owned pages remain restricted to the immutable first-Free-install
1002 + * decision. Paid page groups can additionally opt into the exact Pro edition
1003 + * transition that first makes them available. The Pro activation layer owns
1004 + * that transition state and exposes it through a narrow filter; normal Free or
1005 + * Pro updates therefore remain fail-closed.
1006 + *
1007 + * @param string $required_edition_id First edition that owns the page group.
1008 + *
1009 + * @return bool True only during the qualifying initial activation request.
1010 + */
1011 +function wpbc_should_create_activation_pages( $required_edition_id = 'free' ) {
1012 + $required_edition_id = (string) $required_edition_id;
1013 + $required_edition_level = wpbc_get_activation_page_edition_level( $required_edition_id );
1014 +
1015 + if ( 0 > $required_edition_level ) {
1016 + return false;
1017 + }
1018 +
1019 + if ( function_exists( 'wpbc_is_plugin_initial_install' ) && wpbc_is_plugin_initial_install() ) {
1020 + return true;
1021 + }
1022 +
1023 + if ( 0 === $required_edition_level ) {
1024 + return false;
1025 + }
1026 +
1027 + /**
1028 + * Filter whether the current paid-edition activation newly owns a page group.
1029 + *
1030 + * @since 11.8.1
1031 + *
1032 + * @param bool $should_create_pages Fail-closed default decision.
1033 + * @param string $required_edition_id First edition that owns the page group.
1034 + */
1035 + return (bool) apply_filters( 'wpbc_should_create_paid_edition_activation_pages', false, $required_edition_id );
1036 +}
1037 +
1038 +
1039 +/**
1040 + * Build starter page content with a booking shortcode.
1041 + *
1042 + * @param string $shortcode Booking shortcode.
1043 + *
1044 + * @return string
1045 + */
1046 +function wpbc_get_activation_booking_page_content( $shortcode ) {
1047 +
1048 + $shortcode = trim( (string) $shortcode );
1049 +
1050 + if ( WPBC_IS_PLAYGROUND ) {
1051 + $shortcode = '<style type="text/css"> h1, h2, h3, h4, h5, h6 { font-weight: 500; font-family: var(--wp--preset--font-family--body); } </style>' . $shortcode;
1052 + }
1053 +
1054 + return $shortcode;
1055 +}
1056 +
1057 +
1058 +/**
1059 + * Create new starter pages with booking forms.
1060 + *
1061 + * @param array $default_options_to_add Unused. Kept for backward-compatible direct calls.
1062 + *
307 1063 * @return void
308 1064 */
309 -function wpbc_create_page_with_booking_form( $default_options_to_add = array() ) { //FixIn: 9.6.2.11
1065 +function wpbc_create_page_with_booking_form( $default_options_to_add = array() ) { // FixIn: 9.6.2.11.
310 1066
311 1067 global $wp_rewrite;
312 - if ( is_null( $wp_rewrite ) ) { //FixIn: 9.7.1.1
1068 + if ( is_null( $wp_rewrite ) ) { // FixIn: 9.7.1.1.
313 1069
314 - // Maybe it was not init, yet
1070 + // Maybe it was not init, yet.
315 1071 if ( ! has_action( 'init', 'wpbc_create_page_with_booking_form' ) ) {
316 1072 add_action( 'init', 'wpbc_create_page_with_booking_form', 99 ); // <- priority to load it last
317 1073 }
1074 +
318 1075 return false;
319 1076 }
320 1077
321 1078 // -----------------------------------------------------------------------------------------------------------------
322 1079
323 - $wp_post = get_page_by_path( 'wpbc-booking' );
1080 + wpbc_create_activation_custom_booking_forms();
324 1081
325 - $post_url = '';
1082 + /**
1083 + * Fires after activation starter custom forms are available.
1084 + *
1085 + * Appointment Services uses this boundary to finish its pending starter
1086 + * Service seed with the newly created form ID.
1087 + *
1088 + * @since 11.5.0
1089 + */
1090 + do_action( 'wpbc_activation_custom_booking_forms_created' );
1091 +
1092 + if ( ! wpbc_should_create_activation_pages() ) {
1093 + return;
1094 + }
1095 +
1096 + $configs = wpbc_get_activation_booking_page_configs();
1097 + if ( empty( $configs ) || ! is_array( $configs ) ) {
1098 + return;
1099 + }
326 1100
327 - if ( empty( $wp_post ) ) { // No default page. Create it.
1101 + $front_page_id = 0;
328 1102
329 - $page_params = array(
330 - 'post_title' => esc_html( __( 'Booking Form', 'booking' ) ),
331 - 'post_content' => '[booking resource_id=1]',
332 - 'post_name' => 'wpbc-booking'
333 - );
334 - $post_id = wpbc_create_page( $page_params );
1103 + foreach ( $configs as $config ) {
335 1104
336 - if ( ! empty( $post_id ) ) {
337 - $post_url = wpbc_make_link_relative( get_permalink( $post_id ) );
1105 + $shortcode = isset( $config['shortcode'] ) ? trim( (string) $config['shortcode'] ) : '';
1106 + $shortcode_checks = isset( $config['shortcode_checks'] ) && is_array( $config['shortcode_checks'] )
1107 + ? $config['shortcode_checks']
1108 + : array( $shortcode );
1109 + $resource_id = isset( $config['resource_id'] ) ? absint( $config['resource_id'] ) : 0;
1110 +
1111 + if ( '' === $shortcode ) {
1112 + continue;
338 1113 }
339 1114
340 - } else {
341 - $post_url = wpbc_make_link_relative( get_permalink( $wp_post->ID ) ); // Page already exist, so we need to update the
1115 + $content = wpbc_get_activation_booking_page_content( $shortcode );
1116 + $legacy_page_slugs = isset( $config['legacy_page_slugs'] ) ? (array) $config['legacy_page_slugs'] : array();
1117 + $existing_page = wpbc_get_activation_page_by_slugs( $config['page_slug'], $legacy_page_slugs );
1118 +
1119 + $result_arr = wpbc_add_shortcode_into_page(
1120 + array(
1121 + 'page_post_name' => $config['page_slug'],
1122 + 'page_id' => $existing_page instanceof WP_Post ? $existing_page->ID : 0,
1123 + 'post_title' => $config['page_title'],
1124 + 'shortcode' => $content,
1125 + 'check_exist_shortcode' => $shortcode_checks,
1126 + 'resource_id' => $resource_id,
1127 + )
1128 + );
1129 +
1130 + if ( WPBC_IS_PLAYGROUND && empty( $front_page_id ) && ! empty( $result_arr['relative_url'] ) ) {
1131 + $wp_post = wpbc_get_activation_page_by_slugs( $config['page_slug'], $legacy_page_slugs );
1132 + if ( ! empty( $wp_post ) ) {
1133 + $front_page_id = $wp_post->ID;
1134 + }
1135 + }
342 1136 }
343 1137
344 - // -----------------------------------------------------------------------------------------------------------------
1138 + if ( WPBC_IS_PLAYGROUND && ! empty( $front_page_id ) ) {
1139 + update_option( 'show_on_front', 'page' );
1140 + update_option( 'page_on_front', $front_page_id );
1141 + }
1142 +}
1143 +add_action( 'wpbc_bfb_activation__form_structures_table__after_create', 'wpbc_create_page_with_booking_form', 20 );
1144 +add_action( 'wpbc_bfb_activation__form_structures_table__table_already_exists', 'wpbc_create_page_with_booking_form', 20 );
345 1145
346 - // Check if existing page has our shortcode. We are checking for 'booking' because it can be '[booking]' or '[booking type=1]' ...
347 - if ( ! wpbc_is_shortcode_exist_in_page( $post_url, '[booking' ) ) {
348 - $is_sh_added = wpbc_add_shortcode_to_exist_page( $post_url, '[booking resource_id=1]' );
1146 +
1147 +/**
1148 + * Get published starter pages that contain their expected booking form shortcodes.
1149 + *
1150 + * @return array
1151 + */
1152 +function wpbc_get_published_activation_booking_pages() {
1153 +
1154 + $pages = array();
1155 + $configs = wpbc_get_activation_booking_page_configs();
1156 +
1157 + if ( empty( $configs ) || ! is_array( $configs ) ) {
1158 + return $pages;
349 1159 }
350 1160
1161 + foreach ( $configs as $key => $config ) {
1162 +
1163 + $legacy_page_slugs = isset( $config['legacy_page_slugs'] ) ? (array) $config['legacy_page_slugs'] : array();
1164 + $wp_post = wpbc_get_published_activation_page_by_slugs( $config['page_slug'], $legacy_page_slugs );
1165 + if ( ! ( $wp_post instanceof WP_Post ) ) {
1166 + continue;
1167 + }
1168 +
1169 + $shortcode_checks = isset( $config['shortcode_checks'] ) && is_array( $config['shortcode_checks'] )
1170 + ? $config['shortcode_checks']
1171 + : array();
1172 + $is_shortcode_found = false;
1173 +
1174 + foreach ( $shortcode_checks as $shortcode_check ) {
1175 + if ( '' === (string) $shortcode_check ) {
1176 + continue;
1177 + }
1178 +
1179 + if ( wpbc_is_shortcode_exist_in_page_with_id( $wp_post->ID, $shortcode_check ) ) {
1180 + $is_shortcode_found = true;
1181 + break;
1182 + }
1183 + }
1184 +
1185 + if ( ! $is_shortcode_found ) {
1186 + continue;
1187 + }
1188 +
1189 + $post_url = get_permalink( $wp_post->ID );
1190 + if ( empty( $post_url ) ) {
1191 + continue;
1192 + }
1193 +
1194 + $pages[ $key ] = array(
1195 + 'url' => $post_url,
1196 + 'button_title' => $config['button_title'],
1197 + 'page_title' => $config['page_title'],
1198 + );
1199 + }
1200 +
1201 + return $pages;
351 1202 }
352 -add_bk_action( 'wpbc_before_activation__add_options', 'wpbc_create_page_with_booking_form' );
353 1203
354 1204 // ---------------------------------------------------------------------------------------------------------------------
355 1205
356 1206
@@ -360,13 +1210,17 @@
360 1210 * @param $default_options_to_add
361 1211 *
362 1212 * @return void
363 1213 */
364 -function wpbc_create_page_thank_you( $default_options_to_add ) { //FixIn: 9.6.2.11
1214 +function wpbc_create_page_thank_you( $default_options_to_add ) { // FixIn: 9.6.2.11.
1215 +
1216 + if ( ! wpbc_should_create_activation_pages() ) {
1217 + return false;
1218 + }
1219 +
1220 + global $wp_rewrite;
1221 + if ( is_null( $wp_rewrite ) ) { // FixIn: 9.7.1.1.
365 1222
366 - global $wp_rewrite;
367 - if ( is_null( $wp_rewrite ) ) { //FixIn: 9.7.1.1
368 -
369 1223 // Maybe it was not init, yet
370 1224 if ( ! has_action( 'init', 'wpbc_create_page_thank_you' ) ) {
371 1225 add_action( 'init', 'wpbc_create_page_thank_you', 99 ); // <- priority to load it last
372 1226 }
@@ -379,24 +1233,28 @@
379 1233
380 1234 if ( ( empty( $thank_you_page_url ) ) // If No 'Thank you' page in Settings, or it's set as Empty.
381 1235 || (
382 1236 ( '/thank-you' == wpbc_make_link_relative( get_bk_option( 'booking_thank_you_page_URL' ) ) )
383 - && ( empty( get_page_by_path( 'thank-you' ) ) ) //FixIn: 9.9.0.27
1237 + && ( empty( get_page_by_path( 'thank-you' ) ) ) // FixIn: 9.9.0.27.
384 1238 )
385 1239 || ( '/' == wpbc_make_link_relative( get_bk_option( 'booking_thank_you_page_URL' ) ) )
386 1240 ){
387 - $wp_post = get_page_by_path( 'wpbc-booking-received' );
1241 + $confirmation_page_config = wpbc_get_activation_confirmation_page_config();
1242 + $wp_post = wpbc_get_activation_page_by_slugs(
1243 + $confirmation_page_config['page_slug'],
1244 + $confirmation_page_config['legacy_page_slugs']
1245 + );
388 1246
389 1247 $post_url = '';
390 1248
391 1249 if ( empty( $wp_post ) ) { // No default page. Create it.
392 1250
393 - $page_params = array(
394 - 'post_title' => esc_html( __( 'Booking Received', 'booking' ) ),
395 - 'post_content' => esc_html( __( 'Thank you for your booking. Your booking has been successfully received.', 'booking' ) )
396 - . "\r\n" . ' [booking_confirm]',
397 - 'post_name' => 'wpbc-booking-received'
398 - );
1251 + $page_params = array(
1252 + 'post_title' => esc_html( __( 'Booking Received', 'booking' ) ),
1253 + 'post_content' => esc_html( __( 'Thank you for your booking. Your booking has been successfully received.', 'booking' ) )
1254 + . "\r\n" . ' [booking_confirm]',
1255 + 'post_name' => $confirmation_page_config['page_slug'],
1256 + );
399 1257 $post_id = wpbc_create_page( $page_params );
400 1258
401 1259 if ( ! empty( $post_id ) ) {
402 1260 $post_url = wpbc_make_link_relative( get_permalink( $post_id ) );
@@ -430,12 +1288,16 @@
430 1288 * to some pages different from homepage.
431 1289 *
432 1290 * @return void
433 1291 */
434 -function wpbc_create_page_bookingedit(){ //FixIn: 9.6.2.10
435 -
436 - global $wp_rewrite;
437 - if ( is_null( $wp_rewrite ) ) { //FixIn: 9.7.1.1
1292 +function wpbc_create_page_bookingedit(){ // FixIn: 9.6.2.10.
1293 +
1294 + if ( ! wpbc_should_create_activation_pages( 'personal' ) ) {
1295 + return false;
1296 + }
1297 +
1298 + global $wp_rewrite;
1299 + if ( is_null( $wp_rewrite ) ) { // FixIn: 9.7.1.1.
438 1300 // Maybe it was not init, yet
439 1301 if ( ! has_action( 'init', 'wpbc_create_page_bookingedit' ) ) {
440 1302 add_action( 'init', 'wpbc_create_page_bookingedit', 99 ); // <- priority to load it last
441 1303 }
@@ -441,182 +1303,91 @@
441 1303 }
442 1304 return false;
443 1305 }
444 1306
445 - // Booking Edit page - set default page and URL ---------------------------------------------------------------
446 - $url_booking_edit = get_bk_option( 'booking_url_bookings_edit_by_visitors' );
447 - if (
448 - ( site_url() == $url_booking_edit )
449 - && ( empty( get_page_by_path( 'wpbc-my-booking' ) ) )
450 - ){
451 - $page_params = array(
452 - 'post_content' => '[bookingedit]', // The post content
453 - 'post_name' => 'wpbc-my-booking', // sanitize_title( $post_title )
454 - 'post_title' => esc_html__( 'My Booking', 'booking' ) // Title
455 - );
1307 + $page_configs = wpbc_get_activation_personal_page_configs();
1308 +
1309 + foreach ( $page_configs as $page_config ) {
1310 + $configured_page_url = get_bk_option( $page_config['option_name'] );
1311 + $existing_page = wpbc_get_activation_page_by_slugs(
1312 + $page_config['page_slug'],
1313 + $page_config['legacy_page_slugs']
1314 + );
1315 +
1316 + if ( site_url() === $configured_page_url && ! ( $existing_page instanceof WP_Post ) ) {
1317 + $page_id = wpbc_create_page(
1318 + array(
1319 + 'post_content' => $page_config['shortcode'],
1320 + 'post_name' => $page_config['page_slug'],
1321 + 'post_title' => $page_config['page_title'],
1322 + )
1323 + );
1324 +
1325 + if ( ! empty( $page_id ) ) {
1326 + update_bk_option( $page_config['option_name'], get_permalink( $page_id ) );
1327 + }
1328 + } elseif (
1329 + ( site_url() === $configured_page_url || empty( $configured_page_url ) )
1330 + && $existing_page instanceof WP_Post
1331 + ) {
1332 + update_bk_option( $page_config['option_name'], get_permalink( $existing_page->ID ) );
1333 + }
1334 +
1335 + $relative_page_url = wpbc_make_link_relative( get_bk_option( $page_config['option_name'] ) );
1336 + wpbc_add_shortcode_to_exist_page( $relative_page_url, $page_config['shortcode'] );
1337 + }
456 1338
457 - $post_id = wpbc_create_page( $page_params );
458 -
459 - if ( ! empty( $post_id ) ) {
460 - $post_url = get_permalink( $post_id );
461 - update_bk_option( 'booking_url_bookings_edit_by_visitors', $post_url );
462 - }
463 - } else if (
464 - (
465 - ( site_url() == $url_booking_edit )
466 - || ( empty( $url_booking_edit ) )
467 - )
468 - && ( ! empty( get_page_by_path( 'wpbc-my-booking' ) ) )
469 - ){
470 - $wp_post = get_page_by_path( 'wpbc-my-booking' );
471 - if ( ! empty( $wp_post ) ) {
472 - update_bk_option( 'booking_url_bookings_edit_by_visitors', get_permalink( $wp_post->ID ) );
473 - }
474 - }
475 -
476 - // -----------------------------------------------------------------------------------------------------------------
477 - // Check if existing page has our shortcode
478 - // -----------------------------------------------------------------------------------------------------------------
479 - $booking_edit_relative_url = wpbc_make_link_relative( get_bk_option( 'booking_url_bookings_edit_by_visitors' ) );
480 - $is_added = wpbc_add_shortcode_to_exist_page( $booking_edit_relative_url, '[bookingedit]' );
481 -
482 -
483 - // =================================================================================================================
484 - // =================================================================================================================
485 - // =================================================================================================================
486 -
487 -
488 - // Booking Listing page - set default page and URL ---------------------------------------------------------------
489 - $url_booking_edit = get_bk_option( 'booking_url_bookings_listing_by_customer' );
490 - if (
491 - ( site_url() == $url_booking_edit )
492 - && ( empty( get_page_by_path( 'wpbc-my-bookings-listing' ) ) )
493 - ){
494 -
495 - $page_params = array(
496 - 'post_content' => '[bookingcustomerlisting]', // The post content
497 - 'post_name' => 'wpbc-my-bookings-listing', // sanitize_title( $post_title )
498 - 'post_title' => esc_html__( 'My Bookings Listing', 'booking' ) // Title
499 - );
500 -
501 - $post_id = wpbc_create_page( $page_params );
502 -
503 - if ( ! empty( $post_id ) ) {
504 - $post_url = get_permalink( $post_id );
505 - update_bk_option( 'booking_url_bookings_listing_by_customer', $post_url );
506 - }
507 - } else if (
508 - (
509 - ( site_url() == $url_booking_edit )
510 - || ( empty( $url_booking_edit ) )
511 - )
512 - && ( ! empty( get_page_by_path( 'wpbc-my-bookings-listing' ) ) )
513 - ){
514 - $wp_post = get_page_by_path( 'wpbc-my-bookings-listing' );
515 - if ( ! empty( $wp_post ) ){
516 - update_bk_option( 'booking_url_bookings_listing_by_customer', get_permalink( $wp_post->ID ) );
517 - }
518 - }
519 -
520 -
521 - // -----------------------------------------------------------------------------------------------------------------
522 - // Check if existing page has our shortcode
523 - // -----------------------------------------------------------------------------------------------------------------
524 - $booking_listing_relative_url = wpbc_make_link_relative( get_bk_option( 'booking_url_bookings_listing_by_customer' ) );
525 - $is_added = wpbc_add_shortcode_to_exist_page( $booking_listing_relative_url, '[bookingcustomerlisting]' );
526 -
527 1339 }
528 1340
529 1341
530 -function wpbc_create_page_booking_payment_status(){ //FixIn: 9.6.2.13
531 -
532 - global $wp_rewrite;
533 - if ( is_null( $wp_rewrite ) ) { //FixIn: 9.7.1.1
1342 +function wpbc_create_page_booking_payment_status(){ // FixIn: 9.6.2.13.
1343 +
1344 + if ( ! wpbc_should_create_activation_pages( 'biz_s' ) ) {
1345 + return false;
1346 + }
1347 +
1348 + global $wp_rewrite;
1349 + if ( is_null( $wp_rewrite ) ) { // FixIn: 9.7.1.1.
534 1350 return false;
535 1351 }
536 1352
537 - // Successful Payment page options ---------------------------------------------------------------------------------
538 -
539 - $post_url_relative = false;
540 - $slug = 'wpbc-booking-payment-successful';
541 - if ( empty( get_page_by_path( $slug ) ) ) {
542 - // Create page
543 - $page_params = array(
544 - 'post_title' => esc_html( __( 'Booking Payment Confirmation', 'booking' ) ),
545 - 'post_content' => esc_html( __( 'Thank you for your booking. Your payment for the booking has been successfully received.', 'booking' ) ),
546 - 'post_name' => $slug
547 - );
548 -
549 - $post_id = wpbc_create_page( $page_params );
550 -
551 - if ( ! empty( $post_id ) ) {
552 - $post_url = get_permalink( $post_id );
553 - $post_url_relative = str_replace( site_url(), '', $post_url );
554 - }
555 - }
556 - if ( ! empty( $post_url_relative ) ) {
557 -
558 - //$post_url_relative = wpbc_make_link_absolute( $post_url_relative );
559 -
560 - $payment_systems = array(
561 - 'booking_stripe_v3_order_successful',
562 - 'booking_paypal_return_url',
563 - 'booking_authorizenet_order_successful',
564 - 'booking_sage_order_successful',
565 - 'booking_ideal_return_url',
566 - 'booking_ipay88_return_url'
567 - );
568 -
569 - foreach ( $payment_systems as $payment_system ) {
570 -
571 - if (
572 - ( false === get_bk_option( $payment_system ) )
573 - || ( '/successful' == wpbc_make_link_relative( get_bk_option( $payment_system ) ) )
574 - ) {
575 - update_bk_option( $payment_system, wpbc_make_link_relative( $post_url_relative ) );
576 - }
577 - }
578 - }
579 -
580 - // Failed Payment page options -------------------------------------------------------------------------------------
581 -
582 - $post_url_relative = false;
583 - $slug = 'wpbc-booking-payment-failed';
584 - if ( empty( get_page_by_path( $slug ) ) ) {
585 - // Create page
586 - $page_params = array(
587 - 'post_title' => esc_html( __( 'Booking Payment Failed', 'booking' ) ),
588 - 'post_content' => esc_html( __( 'Payment Unsuccessful. Please contact us for assistance.', 'booking' ) ),
589 - 'post_name' => $slug
590 - );
591 -
592 - $post_id = wpbc_create_page( $page_params );
593 -
594 - if ( ! empty( $post_id ) ) {
595 - $post_url = get_permalink( $post_id );
596 - $post_url_relative = str_replace( site_url(), '', $post_url );
597 - }
598 - }
599 - if ( ! empty( $post_url_relative ) ) {
600 -
601 - //$post_url_relative = wpbc_make_link_absolute( $post_url_relative );
602 -
603 - $payment_systems = array(
604 - 'booking_stripe_v3_order_failed',
605 - 'booking_paypal_cancel_return_url',
606 - 'booking_authorizenet_order_failed',
607 - 'booking_sage_order_failed',
608 - 'booking_ideal_cancel_return_url',
609 - 'booking_ipay88_cancel_return_url'
610 - );
611 -
612 - foreach ( $payment_systems as $payment_system ) {
613 -
614 - if (
615 - ( false === get_bk_option( $payment_system ) )
616 - || ( '/failed' == wpbc_make_link_relative( get_bk_option( $payment_system ) ) )
617 - ) {
618 - update_bk_option( $payment_system, wpbc_make_link_relative( $post_url_relative ) );
619 - }
620 - }
621 - }
622 -}
1353 + $page_configs = wpbc_get_activation_payment_page_configs();
1354 +
1355 + foreach ( $page_configs as $page_config ) {
1356 + $existing_page = wpbc_get_activation_page_by_slugs(
1357 + $page_config['page_slug'],
1358 + $page_config['legacy_page_slugs']
1359 + );
1360 +
1361 + if ( ! ( $existing_page instanceof WP_Post ) ) {
1362 + $page_id = wpbc_create_page(
1363 + array(
1364 + 'post_title' => $page_config['page_title'],
1365 + 'post_content' => $page_config['page_content'],
1366 + 'post_name' => $page_config['page_slug'],
1367 + )
1368 + );
1369 + $existing_page = ! empty( $page_id ) ? get_post( $page_id ) : null;
1370 + }
1371 +
1372 + if ( ! ( $existing_page instanceof WP_Post ) || 'publish' !== $existing_page->post_status ) {
1373 + continue;
1374 + }
1375 +
1376 + $page_url_relative = wpbc_make_link_relative( get_permalink( $existing_page->ID ) );
1377 + if ( empty( $page_url_relative ) ) {
1378 + continue;
1379 + }
1380 +
1381 + if ( ! empty( $page_config['required_shortcode'] ) ) {
1382 + wpbc_add_shortcode_to_exist_page( $page_url_relative, $page_config['required_shortcode'] );
1383 + }
1384 +
1385 + foreach ( $page_config['option_names'] as $option_name ) {
1386 + $configured_url = get_bk_option( $option_name );
1387 +
1388 + if ( wpbc_should_update_activation_payment_url( $configured_url, $page_config['default_url'] ) ) {
1389 + update_bk_option( $option_name, $page_url_relative );
1390 + }
1391 + }
1392 + }
1393 +}