Initial commit: WordPress wp-content (themes, plugins, languages)
- Theme: momentry (custom theme with REST API routes) - Plugins: code-snippets (contains all API proxies) - Languages: zh_TW translations - Excludes: cache, backups, uploads, logs
This commit is contained in:
@@ -0,0 +1,784 @@
|
||||
<?php
|
||||
|
||||
namespace Code_Snippets\REST_API;
|
||||
|
||||
use Code_Snippets\Export;
|
||||
use Code_Snippets\Snippet;
|
||||
use WP_Error;
|
||||
use WP_REST_Controller;
|
||||
use WP_REST_Request;
|
||||
use WP_REST_Response;
|
||||
use WP_REST_Server;
|
||||
use function Code_Snippets\activate_snippet;
|
||||
use function Code_Snippets\clean_active_snippets_cache;
|
||||
use function Code_Snippets\code_snippets;
|
||||
use function Code_Snippets\deactivate_snippet;
|
||||
use function Code_Snippets\trash_snippet;
|
||||
use function Code_Snippets\get_snippet;
|
||||
use function Code_Snippets\get_snippets;
|
||||
use function Code_Snippets\save_snippet;
|
||||
use const Code_Snippets\REST_API_NAMESPACE;
|
||||
|
||||
/**
|
||||
* Allows fetching snippet data through the WordPress REST API.
|
||||
*
|
||||
* @since 3.4.0
|
||||
* @package Code_Snippets
|
||||
*/
|
||||
final class Snippets_REST_Controller extends WP_REST_Controller {
|
||||
|
||||
/**
|
||||
* Current API version.
|
||||
*/
|
||||
public const VERSION = 1;
|
||||
|
||||
/**
|
||||
* The base of this controller's route.
|
||||
*/
|
||||
public const BASE_ROUTE = 'snippets';
|
||||
|
||||
/**
|
||||
* The namespace of this controller's route.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $namespace = REST_API_NAMESPACE . self::VERSION;
|
||||
|
||||
/**
|
||||
* The base of this controller's route.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $rest_base = self::BASE_ROUTE;
|
||||
|
||||
/**
|
||||
* Retrieve this controller's REST API base path, including namespace.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_base_route(): string {
|
||||
return REST_API_NAMESPACE . self::VERSION . '/' . self::BASE_ROUTE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the full base route including the REST API prefix.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_prefixed_base_route(): string {
|
||||
return '/' . rtrim( rest_get_url_prefix(), '/\\' ) . '/' . self::get_base_route();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register REST routes.
|
||||
*/
|
||||
public function register_routes() {
|
||||
$route = '/' . $this->rest_base;
|
||||
$id_route = $route . '/(?P<id>[\d]+)';
|
||||
|
||||
$network_args = array_intersect_key(
|
||||
$this->get_endpoint_args_for_item_schema(),
|
||||
[ 'network' ]
|
||||
);
|
||||
|
||||
// Allow standard collection parameters (page, per_page, etc.) on the collection route.
|
||||
$collection_args = array_merge( $network_args, $this->get_collection_params() );
|
||||
|
||||
register_rest_route(
|
||||
$this->namespace,
|
||||
$route,
|
||||
[
|
||||
[
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => [ $this, 'get_items' ],
|
||||
'permission_callback' => [ $this, 'get_items_permissions_check' ],
|
||||
'args' => $collection_args,
|
||||
],
|
||||
[
|
||||
'methods' => WP_REST_Server::CREATABLE,
|
||||
'callback' => [ $this, 'create_item' ],
|
||||
'permission_callback' => [ $this, 'create_item_permissions_check' ],
|
||||
'args' => $this->get_endpoint_args_for_item_schema( true ),
|
||||
],
|
||||
'schema' => [ $this, 'get_item_schema' ],
|
||||
]
|
||||
);
|
||||
|
||||
register_rest_route(
|
||||
$this->namespace,
|
||||
$id_route,
|
||||
[
|
||||
[
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => [ $this, 'get_item' ],
|
||||
'permission_callback' => [ $this, 'get_item_permissions_check' ],
|
||||
'args' => $network_args,
|
||||
],
|
||||
[
|
||||
'methods' => WP_REST_Server::EDITABLE,
|
||||
'callback' => [ $this, 'update_item' ],
|
||||
'permission_callback' => [ $this, 'update_item_permissions_check' ],
|
||||
'args' => $this->get_endpoint_args_for_item_schema( false ),
|
||||
],
|
||||
[
|
||||
'methods' => WP_REST_Server::DELETABLE,
|
||||
'callback' => [ $this, 'delete_item' ],
|
||||
'permission_callback' => [ $this, 'delete_item_permissions_check' ],
|
||||
'args' => $network_args,
|
||||
],
|
||||
'schema' => [ $this, 'get_item_schema' ],
|
||||
]
|
||||
);
|
||||
|
||||
register_rest_route(
|
||||
$this->namespace,
|
||||
$route . '/schema',
|
||||
[
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => [ $this, 'get_public_item_schema' ],
|
||||
'permission_callback' => '__return_true',
|
||||
]
|
||||
);
|
||||
|
||||
register_rest_route(
|
||||
$this->namespace,
|
||||
$id_route . '/activate',
|
||||
[
|
||||
'methods' => WP_REST_Server::EDITABLE,
|
||||
'callback' => [ $this, 'activate_item' ],
|
||||
'permission_callback' => [ $this, 'toggle_item_permissions_check' ],
|
||||
'schema' => [ $this, 'get_item_schema' ],
|
||||
'args' => $network_args,
|
||||
]
|
||||
);
|
||||
|
||||
register_rest_route(
|
||||
$this->namespace,
|
||||
$id_route . '/deactivate',
|
||||
[
|
||||
'methods' => WP_REST_Server::EDITABLE,
|
||||
'callback' => [ $this, 'deactivate_item' ],
|
||||
'permission_callback' => [ $this, 'toggle_item_permissions_check' ],
|
||||
'schema' => [ $this, 'get_item_schema' ],
|
||||
'args' => $network_args,
|
||||
]
|
||||
);
|
||||
|
||||
register_rest_route(
|
||||
$this->namespace,
|
||||
$id_route . '/export',
|
||||
[
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => [ $this, 'export_item' ],
|
||||
'permission_callback' => [ $this, 'get_item_permissions_check' ],
|
||||
'schema' => [ $this, 'get_item_schema' ],
|
||||
'args' => $network_args,
|
||||
]
|
||||
);
|
||||
|
||||
register_rest_route(
|
||||
$this->namespace,
|
||||
$id_route . '/export-code',
|
||||
[
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => [ $this, 'export_item_code' ],
|
||||
'permission_callback' => [ $this, 'get_item_permissions_check' ],
|
||||
'schema' => [ $this, 'get_item_schema' ],
|
||||
'args' => $network_args,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a collection of snippets, with pagination.
|
||||
*
|
||||
* @param WP_REST_Request $request Full details about the request.
|
||||
*
|
||||
* @return WP_REST_Response Response object on success.
|
||||
*/
|
||||
public function get_items( $request ): WP_REST_Response {
|
||||
$network = $request->get_param( 'network' );
|
||||
$all_snippets = get_snippets( [], $network );
|
||||
$all_snippets = $this->get_network_items( $all_snippets, $network );
|
||||
|
||||
$total_items = count( $all_snippets );
|
||||
$query_params = $request->get_query_params();
|
||||
|
||||
if ( isset( $query_params['per_page'] ) || isset( $query_params['page'] ) ) {
|
||||
$collection_params = $this->get_collection_params();
|
||||
$per_page = isset( $query_params['per_page'] )
|
||||
? max( 1, (int) $query_params['per_page'] )
|
||||
: (int) $collection_params['per_page']['default'];
|
||||
$page_request = (int) $request->get_param( 'page' );
|
||||
$page = max( 1, $page_request ? $page_request : (int) $collection_params['page']['default'] );
|
||||
$total_pages = (int) ceil( $total_items / $per_page );
|
||||
|
||||
$offset = ( $page - 1 ) * $per_page;
|
||||
$snippets = array_slice( $all_snippets, $offset, $per_page );
|
||||
} else {
|
||||
$snippets = $all_snippets;
|
||||
$total_pages = 1;
|
||||
}
|
||||
|
||||
$snippets_data = [];
|
||||
|
||||
foreach ( $snippets as $snippet ) {
|
||||
$snippet_data = $this->prepare_item_for_response( $snippet, $request );
|
||||
$snippets_data[] = $this->prepare_response_for_collection( $snippet_data );
|
||||
}
|
||||
|
||||
$response = rest_ensure_response( $snippets_data );
|
||||
$response->header( 'X-WP-Total', (string) $total_items );
|
||||
$response->header( 'X-WP-TotalPages', (string) $total_pages );
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve and merge shared network snippets.
|
||||
*
|
||||
* @param array<Snippet> $all_snippets List of snippets to merge with.
|
||||
* @param bool|null $network Whether fetching network snippets.
|
||||
*
|
||||
* @return array<Snippet> Modified list of snippets.
|
||||
*/
|
||||
private function get_network_items( array $all_snippets, $network ): array {
|
||||
if ( ! is_multisite() || $network ) {
|
||||
return $all_snippets;
|
||||
}
|
||||
|
||||
$shared_ids = get_site_option( 'shared_network_snippets' );
|
||||
|
||||
if ( ! $shared_ids || ! is_array( $shared_ids ) ) {
|
||||
return $all_snippets;
|
||||
}
|
||||
|
||||
$active_shared_snippets = get_option( 'active_shared_network_snippets', array() );
|
||||
$shared_snippets = get_snippets( $shared_ids, true );
|
||||
|
||||
foreach ( $shared_snippets as $snippet ) {
|
||||
$snippet->shared_network = true;
|
||||
$snippet->active = in_array( $snippet->id, $active_shared_snippets, true );
|
||||
}
|
||||
|
||||
return array_merge( $all_snippets, $shared_snippets );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves one item from the collection.
|
||||
*
|
||||
* @param WP_REST_Request $request Full details about the request.
|
||||
*
|
||||
* @return WP_REST_Response|WP_Error Response object on success.
|
||||
*/
|
||||
public function get_item( $request ) {
|
||||
$snippet_id = $request->get_param( 'id' );
|
||||
$item = get_snippet( $snippet_id, $request->get_param( 'network' ) );
|
||||
|
||||
if ( ! $item->id && 0 !== $snippet_id && '0' !== $snippet_id ) {
|
||||
return new WP_Error(
|
||||
'rest_cannot_get',
|
||||
__( 'The snippet could not be found.', 'code-snippets' ),
|
||||
[ 'status' => 500 ]
|
||||
);
|
||||
}
|
||||
|
||||
$data = $this->prepare_item_for_response( $item, $request );
|
||||
return rest_ensure_response( $data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Create one item from the collection
|
||||
*
|
||||
* @param WP_REST_Request|array $request Full data about the request.
|
||||
*
|
||||
* @return WP_REST_Response|WP_Error
|
||||
*/
|
||||
public function create_item( $request ) {
|
||||
$snippet = $this->prepare_item_for_database( $request );
|
||||
$result = $snippet ? save_snippet( $snippet ) : null;
|
||||
|
||||
return $result ?
|
||||
$this->prepare_item_for_response( $result, $request ) :
|
||||
new WP_Error(
|
||||
'rest_cannot_create',
|
||||
__( 'The snippet could not be created.', 'code-snippets' ),
|
||||
[ 'status' => 500 ]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update one item from the collection
|
||||
*
|
||||
* @param WP_REST_Request $request Full data about the request.
|
||||
*
|
||||
* @return WP_Error|WP_REST_Response
|
||||
*/
|
||||
public function update_item( $request ) {
|
||||
$snippet_id = absint( $request->get_param( 'id' ) );
|
||||
$snippet = $snippet_id ? get_snippet( $snippet_id, $request->get_param( 'network' ) ) : null;
|
||||
|
||||
if ( ! $snippet_id || ! $snippet || ! $snippet->id ) {
|
||||
return new WP_Error(
|
||||
'rest_cannot_update',
|
||||
__( 'Cannot update a snippet without a valid ID.', 'code-snippets' ),
|
||||
[ 'status' => 400 ]
|
||||
);
|
||||
}
|
||||
|
||||
$item = $this->prepare_item_for_database( $request, $snippet );
|
||||
$result = save_snippet( $item );
|
||||
|
||||
if ( $result ) {
|
||||
$request->set_param( 'id', $result->id );
|
||||
return $this->get_item( $request );
|
||||
}
|
||||
|
||||
return new WP_Error(
|
||||
'rest_cannot_update',
|
||||
__( 'The snippet could not be updated.', 'code-snippets' ),
|
||||
[ 'status' => 500 ]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete one item from the collection (trash)
|
||||
*
|
||||
* @param WP_REST_Request $request Full data about the request.
|
||||
*
|
||||
* @return WP_Error|WP_REST_Response
|
||||
*/
|
||||
public function delete_item( $request ) {
|
||||
$item = $this->prepare_item_for_database( $request );
|
||||
$result = trash_snippet( $item->id, $item->network );
|
||||
|
||||
return $result ?
|
||||
new WP_REST_Response( null, 204 ) :
|
||||
new WP_Error(
|
||||
'rest_cannot_delete',
|
||||
__( 'The snippet could not be deleted.', 'code-snippets' ),
|
||||
[ 'status' => 500 ]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate one item in the collection.
|
||||
*
|
||||
* @param WP_REST_Request $request Full data about the request.
|
||||
*
|
||||
* @return WP_Error|WP_REST_Response
|
||||
*/
|
||||
public function activate_item( WP_REST_Request $request ) {
|
||||
$item = $this->prepare_item_for_database( $request );
|
||||
$snippet = $item ? get_snippet( $item->id, $item->network ) : null;
|
||||
|
||||
if ( ! $snippet || ! $snippet->id ) {
|
||||
return new WP_Error(
|
||||
'rest_cannot_activate',
|
||||
__( 'The snippet could not be found.', 'code-snippets' ),
|
||||
[ 'status' => 404 ]
|
||||
);
|
||||
}
|
||||
|
||||
if ( $snippet->shared_network ) {
|
||||
$this->set_shared_network_active( $snippet->id, true );
|
||||
$snippet->active = true;
|
||||
return rest_ensure_response( $snippet );
|
||||
}
|
||||
|
||||
$result = activate_snippet( $snippet->id, $snippet->network );
|
||||
|
||||
return $result instanceof Snippet ?
|
||||
rest_ensure_response( $result ) :
|
||||
new WP_Error(
|
||||
'rest_cannot_activate',
|
||||
$result,
|
||||
[ 'status' => 500 ]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate one item in the collection.
|
||||
*
|
||||
* @param WP_REST_Request $request Full data about the request.
|
||||
*
|
||||
* @return WP_Error|WP_REST_Response
|
||||
*/
|
||||
public function deactivate_item( WP_REST_Request $request ) {
|
||||
$item = $this->prepare_item_for_database( $request );
|
||||
$snippet = $item ? get_snippet( $item->id, $item->network ) : null;
|
||||
|
||||
if ( ! $snippet || ! $snippet->id ) {
|
||||
return new WP_Error(
|
||||
'rest_cannot_activate',
|
||||
__( 'The snippet could not be found.', 'code-snippets' ),
|
||||
[ 'status' => 404 ]
|
||||
);
|
||||
}
|
||||
|
||||
if ( $snippet->shared_network ) {
|
||||
$this->set_shared_network_active( $snippet->id, false );
|
||||
$snippet->active = false;
|
||||
return rest_ensure_response( $snippet );
|
||||
}
|
||||
|
||||
$result = deactivate_snippet( $snippet->id, $snippet->network );
|
||||
|
||||
return $result instanceof Snippet ?
|
||||
rest_ensure_response( $result ) :
|
||||
new WP_Error(
|
||||
'rest_cannot_activate',
|
||||
__( 'The snippet could not be deactivated.', 'code-snippets' ),
|
||||
[ 'status' => 500 ]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle a shared network snippet's active state for the current site only.
|
||||
*
|
||||
* @param int $snippet_id Snippet identifier.
|
||||
* @param bool $active Whether the snippet should be active on the current site.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function set_shared_network_active( int $snippet_id, bool $active ): void {
|
||||
$active_shared_snippets = get_option( 'active_shared_network_snippets', [] );
|
||||
|
||||
if ( ! is_array( $active_shared_snippets ) ) {
|
||||
$active_shared_snippets = [];
|
||||
}
|
||||
|
||||
$already_active = in_array( $snippet_id, $active_shared_snippets, true );
|
||||
|
||||
if ( $active === $already_active ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$active_shared_snippets = $active ?
|
||||
array_merge( $active_shared_snippets, [ $snippet_id ] ) :
|
||||
array_values( array_diff( $active_shared_snippets, [ $snippet_id ] ) );
|
||||
|
||||
update_option( 'active_shared_network_snippets', $active_shared_snippets );
|
||||
clean_active_snippets_cache( code_snippets()->db->ms_table );
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare an instance of the Export class from a request.
|
||||
*
|
||||
* @param WP_REST_Request $request Full data about the request.
|
||||
*
|
||||
* @return Export
|
||||
*/
|
||||
protected function build_export( WP_REST_Request $request ): Export {
|
||||
$item = $this->prepare_item_for_database( $request );
|
||||
return new Export( [ $item->id ], $item->network );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve one item in the collection in JSON export format.
|
||||
*
|
||||
* @param WP_REST_Request $request Full data about the request.
|
||||
*
|
||||
* @return WP_Error|WP_REST_Response
|
||||
*/
|
||||
public function export_item( WP_REST_Request $request ) {
|
||||
$export = $this->build_export( $request );
|
||||
$result = $export->create_export_object();
|
||||
return rest_ensure_response( $result );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve one item in the collection in the code export format.
|
||||
*
|
||||
* @param WP_REST_Request $request Full data about the request.
|
||||
*
|
||||
* @return WP_Error|WP_REST_Response
|
||||
*/
|
||||
public function export_item_code( WP_REST_Request $request ) {
|
||||
$export = $this->build_export( $request );
|
||||
$result = $export->export_snippets_code();
|
||||
|
||||
return rest_ensure_response( $result );
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares one item for create or update operation.
|
||||
*
|
||||
* @param WP_REST_Request $request Request object.
|
||||
* @param Snippet|null $item Existing item to augment.
|
||||
*
|
||||
* @return Snippet The prepared item.
|
||||
*/
|
||||
protected function prepare_item_for_database( $request, ?Snippet $item = null ): ?Snippet {
|
||||
if ( ! $item instanceof Snippet ) {
|
||||
$item = new Snippet();
|
||||
}
|
||||
|
||||
foreach ( $item->get_allowed_fields() as $field ) {
|
||||
if ( isset( $request[ $field ] ) ) {
|
||||
$item->set_field( $field, $request[ $field ] );
|
||||
}
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the item for the REST response.
|
||||
*
|
||||
* @param Snippet $item Snippet object.
|
||||
* @param WP_REST_Request $request Request object.
|
||||
*
|
||||
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
|
||||
*/
|
||||
public function prepare_item_for_response( $item, $request ) {
|
||||
$schema = $this->get_item_schema();
|
||||
$response = [];
|
||||
|
||||
foreach ( array_keys( $schema['properties'] ) as $property ) {
|
||||
$response[ $property ] = $item->$property;
|
||||
}
|
||||
|
||||
return rest_ensure_response( $response );
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether a request targets network-scoped snippets.
|
||||
*
|
||||
* Only the literal boolean `true` (or its common string/integer equivalents)
|
||||
* is treated as a network-scoped request. A missing or null `network` param
|
||||
* means "site-scoped", and must not be escalated to the network capability.
|
||||
*
|
||||
* @param WP_REST_Request $request Full data about the request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_network_scoped_request( $request ): bool {
|
||||
if ( ! is_multisite() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! $request instanceof WP_REST_Request || ! $request->has_param( 'network' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$network = $request->get_param( 'network' );
|
||||
|
||||
if ( is_bool( $network ) ) {
|
||||
return $network;
|
||||
}
|
||||
|
||||
if ( is_string( $network ) ) {
|
||||
return in_array( strtolower( $network ), [ '1', 'true', 'yes' ], true );
|
||||
}
|
||||
|
||||
return (bool) $network;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the current user has permission for the scope implied by the request.
|
||||
*
|
||||
* @param WP_REST_Request $request Full data about the request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function check_request_capability( $request ): bool {
|
||||
if ( $this->is_network_scoped_request( $request ) ) {
|
||||
return code_snippets()->user_can_manage_network_snippets();
|
||||
}
|
||||
|
||||
return code_snippets()->current_user_can();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the request targets a shared network snippet.
|
||||
*
|
||||
* Shared network snippets are stored network-wide but each site decides whether
|
||||
* to activate them via the per-site `active_shared_network_snippets` option. The
|
||||
* `id` route parameter is used to look up the snippet so the result reflects the
|
||||
* actual stored row rather than a value supplied in the request payload.
|
||||
*
|
||||
* @param WP_REST_Request $request Full data about the request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_shared_network_snippet_request( $request ): bool {
|
||||
if ( ! is_multisite() || ! $request instanceof WP_REST_Request ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$snippet_id = absint( $request->get_param( 'id' ) );
|
||||
|
||||
if ( ! $snippet_id ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$snippet = get_snippet( $snippet_id, true );
|
||||
|
||||
return $snippet && $snippet->id && $snippet->shared_network;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given request has access to get items.
|
||||
*
|
||||
* @param WP_REST_Request $request Full data about the request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function get_items_permissions_check( $request ): bool {
|
||||
return $this->check_request_capability( $request );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given request has access to get a specific item.
|
||||
*
|
||||
* Shared network snippets are readable by any user who can manage snippets on
|
||||
* the current site, since the snippet is intentionally exposed to subsites.
|
||||
*
|
||||
* @param WP_REST_Request $request Full data about the request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function get_item_permissions_check( $request ): bool {
|
||||
if ( $this->is_shared_network_snippet_request( $request ) ) {
|
||||
return code_snippets()->current_user_can();
|
||||
}
|
||||
|
||||
return $this->check_request_capability( $request );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given request has access to create items.
|
||||
*
|
||||
* @param WP_REST_Request $request Full data about the request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function create_item_permissions_check( $request ): bool {
|
||||
return $this->check_request_capability( $request );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given request has access to update a specific item.
|
||||
*
|
||||
* @param WP_REST_Request $request Full data about the request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function update_item_permissions_check( $request ): bool {
|
||||
return $this->check_request_capability( $request );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given request has access to delete a specific item.
|
||||
*
|
||||
* @param WP_REST_Request $request Full data about the request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function delete_item_permissions_check( $request ): bool {
|
||||
return $this->check_request_capability( $request );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given request has access to toggle a snippet's activation.
|
||||
*
|
||||
* For shared network snippets the activation toggle only writes to the
|
||||
* per-site `active_shared_network_snippets` option, so the site capability
|
||||
* is sufficient. For all other snippets we keep the strict capability check
|
||||
* that prevents a subsite admin from forging `network=true` to operate on
|
||||
* exclusive network-scoped snippets.
|
||||
*
|
||||
* @param WP_REST_Request $request Full data about the request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function toggle_item_permissions_check( $request ): bool {
|
||||
if ( $this->is_shared_network_snippet_request( $request ) ) {
|
||||
return code_snippets()->current_user_can();
|
||||
}
|
||||
|
||||
return $this->check_request_capability( $request );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get our sample schema for a post.
|
||||
*
|
||||
* @return array<string, mixed> The sample schema for a post
|
||||
*/
|
||||
public function get_item_schema(): array {
|
||||
if ( $this->schema ) {
|
||||
return $this->schema;
|
||||
}
|
||||
|
||||
$this->schema = [
|
||||
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
||||
'title' => 'snippet',
|
||||
'type' => 'object',
|
||||
'properties' => [
|
||||
'id' => [
|
||||
'description' => esc_html__( 'Unique identifier for the snippet.', 'code-snippets' ),
|
||||
'type' => 'integer',
|
||||
'readonly' => true,
|
||||
],
|
||||
'name' => [
|
||||
'description' => esc_html__( 'Descriptive title for the snippet.', 'code-snippets' ),
|
||||
'type' => 'string',
|
||||
],
|
||||
'desc' => [
|
||||
'description' => esc_html__( 'Descriptive text associated with snippet.', 'code-snippets' ),
|
||||
'type' => 'string',
|
||||
],
|
||||
'code' => [
|
||||
'description' => esc_html__( 'Executable snippet code.', 'code-snippets' ),
|
||||
'type' => 'string',
|
||||
],
|
||||
'tags' => [
|
||||
'description' => esc_html__( 'List of tag categories the snippet belongs to.', 'code-snippets' ),
|
||||
'type' => 'array',
|
||||
'items' => [
|
||||
'type' => 'string',
|
||||
],
|
||||
],
|
||||
'scope' => [
|
||||
'description' => esc_html__( 'Context in which the snippet is executable.', 'code-snippets' ),
|
||||
'type' => 'string',
|
||||
],
|
||||
'condition_id' => [
|
||||
'description' => esc_html__( 'Identifier of condition linked to this snippet.', 'code-snippets' ),
|
||||
'type' => 'integer',
|
||||
],
|
||||
'active' => [
|
||||
'description' => esc_html__( 'Snippet activation status.', 'code-snippets' ),
|
||||
'type' => 'boolean',
|
||||
],
|
||||
'priority' => [
|
||||
'description' => esc_html__( 'Relative priority in which the snippet is executed.', 'code-snippets' ),
|
||||
'type' => 'integer',
|
||||
],
|
||||
'network' => [
|
||||
'description' => esc_html__( 'Whether the snippet is network-wide instead of site-wide.', 'code-snippets' ),
|
||||
'type' => [ 'boolean', 'null' ],
|
||||
'default' => null,
|
||||
],
|
||||
'shared_network' => [
|
||||
'description' => esc_html__( 'If a network snippet, whether can be activated on discrete sites instead of network-wide.', 'code-snippets' ),
|
||||
'type' => [ 'boolean', 'null' ],
|
||||
],
|
||||
'modified' => [
|
||||
'description' => esc_html__( 'Date and time when the snippet was last modified, in ISO format.', 'code-snippets' ),
|
||||
'type' => 'string',
|
||||
'format' => 'date-time',
|
||||
'readonly' => true,
|
||||
],
|
||||
'code_error' => [
|
||||
'description' => esc_html__( 'Error message if the snippet code could not be parsed.', 'code-snippets' ),
|
||||
'type' => 'string',
|
||||
'readonly' => true,
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
return $this->schema;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user