account_id(); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only local pagination, strictly bounded in the L3 adapter. $page = isset( $_GET['service_page'] ) && is_scalar( $_GET['service_page'] ) ? absint( $_GET['service_page'] ) : 1; $catalog = $api->catalog( $account_id, max( 1, $page ), 20 ); echo '
'; return; } $this->form( 'services', array_replace( Attributes::defaults( 'services' ), array_intersect_key( DisplayDefaults::values(), Attributes::defaults( 'services' ) ) ), $account_id, __( 'Service catalog', 'waitlistize' ) ); foreach ( $catalog['data'] as $service ) { $attributes = array_replace( Attributes::defaults( 'booking' ), array_intersect_key( DisplayDefaults::values(), Attributes::defaults( 'booking' ) ) ); $attributes['serviceId'] = $service['id']; $this->form( 'booking', $attributes, $account_id, $service['name'], $service ); } if ( ! $catalog['data'] ) { echo '' . esc_html__( 'No services to display.', 'waitlistize' ) . '
'; } for ( $direction = -1; $direction <= 1; $direction += 2 ) { $target = $page + $direction; if ( $target >= 1 && $target <= $catalog['meta']['last_page'] ) { echo '' . esc_html( $direction < 0 ? __( 'Previous', 'waitlistize' ) : __( 'Next', 'waitlistize' ) ) . ' '; } } $this->placements(); echo ''; } private function form( string $kind, array $attributes, int $account_id, string $title, array $service = array() ): void { $attributes['connectionAccountId'] = $account_id; $this->initial = $attributes; echo ''; } private function select( string $name, string $label, array $options ): void { echo ''; } /** Service IDs/attributes remain assertions; request scope is always the token account. */ public function create_draft( array $input ): int|WP_Error { if ( ! current_user_can( 'manage_options' ) || ! current_user_can( 'edit_pages' ) ) { return Services::error( 'rest_forbidden', 403 ); } $kind = $input['kind'] ?? ''; unset( $input['kind'] ); if ( ! in_array( $kind, array( 'booking', 'services' ), true ) ) { return Services::error( 'embed_parameters', 400 ); } $parsed = Attributes::shortcode( $input ); if ( is_wp_error( $parsed ) || $kind !== $parsed['kind'] ) { return Services::error( 'embed_parameters', 400 ); } $attributes = $parsed['attributes']; $api = new Services(); if ( ! $attributes['connectionAccountId'] || $api->account_id() !== $attributes['connectionAccountId'] ) { return Services::error( 'embed_binding', 409 ); } $title = __( 'Waitlistize services', 'waitlistize' ); if ( 'booking' === $kind ) { $service = $api->detail( $attributes['connectionAccountId'], $attributes['serviceId'], $attributes['locale'] ); if ( is_wp_error( $service ) ) { return $service; } $title = wp_strip_all_tags( $service['name'] ); } return wp_insert_post( wp_slash( array( 'post_type' => 'page', 'post_status' => 'draft', 'post_title' => $title, 'post_content' => serialize_block( array( 'blockName' => 'waitlistize/' . $kind, 'attrs' => $attributes, 'innerBlocks' => array(), 'innerHTML' => '', 'innerContent' => array(), ) ), ) ), true ); } public function draft(): void { if ( ! current_user_can( 'manage_options' ) || ! current_user_can( 'edit_pages' ) ) { wp_die( esc_html__( 'Administrator permission is required.', 'waitlistize' ), '', array( 'response' => 403 ) ); } check_admin_referer( 'waitlistize_embed_draft', '_waitlistize_nonce' ); $input = wp_unslash( $_POST ); unset( $input['action'], $input['_waitlistize_nonce'], $input['_wp_http_referer'] ); $id = $this->create_draft( $input ); if ( is_wp_error( $id ) ) { wp_die( esc_html( $id->get_error_message() ), '', array( 'response' => 400 ) ); } wp_safe_redirect( get_edit_post_link( $id, 'raw' ) ); exit; } private function placements(): void { echo '' . esc_html__( 'This limited search checks up to 200 stored posts and pages containing Waitlistize markup. Reusable blocks, templates, widgets, custom fields and other indirect embeds may be missing. This is not a complete inventory.', 'waitlistize' ) . '
'; // phpcs:disable WordPress.WP.PostsPerPage -- Bounded, explicitly limited local placement inventory. $query = new \WP_Query( array( 'post_type' => array( 'post', 'page' ), 'post_status' => array( 'publish', 'draft', 'private', 'pending', 'future' ), 's' => 'waitlistize', 'posts_per_page' => 200, 'no_found_rows' => true, ) ); // phpcs:enable WordPress.WP.PostsPerPage echo '