← All changes
|
includes/page-appointment-services/appointment_services__activate.php
+117
-59
11.5
→
11.9
View file →
| @@ -6,23 +6,21 @@ | ||
| 6 | 6 | define( 'WPBC_APPOINTMENT_SERVICES_DB_VERSION', '1.0.0' ); |
| 7 | 7 | } |
| 8 | 8 | |
| 9 | 9 | /** |
| 10 | - * Return the canonical starter Service used during activation and upgrades. | |
| 10 | + * Return the canonical starter Services used by a new installation. | |
| 11 | 11 | * |
| 12 | - * Keeping one definition prevents newly upgraded sites and Setup Wizard sites | |
| 13 | - * from receiving different starter data. The Provider remains an existing | |
| 14 | - * Booking Resource and is never created or renamed here. | |
| 12 | + * Both Services share the existing default Provider and Booking Form. Their | |
| 13 | + * pictures use the configured starter-asset source, so distributions may use | |
| 14 | + * bundled files or the corresponding Booking Calendar website directory. | |
| 15 | 15 | * |
| 16 | 16 | * @param int $provider_id Existing Booking Resource used as the Provider. |
| 17 | - * @param int $booking_form_id Optional published Booking Form assigned to the Service. | |
| 17 | + * @param int $booking_form_id Optional published Booking Form assigned to the Services. | |
| 18 | 18 | * |
| 19 | - * @return array<string,mixed> Normalized values accepted by the Service repository. | |
| 19 | + * @return array<int,array<string,mixed>> Normalized values accepted by the Service repository. | |
| 20 | 20 | */ |
| 21 | -function wpbc_appointment_services_get_starter_service_values( $provider_id, $booking_form_id = 0 ) { | |
| 22 | - return array( | |
| 23 | - 'title' => __( 'Consultation', 'booking' ), | |
| 24 | - 'description' => __( 'A 30-minute consultation.', 'booking' ), | |
| 21 | +function wpbc_appointment_services_get_starter_services_values( $provider_id, $booking_form_id = 0 ) { | |
| 22 | + $common_values = array( | |
| 25 | 23 | 'duration_minutes' => 30, |
| 26 | 24 | 'buffer_before_minutes' => 0, |
| 27 | 25 | 'buffer_after_minutes' => 0, |
| 28 | 26 | 'base_cost' => '0.00', |
| @@ -28,16 +26,57 @@ | ||
| 28 | 26 | 'base_cost' => '0.00', |
| 29 | 27 | 'booking_form_id' => absint( $booking_form_id ), |
| 30 | 28 | 'status' => 'active', |
| 31 | 29 | 'resource_ids' => array( absint( $provider_id ) ), |
| 32 | - 'metadata' => array( | |
| 33 | - 'quickstart_key' => 'appointment_starter', | |
| 34 | - 'schema_version' => 1, | |
| 30 | + ); | |
| 31 | + | |
| 32 | + return array( | |
| 33 | + array_merge( | |
| 34 | + $common_values, | |
| 35 | + array( | |
| 36 | + 'title' => __( 'Initial Consultation', 'booking' ), | |
| 37 | + 'description' => __( 'A focused first meeting to understand your needs and recommend the right next step.', 'booking' ), | |
| 38 | + 'metadata' => array( | |
| 39 | + 'picture_url' => wpbc_get_starter_asset_url( 'img/services/professional-services-demo_service-initial-consultation.png' ), | |
| 40 | + 'quickstart_key' => 'appointment_starter', | |
| 41 | + 'schema_version' => 1, | |
| 42 | + ), | |
| 43 | + ) | |
| 35 | 44 | ), |
| 45 | + array_merge( | |
| 46 | + $common_values, | |
| 47 | + array( | |
| 48 | + 'title' => __( 'One-to-One Session', 'booking' ), | |
| 49 | + 'description' => __( 'Personalized support tailored to your goals, questions, and schedule.', 'booking' ), | |
| 50 | + 'metadata' => array( | |
| 51 | + 'picture_url' => wpbc_get_starter_asset_url( 'img/services/professional-services-demo_service-one-to-one-session.png' ), | |
| 52 | + 'quickstart_key' => 'appointment_starter_one_to_one', | |
| 53 | + 'schema_version' => 1, | |
| 54 | + ), | |
| 55 | + ) | |
| 56 | + ), | |
| 36 | 57 | ); |
| 37 | 58 | } |
| 38 | 59 | |
| 39 | 60 | /** |
| 61 | + * Return the primary starter Service used by Appointment QuickStart. | |
| 62 | + * | |
| 63 | + * QuickStart creates at most one dedicated Service, while fresh activation | |
| 64 | + * seeds the complete starter set returned by | |
| 65 | + * `wpbc_appointment_services_get_starter_services_values()`. | |
| 66 | + * | |
| 67 | + * @param int $provider_id Existing Booking Resource used as the Provider. | |
| 68 | + * @param int $booking_form_id Optional published Booking Form assigned to the Service. | |
| 69 | + * | |
| 70 | + * @return array<string,mixed> Normalized values accepted by the Service repository. | |
| 71 | + */ | |
| 72 | +function wpbc_appointment_services_get_starter_service_values( $provider_id, $booking_form_id = 0 ) { | |
| 73 | + $starter_services = wpbc_appointment_services_get_starter_services_values( $provider_id, $booking_form_id ); | |
| 74 | + | |
| 75 | + return reset( $starter_services ); | |
| 76 | +} | |
| 77 | + | |
| 78 | +/** | |
| 40 | 79 | * Resolve the published starter form assigned to the default Appointment Service. |
| 41 | 80 | * |
| 42 | 81 | * The activation form registry owns the form identity. This resolver reads its |
| 43 | 82 | * assignment marker so the Service seed does not duplicate a form slug. |
| @@ -110,15 +149,15 @@ | ||
| 110 | 149 | && wpbc_is_table_exists( 'booking_appointment_details' ); |
| 111 | 150 | } |
| 112 | 151 | |
| 113 | 152 | /** |
| 114 | - * Create the starter Service after its database tables are installed. | |
| 153 | + * Create the starter Services after their database tables are installed. | |
| 115 | 154 | * |
| 116 | 155 | * This runs only for a newly created Services table, or when an earlier seed |
| 117 | 156 | * attempt was marked for retry. It deliberately does not inspect an existing |
| 118 | 157 | * empty catalog because administrators may intentionally remove every Service. |
| 119 | 158 | * |
| 120 | - * @return bool True when the starter Service was created successfully. | |
| 159 | + * @return bool True when every starter Service was created successfully. | |
| 121 | 160 | */ |
| 122 | 161 | function wpbc_activation__appointment_services__seed_default_service() { |
| 123 | 162 | global $wpdb; |
| 124 | 163 | |
| @@ -135,57 +174,76 @@ | ||
| 135 | 174 | if ( ! $booking_form_id ) { |
| 136 | 175 | return false; |
| 137 | 176 | } |
| 138 | 177 | |
| 139 | - $starter_service = wpbc_appointment_services_get_starter_service_values( $provider_id, $booking_form_id ); | |
| 140 | - $metadata = wp_json_encode( $starter_service['metadata'] ); | |
| 141 | - $now = current_time( 'mysql' ); | |
| 142 | - $current_user_id = get_current_user_id(); | |
| 143 | - $owner_user_id = function_exists( 'wpbc_appointment_services_get_owner_user_id' ) | |
| 178 | + $starter_services = wpbc_appointment_services_get_starter_services_values( $provider_id, $booking_form_id ); | |
| 179 | + $now = current_time( 'mysql' ); | |
| 180 | + $current_user_id = get_current_user_id(); | |
| 181 | + $owner_user_id = function_exists( 'wpbc_appointment_services_get_owner_user_id' ) | |
| 144 | 182 | ? absint( wpbc_appointment_services_get_owner_user_id() ) |
| 145 | 183 | : 0; |
| 184 | + $created_service_ids = array(); | |
| 185 | + $assignment_inserted = true; | |
| 146 | 186 | |
| 147 | - $service_inserted = $wpdb->insert( | |
| 148 | - wpbc_appointment_services_table_name( 'services' ), | |
| 149 | - array( | |
| 150 | - 'owner_user_id' => $owner_user_id, | |
| 151 | - 'title' => $starter_service['title'], | |
| 152 | - 'description' => $starter_service['description'], | |
| 153 | - 'duration_minutes' => $starter_service['duration_minutes'], | |
| 154 | - 'buffer_before_minutes' => $starter_service['buffer_before_minutes'], | |
| 155 | - 'buffer_after_minutes' => $starter_service['buffer_after_minutes'], | |
| 156 | - 'base_cost' => $starter_service['base_cost'], | |
| 157 | - 'booking_form_id' => $starter_service['booking_form_id'], | |
| 158 | - 'status' => $starter_service['status'], | |
| 159 | - 'metadata' => false === $metadata ? '{}' : $metadata, | |
| 160 | - 'created_by' => $current_user_id, | |
| 161 | - 'modified_by' => $current_user_id, | |
| 162 | - 'creation_date' => $now, | |
| 163 | - 'modification_date' => $now, | |
| 164 | - ), | |
| 165 | - array( '%d', '%s', '%s', '%d', '%d', '%d', '%s', '%d', '%s', '%s', '%d', '%d', '%s', '%s' ) | |
| 166 | - ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery | |
| 167 | - $service_id = absint( $wpdb->insert_id ); | |
| 168 | - if ( false === $service_inserted || ! $service_id ) { | |
| 169 | - return false; | |
| 187 | + foreach ( $starter_services as $starter_service ) { | |
| 188 | + $metadata = wp_json_encode( $starter_service['metadata'] ); | |
| 189 | + $service_inserted = $wpdb->insert( | |
| 190 | + wpbc_appointment_services_table_name( 'services' ), | |
| 191 | + array( | |
| 192 | + 'owner_user_id' => $owner_user_id, | |
| 193 | + 'title' => $starter_service['title'], | |
| 194 | + 'description' => $starter_service['description'], | |
| 195 | + 'duration_minutes' => $starter_service['duration_minutes'], | |
| 196 | + 'buffer_before_minutes' => $starter_service['buffer_before_minutes'], | |
| 197 | + 'buffer_after_minutes' => $starter_service['buffer_after_minutes'], | |
| 198 | + 'base_cost' => $starter_service['base_cost'], | |
| 199 | + 'booking_form_id' => $starter_service['booking_form_id'], | |
| 200 | + 'status' => $starter_service['status'], | |
| 201 | + 'metadata' => false === $metadata ? '{}' : $metadata, | |
| 202 | + 'created_by' => $current_user_id, | |
| 203 | + 'modified_by' => $current_user_id, | |
| 204 | + 'creation_date' => $now, | |
| 205 | + 'modification_date' => $now, | |
| 206 | + ), | |
| 207 | + array( '%d', '%s', '%s', '%d', '%d', '%d', '%s', '%d', '%s', '%s', '%d', '%d', '%s', '%s' ) | |
| 208 | + ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery | |
| 209 | + $service_id = absint( $wpdb->insert_id ); | |
| 210 | + | |
| 211 | + if ( false === $service_inserted || ! $service_id ) { | |
| 212 | + break; | |
| 213 | + } | |
| 214 | + | |
| 215 | + $created_service_ids[] = $service_id; | |
| 216 | + $assignment_inserted = $wpdb->insert( | |
| 217 | + wpbc_appointment_services_table_name( 'service_resources' ), | |
| 218 | + array( | |
| 219 | + 'service_id' => $service_id, | |
| 220 | + 'resource_id' => $provider_id, | |
| 221 | + 'priority' => 0, | |
| 222 | + 'status' => 'active', | |
| 223 | + ), | |
| 224 | + array( '%d', '%d', '%d', '%s' ) | |
| 225 | + ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery | |
| 226 | + | |
| 227 | + if ( false === $assignment_inserted ) { | |
| 228 | + break; | |
| 229 | + } | |
| 170 | 230 | } |
| 171 | 231 | |
| 172 | - $assignment_inserted = $wpdb->insert( | |
| 173 | - wpbc_appointment_services_table_name( 'service_resources' ), | |
| 174 | - array( | |
| 175 | - 'service_id' => $service_id, | |
| 176 | - 'resource_id' => $provider_id, | |
| 177 | - 'priority' => 0, | |
| 178 | - 'status' => 'active', | |
| 179 | - ), | |
| 180 | - array( '%d', '%d', '%d', '%s' ) | |
| 181 | - ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery | |
| 182 | - if ( false === $assignment_inserted ) { | |
| 183 | - $wpdb->delete( | |
| 184 | - wpbc_appointment_services_table_name( 'services' ), | |
| 185 | - array( 'service_id' => $service_id ), | |
| 186 | - array( '%d' ) | |
| 187 | - ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery | |
| 232 | + if ( count( $created_service_ids ) !== count( $starter_services ) || false === $assignment_inserted ) { | |
| 233 | + foreach ( $created_service_ids as $created_service_id ) { | |
| 234 | + $wpdb->delete( | |
| 235 | + wpbc_appointment_services_table_name( 'service_resources' ), | |
| 236 | + array( 'service_id' => $created_service_id ), | |
| 237 | + array( '%d' ) | |
| 238 | + ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery | |
| 239 | + $wpdb->delete( | |
| 240 | + wpbc_appointment_services_table_name( 'services' ), | |
| 241 | + array( 'service_id' => $created_service_id ), | |
| 242 | + array( '%d' ) | |
| 243 | + ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery | |
| 244 | + } | |
| 245 | + | |
| 188 | 246 | return false; |
| 189 | 247 | } |
| 190 | 248 | |
| 191 | 249 | return true; |