id, $menu_slug); } class Plugin { private $loader; private $handler; public function __construct() { $this->load_dependencies(); $this->init(); } public function run() { $this->loader->run(); $this->handler->run(); } private function load_dependencies() { require_once plugin_dir_path(dirname(__FILE__)).'includes/class-constants.php'; require_once plugin_dir_path(dirname(__FILE__)).'includes/class-loader.php'; require_once plugin_dir_path(dirname(__FILE__)).'includes/class-api.php'; require_once plugin_dir_path(dirname(__FILE__)).'includes/class-ajax-handler.php'; } private function init() { $this->loader = new Loader(); $this->loader->add_filter('upload_mimes', $this, 'allow_lordicon_mimes'); $this->loader->add_filter('wp_check_filetype_and_ext', $this, 'check_lordicon_filetype', 10, 4); $this->loader->add_filter('post_mime_types', $this, 'add_json_mime_types'); $this->loader->add_filter('wp_prepare_attachment_for_js', $this, 'prepare_json_attachment_for_js', 10, 3); if (is_admin()) { $this->loader->add_action('admin_enqueue_scripts', $this, 'enqueue_admin_assets'); $this->loader->add_action('enqueue_block_editor_assets', $this, 'enqueue_block_editor_assets'); $this->loader->add_action('admin_menu', $this, 'settings_init_menu'); $this->loader->add_action('admin_init', $this, 'settings_handle_form_submission'); $this->loader->add_filter('plugin_row_meta', $this, 'plugin_links', 10, 3); } else { $define_element = apply_filters('lordicon_define_element', true); if ($define_element) { $this->loader->add_action('wp_enqueue_scripts', $this, 'enqueue_frontend_assets'); } } // Block registration (both admin and frontend) $this->loader->add_action('init', $this, 'register_block_type'); $this->handler = new AjaxHandler(); } public function enqueue_admin_assets() { if (is_settings()) { wp_enqueue_script( 'lordicon-settings-script', plugins_url('/dist/settings.js', dirname(__FILE__)), array(), Constants::plugin_version(), false, ); wp_enqueue_style( 'lordicon-settings-css', plugins_url('/dist/settings.css', dirname(__FILE__)), array(), Constants::plugin_version() ); $this->patch_module('lordicon-settings-script', 'settings'); } } public function enqueue_block_editor_assets() { wp_enqueue_script( 'lordicon-block-js', plugins_url('/dist/block.js', dirname(__FILE__)), array('wp-blocks', 'wp-element', 'wp-components', 'wp-block-editor', 'wp-i18n'), Constants::plugin_version(), false, ); wp_enqueue_style( 'lordicon-block-css', plugins_url('/dist/block.css', dirname(__FILE__)), array('wp-edit-blocks'), Constants::plugin_version() ); $this->patch_module('lordicon-block-js', 'editor'); } public function enqueue_frontend_assets() { wp_enqueue_style( 'lordicon-element-style', plugins_url('/dist/element.css', dirname(__FILE__)), array(), Constants::plugin_version() ); wp_enqueue_script_module( 'lordicon-element-script', plugins_url('/dist/element.js', dirname(__FILE__)), array(), Constants::plugin_version(), ); } private function patch_module(string $scriptHandle, string $context) { $url = admin_url('admin-ajax.php'); $nonce = wp_create_nonce('lordicon_action'); $status = API::get_instance()->status()['data']; $variants = $status ? API::get_instance()->variants()['data'] : []; // Safely get post ID without using $_GET $post_id = 0; if ($context === 'editor') { $post = get_post(); if ($post && $post->ID) { $post_id = $post->ID; } } $config = [ 'url' => $url, 'nonce' => $nonce, 'status' => $status, 'variants' => $variants, 'postId' => $post_id, 'context' => $context, ]; wp_add_inline_script( $scriptHandle, 'window.__LORDICON__ = ' . wp_json_encode($config) . ';', 'after' ); // Patch the script tag to use type="module" add_filter('script_loader_tag', function ($tag, $handle, $src) use ($scriptHandle) { if ($scriptHandle !== $handle) return $tag; $search = sprintf('id="%s-js"', $scriptHandle); $replace = $search . ' type="module"'; return str_replace($search, $replace, $tag); }, 10, 3); } public function register_block_type() { register_block_type(dirname(__DIR__) . '/dist/block.json', array( 'render_callback' => array($this, 'render_block'), )); } public function settings_init_menu() { add_options_page( 'Lordicon Settings', 'Lordicon', 'manage_options', 'lordicon-settings', array($this, 'render_settings'), ); } public function settings_handle_form_submission() { // Check if form is submitted if ( ! isset( $_POST['lordicon_settings'], $_POST['lordicon_nonce'] ) ) { return; } // Sanitize nonce $nonce = sanitize_text_field( wp_unslash( $_POST['lordicon_nonce'] ) ); if ( ! wp_verify_nonce( $nonce, 'lordicon_settings_action' ) ) { return; } // Sanitize settings $settings = array_map( 'sanitize_text_field', (array) wp_unslash( $_POST['lordicon_settings'] ) ); // Save settings update_option( 'lordicon_settings', $settings ); // Message add_settings_error( 'lordicon_settings', 'settings_updated', 'Settings saved.', 'updated' ); } public function plugin_links($plugin_links, $plugin_file, $plugin_data) { $links = array(); if (isset($plugin_data['AuthorName']) && $plugin_data['AuthorName'] == 'Lordicon') { $links = array( 'Settings', ); } return array_merge($plugin_links, $links); } public function allow_lordicon_mimes($mimes) { if (!isset($mimes['json'])) { $mimes['json'] = 'application/json'; } if (!isset($mimes['svg'])) { $mimes['svg'] = 'image/svg+xml'; } return $mimes; } public function add_json_mime_types($mime_types) { $mime_types['application/json'] = array( __('Lordicon Files', 'lordicon'), __('Manage Lordicon Files', 'lordicon'), // translators: %s is the number of Lordicon files _n_noop('Lordicon File (%s)', 'Lordicon Files (%s)', 'lordicon'), ); return $mime_types; } public function prepare_json_attachment_for_js($response, $attachment, $meta) { if ($response['mime'] === 'application/json') { $response['icon'] = plugins_url('assets/lordicon-icon.png', dirname(__FILE__)); if (get_post_meta($attachment->ID, '_lordicon_type', true) === 'json') { $response['subtype'] = 'lordicon-json'; $response['title'] = $response['title']; } } return $response; } public function check_lordicon_filetype($data, $file, $filename, $mimes) { if (substr($filename, -5) === '.json') { $data['ext'] = 'json'; $data['type'] = 'application/json'; } if (substr($filename, -4) === '.svg') { $data['ext'] = 'svg'; $data['type'] = 'image/svg+xml'; } return $data; } public function render_block( $attributes, $content ) { $icon = $attributes['icon'] ?? null; $json_attachment_id = isset( $attributes['jsonAttachmentId'] ) ? intval( $attributes['jsonAttachmentId'] ) : 0; $svg_attachment_id = isset( $attributes['svgAttachmentId'] ) ? intval( $attributes['svgAttachmentId'] ) : 0; $anchor = $attributes['anchor'] ?? ''; $class_name = $attributes['className'] ?? ''; $display = $attributes['properties']['display'] ?? 'block'; $format = $attributes['properties']['format'] ?? 'json'; if ( ! $icon ) { return ''; } $json_src = $json_attachment_id ? wp_get_attachment_url( $json_attachment_id ) : ''; $svg_src = $svg_attachment_id ? wp_get_attachment_url( $svg_attachment_id ) : ''; // Classes $css_classes = [ 'lordicon-wrapper' ]; if ( 'block' !== $display ) { $css_classes[] = 'lordicon-wrapper-' . sanitize_html_class( $display ); } if ( ! empty( $class_name ) ) { $css_classes[] = sanitize_html_class( $class_name ); } $class_attr = esc_attr( implode( ' ', $css_classes ) ); // ID (anchor) $id_attr = ''; if ( ! empty( $anchor ) ) { $id_attr = ' id="' . esc_attr( $anchor ) . '"'; } // Prepare attributes as key => value (value true means boolean attr) $lord_icon_attrs = []; if ( $json_src ) { $lord_icon_attrs['src'] = esc_url( $json_src ); // trigger $allowed_triggers = [ 'in', 'hover', 'click', 'loop', 'morph' ]; $trigger = 'hover'; if ( ! empty( $attributes['properties']['state'] ) ) { $state_parts = explode( '-', $attributes['properties']['state'] ); $potential_trigger = $state_parts[0] ?? ''; if ( in_array( $potential_trigger, $allowed_triggers, true ) ) { $trigger = $potential_trigger; } } $lord_icon_attrs['trigger'] = $trigger; // size -> style attribute if ( ! empty( $attributes['properties']['size'] ) && intval( $attributes['properties']['size'] ) > 0 ) { $size_val = intval( $attributes['properties']['size'] ); $lord_icon_attrs['style'] = "width:{$size_val}px;height:{$size_val}px;"; } // stroke if ( isset( $attributes['properties']['stroke'] ) && $attributes['properties']['stroke'] !== 2 ) { $lord_icon_attrs['stroke'] = (string) $attributes['properties']['stroke']; } // colors (name:value,name:value) if ( ! empty( $attributes['properties']['colors'] ) && is_array( $attributes['properties']['colors'] ) ) { $color_pairs = []; foreach ( $attributes['properties']['colors'] as $name => $value ) { $color_pairs[] = sanitize_key( (string) $name ) . ':' . sanitize_text_field( (string) $value ); } $lord_icon_attrs['colors'] = implode( ',', $color_pairs ); } // state if ( ! empty( $attributes['properties']['state'] ) ) { $lord_icon_attrs['state'] = sanitize_text_field( $attributes['properties']['state'] ); } // speed (float with dot) if ( isset( $attributes['properties']['speed'] ) ) { $lord_icon_attrs['speed'] = number_format( floatval( $attributes['properties']['speed'] ), 2, '.', '' ); } // target if ( ! empty( $attributes['properties']['target'] ) ) { $lord_icon_attrs['target'] = sanitize_text_field( $attributes['properties']['target'] ); } // sequence (forces trigger=sequence) if ( ! empty( $attributes['properties']['sequence'] ) ) { $lord_icon_attrs['sequence'] = sanitize_text_field( $attributes['properties']['sequence'] ); $lord_icon_attrs['trigger'] = 'sequence'; } // intro (boolean attribute) $has_intro = ! empty( $attributes['properties']['intro'] ) && true === $attributes['properties']['intro']; // loading policy $lord_icon_attrs['loading'] = ( ! empty( $svg_src ) && ! $has_intro ) ? 'interaction' : 'lazy'; } ob_start(); ?>
> $value ) : ?> > 0 ) : ?> style="width:px;height:px;" />