<?php /** * Class SiteOrigin_Widget_Field_Icon */ class SiteOrigin_Widget_Field_Icon extends SiteOrigin_Widget_Field_Base { /** * The number of visible rows in the icons selector. * * @var int */ protected $rows = 3; protected $icons_callback; protected function initialize() { if ( ! empty( $this->default ) ) { $widget_icon_families = $this->get_widget_icon_families(); // If there are no icon families, don't proceed. if ( empty( $widget_icon_families ) ) { return; } $icon_families_styles = self::get_icon_families_styles( $widget_icon_families ); $value_parts = self::get_value_parts( $this->default, $icon_families_styles ); // Check if the font family of the default icon, and the icon exists. // The last check accounts for the Font Awesome Migration code that adds a default style. if ( ! isset( $widget_icon_families[ $value_parts['family'] ] ) || ! isset( $widget_icon_families[ $value_parts['family'] ]['icons'] ) || empty( $widget_icon_families[ $value_parts['family'] ]['icons'][ $value_parts['icon'] ] ) ) { $this->default = null; } } } protected function render_field( $value, $instance ) { $widget_icon_families = $this->get_widget_icon_families(); // Get an array of available icon families styles to pass to self::get_value_parts() $icon_families_styles = self::get_icon_families_styles( $widget_icon_families ); $value_parts = self::get_value_parts( $value, $icon_families_styles ); if ( ! empty( $value ) ) { $value_family = $value_parts['family']; $value_style = empty( $value_parts['style'] ) ? '' : ( '-' . $value_parts['style'] ); $value = $value_parts['family'] . $value_style . '-' . $value_parts['icon']; } else { $value_family = key( $widget_icon_families ); } ?> <div class="siteorigin-widget-icon-selector-current" tabindex="0"> <div class="siteorigin-widget-icon"> <span></span> <?php if ( ! empty( $value ) ) { echo '<span class="sow-icon-clear">' . siteorigin_widget_get_icon( $value, true ) . '</span>'; } ?> </div> <label> <?php echo esc_html__( 'Choose Icon', 'so-widgets-bundle' ); ?> </label> </div> <a class="so-icon-remove" style="display: <?php echo ! empty( $value ) ? 'inline-block' : 'none'; ?>;" tabindex="0"><?php esc_html_e( 'Remove', 'so-widgets-bundle' ); ?></a> <div class="clear"></div> <div class="siteorigin-widget-icon-selector siteorigin-widget-field-subcontainer"> <div class="siteorigin-widget-icon-selector-header"> <select class="siteorigin-widget-icon-family" > <?php foreach ( $widget_icon_families as $family_id => $family_info ) { ?> <option value="<?php echo esc_attr( $family_id ); ?>" <?php selected( $value_family, $family_id ); ?> <?php if ( ! empty( $this->icons_callback ) ) { echo 'data-icons="' . esc_attr( json_encode( $family_info ) ) . '"'; } ?> > <?php echo esc_html( $family_info['name'] ); ?> (<?php echo count( $family_info['icons'] ); ?>) </option> <?php } ?> </select> <?php if ( ! empty( $widget_icon_families[$value_family]['styles'] ) ) { $family_styles = $widget_icon_families[ $value_family ]['styles']; ?> <select class="siteorigin-widget-icon-family-styles"> <?php foreach ( $family_styles as $family_style => $family_style_name ) { ?> <option value="<?php echo esc_attr( $family_style ); ?>" <?php selected( $value_parts['style'], $family_style ); ?>> <?php echo esc_html( $family_style_name ); ?> </option> <?php } ?> </select> <?php }?> <input type="search" class="siteorigin-widget-icon-search" placeholder="<?php esc_attr_e( 'Search Icons', 'so-widgets-bundle' ); ?>" /> </div> <input type="hidden" name="<?php echo esc_attr( $this->element_name ); ?>" value="<?php echo esc_attr( $value ); ?>" class="siteorigin-widget-icon-icon siteorigin-widget-input" /> <div class="siteorigin-widget-icon-icons" style="height: <?php echo( $this->rows * 54 ) - 3; ?>px;"></div> </div> <?php } protected function sanitize_field_input( $value, $instance ) { $sanitized_value = $value; // Alphanumeric characters and hyphens. if ( preg_match( '/[\w\d]+[\w\d-]*/', $sanitized_value, $sanitized_matches ) ) { $sanitized_value = $sanitized_matches[0]; } else { $sanitized_value = ''; } $widget_icon_families = $this->get_widget_icon_families(); $icon_families_styles = self::get_icon_families_styles( $widget_icon_families ); $value_parts = self::get_value_parts( $sanitized_value, $icon_families_styles ); if ( ! ( isset( $widget_icon_families[$value_parts['family']] ) && isset( $widget_icon_families[$value_parts['family']]['icons'][$value_parts['icon']] ) ) ) { $sanitized_value = isset( $this->default ) ? $this->default : ''; } return $sanitized_value; } private function get_widget_icon_families() { if ( ! empty( $this->icons_callback ) ) { // We'll get the icons from the callback function $widget_icon_families = call_user_func( $this->icons_callback ); } else { // We'll get icons from the main filter $widget_icon_families = self::get_icon_families(); } return $widget_icon_families; } public static function get_icon_families() { static $widget_icon_families; if ( empty( $widget_icon_families ) ) { $widget_icon_families = apply_filters( 'siteorigin_widgets_icon_families', array() ); } return $widget_icon_families; } public static function get_value_parts( $value, $icon_families_styles = null ) { list( $value_family, $value_icon ) = ( ! empty( $value ) && strpos( $value, '-' ) !== false ) ? explode( '-', $value, 2 ) : array( '', '' ); // Check if icon families have styles. See $this->sanitize_field_input() if ( $icon_families_styles !== null ) { foreach ( $icon_families_styles as $icon_family => $icon_family_styles ) { foreach ( $icon_family_styles as $icon_family_style => $icon_family_style_name ) { // Check the icon value for matching styles if ( substr( $value_icon, 0, strlen( $icon_family_style ) ) === $icon_family_style ) { $value_icon = substr( $value_icon, strlen( $icon_family_style . '-' ) ); $value_style = $icon_family_style; break 2; } } } } // Trigger loading of the icon families and their filters. This isn't ideal, but necessary to ensure possible // migrations are available. self::get_icon_families(); $value_family = sanitize_text_field( $value_family ); return apply_filters( 'siteorigin_widgets_icon_migrate_' . $value_family, array( 'family' => $value_family, 'style' => ! empty( $value_style ) ? sanitize_text_field( $value_style ) : null, 'icon' => sanitize_text_field( $value_icon ), ) ); } public static function get_icon_families_styles( $widget_icon_families ) { // Store an array of icon family styles to pass to self::get_value_parts() $icon_families_styles = []; foreach ( $widget_icon_families as $key => $val ) { if ( array_key_exists( 'styles', $val ) ) { $icon_families_styles[ $key ] = $val[ 'styles' ]; } } return $icon_families_styles; } public function enqueue_scripts() { wp_enqueue_script( 'so-icon-field', plugin_dir_url( __FILE__ ) . 'js/icon-field' . SOW_BUNDLE_JS_SUFFIX . '.js', array( 'jquery' ), SOW_BUNDLE_VERSION ); wp_enqueue_style( 'so-icon-field', plugin_dir_url( __FILE__ ) . 'css/icon-field.css', array(), SOW_BUNDLE_VERSION ); } }