[1-9][0-9]*)/items', array( 'methods' => 'GET', 'permission_callback' => array( self::class, 'context_permission' ), 'callback' => array( self::class, 'items' ), 'args' => array( 'page' => array( 'type' => 'integer', 'minimum' => 1, 'maximum' => 100000, 'default' => 1, ), 'per_page' => array( 'type' => 'integer', 'minimum' => 1, 'maximum' => 100, 'default' => 50, ), 'search' => array( 'type' => 'string', 'maxLength' => 200, 'default' => '', ), ), ) ); foreach ( array( 'move', 'undo', 'scope', 'reset' ) as $action ) { $args = array( 'revision' => array( 'type' => 'integer', 'minimum' => 0, 'required' => true, ), 'operation' => array( 'type' => 'string', 'format' => 'uuid', 'required' => true, ), ); if ( 'move' === $action ) { $args['object_id'] = array( 'type' => 'integer', 'minimum' => 1, 'required' => true, ); $args['position'] = array( 'type' => 'string', 'enum' => array( 'first', 'last', 'before', 'after' ), 'required' => true, ); $args['target_id'] = array( 'type' => 'integer', 'minimum' => 0, 'default' => 0, ); } if ( 'scope' === $action ) { $args['scope'] = array( 'type' => 'string', 'enum' => array( 'backend', 'block', 'archive' ), 'required' => true, ); } register_rest_route( 'threepo/v1', '/contexts/(?P[1-9][0-9]*)/' . $action, array( 'methods' => 'POST', 'permission_callback' => array( self::class, 'context_permission' ), 'callback' => array( self::class, 'mutate' ), 'args' => $args, ) ); } } /** * @return bool|\WP_Error */ public static function logged() { return is_user_logged_in() ? true : Store::error( 'login', __( 'Please sign in.', '3task-post-order' ), 401 ); } public static function register(): void { self::ordering_routes(); register_rest_route( 'threepo/v1', '/contexts/(?P[1-9][0-9]*)', array( 'methods' => 'DELETE', 'permission_callback' => static function () { return current_user_can( 'manage_options' ) ? true : Store::error( 'forbidden', __( 'Administrator access is required.', '3task-post-order' ), rest_authorization_required_code() ); }, 'callback' => static function ( WP_REST_Request $r ) { return Store::delete( (int) $r['id'] ); }, ) ); register_rest_route( 'threepo/v1', '/contexts', array( array( 'methods' => 'GET', 'permission_callback' => array( self::class, 'logged' ), 'callback' => static function () { return Store::contexts(); }, ), array( 'methods' => 'POST', 'permission_callback' => static function () { return current_user_can( 'manage_options' ) ? true : Store::error( 'forbidden', __( 'Administrator access is required.', '3task-post-order' ), rest_authorization_required_code() ); }, 'callback' => array( self::class, 'create' ), 'args' => array( 'kind' => array( 'type' => 'string', 'enum' => array( 'post', 'term' ), 'required' => true, ), 'object_type' => array( 'type' => 'string', 'pattern' => '^[a-z0-9_-]{1,32}$', 'required' => true, ), 'taxonomy' => array( 'type' => 'string', 'pattern' => '^[a-z0-9_-]{0,32}$', 'default' => '', ), 'term_id' => array( 'type' => 'integer', 'minimum' => 0, 'default' => 0, ), 'parent_id' => array( 'type' => 'integer', 'minimum' => 0, 'default' => 0, ), 'label' => array( 'type' => 'string', 'minLength' => 1, 'maxLength' => 120, 'required' => true, ), ), ), ) ); } /** * @return bool|\WP_Error */ public static function context_permission( WP_REST_Request $r ) { if ( ! is_user_logged_in() ) { return self::logged(); } $c = Store::get( (int) $r['id'] ); return $c && Store::allowed( $c ) ? true : Store::error( 'forbidden', __( 'This ordering context is unavailable.', '3task-post-order' ), 403 ); } /** * @return array */ public static function items( WP_REST_Request $r ) { return Order::items( Store::get( (int) $r['id'] ), (int) $r['page'], (int) $r['per_page'], (string) $r['search'] ); } /** * @return array|\WP_Error */ public static function mutate( WP_REST_Request $r ) { $action = strtolower( basename( $r->get_route() ) ); $keys = array( 'revision', 'operation' ); if ( 'move' === $action ) { $keys = array_merge( $keys, array( 'object_id', 'position', 'target_id' ) ); } if ( 'scope' === $action ) { $keys[] = 'scope'; } $body = self::body( $r, $keys ); if ( is_wp_error( $body ) ) { return $body; } $data = array(); foreach ( $keys as $key ) { $data[ $key ] = $r[ $key ]; } return Order::mutate( (int) $r['id'], $action, $data ); } /** * @param list $allowed Validated values. * @return array|\WP_Error */ public static function body( WP_REST_Request $request, array $allowed ) { if ( strlen( (string) $request->get_body() ) > 65536 ) { return Store::error( 'size', __( 'The request is too large.', '3task-post-order' ), 413 ); } $body = json_decode( (string) $request->get_body(), true, 32 ); if ( ! is_array( $body ) || array_diff( array_keys( $body ), $allowed ) ) { return Store::error( 'fields', __( 'The request contains unsupported fields.', '3task-post-order' ) ); } return $body; } /** * @return \WP_REST_Response|\WP_Error */ public static function create( WP_REST_Request $request ) { $body = self::body( $request, array( 'kind', 'object_type', 'taxonomy', 'term_id', 'parent_id', 'label' ) ); if ( is_wp_error( $body ) ) { return $body; } $data = array(); foreach ( array( 'kind', 'object_type', 'taxonomy', 'term_id', 'parent_id', 'label' ) as $key ) { $data[ $key ] = $request[ $key ]; } $data['label'] = sanitize_text_field( $data['label'] ); $result = Store::create( $data ); return is_wp_error( $result ) ? $result : new WP_REST_Response( $result, 201 ); } }