Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
<?php

/**
* WordPress 7.1 icon categories registry compatibility.
*
* @package gutenberg
*/

/**
* Icon categories registry for the WordPress 7.1 compatibility layer.
*/
class Gutenberg_Icon_Categories_Registry_7_1 {
/**
* Registered icon categories.
*
* @var array[]
*/
private $registered_categories = array();

/**
* Container for the main instance of the class.
*
* @var Gutenberg_Icon_Categories_Registry_7_1|null
*/
private static $instance = null;

/**
* Constructor.
*
* Keep this protected because this class is a singleton.
*/
protected function __construct() {}

/**
* Registers an icon category.
*
* @param string $category_name Unique category name.
* @param array $category_properties {
* List of category properties.
*
* @type string $label Required. A human-readable label for the category.
* @type string $description Optional. A description for the category.
* }
* @return bool True on success, false otherwise.
*/
public function register( $category_name, $category_properties ) {
if ( ! is_string( $category_name ) || '' === $category_name ) {
_doing_it_wrong(
__METHOD__,
__( 'Icon category name must be a non-empty string.', 'gutenberg' ),
'7.1.0'
);
return false;
}

if ( sanitize_key( $category_name ) !== $category_name ) {
_doing_it_wrong(
__METHOD__,
__( 'Icon category name must contain only lowercase alphanumeric characters, dashes, and underscores.', 'gutenberg' ),
'7.1.0'
);
return false;
}

if ( ! is_array( $category_properties ) ) {
_doing_it_wrong(
__METHOD__,
__( 'Icon category properties must be an array.', 'gutenberg' ),
'7.1.0'
);
return false;
}

if ( $this->is_registered( $category_name ) ) {
_doing_it_wrong(
__METHOD__,
sprintf(
/* translators: %s: Icon category name. */
__( 'Icon category "%s" is already registered.', 'gutenberg' ),
$category_name
),
'7.1.0'
);
return false;
}

$allowed_keys = array_fill_keys( array( 'label', 'description' ), true );
foreach ( array_keys( $category_properties ) as $key ) {
if ( ! isset( $allowed_keys[ $key ] ) ) {
_doing_it_wrong(
__METHOD__,
sprintf(
/* translators: %s: Invalid icon category property key. */
__( 'Invalid icon category property: "%s".', 'gutenberg' ),
$key
),
'7.1.0'
);
return false;
}
}

if ( ! isset( $category_properties['label'] ) || ! is_string( $category_properties['label'] ) || '' === $category_properties['label'] ) {
_doing_it_wrong(
__METHOD__,
__( 'Icon category label must be a non-empty string.', 'gutenberg' ),
'7.1.0'
);
return false;
}

if ( isset( $category_properties['description'] ) && ! is_string( $category_properties['description'] ) ) {
_doing_it_wrong(
__METHOD__,
__( 'Icon category description must be a string.', 'gutenberg' ),
'7.1.0'
);
return false;
}

$category = array_merge(
$category_properties,
array( 'name' => $category_name )
);

$this->registered_categories[ $category_name ] = $category;

return true;
}

/**
* Unregisters an icon category.
*
* @param string $category_name Category name.
* @return bool True if the category was unregistered, false otherwise.
*/
public function unregister( $category_name ) {
if ( ! $this->is_registered( $category_name ) ) {
return false;
}

unset( $this->registered_categories[ $category_name ] );
return true;
}

/**
* Retrieves all registered icon categories.
*
* @return array[] Array of registered icon category objects.
*/
public function get_all_registered() {
$categories = array_values( $this->registered_categories );
usort(
$categories,
static function ( $left, $right ) {
return strnatcasecmp( $left['name'], $right['name'] );
}
);

return $categories;
}

/**
* Retrieves a single registered icon category.
*
* @param string $category_name Category name.
* @return array|null Registered category object, or null if not found.
*/
public function get_registered( $category_name ) {
if ( ! $this->is_registered( $category_name ) ) {
return null;
}

return $this->registered_categories[ $category_name ];
}

/**
* Checks if an icon category is registered.
*
* @param string $category_name Category name.
* @return bool True when the category exists.
*/
public function is_registered( $category_name ) {
return isset( $this->registered_categories[ $category_name ] );
}

/**
* Returns the singleton instance.
*
* @return Gutenberg_Icon_Categories_Registry_7_1 Registry instance.
*/
public static function get_instance() {
if ( null === self::$instance ) {
self::$instance = new self();
}

return self::$instance;
}
}
84 changes: 84 additions & 0 deletions lib/compat/wordpress-7.1/class-gutenberg-icons-registry-7-1.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,95 @@ protected function __construct() {
array(
'label' => $icon_data['label'],
'filePath' => $icons_directory . $icon_data['filePath'],
'category' => ! empty( $icon_data['category'] ) && is_string( $icon_data['category'] )
? $icon_data['category']
: null,
)
Comment on lines 46 to 51
);
}
}

/**
* Modified to point $manifest_path to Gutenberg packages
*/
protected function register( $icon_name, $icon_properties ) {
if ( ! isset( $icon_name ) || ! is_string( $icon_name ) ) {
_doing_it_wrong(
__METHOD__,
__( 'Icon name must be a string.', 'gutenberg' ),
'7.0.0'
);
return false;
}

$allowed_keys = array_fill_keys( array( 'label', 'content', 'filePath', 'category' ), 1 );
foreach ( array_keys( $icon_properties ) as $key ) {
if ( ! array_key_exists( $key, $allowed_keys ) ) {
_doing_it_wrong(
__METHOD__,
sprintf(
// translators: %s is the name of any user-provided key
__( 'Invalid icon property: "%s".', 'gutenberg' ),
$key
),
'7.0.0'
);
return false;
}
}

if ( ! isset( $icon_properties['label'] ) || ! is_string( $icon_properties['label'] ) ) {
_doing_it_wrong(
__METHOD__,
__( 'Icon label must be a string.', 'gutenberg' ),
'7.0.0'
);
return false;
}

if (
( ! isset( $icon_properties['content'] ) && ! isset( $icon_properties['filePath'] ) ) ||
( isset( $icon_properties['content'] ) && isset( $icon_properties['filePath'] ) )
) {
_doing_it_wrong(
__METHOD__,
__( 'Icons must provide either `content` or `filePath`.', 'gutenberg' ),
'7.0.0'
);
return false;
}

if ( isset( $icon_properties['content'] ) ) {
if ( ! is_string( $icon_properties['content'] ) ) {
_doing_it_wrong(
__METHOD__,
__( 'Icon content must be a string.', 'gutenberg' ),
'7.0.0'
);
return false;
}

$sanitized_icon_content = $this->sanitize_icon_content( $icon_properties['content'] );
if ( empty( $sanitized_icon_content ) ) {
_doing_it_wrong(
__METHOD__,
__( 'Icon content does not contain valid SVG markup.', 'gutenberg' ),
'7.0.0'
);
return false;
}
}

$icon = array_merge(
$icon_properties,
array( 'name' => $icon_name )
);

$this->registered_icons[ $icon_name ] = $icon;

return true;
}

/**
* Modified to also search in icon labels
*/
Expand Down
Loading
Loading