monorepo/native/wordpress/maple-icons-wp/includes/class-mi-icon-sets.php
2026-02-02 14:17:16 -05:00

328 lines
11 KiB
PHP

<?php
/**
* Icon Sets class - Static definitions of all preset icon sets.
*
* @package MapleIcons
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class MI_Icon_Sets
*
* Provides static definitions and utilities for preset icon sets.
*/
class MI_Icon_Sets {
/**
* Get all available preset icon sets.
*
* @return array Array of icon set configurations.
*/
public static function get_all() {
return array(
'heroicons' => array(
'slug' => 'heroicons',
'name' => 'Heroicons',
'version' => '2.1.1',
'license' => 'MIT',
'url' => 'https://heroicons.com',
'cdn_base' => 'https://cdn.jsdelivr.net/npm/heroicons@2.1.1/',
'styles' => array(
'outline' => array(
'path' => '24/outline',
'label' => 'Outline',
),
'solid' => array(
'path' => '24/solid',
'label' => 'Solid',
),
'mini' => array(
'path' => '20/solid',
'label' => 'Mini',
),
),
'default_style' => 'outline',
'viewbox' => '0 0 24 24',
'normalize' => false,
'color_fix' => false,
'description' => 'Beautiful hand-crafted SVG icons by the makers of Tailwind CSS.',
'icon_count' => 292,
),
'lucide' => array(
'slug' => 'lucide',
'name' => 'Lucide',
'version' => '0.303.0',
'license' => 'ISC',
'url' => 'https://lucide.dev',
'cdn_base' => 'https://cdn.jsdelivr.net/npm/lucide-static@0.303.0/',
'styles' => array(
'icons' => array(
'path' => 'icons',
'label' => 'Default',
),
),
'default_style' => 'icons',
'viewbox' => '0 0 24 24',
'normalize' => false,
'color_fix' => false,
'description' => 'Beautiful & consistent icon toolkit made by the community.',
'icon_count' => 1411,
),
'feather' => array(
'slug' => 'feather',
'name' => 'Feather',
'version' => '4.29.1',
'license' => 'MIT',
'url' => 'https://feathericons.com',
'cdn_base' => 'https://cdn.jsdelivr.net/npm/feather-icons@4.29.1/',
'styles' => array(
'icons' => array(
'path' => 'dist/icons',
'label' => 'Default',
),
),
'default_style' => 'icons',
'viewbox' => '0 0 24 24',
'normalize' => false,
'color_fix' => false,
'description' => 'Simply beautiful open source icons.',
'icon_count' => 287,
),
'phosphor' => array(
'slug' => 'phosphor',
'name' => 'Phosphor',
'version' => '2.1.1',
'license' => 'MIT',
'url' => 'https://phosphoricons.com',
'cdn_base' => 'https://cdn.jsdelivr.net/npm/@phosphor-icons/core@2.1.1/',
'styles' => array(
'regular' => array(
'path' => 'assets/regular',
'label' => 'Regular',
),
'bold' => array(
'path' => 'assets/bold',
'label' => 'Bold',
),
'light' => array(
'path' => 'assets/light',
'label' => 'Light',
),
'thin' => array(
'path' => 'assets/thin',
'label' => 'Thin',
),
'fill' => array(
'path' => 'assets/fill',
'label' => 'Fill',
),
'duotone' => array(
'path' => 'assets/duotone',
'label' => 'Duotone',
),
),
'default_style' => 'regular',
'viewbox' => '0 0 256 256',
'normalize' => true, // Needs viewBox normalization to 24x24.
'color_fix' => false,
'description' => 'A flexible icon family for interfaces, diagrams, presentations, and more.',
'icon_count' => 1248,
),
'material' => array(
'slug' => 'material',
'name' => 'Material Design Icons',
'version' => '0.14.13',
'license' => 'Apache-2.0',
'url' => 'https://fonts.google.com/icons',
'cdn_base' => 'https://cdn.jsdelivr.net/npm/@material-design-icons/svg@0.14.13/',
'styles' => array(
'filled' => array(
'path' => 'filled',
'label' => 'Filled',
),
'outlined' => array(
'path' => 'outlined',
'label' => 'Outlined',
),
'round' => array(
'path' => 'round',
'label' => 'Round',
),
'sharp' => array(
'path' => 'sharp',
'label' => 'Sharp',
),
'two-tone' => array(
'path' => 'two-tone',
'label' => 'Two Tone',
),
),
'default_style' => 'filled',
'viewbox' => '0 0 24 24',
'normalize' => false,
'color_fix' => true, // Needs hardcoded color replacement.
'description' => 'Material Design Icons by Google. Beautiful, delightful, and easy to use.',
'icon_count' => 2189,
),
);
}
/**
* Get a specific icon set by slug.
*
* @param string $slug Icon set slug.
* @return array|null Icon set configuration or null if not found.
*/
public static function get( $slug ) {
$sets = self::get_all();
return isset( $sets[ $slug ] ) ? $sets[ $slug ] : null;
}
/**
* Get all available set slugs.
*
* @return array Array of set slugs.
*/
public static function get_slugs() {
return array_keys( self::get_all() );
}
/**
* Validate that a slug is a valid preset.
*
* @param string $slug Slug to validate.
* @return bool True if valid, false otherwise.
*/
public static function is_valid_slug( $slug ) {
return in_array( $slug, self::get_slugs(), true );
}
/**
* Validate that a style is valid for a given set.
*
* @param string $slug Icon set slug.
* @param string $style Style slug.
* @return bool True if valid, false otherwise.
*/
public static function is_valid_style( $slug, $style ) {
$set = self::get( $slug );
if ( ! $set ) {
return false;
}
return isset( $set['styles'][ $style ] );
}
/**
* Get the CDN URL for a specific icon.
*
* @param string $slug Icon set slug.
* @param string $style Style slug.
* @param string $name Icon name.
* @return string|null CDN URL or null if invalid.
*/
public static function get_cdn_url( $slug, $style, $name ) {
$set = self::get( $slug );
if ( ! $set || ! isset( $set['styles'][ $style ] ) ) {
return null;
}
$style_config = $set['styles'][ $style ];
return $set['cdn_base'] . $style_config['path'] . '/' . $name . '.svg';
}
/**
* Get the local file path for a specific icon.
*
* @param string $slug Icon set slug.
* @param string $style Style slug.
* @param string $name Icon name.
* @return string Local file path.
*/
public static function get_local_path( $slug, $style, $name ) {
return MI_ICONS_DIR . $slug . '/' . $style . '/' . $name . '.svg';
}
/**
* Get the local URL for a specific icon.
*
* @param string $slug Icon set slug.
* @param string $style Style slug.
* @param string $name Icon name.
* @return string Local URL.
*/
public static function get_local_url( $slug, $style, $name ) {
return MI_ICONS_URL . $slug . '/' . $style . '/' . $name . '.svg';
}
/**
* Get the manifest file path for a set.
*
* @param string $slug Icon set slug.
* @return string Manifest file path.
*/
public static function get_manifest_path( $slug ) {
return MI_PRESETS_DIR . $slug . '.json';
}
/**
* Load and parse a manifest file.
*
* @param string $slug Icon set slug.
* @return array|WP_Error Manifest data or error.
*/
public static function load_manifest( $slug ) {
$path = self::get_manifest_path( $slug );
if ( ! file_exists( $path ) ) {
return new WP_Error(
'manifest_not_found',
sprintf(
/* translators: %s: Icon set name */
__( 'Manifest file not found for %s.', 'maple-icons' ),
$slug
)
);
}
$content = file_get_contents( $path ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
if ( false === $content ) {
return new WP_Error(
'manifest_read_error',
__( 'Could not read manifest file.', 'maple-icons' )
);
}
$manifest = json_decode( $content, true );
if ( json_last_error() !== JSON_ERROR_NONE ) {
return new WP_Error(
'manifest_parse_error',
__( 'Could not parse manifest file.', 'maple-icons' )
);
}
return $manifest;
}
/**
* Get style labels for a set.
*
* @param string $slug Icon set slug.
* @return array Array of style labels.
*/
public static function get_style_labels( $slug ) {
$set = self::get( $slug );
if ( ! $set ) {
return array();
}
$labels = array();
foreach ( $set['styles'] as $style_slug => $style_config ) {
$labels[ $style_slug ] = $style_config['label'];
}
return $labels;
}
}