<?php
|
namespace JVBase;
|
|
use JVBase\managers\CacheManager;
|
|
if (!defined('ABSPATH')) {
|
exit; // Exit if accessed directly
|
}
|
class JVBIcons
|
{
|
static array $processing = ['map' => [],'label' => []];
|
protected string $style;
|
protected array $styles = [
|
'regular',
|
'bold',
|
'duotone',
|
'fill',
|
'light',
|
'thin'
|
];
|
|
protected array $labels = [
|
'submenu' => 'Toggle Menu',
|
'dashboard' => 'Dashboard',
|
'arrow-fat-down' => 'Downvote',
|
'arrow-fat-up' => 'Upvote',
|
'hamburger' => 'Menu',
|
'check-square-offset'=> 'Approval Requests',
|
'h1' => 'Heading 1',
|
'h2' => 'Heading 2',
|
'h3' => 'Heading 3',
|
'note-pencil' => 'Notes',
|
'sun-dim' => 'Light Mode',
|
'moon' => 'Dark Mode',
|
'grid' => 'Grid View',
|
'list' => 'List View',
|
'clock-clockwise' => 'Upcoming Events',
|
'clock-counter-clockwise'=>'Past Events',
|
'repeat' => 'Recurring Events',
|
'floppy-disk' => 'Save',
|
];
|
|
protected array $map = [
|
'time' => 'clock',
|
'back' => 'arrow-u-up-left',
|
'logo' => 'logo.svg',
|
'logo-basic' => 'logo-basic.svg',
|
'save' => 'floppy-disk',
|
'restore' => 'arrow-counter-clockwise',
|
'help' => 'question',
|
'upload' => 'cloud-arrow-up',
|
'download' => 'cloud-arrow-down',
|
'synced' => 'cloud-check',
|
'syncing' => 'cloud-sync-thin.svg',
|
'offline' => 'cloud-slash',
|
'error' => 'cloud-warning',
|
'cart' => 'shopping-cart',
|
'delete' => 'trash',
|
'edit' => 'pencil-simple',
|
'bio' => 'user',
|
'login' => 'sign-in',
|
'logout' => 'sign-out',
|
'future' => 'clock-clockwise',
|
'past' => 'clock-counter-clockwise',
|
'light' => 'sun-dim',
|
'dark' => 'moon',
|
'h1' => 'text-h-one',
|
'h2' => 'text-h-two',
|
'h3' => 'text-h-three',
|
'bold' => 'text-b',
|
'italic' => 'text-italic',
|
'underline' => 'text-underline',
|
'strike' => 'text-strikethrough',
|
'image' => 'image-square',
|
'reply' => 'arrow-bend-up-left',
|
'approval' => 'check-square-offset',
|
'response' => 'chat-teardrop',
|
'karma' => 'scales',
|
'show' => 'eye',
|
'publish' => 'eye',
|
'hide' => 'eye-closed',
|
'draft' => 'eye-closed',
|
'asc' => 'sort-ascending',
|
'desc' => 'sort-descending',
|
'all' => 'infinity',
|
'random' => 'shuffle',
|
'location' => 'map-pin',
|
'hours' => 'clock',
|
'favourite' => 'heart',
|
'email' => 'envelope',
|
'text' => 'chat',
|
'integrations' => 'plugs-connected',
|
'connected' => 'plugs-connected',
|
'disconnected' => 'plugs',
|
'umami' => 'chart-line',
|
'square-up' => 'square-logo',
|
'tiktok' => 'tiktok-logo',
|
'threads' => 'threads-logo',
|
'twitch' => 'twitch-logo',
|
'snapchat' => 'snapchat-logo',
|
'linktree' => 'linktree-logo',
|
'fediverse' => 'fediverse-logo',
|
'mastadon' => 'mastadon-logo',
|
'youtube' => 'youtube-logo',
|
'twitter' => 'twitter-logo',
|
'messenger' => 'messenger-logo',
|
'facebook' => 'facebook-logo',
|
'instagram' => 'instagram-logo',
|
'dash' => 'door',
|
'event' => 'calendar',
|
'events' => 'calendar',
|
'settings' => 'gear-six',
|
'grid' => 'squares-four',
|
'list' => 'rows',
|
'pinned' => 'push-pin',
|
'search' => 'magnifying-glass',
|
'add' => 'plus-square',
|
'minus' => 'minus-square',
|
'support' => 'question',
|
'grab' => 'dots-six-vertical',
|
'checkout' => 'receipt',
|
'home' => 'house',
|
'elbow-right-down' => 'arrow-elbow-right-down',
|
'elbow-right-up'=> 'arrow-elbow-right-up',
|
'elbow-left-down'=> 'arrow-elbow-left-down',
|
'elbow-left-up' => 'arrow-elbow-left-up',
|
'menu' => 'list',
|
'submenu' => 'caret-down',
|
'close' => 'x',
|
'close-square' => 'x-square',
|
'dashboard' => 'door',
|
'system' => 'gear-six',
|
'options' => 'gear-six',
|
'news' => 'newspaper',
|
'metrics' => 'chart-line',
|
'prev' => 'caret-left',
|
'up' => 'caret-circle-up',
|
'right' => 'caret-double-right',
|
'left' => 'caret-double-left',
|
'next' => 'caret-right',
|
'refresh' => 'arrows-clockwise',
|
'pending' => 'arrows-clockwise',
|
'copy' => 'copy-simple',
|
'align-center' => 'text-align-center',
|
'align-left' => 'text-align-left',
|
'align-right' => 'text-align-right',
|
'alphabetical' => 'alphabetical.svg',
|
'date' => 'calendar',
|
'down' => 'caret-double-down',
|
'tattoo' => 'drop-simple',
|
'tattoos' => 'drop-simple',
|
'theme' => 'folder-open',
|
'arttheme' => 'folder-open',
|
'style' => 'hash',
|
'artstyle' => 'hash',
|
'colour' => 'drop',
|
'placement' => 'person-arms-spread',
|
'artmedia' => 'squares-four',
|
'artist' => 'user',
|
'client' => 'user',
|
'artists' => 'users-three',
|
'partner' => 'currency-circle-dollar',
|
'shop' => 'storefront',
|
'piercing' => 'needle',
|
'piercings' => 'needle',
|
'artwork' => 'palette',
|
'artform' => 'shapes',
|
'city' => 'map-pin',
|
'type' => 'users-three',
|
'pstyle' => 'nut',
|
'project' => 'code',
|
'map' => 'map-trifold',
|
'offer' => 'gift',
|
'referrals' => 'hand-heart'
|
];
|
|
|
private const ICON_GROUPS = [
|
'navigation' => [
|
'back' => ['filename' => 'back', 'label' => 'Back', 'size' => 24],
|
'home' => ['filename' => 'house', 'label' => 'Home'],
|
'right' => ['filename' => 'arrow-fat-right', 'label' => ''],
|
'elbow-right-down'=> ['filename' => 'arrow-elbow-right-down', 'label' => ''],
|
'elbow-right-up'=> ['filename' => 'arrow-elbow-right-up', 'label' => ''],
|
'elbow-left-down'=> ['filename' => 'arrow-elbow-left-down', 'label' => ''],
|
'elbow-left-up'=> ['filename' => 'arrow-elbow-left-up', 'label' => ''],
|
'menu' => ['filename' => 'list', 'label' => 'Toggle Menu', 'size' => 32],
|
'submenu' => ['filename' => 'caret-down', 'label' => 'Toggle Submenu'],
|
'close' => ['filename' => 'x', 'label' => 'Close', 'size' => 32],
|
'close-square' => ['filename' => 'x-square', 'label' => 'Close'],
|
'dashboard' => ['filename' => 'door', 'label'=> 'Behind the Scenes', 'size' => 24],
|
'dash' => ['filename' => 'door', 'label'=> 'Behind the Scenes', 'size' => 24],
|
'settings' => ['filename' => 'gear-six', 'label'=> 'Settings', 'size' => 24],
|
'system' => ['filename' => 'gear-six', 'label'=> 'Settings', 'size' => 24],
|
'options' => ['filename' => 'gear-six', 'label'=> 'Options', 'size' => 24],
|
'news' => ['filename' => 'newspaper', 'label' => 'News', 'size' => 24],
|
'metrics' => ['filename' => 'chart-line', 'label' => 'Metrics', 'size' => 24],
|
'prev' => ['filename' => 'caret-left', 'label' => 'Previous', 'size' => 24],
|
'up' => ['filename' => 'caret-circle-up', 'label' => 'Up', 'size' => 24],
|
'down' => ['filename' => 'caret-double-down', 'label' => 'Down', 'size' => 24],
|
'right' => ['filename' => 'caret-double-right', 'label' => 'Right', 'size' => 24],
|
'next' => ['filename' => 'caret-right', 'label' => 'Next', 'size' => 24],
|
'refresh' => ['filename' => 'arrows-clockwise', 'label' => 'Refresh', 'size' => 24],
|
'pending' => ['filename' => 'arrows-clockwise', 'label' => 'Refresh', 'size' => 24],
|
'clock' => ['filename' => 'clock', 'label' => 'Hours'],
|
'copy' => ['filename' => 'copy-simple', 'label' => 'Duplicate'],
|
'list-heart' => ['filename' => 'list-heart', 'label'=> 'Lists'],
|
'downvoted' => ['filename' => 'arrow-fat-down-fill.svg', 'label'=> 'Downvote'],
|
'upvoted' => ['filename' => 'arrow-fat-up-fill.svg', 'label'=> 'Upvote'],
|
'downvote' => ['filename' => 'arrow-fat-down', 'label'=> 'Downvote'],
|
'upvote' => ['filename' => 'arrow-fat-up', 'label'=> 'Upvote'],
|
'karma' => ['filename' => 'scales', 'label'=> 'Karma'],
|
'response' => ['filename' => 'chat-teardrop', 'label' => 'Responses'],
|
'reply' => ['filename' => 'arrow-bend-up-left', 'label' => 'Reply'],
|
'approval' => ['filename' => 'check-square-offset', 'label' => 'Approval Requests'],
|
'check' => ['filename' => 'check-circle', 'label' => 'done'],
|
'hamburger' => ['filename' => 'hamburger', 'label' => 'menu']
|
],
|
'formatting' => [
|
'paragraph' => ['filename' => 'paragraph', 'label' => 'Paragraph', 'size' => 24],
|
'h1' => ['filename' => 'text-h-one', 'label' => 'Heading 1', 'size' => 24],
|
'h2' => ['filename' => 'text-h-two', 'label' => 'Heading 2', 'size' => 24],
|
'h3' => ['filename' => 'text-h-three', 'label' => 'Heading 3', 'size' => 24],
|
'bold' => ['filename' => 'text-b-bold.svg', 'label' => 'Bold', 'size' => 24],
|
'italic' => ['filename' => 'text-italic', 'label' => 'Italic', 'size' => 24],
|
'underline' => ['filename' => 'text-underline', 'label' => 'Underline', 'size' => 24],
|
'strike' => ['filename' => 'text-strikethrough', 'label' => 'Strikethrough', 'size' => 24],
|
'list-bullets' => ['filename' => 'list-bullets', 'label' => 'Bulleted List', 'size' => 24],
|
'list-numbers' => ['filename' => 'list-numbers', 'label' => 'Numbered List', 'size' => 24],
|
'image' => ['filename' => 'image-square', 'label' => 'Image', 'size' => 24],
|
'align-left' => ['filename' => 'text-align-left', 'label' => 'Align Left', 'size' => 24],
|
'align-right' => ['filename' => 'text-align-right', 'label' => 'Align Right', 'size' => 24],
|
'align-center' => ['filename' => 'text-align-center', 'label' => 'Align Center', 'size' => 24],
|
'link' =>['filename' => 'link', 'label' => 'Link', 'size' => 24],
|
'note' => ['filename' => 'note-pencil', 'label' => 'Notes', 'size' => 24],
|
'password' => ['filename' => 'password', 'label' => 'Password']
|
],
|
'theme' => [
|
'light' => ['filename' => 'sun-dim', 'label' => 'Light Mode'],
|
'dark' => ['filename' => 'moon', 'label' => 'Dark Mode'],
|
'grid' => ['filename' => 'squares-four', 'label' => 'Grid View'],
|
'list' => ['filename' => 'rows', 'label' => 'List View'],
|
],
|
'content' => [
|
'offer' => ['filename'=>'gift', 'label'=>'Offer'],
|
'logo' => ['filename' => 'logo.svg', 'label' => 'North\'eh', 'size' => 20],
|
'logo-basic' => ['filename' => 'logo-basic.svg', 'label' => 'North\'eh', 'size' => 20],
|
'theme' => ['filename' => 'folder-open', 'label' => 'Theme', 'size' => 20],
|
'arttheme' => ['filename' => 'folder-open', 'label' => 'Art Theme', 'size' => 20],
|
'style' => ['filename' => 'hash', 'label' => 'Style', 'size' => 20],
|
'artstyle' => ['filename' => 'hash', 'label' => 'Art Style', 'size' => 20],
|
'colour' => ['filename' => 'drop', 'label' => 'Colour', 'size' => 20],
|
'placement' => ['filename' => 'person-arms-spread', 'label' => 'Placement', 'size' => 20],
|
'artmedia' => ['filename' => 'squares-four', 'label' => 'Media', 'size' => 20],
|
'artist' => ['filename' => 'user', 'label'=> 'Artist', 'size' => 24],
|
'client' => ['filename' => 'user', 'label'=> 'Artist', 'size' => 24],
|
'artists' => ['filename' => 'users-three', 'label' => 'Artists'],
|
'partner' => ['filename' => 'currency-circle-dollar', 'label' => 'Partner'],
|
'shop' => ['filename' => 'storefront', 'label' => 'Shop', 'size' => 20],
|
'tattoo' => ['filename' => 'drop-simple', 'label' => 'Tattoo', 'size' => 20],
|
'tattoos' => ['filename' => 'drop-simple', 'label' => 'Your Tattoos', 'size' => 20],
|
'event' => ['filename' => 'calendar', 'label' => 'Event', 'size' => 20],
|
'events' => ['filename' => 'calendar', 'label' => 'Your Events', 'size' => 20],
|
'piercing' => ['filename' => 'needle', 'label' => 'Piercings', 'size' => 20],
|
'piercings' => ['filename' => 'needle', 'label' => 'Your Piercings', 'size' => 20],
|
'artwork' => ['filename' => 'palette', 'label' => 'Artwork', 'size' => 20],
|
'artform' => ['filename' => 'shapes', 'label' => 'Art Form', 'size' => 20],
|
'city' => ['filename' => 'map-pin', 'label' => 'City', 'size' => 20],
|
'type' => ['filename' => 'users-three', 'label' => 'Artist Type', 'size' => 20],
|
'pstyle' => ['filename' => 'nut', 'label' => 'Body Modifications', 'size' => 20],
|
'past' => ['filename' => 'clock-counter-clockwise', 'label' => 'Past Events', 'size' => 20],
|
'future' => ['filename' => 'clock-clockwise', 'label' => 'Upcoming Events', 'size' => 20],
|
'repeat' => ['filename' => 'repeat', 'label' => 'Recurring Events', 'size' => 20],
|
'project' => ['filename' => 'code', 'label' => 'Project'],
|
'gauge' => ['filename' => 'gauge', 'label'=> 'Dashboard'],
|
'map' => ['filename' => 'map-trifold', 'label' => 'Map'],
|
],
|
'users' => [
|
'new-user' => ['filename' => 'user-circle-plus', 'label' => 'New Artist'],
|
'user' => ['filename' => 'user', 'label' => 'Artist', 'size' => 20],
|
'bio' => ['filename' => 'user', 'label' => 'Your Bio', 'size' => 20],
|
'login' => ['filename' => 'sign-in', 'label' => 'Login'],
|
'logout' => ['filename' => 'sign-out', 'label' => 'Logout']
|
],
|
'actions' => [
|
'save' => ['filename' => 'floppy-disk', 'label' => 'Save'],
|
'restore'=> ['filename' => 'arrow-counter-clockwise', 'label' => 'Restore', 'size' => 32],
|
'edit' => ['filename' => 'pencil-simple', 'label' => 'Edit', 'size' => 24],
|
'delete'=> ['filename' => 'trash', 'label' => 'Delete', 'size' => 32],
|
'search'=> ['filename' => 'magnifying-glass', 'label' => 'Search', 'size' => 32],
|
'add' => ['filename' => 'plus-square', 'label' => 'Add New', 'size' => 32],
|
'minus' => ['filename' => 'minus-square', 'label' => 'Collapse', 'size' => 32],
|
'help' => ['filename' => 'question', 'label' => 'Toggle Quick Help'],
|
'support' => ['filename' => 'question', 'label' => 'Toggle Quick Help'],
|
'grab' => ['filename' => 'dots-six-vertical', 'label'=> 'Grab'],
|
'share' => ['filename' => 'share', 'label' => 'Share', 'size'=> 24],
|
'cart' => ['filename' => 'shopping-cart', 'label' => 'Your Cart', 'size'=> 24],
|
'checkout' => ['filename' => 'receipt', 'label' => 'Checkout', 'size'=> 24],
|
'upload' => ['filename' => 'cloud-arrow-up', 'label' => 'Upload to Server', 'size'=> 24],
|
'download' => ['filename' => 'cloud-arrow-down', 'label' => 'Downloading', 'size'=> 24],
|
'synced' => ['filename' => 'cloud-check', 'label' => 'Synced', 'size'=> 24],
|
'syncing' => ['filename' => 'cloud-sync-thin.svg', 'label' => 'Synced', 'size'=> 24],
|
'cloud' => ['filename' => 'cloud', 'label' => 'Synced', 'size'=> 24],
|
// 'pending' => ['filename' => 'cloud', 'label' => 'Synced', 'size'=> 24],
|
'offline' => ['filename' => 'cloud-slash', 'label' => 'Offline', 'size'=> 24],
|
'error' => ['filename' => 'cloud-warning', 'label' => 'Upload Failed', 'size'=> 24],
|
|
],
|
'status' => [
|
'show' => ['filename' => 'eye', 'label' => 'Show', 'size' => 20],
|
'publish' => ['filename' => 'eye', 'label' => 'Public', 'size' => 20],
|
'hide' => ['filename' => 'eye-closed', 'label' => 'Hide', 'size' => 20],
|
'draft' => ['filename' => 'eye-closed', 'label' => 'Hidden', 'size' => 20],
|
'pinned' => ['filename' => 'push-pin-simple', 'label' => 'Pin', 'size' => 32],
|
'bell' => ['filename' => 'bell', 'label' => 'Notification', 'size' => 32],
|
'bell-ringing' => ['filename' => 'bell-ringing', 'label' => 'Notification', 'size' => 32]
|
],
|
'sorting' => [
|
'table' => ['filename' => 'table', 'label' => 'Table View', 'size' => 20],
|
'columns' => ['filename' => 'columns', 'label' => 'Show Columns', 'size' => 20],
|
'alphabetical' => ['filename' => 'alphabetical', 'label' => 'Alphabetical', 'size' => 20],
|
'calendar' => ['filename' => 'calendar-heart', 'label' => 'Date', 'size' => 20],
|
'asc' => ['filename' => 'sort-ascending', 'label' => 'Sort Ascending', 'size' => 20],
|
'ASC' => ['filename' => 'sort-ascending', 'label' => 'Sort Ascending', 'size' => 20],
|
'desc' => ['filename' => 'sort-descending', 'label' => 'Sort Descending', 'size' => 20],
|
'DESC' => ['filename' => 'sort-descending', 'label' => 'Sort Descending', 'size' => 20],
|
'filter' => ['filename' => 'faders', 'label' => 'Filter'],
|
'all' => ['filename' => 'infinity', 'label' => 'All', 'size' => 32],
|
'random' => ['filename' => 'shuffle', 'label' => 'Random', 'size' => 20]
|
],
|
'business' => [
|
'location' => ['filename' => 'map-pin', 'label' => 'Location'],
|
'hours' => ['filename' => 'clock', 'label' => 'Hours'],
|
'star' => ['filename' => 'star', 'label' => 'Empty Star'],
|
'star-fill' => ['filename' => 'star-fill.svg', 'label' => 'Star'],
|
'star-half' => ['filename' => 'star-half-fill.svg', 'label' => 'Half Star'],
|
],
|
'social' => [
|
'heart' => ['filename' => 'heart', 'label' => 'Favourite', 'size' => 24],
|
'favourite' => ['filename' => 'heart', 'label' => 'Favourite', 'size' => 24],
|
'favourites'=> ['filename' => 'heart', 'label' => 'Your Favourites', 'size' => 24],
|
'heart-fill'=> ['filename' => 'heart-fill.svg', 'label' => 'Favourited', 'size' => 24],
|
'share' => ['filename' => 'share', 'label' => 'Share', 'size' => 32],
|
'email' => ['filename' => 'envelope','label'=> 'Email'],
|
'text' => ['filename' => 'chat','label'=> 'Text'],
|
'phone' => ['filename' => 'phone','label'=> 'Call'],
|
],
|
'external' => [
|
'integrations' => ['filename' => 'plugs-connected', 'label' => 'Integrations'],
|
'connected' => ['filename' => 'plugs-connected', 'label' => 'Connected'],
|
'disconnected' => ['filename' => 'plugs', 'label' => 'Disconnected'],
|
'instagram' => ['filename' => 'instagram-logo', 'label' => 'Instagram'],
|
'facebook' => ['filename' => 'facebook-logo', 'label' => 'Facebook'],
|
'messenger' => ['filename' => 'messenger-logo', 'label' => 'Facebook Messenger'],
|
'twitter' => ['filename' => 'twitter-logo', 'label' => 'Twitter'],
|
'x' => ['filename' => 'x-logo', 'label' => 'X'],
|
'youtube' => ['filename' => 'youtube-logo', 'label' => 'YouTube'],
|
'mastadon' => ['filename' => 'mastadon-logo', 'label' => 'Mastadon'],
|
'fediverse' => ['filename' => 'fediverse-logo', 'label' => 'Fediverse'],
|
'linktree' => ['filename' => 'linktree-logo', 'label' => 'LinkTree'],
|
'snapchat' => ['filename' => 'snapchat-logo', 'label' => 'Snapchat'],
|
'twitch' => ['filename' => 'twitch-logo', 'label' => 'Twitch'],
|
'threads' => ['filename' => 'threads-logo', 'label' => 'Threads'],
|
'tiktok' => ['filename' => 'tiktok-logo', 'label' => 'TikTok'],
|
'square-up' => ['filename' => 'square-logo', 'label' => 'Square'],
|
'umami' => ['filename' => 'chart-line', 'label' => 'Umami'],
|
]
|
];
|
private string $defaultStyle = '-thin';
|
private int $defaultSize = 16;
|
protected string $name;
|
protected array $used;
|
protected int $size = 20;
|
protected CacheManager $cache;
|
|
public function __construct()
|
{
|
$this->cache = CacheManager::for('icons', WEEK_IN_SECONDS);
|
// $this->cache->invalidateGroup('icons');
|
$this->style = JVB_SITE['icons']??'regular';
|
|
|
$this->used = get_option(BASE.'used_icons', [
|
$this->style => [
|
'heart',
|
'hours',
|
'random',
|
'alphabetical',
|
'calendar',
|
'asc',
|
'desc',
|
'all',
|
'paragraph',
|
'h1',
|
'h2',
|
'h3',
|
'bold',
|
'italic',
|
'underline',
|
'strike',
|
'list-bullets',
|
'list-numbers',
|
'image',
|
'align-left',
|
'align-right',
|
'align-center',
|
'link',
|
'note',
|
'password',
|
'light',
|
'left',
|
'dark',
|
'grid',
|
'list',
|
'save',
|
'restore',
|
'edit',
|
'delete',
|
'search',
|
'add',
|
'minus',
|
'help',
|
'support',
|
'grab',
|
'share',
|
'cart',
|
'checkout',
|
'upload',
|
'download',
|
'synced',
|
'syncing',
|
'cloud',
|
'offline',
|
'error',
|
'show',
|
'publish',
|
'hide',
|
'draft',
|
'pinned',
|
'bell',
|
'bell-ringing',
|
'back',
|
'home',
|
'right',
|
'elbow-right-down',
|
'elbow-right-up',
|
'elbow-left-down',
|
'elbow-left-up',
|
'menu',
|
'submenu',
|
'close',
|
'close-square',
|
'dashboard',
|
'dash',
|
'settings',
|
'system',
|
'options',
|
'news',
|
'metrics',
|
'prev',
|
'up',
|
'down',
|
'right',
|
'copy',
|
'next',
|
'refresh',
|
'pending',
|
'clock',
|
'copy',
|
'list-heart',
|
'karma',
|
'response',
|
'reply',
|
'approval',
|
'check',
|
'hamburger',
|
'location',
|
'hours',
|
'star',
|
'star-half',
|
'exclamation-mark'
|
],
|
'fill' => [
|
'heart',
|
'arrow-fat-down',
|
'arrow-fat-up',
|
'star'
|
]
|
]);
|
}
|
|
protected function updateUsed():void
|
{
|
$icons = [];
|
foreach ($this->used as $style => $items) {
|
$temp = array_unique($items);
|
sort($temp);
|
$icons[$style] = $temp;
|
}
|
update_option(BASE . 'used_icons', $icons);
|
}
|
|
protected function checkMap(string $name): string
|
{
|
$result = apply_filters('jvbIconMap', (array_key_exists($name, $this->map)) ? $this->map[$name] : $name, $name);
|
return $result;
|
}
|
|
protected function checkName(string $name) {
|
$name = $this->checkMap($name);
|
$path = (str_contains($name, '.svg')) ? '/assets/icons/' : '/assets/phosphor-icons/regular/';
|
$filename = (str_contains($name, '.svg')) ? $name : $name.'.svg';
|
return file_exists(JVB_DIR . $path . $filename);
|
}
|
public function getIcon(string $name, array $options = []):?string
|
{
|
if (!$this->checkName($name)) {
|
error_log('[Icons]Icon not found for: '.print_r($name, true));
|
return '';
|
}
|
$style = (array_key_exists('style', $options) && in_array($options['style'], $this->styles)) ? $options['style'] : 'regular';
|
|
$update = false;
|
if (!array_key_exists($style, $this->used)) {
|
$this->used[$style] = [];
|
$update = true;
|
}
|
if (!in_array($name, $this->used[$style])) {
|
$this->used[$style][] = $name;
|
$update = true;
|
}
|
if ($update) {
|
$this->updateUsed();
|
}
|
|
$name = $this->checkMap($name);
|
$this->name = str_replace('.svg', '', $name);
|
|
|
// Merge options with defaults and icon config
|
$options = array_merge([
|
'title' => $options['label']??$this->getIconLabel($name),
|
'size' => $options['size'] ?? $this->size,
|
'style' => $style,
|
'class' => '',
|
'wrap' => true,
|
'color' => 'currentColor'
|
], $options);
|
|
return $this->cache->remember(
|
array_merge($options, ['name' => $name]),
|
function () use ($name, $options) {
|
return $this->buildIcon($name, $options);
|
}
|
);
|
}
|
|
public function getIconsByGroup(string $group):array
|
{
|
if (!isset(self::ICON_GROUPS[$group])) {
|
return [];
|
}
|
|
$icons = [];
|
foreach (self::ICON_GROUPS[$group] as $name => $config) {
|
$icons[$name] = $this->getIcon($name);
|
}
|
|
return array_filter($icons);
|
}
|
|
public function getAllIcons():array
|
{
|
$icons = [];
|
foreach (self::ICON_GROUPS as $group => $groupIcons) {
|
foreach ($groupIcons as $name => $config) {
|
$icons[$name] = $this->getIcon($name);
|
}
|
}
|
|
return array_filter($icons);
|
}
|
|
public function getGroups():array
|
{
|
return array_keys(self::ICON_GROUPS);
|
}
|
|
private function findIconConfig(string $name):?array
|
{
|
foreach (self::ICON_GROUPS as $groupIcons) {
|
if (isset($groupIcons[$name])) {
|
return $groupIcons[$name];
|
}
|
}
|
return null;
|
}
|
|
private function buildIcon(string $name, array $options):?string
|
{
|
|
$filepath = $this->buildFilePath($name, $options['style']);
|
if (!file_exists($filepath)) {
|
error_log("Icon file not found: $filepath");
|
return null;
|
}
|
|
$svg = file_get_contents($filepath);
|
if ($svg === false) {
|
return null;
|
}
|
|
return $this->formatSvg($svg, $options);
|
}
|
|
private function buildFilePath(string $filename, string $style = ''):string
|
{
|
$svg = false;
|
if (str_contains($filename, '.svg')) {
|
$svg = true;
|
$nameExtra = '';
|
$path = '/assets/icons/';
|
} else {
|
$nameExtra = ($style === 'regular') ? '' : '-'.$style;
|
$path = '/assets/phosphor-icons/';
|
}
|
|
$filename = (str_contains($filename, '.svg')) ? $filename : $filename . $nameExtra . '.svg';
|
$style = ($style === '') ? '' : $style .'/';
|
$style = ($svg) ? '' : $style;
|
return JVB_DIR . $path . $style . $filename;
|
}
|
|
private function formatSvg(string $svg, array $options): string
|
{
|
// Clean up SVG
|
$svg = preg_replace("/([\n\t]+)/", ' ', $svg);
|
$svg = preg_replace('/>\s*</', '><', $svg);
|
|
// Add size attributes - FIXED: assign results back to $svg
|
if ($options['size'] !== 32) {
|
$svg = str_replace('width="32"', 'width="' . (int)$options['size'] . '"', $svg);
|
$svg = str_replace('height="32"', 'height="' . (int)$options['size'] . '"', $svg);
|
}
|
|
// Add color if provided - FIXED: assign results back to $svg
|
if ($options['color'] !== 'currentColor') {
|
$svg = str_replace('currentColor', $options['color'], $svg);
|
}
|
|
// Add title if provided
|
if (!empty($options['title'])) {
|
$svg = str_replace('<svg', '<svg title="' . esc_attr($options['title']) . '"', $svg);
|
$svg = str_replace('aria-hidden="true"', '', $svg);
|
}
|
|
$classes = trim('icon row ' . $this->name . ' ' . $options['class']);
|
if (array_key_exists('wrap', $options) && $options['wrap'] === false) {
|
return $svg;
|
}
|
return sprintf(
|
'<i class="%s">%s</i>',
|
esc_attr($classes),
|
$svg
|
);
|
}
|
|
/****************************
|
* Converts to CSS icon
|
***************************/
|
public function getCSSIcon(string $name, array $options = []): ?string
|
{
|
if (!$this->checkName($name)) {
|
return '';
|
}
|
$name = $this->checkMap($name);
|
$style = (array_key_exists('style', $options) && in_array($options['style'], $this->styles)) ? $options['style'] : 'regular';
|
|
$this->name = str_replace('.svg', '', $name);
|
|
// Merge options with defaults and icon config
|
$options = array_merge([
|
'title' => $options['label']??$this->getIconLabel($name),
|
'size' => $options['size'] ?? $this->size,
|
'style' => $style,
|
'class' => '',
|
'wrap' => true,
|
'color' => 'currentColor'
|
], $options);
|
|
$svg = $this->cache->remember(
|
array_merge($options, ['name' => $name, 'css' => true]),
|
function() use ($name, $options) {
|
return $this->buildRawSvg($name, $options);
|
}
|
);
|
// Convert to base64 data URI
|
$svg = ($svg) ? 'data:image/svg+xml;base64,' . base64_encode($svg) : null;
|
return $svg;
|
}
|
|
private function buildRawSvg(string $filename, array $options): ?string
|
{
|
$filepath = $this->buildFilePath($filename, $options['style']);
|
if (!file_exists($filepath)) {
|
error_log("Icon file not found: $filepath");
|
return null;
|
}
|
|
$svg = file_get_contents($filepath);
|
if ($svg === false) {
|
return null;
|
}
|
|
return $this->formatRawSvg($svg, $options);
|
}
|
|
private function formatRawSvg(string $svg, array $options): string
|
{
|
// Clean up SVG
|
$svg = preg_replace("/([\n\t]+)/", ' ', $svg);
|
$svg = preg_replace('/>\s*</', '><', $svg);
|
|
// Add size attributes - FIXED: assign results back to $svg
|
if ($options['size'] > 0) {
|
$svg = str_replace('width="32"', 'width="' . (int)$options['size'] . '"', $svg);
|
$svg = str_replace('height="32"', 'height="' . (int)$options['size'] . '"', $svg);
|
}
|
|
// Add color if provided and not currentColor - FIXED: assign results back to $svg
|
if ($options['color'] !== 'currentColor') {
|
$svg = str_replace('currentColor', $options['color'], $svg);
|
}
|
|
return $svg;
|
}
|
|
public function localizeIcons():array
|
{
|
if (empty($this->used)) {
|
return [];
|
}
|
$used = [];
|
foreach ($this->used as $style => $icons) {
|
foreach ($icons as $icon) {
|
$used[$icon] = $this->getIcon($icon, ['style' => $style]);
|
}
|
}
|
return $used;
|
}
|
|
public function getIconLabel(string $name): string
|
{
|
$name = str_replace('.svg', '', $name);
|
$label = (array_key_exists($name, $this->labels)) ? $this->labels[$name] : '';
|
|
$result = apply_filters('jvbIconLabel', $label, $name);
|
|
return $result;
|
}
|
}
|