Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Font Library: Improve font collection rest controller #58222

Merged
merged 19 commits into from
Jan 26, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 16 additions & 28 deletions lib/experimental/fonts/font-library/class-wp-font-collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class WP_Font_Collection {
*
* @var string
*/
private $slug;
public $slug;

/**
* The name of the font collection.
Expand All @@ -36,7 +36,7 @@ class WP_Font_Collection {
*
* @var string
*/
private $name;
public $name;

/**
* Description of the font collection.
Expand All @@ -45,7 +45,7 @@ class WP_Font_Collection {
*
* @var string
*/
private $description;
public $description;

/**
* Source of the font collection.
Expand All @@ -54,7 +54,7 @@ class WP_Font_Collection {
*
* @var string
*/
private $src;
public $src;

/**
* Array of font families in the collection.
Expand All @@ -63,7 +63,7 @@ class WP_Font_Collection {
*
* @var array
*/
private $font_families;
public $font_families;

/**
* Categories associated with the font collection.
Expand All @@ -72,7 +72,7 @@ class WP_Font_Collection {
*
* @var array
*/
private $categories;
public $categories;


/**
Expand Down Expand Up @@ -138,34 +138,22 @@ public static function is_config_valid( $config ) {
( empty( $config['src'] ) && empty( $config['font_families'] ) ) ||
( ! empty( $config['src'] ) && ! empty( $config['font_families'] ) )
) {
_doing_it_wrong( __METHOD__, __( 'Font Collection config "src" option OR "font_families" option are required.', 'gutenberg' ), '6.5.0' );
_doing_it_wrong(
__METHOD__,
sprintf(
/* translators: %1$s: src, %2$s: font_families */
__( 'Font Collection config "%1$s" option OR "%2$s" option are required.', 'gutenberg' ),
matiasbenedetto marked this conversation as resolved.
Show resolved Hide resolved
'src',
'font_families'
),
'6.5.0'
);
return false;
}

return true;
}

/**
* Gets the font collection config.
*
* @since 6.5.0
*
* @return array {
* An array of font collection config.
*
* @type string $slug The font collection's unique slug.
* @type string $name The font collection's name.
* @type string $description The font collection's description.
* }
*/
public function get_config() {
return array(
'slug' => $this->slug,
'name' => $this->name,
'description' => $this->description,
);
}

/**
* Gets the font collection content.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public static function register_font_collection( $config ) {

$new_collection = new WP_Font_Collection( $config );

if ( self::is_collection_registered( $new_collection->get_config()['slug'] ) ) {
if ( self::is_collection_registered( $new_collection->slug ) ) {
$error_message = sprintf(
/* translators: %s: Font collection slug. */
__( 'Font collection with slug: "%s" is already registered.', 'gutenberg' ),
Expand All @@ -82,7 +82,7 @@ public static function register_font_collection( $config ) {
);
return new WP_Error( 'font_collection_registration_error', $error_message );
}
self::$collections[ $new_collection->get_config()['slug'] ] = $new_collection;
self::$collections[ $new_collection->slug ] = $new_collection;
return $new_collection;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ public function register_routes() {
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_items' ),
'permission_callback' => array( $this, 'get_items_permissions_check' ),
'args' => $this->get_collection_params(),
),
'schema' => array( $this, 'get_public_item_schema' ),
)
);

Expand All @@ -57,6 +59,7 @@ public function register_routes() {
'callback' => array( $this, 'get_item' ),
'permission_callback' => array( $this, 'get_items_permissions_check' ),
),
creativecoder marked this conversation as resolved.
Show resolved Hide resolved
'schema' => array( $this, 'get_public_item_schema' ),
)
);
}
Expand All @@ -68,13 +71,61 @@ public function register_routes() {
*
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
*/
public function get_items( $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
$collections = array();
foreach ( WP_Font_Library::get_font_collections() as $collection ) {
$collections[] = $collection->get_config();
public function get_items( $request ) {
$collections_all = WP_Font_Library::get_font_collections();

$page = $request['page'];
$per_page = $request['per_page'];
$total_items = count( $collections_all );
$max_pages = ceil( $total_items / $per_page );

if ( $page > $max_pages && $total_items > 0 ) {
return new WP_Error(
'rest_post_invalid_page_number',
__( 'The page number requested is larger than the number of pages available.', 'gutenberg' ),
matiasbenedetto marked this conversation as resolved.
Show resolved Hide resolved
array( 'status' => 400 )
);
}

$collections_page = array_slice( $collections_all, ( $page - 1 ) * $per_page, $per_page );

$items = array();
foreach ( $collections_page as $collection ) {
$item = $this->prepare_item_for_response( $collection, $request );
if ( is_wp_error( $item ) ) {
return $item;
}
$item = $this->prepare_response_for_collection( $item );
$items[] = $item;
}

$response = rest_ensure_response( $items );

$response->header( 'X-WP-Total', (int) $total_items );
$response->header( 'X-WP-TotalPages', (int) $max_pages );

$request_params = $request->get_query_params();
$collection_url = rest_url( $this->namespace . '/' . $this->rest_base );
$base = add_query_arg( urlencode_deep( $request_params ), $collection_url );

if ( $page > 1 ) {
$prev_page = $page - 1;

if ( $prev_page > $max_pages ) {
$prev_page = $max_pages;
}

$prev_link = add_query_arg( 'page', $prev_page, $base );
$response->link_header( 'prev', $prev_link );
}
if ( $max_pages > $page ) {
$next_page = $page + 1;
$next_link = add_query_arg( 'page', $next_page, $base );

$response->link_header( 'next', $next_link );
}

return rest_ensure_response( $collections, 200 );
return $response;
}

/**
Expand All @@ -95,17 +146,126 @@ public function get_item( $request ) {
return $collection;
}

$config = $collection->get_config();
$contents = $collection->get_content();
$item = $this->prepare_item_for_response( $collection, $request );

// If there was an error getting the collection data, return the error.
if ( is_wp_error( $contents ) ) {
$contents->add_data( array( 'status' => 500 ) );
return $contents;
if ( is_wp_error( $item ) ) {
return $item;
}

$collection_data = array_merge( $config, $contents );
return rest_ensure_response( $collection_data );
return $item;
}

/*
* Prepare a single collection output for response.
*
* @since 6.5.0
*
* @param WP_Font_Collection $collection Collection object.
* @param WP_REST_Request $request Request object.
* @return array|WP_Error
*/
public function prepare_item_for_response( $collection, $request ) {
$fields = $this->get_fields_for_response( $request );
$item = array();

$config_fields = array( 'slug', 'name', 'description' );
foreach ( $config_fields as $field ) {
if ( in_array( $field, $fields, true ) ) {
$item[ $field ] = $collection->$field;
}
}

$data_fields = array( 'font_families', 'categories' );
if ( in_array( 'font_families', $fields, true ) || in_array( 'categories', $fields, true ) ) {
$content = $collection->get_content();

// If there was an error getting the collection data, return the error.
if ( is_wp_error( $content ) ) {
$content->add_data( array( 'status' => 500 ) );
return $content;
}

foreach ( $data_fields as $field ) {
if ( in_array( $field, $fields, true ) ) {
$item[ $field ] = $content[ $field ];
}
}
}
creativecoder marked this conversation as resolved.
Show resolved Hide resolved

return rest_ensure_response( $item );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we also need to add links, including a prepare_links method for the controller.

Suggested change
return rest_ensure_response( $item );
$response = rest_ensure_response( $item );
if ( rest_is_field_included( '_links', $fields ) ) {
$links = $this->prepare_links( $collection );
$response->add_links( $links );
}
/**
* Filters the collection data for a REST API response.
*
* @since 6.5.0
*
* @param WP_REST_Response $response The response object.
* @param WP_Font_Collection $collection Font Collection object.
* @param WP_REST_Request $request. Request object.
*/
return apply_filters( "rest_prepare_font_collection", $response, $collection, $request );

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added here: 7372ddc

}

/**
* Retrieves the font collection's schema, conforming to JSON Schema.
*
* @since 6.5.0
*
* @return array Item schema data.
*/
public function get_item_schema() {
if ( $this->schema ) {
return $this->add_additional_fields_schema( $this->schema );
}

$schema = array(
'$schema' => 'http://json-schema.org/draft-04/schema#',
'title' => 'font-collection',
'type' => 'object',
'properties' => array(
'slug' => array(
'description' => __( 'Unique identifier for the font collection.', 'gutenberg' ),
'type' => 'string',
'context' => array( 'view', 'edit' ),
creativecoder marked this conversation as resolved.
Show resolved Hide resolved
'readonly' => true,
),
'name' => array(
'description' => __( 'The name for the font collection.', 'gutenberg' ),
'type' => 'string',
'context' => array( 'view', 'edit' ),
),
'description' => array(
'description' => __( 'The description for the font collection.', 'gutenberg' ),
'type' => 'string',
'context' => array( 'view', 'edit' ),
),
'font_families' => array(
'description' => __( 'The font families for the font collection.', 'gutenberg' ),
'type' => 'array',
'context' => array( 'view', 'edit' ),
),
'categories' => array(
'description' => __( 'The categories for the font collection.', 'gutenberg' ),
'type' => 'array',
'context' => array( 'view', 'edit' ),
),
),
);

$this->schema = $schema;

return $this->add_additional_fields_schema( $this->schema );
}

/**
* Retrieves the search params for the font collections.
*
* @since 6.5.0
*
* @return array Collection parameters.
*/
public function get_collection_params() {
$query_params = parent::get_collection_params();

unset( $query_params['search'] );

creativecoder marked this conversation as resolved.
Show resolved Hide resolved
/**
* Filters REST API collection parameters for the font collections controller.
*
* @since 6.5.0
*
* @param array $query_params JSON Schema-formatted collection parameters.
*/
return apply_filters( 'rest_font_collections_collection_params', $query_params );
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export async function fetchUninstallFontFamily( fontFamilyId ) {

export async function fetchFontCollections() {
const config = {
path: FONT_COLLECTIONS_URL,
path: `${ FONT_COLLECTIONS_URL }?_fields=slug,name,description`,
method: 'GET',
};
return await apiFetch( config );
Expand Down
Loading
Loading