%s', esc_attr( (string) $stroke ), $svg ); } return $svg; } /** * Get all available icons * * @return array Associative array of icon_name => svg_markup. */ function airowp_get_all_icons() { static $icons = null; // Cache icons in static variable for performance. if ( null !== $icons ) { return $icons; } $icons = array( 'accordion' => '', 'arrow-down' => '', 'arrow-left' => '', 'arrow-right' => '', 'arrow-up' => '', 'at-sign' => '', 'bank' => '', 'barcode' => '', 'battery' => '', 'bell' => '', 'blocks' => '', 'book' => '', 'bookmark' => '', 'box' => '', 'briefcase' => '', 'building' => '', 'calendar' => '', 'camera' => '', 'car' => '', 'certificate' => '', 'chart' => '', 'chat' => '', 'check' => '', 'checkbox' => '', 'checkbox-checked' => '', 'chevron-left' => '', 'chevron-right' => '', 'circle-check' => '', 'clipboard' => '', 'clock' => '', 'cloud' => '', 'code' => '', 'coffee' => '', 'coin' => '', 'comment' => '', 'compass' => '', 'container' => '', 'copy' => '', 'counter' => '', 'countdown' => '', 'credit-card' => '', 'cursor-click' => '', 'database' => '', 'discord' => '', 'dollar' => '', 'download' => '', 'dropdown' => '', 'dumbbell' => '', 'edit' => '', 'envelope' => '', 'eye' => '', 'eye-off' => '', 'facebook' => '', 'file' => '', 'filter' => '', 'fire' => '', 'fitness' => '', 'flex' => '', 'flip-card' => '', 'folder' => '', 'form' => '', 'gift' => '', 'github' => '', 'globe' => '', 'graduation-cap' => '', 'grid' => '', 'handshake' => '', 'headphones' => '', 'heart' => '', 'home' => '', 'hotel' => '', 'icon-button' => '', 'icon-list' => '', 'image' => '', 'image-accordion' => '', 'info' => '', 'instagram' => '', 'keyboard' => '', 'layers' => '', 'leaf' => '', 'lightbulb' => '', 'lightning' => '', 'link' => '', 'linkedin' => '', 'list' => '', 'location' => '', 'lock' => '', 'medkit' => '', 'marquee' => '', 'menu' => '', 'microphone' => '', 'minus' => '', 'monitor' => '', 'moon' => '', 'mouse' => '', 'music' => '', 'number-field' => '', 'pause' => '', 'percentage' => '', 'phone' => '', 'pill' => '', 'pin' => '', 'pinterest' => '', 'plane' => '', 'play' => '', 'plus' => '', 'presentation' => '', 'printer' => '', 'progress-bar' => '', 'radio' => '', 'radio-checked' => '', 'quote' => '', 'receipt' => '', 'reddit' => '', 'refresh' => '', 'refresh-cw' => '', 'restaurant' => '', 'reveal' => '', 'rocket' => '', 'search' => '', 'send' => '', 'settings' => '', 'share' => '', 'shield' => '', 'shield-check' => '', 'shopping-cart' => '', 'slack' => '', 'slider' => '', 'smartphone' => '', 'speaker' => '', 'star' => '', 'stack' => '', 'store' => '', 'suitcase' => '', 'sun' => '', 'tablet' => '', 'tabs' => '', 'tag' => '', 'target' => '', 'text-field' => '', 'thumbs-up' => '', 'tiktok' => '', 'times' => '', 'toggle' => '', 'toggle-on' => '', 'trash' => '', 'trending-up' => '', 'trophy' => '', 'truck' => '', 'x' => '', // Backward compatibility: 'twitter' was renamed to 'x'. Existing saved blocks may reference data-icon-name="twitter". 'twitter' => '', 'unlock' => '', 'upload' => '', 'user' => '', 'users' => '', 'verified-check' => '', 'video' => '', 'wallet' => '', 'warning' => '', 'whatsapp' => '', 'wifi' => '', 'youtube' => '', ); return $icons; } /** * Get icon alias map. * * Maps alternate icon names to their canonical names in the icon library. * Single source of truth: data/icon-aliases.json (shared with JS). * * @return array Associative array of alias => canonical_name. */ function airowp_get_icon_aliases() { static $aliases = null; if ( null !== $aliases ) { return $aliases; } $file = __DIR__ . '/icon-aliases.json'; if ( ! file_exists( $file ) ) { $aliases = array(); return $aliases; } // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents, WordPressVIPMinimum.Performance.FetchingRemoteData.FileGetContentsUnknown -- Reading local plugin file. $aliases = json_decode( file_get_contents( $file ), true ) ?? array(); return $aliases; } /** * Sanitize icon slug to prevent XSS * * Allow only: lowercase letters, numbers, hyphens. * * @param string $icon Icon slug to sanitize. * @return string Sanitized icon slug. */ function airowp_sanitize_icon_slug( $icon ) { if ( empty( $icon ) || ! is_string( $icon ) ) { return ''; } // Only allow safe characters for icon names. return preg_replace( '/[^a-z0-9\-]/', '', strtolower( $icon ) ); } /** * Render accordion icon SVG * * Generates icon SVG for accordion items. * * @param string $icon_style Icon style (chevron, plus-minus, caret, none). * @param bool $is_open Whether accordion item is open. * @return string Icon HTML markup. */ function airowp_accordion_render_icon( $icon_style, $is_open ) { if ( 'none' === $icon_style ) { return ''; } $icon_svg = ''; switch ( $icon_style ) { case 'plus-minus': if ( $is_open ) { $icon_svg = ''; } else { $icon_svg = ''; } break; case 'caret': $icon_svg = ''; break; case 'chevron': default: $icon_svg = ''; } return ''; }