'accessible_form', 'post_status' => array( 'publish', 'draft', 'pending', 'private', 'future' ), 'posts_per_page' => 20, 'paged' => max( 1, (int) $page ), 's' => wp_html_excerpt( sanitize_text_field( $search ), 200, '' ), // A name fragment is literal; WordPress otherwise drops single-letter terms. 'sentence' => true, 'search_columns' => array( 'post_title' ), 'orderby' => array( 'title' => 'ASC', 'ID' => 'ASC' ), ) ); $items = array(); foreach ( $query->posts as $post ) { if ( 'entries' === $mode ? Capabilities::form( $post->ID ) : current_user_can( 'edit_post', $post->ID ) ) { $items[] = array( 'id' => (int) $post->ID, 'label' => ( $post->post_title ?: __( '(no title)', 'accessible-forms-by-accessible-org' ) ) . ' (#' . $post->ID . ')' ); } } return array( 'items' => $items, 'pages' => (int) $query->max_num_pages ); } public static function admin_search() { check_ajax_referer( 'accessible_forms_admin_forms', 'nonce' ); $mode = 'entries' === sanitize_key( wp_unslash( $_POST['mode'] ?? '' ) ) ? 'entries' : 'edit'; if ( ! current_user_can( 'entries' === $mode ? 'read_accessible_form_entries' : 'edit_accessible_forms' ) ) { wp_send_json_error( array( 'message' => __( 'You cannot browse these forms.', 'accessible-forms-by-accessible-org' ) ), 403 ); } wp_send_json_success( self::admin_options( sanitize_text_field( wp_unslash( $_POST['search'] ?? '' ) ), absint( $_POST['page'] ?? 1 ), $mode ) ); } public static function register() { $permission = array( self::class, 'can_use_editor' ); register_rest_route( 'accessible-forms/v1', '/forms', array( 'methods' => 'GET', 'callback' => array( self::class, 'search' ), 'permission_callback' => $permission, 'args' => array( 'search' => array( 'type' => 'string', 'default' => '', 'sanitize_callback' => 'sanitize_text_field', ), 'page' => array( 'type' => 'integer', 'default' => 1, 'minimum' => 1, ), ), ) ); foreach ( array( '' => 'item', '/preview' => 'preview', ) as $suffix => $callback ) { register_rest_route( 'accessible-forms/v1', '/forms/by-key/(?Paf_[a-f0-9]{16})' . $suffix, array( 'methods' => 'GET', 'callback' => array( self::class, $callback ), 'permission_callback' => $permission, 'args' => array( 'key' => array( 'type' => 'string' ) ), ) ); register_rest_route( 'accessible-forms/v1', '/forms/(?P\d+)' . $suffix, array( 'methods' => 'GET', 'callback' => array( self::class, $callback ), 'permission_callback' => $permission, 'args' => array( 'id' => array( 'type' => 'integer', 'minimum' => 1, ), ), ) ); } } public static function can_use_editor() { return current_user_can( 'edit_posts' ) || current_user_can( 'edit_pages' ) || (bool) ContentTypes::types( true ); } private static function describe( $post ) { return array( 'id' => (int) $post->ID, 'key' => FormKey::get( $post->ID ), 'title' => $post->post_title ?: __( 'Untitled form', 'accessible-forms-by-accessible-org' ), 'edit_url' => current_user_can( 'edit_post', $post->ID ) ? get_edit_post_link( $post->ID, 'raw' ) : '', ); } private static function response( $data ) { $response = new \WP_REST_Response( $data ); $response->header( 'Cache-Control', 'no-store' ); return $response; } public static function search( $request ) { $query = new \WP_Query( array( 'post_type' => 'accessible_form', 'post_status' => 'publish', 'posts_per_page' => 20, 'paged' => $request['page'], 's' => $request['search'], 'orderby' => array( 'title' => 'ASC', 'ID' => 'ASC', ), ) ); return self::response( array( 'items' => array_map( array( self::class, 'describe' ), $query->posts ), 'total' => (int) $query->found_posts, 'pages' => (int) $query->max_num_pages, ) ); } private static function published( $id ) { $post = get_post( (int) $id ); return $post && 'accessible_form' === $post->post_type && 'publish' === $post->post_status ? $post : null; } public static function item( $request ) { $post = self::published( FormKey::resolve( $request['id'] ?? 0, $request['key'] ?? '' ) ); return $post ? self::response( self::describe( $post ) ) : new \WP_Error( 'accessible_forms_unavailable', __( 'This form is unavailable. Choose a published form.', 'accessible-forms-by-accessible-org' ), array( 'status' => 404 ) ); } public static function preview( $request ) { $post = self::published( FormKey::resolve( $request['id'] ?? 0, $request['key'] ?? '' ) ); if ( ! $post ) { return new \WP_Error( 'accessible_forms_unavailable', __( 'This form is unavailable. Choose a published form.', 'accessible-forms-by-accessible-org' ), array( 'status' => 404 ) ); } // A preview never submits, exposes recipients, or loads an external spam widget. // A page editor previews the same published version visitors receive. // Unpublished changes belong in the form builder's own preview. $schema = Schema::get( $post->ID ); return self::response( array( 'html' => Renderer::render( $post->ID, array(), true, $schema ) ) ); } }