Initial commit

This commit is contained in:
2020-04-07 13:03:04 +00:00
committed by Gitium
commit 00f842d9bf
1673 changed files with 471161 additions and 0 deletions

View File

@ -0,0 +1,430 @@
<?php
/**
* Front end functionalities
*
* @package Menu_Icons
* @author Dzikri Aziz <kvcrvt@gmail.com>
*/
final class Menu_Icons_Front_End {
/**
* Icon types
*
* @since 0.9.0
* @access protected
* @var array
*/
protected static $icon_types = array();
/**
* Default icon style
*
* @since 0.9.0
* @access protected
* @var array
*/
protected static $default_style = array(
'font_size' => array(
'property' => 'font-size',
'value' => '1.2',
'unit' => 'em',
),
'vertical_align' => array(
'property' => 'vertical-align',
'value' => 'middle',
'unit' => null,
),
'svg_width' => array(
'property' => 'width',
'value' => '1',
'unit' => 'em',
),
);
/**
* Hidden label class
*
* @since 0.9.0
* @access protected
* @var string
*/
protected static $hidden_label_class = 'visuallyhidden';
/**
* Add hooks for front-end functionalities
*
* @since 0.9.0
*/
public static function init() {
$active_types = Menu_Icons_Settings::get( 'global', 'icon_types' );
if ( empty( $active_types ) ) {
return;
}
foreach ( Menu_Icons::get( 'types' ) as $type ) {
if ( in_array( $type->id, $active_types, true ) ) {
self::$icon_types[ $type->id ] = $type;
}
}
/**
* Allow themes/plugins to override the hidden label class
*
* @since 0.8.0
* @param string $hidden_label_class Hidden label class.
* @return string
*/
self::$hidden_label_class = apply_filters( 'menu_icons_hidden_label_class', self::$hidden_label_class );
/**
* Allow themes/plugins to override default inline style
*
* @since 0.9.0
* @param array $default_style Default inline style.
* @return array
*/
self::$default_style = apply_filters( 'menu_icons_default_style', self::$default_style );
add_action( 'wp_enqueue_scripts', array( __CLASS__, '_enqueue_styles' ), 7 );
add_filter( 'wp_nav_menu_args', array( __CLASS__, '_add_menu_item_title_filter' ) );
add_filter( 'wp_nav_menu', array( __CLASS__, '_remove_menu_item_title_filter' ) );
}
/**
* Get nav menu ID based on arguments passed to wp_nav_menu()
*
* @since 0.3.0
* @param array $args wp_nav_menu() Arguments
* @return mixed Nav menu ID or FALSE on failure
*/
public static function get_nav_menu_id( $args ) {
$args = (object) $args;
$menu = wp_get_nav_menu_object( $args->menu );
// Get the nav menu based on the theme_location
if ( ! $menu
&& $args->theme_location
&& ( $locations = get_nav_menu_locations() )
&& isset( $locations[ $args->theme_location ] )
) {
$menu = wp_get_nav_menu_object( $locations[ $args->theme_location ] );
}
// get the first menu that has items if we still can't find a menu
if ( ! $menu && ! $args->theme_location ) {
$menus = wp_get_nav_menus();
foreach ( $menus as $menu_maybe ) {
if ( $menu_items = wp_get_nav_menu_items( $menu_maybe->term_id, array( 'update_post_term_cache' => false ) ) ) {
$menu = $menu_maybe;
break;
}
}
}
if ( is_object( $menu ) && ! is_wp_error( $menu ) ) {
return $menu->term_id;
} else {
return false;
}
}
/**
* Enqueue stylesheets
*
* @since 0.1.0
* @wp_hook action wp_enqueue_scripts
* @link http://codex.wordpress.org/Plugin_API/Action_Reference/wp_enqueue_scripts
*/
public static function _enqueue_styles() {
foreach ( self::$icon_types as $type ) {
if ( wp_style_is( $type->stylesheet_id, 'registered' ) ) {
wp_enqueue_style( $type->stylesheet_id );
}
}
/**
* Allow plugins/themes to override the extra stylesheet location
*
* @since 0.9.0
* @param string $extra_stylesheet_uri Extra stylesheet URI.
*/
$extra_stylesheet_uri = apply_filters(
'menu_icons_extra_stylesheet_uri',
sprintf( '%scss/extra%s.css', Menu_Icons::get( 'url' ), kucrut_get_script_suffix() )
);
wp_enqueue_style(
'menu-icons-extra',
$extra_stylesheet_uri,
false,
Menu_Icons::VERSION
);
}
/**
* Add filter to 'the_title' hook
*
* We need to filter the menu item title but **not** regular post titles.
* Thus, we're adding the filter when `wp_nav_menu()` is called.
*
* @since 0.1.0
* @wp_hook filter wp_nav_menu_args
* @param array $args Not used.
*
* @return array
*/
public static function _add_menu_item_title_filter( $args ) {
add_filter( 'the_title', array( __CLASS__, '_add_icon' ), 999, 2 );
return $args;
}
/**
* Remove filter from 'the_title' hook
*
* Because we don't want to filter post titles, we need to remove our
* filter when `wp_nav_menu()` exits.
*
* @since 0.1.0
* @wp_hook filter wp_nav_menu
* @param array $nav_menu Not used.
* @return array
*/
public static function _remove_menu_item_title_filter( $nav_menu ) {
remove_filter( 'the_title', array( __CLASS__, '_add_icon' ), 999, 2 );
return $nav_menu;
}
/**
* Add icon to menu item title
*
* @since 0.1.0
* @since 0.9.0 Renamed the method to `add_icon()`.
* @wp_hook filter the_title
* @param string $title Menu item title.
* @param int $id Menu item ID.
*
* @return string
*/
public static function _add_icon( $title, $id ) {
$meta = Menu_Icons_Meta::get( $id );
$icon = self::get_icon( $meta );
if ( empty( $icon ) ) {
return $title;
}
$title_class = ! empty( $meta['hide_label'] ) ? self::$hidden_label_class : '';
$title_wrapped = sprintf(
'<span%s>%s</span>',
( ! empty( $title_class ) ) ? sprintf( ' class="%s"', esc_attr( $title_class ) ) : '',
$title
);
if ( 'after' === $meta['position'] ) {
$title_with_icon = "{$title_wrapped}{$icon}";
} else {
$title_with_icon = "{$icon}{$title_wrapped}";
}
/**
* Allow plugins/themes to override menu item markup
*
* @since 0.8.0
*
* @param string $title_with_icon Menu item markup after the icon is added.
* @param integer $id Menu item ID.
* @param array $meta Menu item metadata values.
* @param string $title Original menu item title.
*
* @return string
*/
$title_with_icon = apply_filters( 'menu_icons_item_title', $title_with_icon, $id, $meta, $title );
return $title_with_icon;
}
/**
* Get icon
*
* @since 0.9.0
* @param array $meta Menu item meta value.
* @return string
*/
public static function get_icon( $meta ) {
$icon = '';
// Icon type is not set.
if ( empty( $meta['type'] ) ) {
return $icon;
}
// Icon is not set.
if ( empty( $meta['icon'] ) ) {
return $icon;
}
// Icon type is not registered/enabled.
if ( ! isset( self::$icon_types[ $meta['type'] ] ) ) {
return $icon;
}
$type = self::$icon_types[ $meta['type'] ];
$callbacks = array(
array( $type, 'get_icon' ),
array( __CLASS__, "get_{$type->id}_icon" ),
array( __CLASS__, "get_{$type->template_id}_icon" ),
);
foreach ( $callbacks as $callback ) {
if ( is_callable( $callback ) ) {
$icon = call_user_func( $callback, $meta );
break;
}
}
return $icon;
}
/**
* Get icon style
*
* @since 0.9.0
* @param array $meta Menu item meta value.
* @param array $keys Style properties.
* @param bool $as_attribute Optional. Whether to output the style as HTML attribute or value only.
* Defaults to TRUE.
* @return string
*/
public static function get_icon_style( $meta, $keys, $as_attribute = true ) {
$style_a = array();
$style_s = '';
foreach ( $keys as $key ) {
if ( ! isset( self::$default_style[ $key ] ) ) {
continue;
}
$rule = self::$default_style[ $key ];
if ( ! isset( $meta[ $key ] ) || $meta[ $key ] === $rule['value'] ) {
continue;
}
$value = $meta[ $key ];
if ( ! empty( $rule['unit'] ) ) {
$value .= $rule['unit'];
}
$style_a[ $rule['property'] ] = $value;
}
if ( empty( $style_a ) ) {
return $style_s;
}
foreach ( $style_a as $key => $value ) {
$style_s .= "{$key}:{$value};";
}
$style_s = esc_attr( $style_s );
if ( $as_attribute ) {
$style_s = sprintf( ' style="%s"', $style_s );
}
return $style_s;
}
/**
* Get icon classes
*
* @since 0.9.0
* @param array $meta Menu item meta value.
* @param string $output Whether to output the classes as string or array. Defaults to string.
* @return string|array
*/
public static function get_icon_classes( $meta, $output = 'string' ) {
$classes = array( '_mi' );
if ( empty( $meta['hide_label'] ) ) {
$classes[] = "_{$meta['position']}";
}
if ( 'string' === $output ) {
$classes = implode( ' ', $classes );
}
return $classes;
}
/**
* Get font icon
*
* @since 0.9.0
* @param array $meta Menu item meta value.
* @return string
*/
public static function get_font_icon( $meta ) {
$classes = sprintf( '%s %s %s', self::get_icon_classes( $meta ), $meta['type'], $meta['icon'] );
$style = self::get_icon_style( $meta, array( 'font_size', 'vertical_align' ) );
return sprintf( '<i class="%s" aria-hidden="true"%s></i>', esc_attr( $classes ), $style );
}
/**
* Get image icon
*
* @since 0.9.0
* @param array $meta Menu item meta value.
* @return string
*/
public static function get_image_icon( $meta ) {
$args = array(
'class' => sprintf( '%s _image', self::get_icon_classes( $meta ) ),
'aria-hidden' => 'true',
);
$style = self::get_icon_style( $meta, array( 'vertical_align' ), false );
if ( ! empty( $style ) ) {
$args['style'] = $style;
}
return wp_get_attachment_image( $meta['icon'], $meta['image_size'], false, $args );
}
/**
* Get SVG icon
*
* @since 0.9.0
* @param array $meta Menu item meta value.
* @return string
*/
public static function get_svg_icon( $meta ) {
$classes = sprintf( '%s _svg', self::get_icon_classes( $meta ) );
$style = self::get_icon_style( $meta, array( 'svg_width', 'vertical_align' ) );
return sprintf(
'<img src="%s" class="%s" aria-hidden="true"%s />',
esc_url( wp_get_attachment_url( $meta['icon'] ) ),
esc_attr( $classes ),
$style
);
}
}

View File

@ -0,0 +1,23 @@
<?php
/**
* Misc. functions for backward-compatibility.
*/
if ( ! function_exists( 'wp_get_attachment_image_url' ) ) {
/**
* Get the URL of an image attachment.
*
* @since 4.4.0
*
* @param int $attachment_id Image attachment ID.
* @param string|array $size Optional. Image size to retrieve. Accepts any valid image size, or an array
* of width and height values in pixels (in that order). Default 'thumbnail'.
* @param bool $icon Optional. Whether the image should be treated as an icon. Default false.
* @return string|false Attachment URL or false if no image is available.
*/
function wp_get_attachment_image_url( $attachment_id, $size = 'thumbnail', $icon = false ) {
$image = wp_get_attachment_image_src( $attachment_id, $size, $icon );
return isset( $image['0'] ) ? $image['0'] : false;
}
}

View File

@ -0,0 +1,575 @@
<?php
/**
* Form Fields
*
* A prototype for the new "Form Fields" plugin, a standalone plugin and
* extension for the upcoming "Settings" plugin, a rewrite of KC Settings.
*
* @author Dzikri Aziz <kvcrvt@gmail.com>
*/
/**
* Form Fields
*/
abstract class Kucrut_Form_Field {
/**
* Holds field & argument defaults
*
* @since 0.1.0
* @var array
* @access protected
*/
protected static $defaults = array(
'field' => array(
'id' => '',
'type' => 'text',
'value' => null,
'default' => null,
'attributes' => array(),
'description' => '',
'choices' => array(),
),
'args' => array(
'keys' => array(),
'inline_description' => false,
),
);
/**
* Holds field attributes
*
* @since 0.1.0
* @var array
* @access protected
*/
protected static $types = array(
'text' => 'Kucrut_Form_Field_Text',
'number' => 'Kucrut_Form_Field_Text',
'url' => 'Kucrut_Form_Field_Text',
'color' => 'Kucrut_Form_Field_Text',
'date' => 'Kucrut_Form_Field_Text',
'hidden' => 'Kucrut_Form_Field_Text',
'checkbox' => 'Kucrut_Form_Field_Checkbox',
'radio' => 'Kucrut_Form_Field_Radio',
'textarea' => 'Kucrut_Form_Field_Textarea',
'select' => 'Kucrut_Form_Field_Select',
'select_multiple' => 'Kucrut_Form_Field_Select_Multiple',
'select_pages' => 'Kucrut_Form_Field_Select_Pages',
'special' => 'Kucrut_Form_Field_Special',
);
/**
* Holds forbidden attributes
*
* @since 0.1.0
* @var array
* @access protected
*/
protected static $forbidden_attributes = array(
'id',
'name',
'value',
'checked',
'multiple',
);
/**
* Holds allowed html tags
*
* @since 0.1.0
* @var array
* @access protected
*/
protected $allowed_html = array(
'a' => array(
'href' => true,
'target' => true,
'title' => true,
),
'code' => true,
'em' => true,
'p' => array( 'class' => true ),
'span' => array( 'class' => true ),
'strong' => true,
);
/**
* Holds constructed field
*
* @since 0.1.0
* @var array
* @access protected
*/
protected $field;
/**
* Holds field attributes
*
* @since 0.1.0
* @var array
* @access protected
*/
protected $attributes = array();
/**
* Loader
*
* @param string URL path to this directory
*/
final public static function load( $url_path = null ) {
// Set URL path for assets
if ( ! is_null( $url_path ) ) {
self::$url_path = $url_path;
} else {
self::$url_path = plugin_dir_url( __FILE__ );
}
// Supported field types
self::$types = apply_filters(
'form_field_types',
self::$types
);
}
/**
* Create field
*
* @param array $field Field array
* @param array $args Extra field arguments
*/
final public static function create( array $field, $args = array() ) {
$field = wp_parse_args( $field, self::$defaults['field'] );
if ( ! isset( self::$types[ $field['type'] ] )
|| ! is_subclass_of( self::$types[ $field['type'] ], __CLASS__ )
) {
trigger_error(
sprintf(
esc_html__( '%1$s: Type %2$s is not supported, reverting to text.', 'menu-icons' ),
__CLASS__,
esc_html( $field['type'] )
),
E_USER_WARNING
);
$field['type'] = 'text';
}
if ( is_null( $field['value'] ) && ! is_null( $field['default'] ) ) {
$field['value'] = $field['default'];
}
foreach ( self::$forbidden_attributes as $key ) {
unset( $field['attributes'][ $key ] );
}
$args = (object) wp_parse_args( $args, self::$defaults['args'] );
$class = self::$types[ $field['type'] ];
return new $class( $field, $args );
}
/**
* Constructor
*
* @since 0.1.0
* @param array $field Field array
* @param object $args Extra field arguments
*/
public function __construct( $field, $args ) {
$this->field = $field;
$this->args = $args;
if ( ! is_array( $this->args->keys ) ) {
$this->args->keys = array();
}
$this->args->keys[] = $field['id'];
$this->attributes['id'] = $this->create_id();
$this->attributes['name'] = $this->create_name();
$this->attributes = wp_parse_args(
$this->attributes,
(array) $field['attributes']
);
$this->set_properties();
}
/**
* Attribute
*
* @since 0.1.0
* @param string $key Attribute key
* @return mixed NULL if attribute doesn't exist
*/
public function __get( $key ) {
foreach ( array( 'attributes', 'field' ) as $group ) {
if ( isset( $this->{$group}[ $key ] ) ) {
return $this->{$group}[ $key ];
}
}
return null;
}
/**
* Create id/name attribute
*
* @since 0.1.0
* @param string $format Attribute format
*/
protected function create_id_name( $format ) {
return call_user_func_array(
'sprintf',
array_merge(
array( $format ),
$this->args->keys
)
);
}
/**
* Create id attribute
*
* @since 0.1.0
* @access protected
* @return string
*/
protected function create_id() {
$format = implode( '-', $this->args->keys );
return $this->create_id_name( $format );
}
/**
* Create name attribute
*
* @since 0.1.0
* @access protected
* @return string
*/
protected function create_name() {
$format = '%s';
$format .= str_repeat( '[%s]', ( count( $this->args->keys ) - 1 ) );
return $this->create_id_name( $format );
}
/**
* Set field properties
*
* @since 0.1.0
*/
protected function set_properties() {}
/**
* Build field attributes
*
* @since 0.1.0
* @param array $excludes Attributes to be excluded
* @return string
*/
protected function build_attributes( $excludes = array() ) {
$excludes = array_filter( (array) $excludes );
$attributes = '';
foreach ( $this->attributes as $key => $value ) {
if ( in_array( $key, $excludes, true ) ) {
continue;
}
if ( 'class' === $key ) {
$value = implode( ' ', (array) $value );
}
$attributes .= sprintf(
' %s="%s"',
esc_attr( $key ),
esc_attr( $value )
);
}
return $attributes;
}
/**
* Print field
*
* @since 0.1.0
*/
abstract public function render();
/**
* Print field description
*
* @since 0.1.0
*/
public function description() {
if ( ! empty( $this->field['description'] ) ) {
$tag = ( ! empty( $this->args->inline_description ) ) ? 'span' : 'p';
printf( // WPCS: XSS ok.
'<%1$s class="description">%2$s</%1$s>',
$tag,
wp_kses( $this->field['description'], $this->allowed_html )
);
}
}
}
/**
* Field: text
*/
class Kucrut_Form_Field_Text extends Kucrut_Form_Field {
protected $template = '<input type="%s" value="%s"%s />';
protected function set_properties() {
if ( ! is_string( $this->field['value'] ) ) {
$this->field['value'] = '';
}
if ( in_array( $this->field['type'], array( 'text', 'url' ), true ) ) {
if ( ! isset( $this->attributes['class'] ) ) {
$this->attributes['class'] = array();
}
$this->attributes['class'] = array_unique(
array_merge(
array( 'regular-text' ),
$this->attributes['class']
)
);
}
}
public function render() {
printf( // WPCS: xss ok
$this->template,
esc_attr( $this->field['type'] ),
esc_attr( $this->field['value'] ),
$this->build_attributes()
);
$this->description();
}
}
/**
* Field: Textarea
*/
class Kucrut_Form_Field_Textarea extends Kucrut_Form_Field {
protected $template = '<textarea%s>%s</textarea>';
protected $attributes = array(
'class' => 'widefat',
'cols' => 50,
'rows' => 5,
);
public function render() {
printf( // WPCS: XSS ok.
$this->template,
$this->build_attributes(),
esc_textarea( $this->field['value'] )
);
}
}
/**
* Field: Checkbox
*/
class Kucrut_Form_Field_Checkbox extends Kucrut_Form_Field {
protected $template = '<label><input type="%s" value="%s"%s%s /> %s</label><br />';
protected function set_properties() {
$this->field['value'] = array_filter( (array) $this->field['value'] );
$this->attributes['name'] .= '[]';
}
protected function checked( $value ) {
return checked( in_array( $value, $this->field['value'], true ), true, false );
}
public function render() {
foreach ( $this->field['choices'] as $value => $label ) {
printf( // WPCS: XSS ok.
$this->template,
$this->field['type'],
esc_attr( $value ),
$this->checked( $value ),
$this->build_attributes( 'id' ),
esc_html( $label )
);
}
}
}
/**
* Field: Radio
*/
class Kucrut_Form_Field_Radio extends Kucrut_Form_Field_Checkbox {
protected function set_properties() {
if ( ! is_string( $this->field['value'] ) ) {
$this->field['value'] = '';
}
}
protected function checked( $value ) {
return checked( $value, $this->field['value'], false );
}
}
/**
* Field: Select
*/
class Kucrut_Form_Field_Select extends Kucrut_Form_Field {
protected $template = '<option value="%s"%s>%s</option>';
protected function set_properties() {
if ( ! is_string( $this->field['value'] ) ) {
$this->field['value'] = '';
}
}
protected function selected( $value ) {
return selected( ( $value === $this->field['value'] ), true, false );
}
public function render() {
?>
<select<?php echo $this->build_attributes() // xss ok ?>>
<?php foreach ( $this->field['choices'] as $index => $choice ) : ?>
<?php
if ( is_array( $choice ) ) {
$value = $choice['value'];
$label = $choice['label'];
} else {
$value = $index;
$label = $choice;
}
?>
<?php
printf( // WPCS: XSS ok.
$this->template,
esc_attr( $value ),
$this->selected( $value ),
esc_html( $label )
);
?>
<?php endforeach; ?>
</select>
<?php
}
}
/**
* Field: Multiple Select
*/
class Kucrut_Form_Field_Select_Multiple extends Kucrut_Form_Field_Select {
protected function set_properties() {
$this->field['value'] = array_filter( (array) $this->field['value'] );
$this->attributes['name'] .= '[]';
$this->attributes['multiple'] = 'multiple';
}
protected function selected( $value ) {
return selected( in_array( $value, $this->field['value'], true ), true, false );
}
}
/**
* Field: Select Pages
*/
class Kucrut_Form_Field_Select_Pages extends Kucrut_Form_Field_Select {
protected $wp_dropdown_pages_args = array(
'depth' => 0,
'child_of' => 0,
'option_none_value' => '',
);
public function __construct( $field, $args ) {
$this->wp_dropdown_pages_args['show_option_none'] = __( '&mdash; Select &mdash;', 'menu-icons' );
parent::__construct( $field, $args );
}
public function set_properties() {
parent::set_properties();
if ( empty( $this->args->wp_dropdown_pages_args ) ) {
$this->args->wp_dropdown_pages_args = array();
}
// Apply defeaults
$this->args->wp_dropdown_pages_args = wp_parse_args(
$this->args->wp_dropdown_pages_args,
$this->wp_dropdown_pages_args
);
// Force some args
$this->args->wp_dropdown_pages_args = array_merge(
$this->args->wp_dropdown_pages_args,
array(
'echo' => true,
'name' => $this->attributes['name'],
'id' => $this->attributes['id'],
'selected' => $this->field['value'],
)
);
}
public function render() {
wp_dropdown_pages( $this->args->wp_dropdown_pages_args ); // WPCS: XSS ok.
}
}
/**
* Field: Special (Callback)
*/
class Kucrut_Form_Field_Special extends Kucrut_Form_Field {
public function render() {
call_user_func_array(
$this->field['render_cb'],
array( $this )
);
}
}

View File

@ -0,0 +1,111 @@
<?php
/**
* Misc. helper functions
*
* @author Dzikri Aziz <kvcrvt@gmail.com>
*/
if ( ! function_exists( 'kucrut_get_array_value_deep' ) ) {
/**
* Get value of a multidimensional array
*
* @since 0.1.0
* @param array $array Haystack
* @param array $keys Needles
* @return mixed
*/
function kucrut_get_array_value_deep( array $array, array $keys ) {
if ( empty( $array ) || empty( $keys ) ) {
return $array;
}
foreach ( $keys as $idx => $key ) {
unset( $keys[ $idx ] );
if ( ! isset( $array[ $key ] ) ) {
return null;
}
if ( ! empty( $keys ) ) {
$array = $array[ $key ];
}
}
if ( ! isset( $array[ $key ] ) ) {
return null;
}
return $array[ $key ];
}
}
if ( ! function_exists( 'kucrut_validate' ) ) {
/**
* Validate settings values
*
* @param array $values Settings values
* @return array
*/
function kucrut_validate( $values, $sanitize_cb = 'wp_kses_data' ) {
foreach ( $values as $key => $value ) {
if ( is_array( $value ) ) {
$values[ $key ] = kucrut_validate( $value );
} else {
$values[ $key ] = call_user_func_array(
$sanitize_cb,
array( $value )
);
}
}
return $values;
}
}
if ( ! function_exists( 'kucrut_get_image_sizes' ) ) {
/**
* Get image sizes
*
* @since 0.9.0
* @access protected
* @return array
*/
function kucrut_get_image_sizes() {
$_sizes = array(
'thumbnail' => __( 'Thumbnail', 'menu-icons' ),
'medium' => __( 'Medium', 'menu-icons' ),
'large' => __( 'Large', 'menu-icons' ),
'full' => __( 'Full Size', 'menu-icons' ),
);
$_sizes = apply_filters( 'image_size_names_choose', $_sizes );
$sizes = array();
foreach ( $_sizes as $value => $label ) {
$sizes[] = array(
'value' => $value,
'label' => $label,
);
}
return $sizes;
}
}
if ( ! function_exists( 'kucrut_get_script_suffix' ) ) {
/**
* Get script & style suffix
*
* When SCRIPT_DEBUG is defined true, this will return '.min'.
*
* @return string
*/
function kucrut_get_script_suffix() {
return ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
}
}

View File

@ -0,0 +1,127 @@
<script type="text/html" id="tmpl-menu-icons-item-field-preview-font">
<i class="_icon {{data.type}} {{ data.icon }}"></i>
</script>
<script type="text/html" id="tmpl-menu-icons-item-field-preview-image">
<img src="{{ data.url }}" class="_icon" />
</script>
<script type="text/html" id="tmpl-menu-icons-item-field-preview-svg">
<img src="{{ data.url }}" class="_icon" />
</script>
<script type="text/html" id="tmpl-menu-icons-item-sidebar-preview-font-before">
<a href="#">
<i class="_icon {{ data.type }} {{ data.icon }} _{{ data.position }}"
style="font-size:{{ data.font_size }}em; vertical-align:{{ data.vertical_align }};"
></i>
<span>{{ data.title }}</span>
</a>
</script>
<script type="text/html" id="tmpl-menu-icons-item-sidebar-preview-font-after">
<a href="#">
<span>{{ data.title }}</span>
<i class="_icon {{ data.type }} {{ data.icon }} _{{ data.position }}"
style="font-size:{{ data.font_size }}em; vertical-align:{{ data.vertical_align }};"
></i>
</a>
</script>
<script type="text/html" id="tmpl-menu-icons-item-sidebar-preview-font-hide_label">
<a href="#">
<i class="_icon {{ data.type }} {{ data.icon }} _{{ data.position }}"
style="font-size:{{ data.font_size }}em; vertical-align:{{ data.vertical_align }};"
></i>
</a>
</script>
<script type="text/html" id="tmpl-menu-icons-item-sidebar-preview-image-before">
<a href="#">
<img src="{{ data.url }}"
alt="{{ data.alt }}"
class="_icon {{ data.type }} _{{ data.position }}"
style="vertical-align:{{ data.vertical_align }};"
/>
<span>{{ data.title }}</span>
</a>
</script>
<script type="text/html" id="tmpl-menu-icons-item-sidebar-preview-image-after">
<a href="#">
<span>{{ data.title }}</span>
<img src="{{ data.url }}"
alt="{{ data.alt }}"
class="_icon {{ data.type }} _{{ data.position }}"
style="vertical-align:{{ data.vertical_align }};"
/>
</a>
</script>
<script type="text/html" id="tmpl-menu-icons-item-sidebar-preview-image-hide_label">
<a href="#">
<img src="{{ data.url }}"
alt="{{ data.alt }}"
class="_icon {{ data.type }} _{{ data.position }}"
style="vertical-align:{{ data.vertical_align }};"
/>
</a>
</script>
<script type="text/html" id="tmpl-menu-icons-item-sidebar-preview-svg-before">
<a href="#">
<img src="{{ data.url }}"
alt="{{ data.alt }}"
class="_icon _{{data.type}}"
style="width:{{data.svg_width}}em;vertical-align:{{ data.vertical_align }}"
/>
<span>{{ data.title }}</span>
</a>
</script>
<script type="text/html" id="tmpl-menu-icons-item-sidebar-preview-svg-after">
<a href="#">
<span>{{ data.title }}</span>
<img src="{{ data.url }}"
alt="{{ data.alt }}"
class="_icon _{{data.type}}"
style="width:{{data.svg_width}}em;vertical-align:{{ data.vertical_align }}"
/>
</a>
</script>
<script type="text/html" id="tmpl-menu-icons-item-sidebar-preview-svg-hide_label">
<a href="#">
<img src="{{ data.url }}"
alt="{{ data.alt }}"
class="_icon _{{data.type}}"
style="width:{{data.svg_width}}em;vertical-align:{{ data.vertical_align }}"
/>
</a>
</script>
<script type="text/html" id="tmpl-menu-icons-settings-field-text">
<span>{{ data.label }}</span>
<input type="text" data-setting="{{ data.id }}" value="{{ data.value }}" />
</script>
<script type="text/html" id="tmpl-menu-icons-settings-field-number">
<span>{{ data.label }}</span>
<input type="number" min="{{ data.attributes.min }}" step="{{ data.attributes.step }}" data-setting="{{ data.id }}" value="{{ data.value }}" />
<# if ( data.description ) { #><em>{{ data.description }} </em><# } #>
</script>
<script type="text/html" id="tmpl-menu-icons-settings-field-select">
<span>{{ data.label }}</span>
<select data-setting="{{ data.id }}">
<# _.each( data.choices, function( choice ) { #>
<# if ( data.value === choice.value ) { #>
<option selected="selected" value="{{ choice.value }}">{{ choice.label }}</option>
<# } else { #>
<option value="{{ choice.value }}">{{ choice.label }}</option>
<# } #>
<# } ); #>
</select>
</script>
<?php do_action( 'menu_icons_js_templates' );

View File

@ -0,0 +1,154 @@
<?php
/**
* Menu item metadata
*
* @package Menu_Icons
* @author Dzikri Aziz <kvcrvt@gmail.com>
*/
final class Menu_Icons_Meta {
const KEY = 'menu-icons';
/**
* Default meta value
*
* @since 0.9.0
* @access protected
* @var array
*/
protected static $defaults = array(
'type' => '',
'icon' => '',
'url' => '',
);
/**
* Initialize metadata functionalities
*
* @since 0.9.0
*/
public static function init() {
add_filter( 'is_protected_meta', array( __CLASS__, '_protect_meta_key' ), 10, 3 );
}
/**
* Protect meta key
*
* This prevents our meta key from showing up on Custom Fields meta box.
*
* @since 0.3.0
* @wp_hook filter is_protected_meta
* @param bool $protected Protection status.
* @param string $meta_key Meta key.
* @param string $meta_type Meta type.
* @return bool Protection status.
*/
public static function _protect_meta_key( $protected, $meta_key, $meta_type ) {
if ( self::KEY === $meta_key ) {
$protected = true;
}
return $protected;
}
/**
* Get menu item meta value
*
* @since 0.3.0
* @since 0.9.0 Add $defaults parameter.
* @param int $id Menu item ID.
* @param array $defaults Optional. Default value.
* @return array
*/
public static function get( $id, $defaults = array() ) {
$defaults = wp_parse_args( $defaults, self::$defaults );
$value = get_post_meta( $id, self::KEY, true );
$value = wp_parse_args( (array) $value, $defaults );
// Backward-compatibility.
if ( empty( $value['icon'] ) &&
! empty( $value['type'] ) &&
! empty( $value[ "{$value['type']}-icon" ] )
) {
$value['icon'] = $value[ "{$value['type']}-icon" ];
}
if ( ! empty( $value['width'] ) ) {
$value['svg_width'] = $value['width'];
}
unset( $value['width'] );
if ( isset( $value['position'] ) &&
! in_array( $value['position'], array( 'before', 'after' ), true )
) {
$value['position'] = $defaults['position'];
}
if ( isset( $value['size'] ) && ! isset( $value['font_size'] ) ) {
$value['font_size'] = $value['size'];
unset( $value['size'] );
}
// The values below will NOT be saved
if ( ! empty( $value['icon'] ) &&
in_array( $value['type'], array( 'image', 'svg' ), true )
) {
$value['url'] = wp_get_attachment_image_url( $value['icon'], 'thumbnail', false );
}
return $value;
}
/**
* Update menu item metadata
*
* @since 0.9.0
*
* @param int $id Menu item ID.
* @param mixed $value Metadata value.
*
* @return void
*/
public static function update( $id, $value ) {
/**
* Allow plugins/themes to filter the values
*
* Deprecated.
*
* @since 0.1.0
* @param array $value Metadata value.
* @param int $id Menu item ID.
*/
$_value = apply_filters( 'menu_icons_values', $value, $id );
if ( $_value !== $value && WP_DEBUG ) {
_deprecated_function( 'menu_icons_values', '0.8.0', 'menu_icons_item_meta_values' );
}
/**
* Allow plugins/themes to filter the values
*
* @since 0.8.0
* @param array $value Metadata value.
* @param int $id Menu item ID.
*/
$value = apply_filters( 'menu_icons_item_meta_values', $_value, $id );
// Don't bother saving if `type` or `icon` is not set.
if ( empty( $value['type'] ) || empty( $value['icon'] ) ) {
$value = false;
}
// Update
if ( ! empty( $value ) ) {
update_post_meta( $id, self::KEY, $value );
} else {
delete_post_meta( $id, self::KEY );
}
}
}

View File

@ -0,0 +1,302 @@
<?php
/**
* Menu editor handler
*
* @package Menu_Icons
* @author Dzikri Aziz <kvcrvt@gmail.com>
*/
/**
* Nav menu admin
*/
final class Menu_Icons_Picker {
/**
* Initialize class
*
* @since 0.1.0
*/
public static function init() {
add_action( 'load-nav-menus.php', array( __CLASS__, '_load_nav_menus' ) );
add_filter( 'wp_edit_nav_menu_walker', array( __CLASS__, '_filter_wp_edit_nav_menu_walker' ), 99 );
add_filter( 'wp_nav_menu_item_custom_fields', array( __CLASS__, '_fields' ), 10, 4 );
add_filter( 'manage_nav-menus_columns', array( __CLASS__, '_columns' ), 99 );
add_action( 'wp_update_nav_menu_item', array( __CLASS__, '_save' ), 10, 3 );
add_filter( 'icon_picker_type_props', array( __CLASS__, '_add_extra_type_props_data' ), 10, 3 );
}
/**
* Load Icon Picker
*
* @since 0.9.0
* @wp_hook action load-nav-menus.php
*/
public static function _load_nav_menus() {
Icon_Picker::instance()->load();
add_action( 'print_media_templates', array( __CLASS__, '_media_templates' ) );
}
/**
* Custom walker
*
* @since 0.3.0
* @access protected
* @wp_hook filter wp_edit_nav_menu_walker
*/
public static function _filter_wp_edit_nav_menu_walker( $walker ) {
// Load menu item custom fields plugin
if ( ! class_exists( 'Menu_Item_Custom_Fields_Walker' ) ) {
require_once Menu_Icons::get( 'dir' ) . 'includes/library/menu-item-custom-fields/walker-nav-menu-edit.php';
}
$walker = 'Menu_Item_Custom_Fields_Walker';
return $walker;
}
/**
* Get menu item setting fields
*
* @since 0.9.0
* @access protected
* @param array $meta Menu item meta value.
* @return array
*/
protected static function _get_menu_item_fields( $meta ) {
$fields = array_merge(
array(
array(
'id' => 'type',
'label' => __( 'Type', 'menu-icons' ),
'value' => $meta['type'],
),
array(
'id' => 'icon',
'label' => __( 'Icon', 'menu-icons' ),
'value' => $meta['icon'],
),
),
Menu_Icons_Settings::get_settings_fields( $meta )
);
return $fields;
}
/**
* Print fields
*
* @since 0.1.0
* @access protected
* @uses add_action() Calls 'menu_icons_before_fields' hook
* @uses add_action() Calls 'menu_icons_after_fields' hook
* @wp_hook action menu_item_custom_fields
*
* @param object $item Menu item data object.
* @param int $depth Nav menu depth.
* @param array $args Menu item args.
* @param int $id Nav menu ID.
*
* @return string Form fields
*/
public static function _fields( $id, $item, $depth, $args ) {
$input_id = sprintf( 'menu-icons-%d', $item->ID );
$input_name = sprintf( 'menu-icons[%d]', $item->ID );
$menu_settings = Menu_Icons_Settings::get_menu_settings( Menu_Icons_Settings::get_current_menu_id() );
$meta = Menu_Icons_Meta::get( $item->ID, $menu_settings );
$fields = self::_get_menu_item_fields( $meta );
?>
<div class="field-icon description-wide menu-icons-wrap" data-id="<?php echo json_encode( $item->ID ); ?>">
<?php
/**
* Allow plugins/themes to inject HTML before menu icons' fields
*
* @param object $item Menu item data object.
* @param int $depth Nav menu depth.
* @param array $args Menu item args.
* @param int $id Nav menu ID.
*
*/
do_action( 'menu_icons_before_fields', $item, $depth, $args, $id );
?>
<p class="description submitbox">
<label><?php esc_html_e( 'Icon:', 'menu-icons' ) ?></label>
<?php printf( '<a class="_select">%s</a>', esc_html__( 'Select', 'menu-icons' ) ); ?>
<?php printf( '<a class="_remove submitdelete hidden">%s</a>', esc_html__( 'Remove', 'menu-icons' ) ); ?>
</p>
<div class="_settings hidden">
<?php
foreach ( $fields as $field ) {
printf(
'<label>%1$s: <input type="text" name="%2$s" class="_mi-%3$s" value="%4$s" /></label><br />',
esc_html( $field['label'] ),
esc_attr( "{$input_name}[{$field['id']}]" ),
esc_attr( $field['id'] ),
esc_attr( $field['value'] )
);
}
// The fields below will not be saved. They're only used for the preview.
printf( '<input type="hidden" class="_mi-url" value="%s" />', esc_attr( $meta['url'] ) );
?>
</div>
<?php
/**
* Allow plugins/themes to inject HTML after menu icons' fields
*
* @param object $item Menu item data object.
* @param int $depth Nav menu depth.
* @param array $args Menu item args.
* @param int $id Nav menu ID.
*
*/
do_action( 'menu_icons_after_fields', $item, $depth, $args, $id );
?>
</div>
<?php
}
/**
* Add our field to the screen options toggle
*
* @since 0.1.0
* @access private
* @wp_hook action manage_nav-menus_columns
* @link http://codex.wordpress.org/Plugin_API/Filter_Reference/manage_posts_columns
*
* @param array $columns Menu item columns
*
* @return array
*/
public static function _columns( $columns ) {
$columns['icon'] = __( 'Icon', 'menu-icons' );
return $columns;
}
/**
* Save menu item's icons metadata
*
* @since 0.1.0
* @access protected
* @wp_hook action wp_update_nav_menu_item
* @link http://codex.wordpress.org/Plugin_API/Action_Reference/wp_update_nav_menu_item
*
* @param int $menu_id Nav menu ID.
* @param int $menu_item_db_id Menu item ID.
* @param array $menu_item_args Menu item data.
*/
public static function _save( $menu_id, $menu_item_db_id, $menu_item_args ) {
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
return;
}
$screen = get_current_screen();
if ( ! $screen instanceof WP_Screen || 'nav-menus' !== $screen->id ) {
return;
}
check_admin_referer( 'update-nav_menu', 'update-nav-menu-nonce' );
// Sanitize
if ( ! empty( $_POST['menu-icons'][ $menu_item_db_id ] ) ) {
$value = array_map(
'sanitize_text_field',
wp_unslash( (array) $_POST['menu-icons'][ $menu_item_db_id ] )
);
} else {
$value = array();
}
Menu_Icons_Meta::update( $menu_item_db_id, $value );
}
/**
* Get and print media templates from all types
*
* @since 0.2.0
* @since 0.9.0 Deprecate menu_icons_media_templates filter.
* @wp_hook action print_media_templates
*/
public static function _media_templates() {
$id_prefix = 'tmpl-menu-icons';
// Deprecated.
$templates = apply_filters( 'menu_icons_media_templates', array() );
if ( ! empty( $templates ) ) {
if ( WP_DEBUG ) {
_deprecated_function( 'menu_icons_media_templates', '0.9.0', 'menu_icons_js_templates' );
}
foreach ( $templates as $key => $template ) {
$id = sprintf( '%s-%s', $id_prefix, $key );
self::_print_tempate( $id, $template );
}
}
require_once dirname( __FILE__ ) . '/media-template.php';
}
/**
* Print media template
*
* @since 0.2.0
* @param string $id Template ID.
* @param string $template Media template HTML.
*/
protected static function _print_tempate( $id, $template ) {
?>
<script type="text/html" id="<?php echo esc_attr( $id ) ?>">
<?php echo $template; // xss ok ?>
</script>
<?php
}
/**
* Add extra icon type properties data
*
* @since 0.9.0
* @wp_hook action icon_picker_type_props
*
* @param array $props Icon type properties.
* @param string $id Icon type ID.
* @param Icon_Picker_Type $type Icon_Picker_Type object.
*
* @return array
*/
public static function _add_extra_type_props_data( $props, $id, $type ) {
$settings_fields = array(
'hide_label',
'position',
'vertical_align',
);
if ( 'Font' === $props['controller'] ) {
$settings_fields[] = 'font_size';
}
switch ( $id ) {
case 'image':
$settings_fields[] = 'image_size';
break;
case 'svg':
$settings_fields[] = 'svg_width';
break;
}
$props['data']['settingsFields'] = $settings_fields;
return $props;
}
}

View File

@ -0,0 +1,746 @@
<?php
/**
* Settings
*
* @package Menu_Icons
* @author Dzikri Aziz <kvcrvt@gmail.com>
*/
/**
* Menu Icons Settings module
*/
final class Menu_Icons_Settings {
const UPDATE_KEY = 'menu-icons-settings-update';
const RESET_KEY = 'menu-icons-settings-reset';
const TRANSIENT_KEY = 'menu_icons_message';
/**
* Default setting values
*
* @since 0.3.0
* @var array
* @access protected
*/
protected static $defaults = array(
'global' => array(
'icon_types' => array( 'dashicons' ),
),
);
/**
* Setting values
*
* @since 0.3.0
* @var array
* @access protected
*/
protected static $settings = array();
/**
* Script dependencies
*
* @since 0.9.0
* @access protected
* @var array
*/
protected static $script_deps = array( 'jquery' );
/**
* Settings init
*
* @since 0.3.0
*/
public static function init() {
/**
* Allow themes/plugins to override the default settings
*
* @since 0.9.0
*
* @param array $default_settings Default settings.
*/
self::$defaults = apply_filters( 'menu_icons_settings_defaults', self::$defaults );
self::$settings = get_option( 'menu-icons', self::$defaults );
foreach ( self::$settings as $key => &$value ) {
if ( 'global' === $key ) {
// Remove unregistered icon types.
$value['icon_types'] = array_values(
array_intersect(
array_keys( Menu_Icons::get( 'types' ) ),
array_filter( (array) $value['icon_types'] )
)
);
} else {
// Backward-compatibility.
if ( isset( $value['width'] ) && ! isset( $value['svg_width'] ) ) {
$value['svg_width'] = $value['width'];
}
unset( $value['width'] );
}
}
unset( $value );
/**
* Allow themes/plugins to override the settings
*
* @since 0.9.0
*
* @param array $settings Menu Icons settings.
*/
self::$settings = apply_filters( 'menu_icons_settings', self::$settings );
if ( self::is_menu_icons_disabled_for_menu() ) {
return;
}
if ( ! empty( self::$settings['global']['icon_types'] ) ) {
require_once Menu_Icons::get( 'dir' ) . 'includes/picker.php';
Menu_Icons_Picker::init();
self::$script_deps[] = 'icon-picker';
}
add_action( 'load-nav-menus.php', array( __CLASS__, '_load_nav_menus' ), 1 );
add_action( 'wp_ajax_menu_icons_update_settings', array( __CLASS__, '_ajax_menu_icons_update_settings' ) );
}
/**
* Check if menu icons is disabled for a menu
*
* @since 0.8.0
*
* @param int $menu_id Menu ID. Defaults to current menu being edited.
*
* @return bool
*/
public static function is_menu_icons_disabled_for_menu( $menu_id = 0 ) {
if ( empty( $menu_id ) ) {
$menu_id = self::get_current_menu_id();
}
// When we're creating a new menu or the recently edited menu
// could not be found.
if ( empty( $menu_id ) ) {
return true;
}
$menu_settings = self::get_menu_settings( $menu_id );
$is_disabled = ! empty( $menu_settings['disabled'] );
return $is_disabled;
}
/**
* Get ID of menu being edited
*
* @since 0.7.0
* @since 0.8.0 Get the recently edited menu from user option.
*
* @return int
*/
public static function get_current_menu_id() {
global $nav_menu_selected_id;
if ( ! empty( $nav_menu_selected_id ) ) {
return $nav_menu_selected_id;
}
if ( is_admin() && isset( $_REQUEST['menu'] ) ) {
$menu_id = absint( $_REQUEST['menu'] );
} else {
$menu_id = absint( get_user_option( 'nav_menu_recently_edited' ) );
}
return $menu_id;
}
/**
* Get menu settings
*
* @since 0.3.0
*
* @param int $menu_id
*
* @return array
*/
public static function get_menu_settings( $menu_id ) {
$menu_settings = self::get( sprintf( 'menu_%d', $menu_id ) );
$menu_settings = apply_filters( 'menu_icons_menu_settings', $menu_settings, $menu_id );
if ( ! is_array( $menu_settings ) ) {
$menu_settings = array();
}
return $menu_settings;
}
/**
* Get setting value
*
* @since 0.3.0
* @return mixed
*/
public static function get() {
$args = func_get_args();
return kucrut_get_array_value_deep( self::$settings, $args );
}
/**
* Prepare wp-admin/nav-menus.php page
*
* @since 0.3.0
* @wp_hook action load-nav-menus.php
*/
public static function _load_nav_menus() {
add_action( 'admin_enqueue_scripts', array( __CLASS__, '_enqueue_assets' ), 99 );
/**
* Allow settings meta box to be disabled.
*
* @since 0.4.0
*
* @param bool $disabled Defaults to FALSE.
*/
$settings_disabled = apply_filters( 'menu_icons_disable_settings', false );
if ( true === $settings_disabled ) {
return;
}
self::_maybe_update_settings();
self::_add_settings_meta_box();
add_action( 'admin_notices', array( __CLASS__, '_admin_notices' ) );
}
/**
* Update settings
*
* @since 0.3.0
*/
public static function _maybe_update_settings() {
if ( ! empty( $_POST['menu-icons']['settings'] ) ) {
check_admin_referer( self::UPDATE_KEY, self::UPDATE_KEY );
$redirect_url = self::_update_settings( $_POST['menu-icons']['settings'] ); // Input var okay.
wp_redirect( $redirect_url );
} elseif ( ! empty( $_REQUEST[ self::RESET_KEY ] ) ) {
check_admin_referer( self::RESET_KEY, self::RESET_KEY );
wp_redirect( self::_reset_settings() );
}
}
/**
* Update settings
*
* @since 0.7.0
* @access protected
*
* @param array $values Settings values.
*
* @return string Redirect URL.
*/
protected static function _update_settings( $values ) {
update_option(
'menu-icons',
wp_parse_args(
kucrut_validate( $values ),
self::$settings
)
);
set_transient( self::TRANSIENT_KEY, 'updated', 30 );
$redirect_url = remove_query_arg(
array( 'menu-icons-reset' ),
wp_get_referer()
);
return $redirect_url;
}
/**
* Reset settings
*
* @since 0.7.0
* @access protected
* @return string Redirect URL.
*/
protected static function _reset_settings() {
delete_option( 'menu-icons' );
set_transient( self::TRANSIENT_KEY, 'reset', 30 );
$redirect_url = remove_query_arg(
array( self::RESET_KEY, 'menu-icons-updated' ),
wp_get_referer()
);
return $redirect_url;
}
/**
* Settings meta box
*
* @since 0.3.0
* @access private
*/
private static function _add_settings_meta_box() {
add_meta_box(
'menu-icons-settings',
__( 'Menu Icons Settings', 'menu-icons' ),
array( __CLASS__, '_meta_box' ),
'nav-menus',
'side',
'low',
array()
);
}
/**
* Update settings via ajax
*
* @since 0.7.0
* @wp_hook action wp_ajax_menu_icons_update_settings
*/
public static function _ajax_menu_icons_update_settings() {
check_ajax_referer( self::UPDATE_KEY, self::UPDATE_KEY );
if ( empty( $_POST['menu-icons']['settings'] ) ) {
wp_send_json_error();
}
$redirect_url = self::_update_settings( $_POST['menu-icons']['settings'] ); // Input var okay.
wp_send_json_success( array( 'redirectUrl' => $redirect_url ) );
}
/**
* Print admin notices
*
* @since 0.3.0
* @wp_hook action admin_notices
*/
public static function _admin_notices() {
$messages = array(
'updated' => __( '<strong>Menu Icons Settings</strong> have been successfully updated.', 'menu-icons' ),
'reset' => __( '<strong>Menu Icons Settings</strong> have been successfully reset.', 'menu-icons' ),
);
$message_type = get_transient( self::TRANSIENT_KEY );
if ( ! empty( $message_type ) && ! empty( $messages[ $message_type ] ) ) {
printf(
'<div class="updated notice is-dismissible"><p>%s</p></div>',
wp_kses( $messages[ $message_type ], array( 'strong' => true ) )
);
}
delete_transient( self::TRANSIENT_KEY );
}
/**
* Settings meta box
*
* @since 0.3.0
*/
public static function _meta_box() {
?>
<div class="taxonomydiv">
<ul id="menu-icons-settings-tabs" class="taxonomy-tabs add-menu-item-tabs hide-if-no-js">
<?php foreach ( self::get_fields() as $section ) : ?>
<?php
printf(
'<li><a href="#" title="%s" class="mi-settings-nav-tab" data-type="menu-icons-settings-%s">%s</a></li>',
esc_attr( $section['description'] ),
esc_attr( $section['id'] ),
esc_html( $section['title'] )
);
?>
<?php endforeach; ?>
<?php
printf(
'<li><a href="#" class="mi-settings-nav-tab" data-type="menu-icons-settings-extensions">%s</a></li>',
esc_html__( 'Extensions', 'menu-icons' )
);
?>
</ul>
<?php foreach ( self::_get_fields() as $section_index => $section ) : ?>
<div id="menu-icons-settings-<?php echo esc_attr( $section['id'] ) ?>"
class="tabs-panel _<?php echo esc_attr( $section_index ) ?>">
<h4 class="hide-if-js"><?php echo esc_html( $section['title'] ) ?></h4>
<?php foreach ( $section['fields'] as $field ) : ?>
<div class="_field">
<?php
printf(
'<label for="%s" class="_main">%s</label>',
esc_attr( $field->id ),
esc_html( $field->label )
);
?>
<?php $field->render() ?>
</div>
<?php endforeach; ?>
</div>
<?php endforeach; ?>
<div id="menu-icons-settings-extensions" class="tabs-panel _extensions">
<h4 class="hide-if-js"><?php echo esc_html__( 'Extensions', 'menu-icons' ) ?></h4>
<ul>
<li><a target="_blank" href="http://wordpress.org/plugins/menu-icons-icomoon/">IcoMoon</a></li>
</ul>
</div>
</div>
<p class="submitbox button-controls">
<?php wp_nonce_field( self::UPDATE_KEY, self::UPDATE_KEY ) ?>
<span class="list-controls">
<?php
printf(
'<a href="%s" title="%s" class="select-all submitdelete">%s</a>',
esc_url(
wp_nonce_url(
admin_url( '/nav-menus.php' ),
self::RESET_KEY,
self::RESET_KEY
)
),
esc_attr__( 'Discard all changes and reset to default state', 'menu-icons' ),
esc_html__( 'Reset', 'menu-icons' )
);
?>
</span>
<span class="add-to-menu">
<span class="spinner"></span>
<?php
submit_button(
__( 'Save Settings', 'menu-icons' ),
'secondary',
'menu-icons-settings-save',
false
);
?>
</span>
</p>
<?php
}
/**
* Get settings sections
*
* @since 0.3.0
* @uses apply_filters() Calls 'menu_icons_settings_sections'.
* @return array
*/
public static function get_fields() {
$menu_id = self::get_current_menu_id();
$icon_types = wp_list_pluck( Menu_Icons::get( 'types' ), 'name' );
asort( $icon_types );
$sections = array(
'global' => array(
'id' => 'global',
'title' => __( 'Global', 'menu-icons' ),
'description' => __( 'Global settings', 'menu-icons' ),
'fields' => array(
array(
'id' => 'icon_types',
'type' => 'checkbox',
'label' => __( 'Icon Types', 'menu-icons' ),
'choices' => $icon_types,
'value' => self::get( 'global', 'icon_types' ),
),
),
'args' => array(),
),
);
if ( ! empty( $menu_id ) ) {
$menu_term = get_term( $menu_id, 'nav_menu' );
$menu_key = sprintf( 'menu_%d', $menu_id );
$menu_settings = self::get_menu_settings( $menu_id );
$sections['menu'] = array(
'id' => $menu_key,
'title' => __( 'Current Menu', 'menu-icons' ),
'description' => sprintf(
__( '"%s" menu settings', 'menu-icons' ),
apply_filters( 'single_term_title', $menu_term->name )
),
'fields' => self::get_settings_fields( $menu_settings ),
'args' => array( 'inline_description' => true ),
);
}
return apply_filters( 'menu_icons_settings_sections', $sections, $menu_id );
}
/**
* Get settings fields
*
* @since 0.4.0
*
* @param array $values Values to be applied to each field.
*
* @uses apply_filters() Calls 'menu_icons_settings_fields'.
* @return array
*/
public static function get_settings_fields( array $values = array() ) {
$fields = array(
'hide_label' => array(
'id' => 'hide_label',
'type' => 'select',
'label' => __( 'Hide Label', 'menu-icons' ),
'default' => '',
'choices' => array(
array(
'value' => '',
'label' => __( 'No', 'menu-icons' ),
),
array(
'value' => '1',
'label' => __( 'Yes', 'menu-icons' ),
),
),
),
'position' => array(
'id' => 'position',
'type' => 'select',
'label' => __( 'Position', 'menu-icons' ),
'default' => 'before',
'choices' => array(
array(
'value' => 'before',
'label' => __( 'Before', 'menu-icons' ),
),
array(
'value' => 'after',
'label' => __( 'After', 'menu-icons' ),
),
),
),
'vertical_align' => array(
'id' => 'vertical_align',
'type' => 'select',
'label' => __( 'Vertical Align', 'menu-icons' ),
'default' => 'middle',
'choices' => array(
array(
'value' => 'super',
'label' => __( 'Super', 'menu-icons' ),
),
array(
'value' => 'top',
'label' => __( 'Top', 'menu-icons' ),
),
array(
'value' => 'text-top',
'label' => __( 'Text Top', 'menu-icons' ),
),
array(
'value' => 'middle',
'label' => __( 'Middle', 'menu-icons' ),
),
array(
'value' => 'baseline',
'label' => __( 'Baseline', 'menu-icons' ),
),
array(
'value' => 'text-bottom',
'label' => __( 'Text Bottom', 'menu-icons' ),
),
array(
'value' => 'bottom',
'label' => __( 'Bottom', 'menu-icons' ),
),
array(
'value' => 'sub',
'label' => __( 'Sub', 'menu-icons' ),
),
),
),
'font_size' => array(
'id' => 'font_size',
'type' => 'number',
'label' => __( 'Font Size', 'menu-icons' ),
'default' => '1.2',
'description' => 'em',
'attributes' => array(
'min' => '0.1',
'step' => '0.1',
),
),
'svg_width' => array(
'id' => 'svg_width',
'type' => 'number',
'label' => __( 'SVG Width', 'menu-icons' ),
'default' => '1',
'description' => 'em',
'attributes' => array(
'min' => '.5',
'step' => '.1',
),
),
'image_size' => array(
'id' => 'image_size',
'type' => 'select',
'label' => __( 'Image Size', 'menu-icons' ),
'default' => 'thumbnail',
'choices' => kucrut_get_image_sizes(),
),
);
$fields = apply_filters( 'menu_icons_settings_fields', $fields );
foreach ( $fields as &$field ) {
if ( isset( $values[ $field['id'] ] ) ) {
$field['value'] = $values[ $field['id'] ];
}
if ( ! isset( $field['value'] ) && isset( $field['default'] ) ) {
$field['value'] = $field['default'];
}
}
unset( $field );
return $fields;
}
/**
* Get processed settings fields
*
* @since 0.3.0
* @access private
* @return array
*/
private static function _get_fields() {
if ( ! class_exists( 'Kucrut_Form_Field' ) ) {
require_once Menu_Icons::get( 'dir' ) . 'includes/library/form-fields.php';
}
$keys = array( 'menu-icons', 'settings' );
$sections = self::get_fields();
foreach ( $sections as &$section ) {
$_keys = array_merge( $keys, array( $section['id'] ) );
$_args = array_merge( array( 'keys' => $_keys ), $section['args'] );
foreach ( $section['fields'] as &$field ) {
$field = Kucrut_Form_Field::create( $field, $_args );
}
unset( $field );
}
unset( $section );
return $sections;
}
/**
* Enqueue scripts & styles for Appearance > Menus page
*
* @since 0.3.0
* @wp_hook action admin_enqueue_scripts
*/
public static function _enqueue_assets() {
$url = Menu_Icons::get( 'url' );
$suffix = kucrut_get_script_suffix();
if ( defined( 'MENU_ICONS_SCRIPT_DEBUG' ) && MENU_ICONS_SCRIPT_DEBUG ) {
$script_url = '//localhost:8081/';
} else {
$script_url = $url;
}
wp_enqueue_style(
'menu-icons',
"{$url}css/admin{$suffix}.css",
false,
Menu_Icons::VERSION
);
wp_enqueue_script(
'menu-icons',
"{$script_url}js/admin{$suffix}.js",
self::$script_deps,
Menu_Icons::VERSION,
true
);
$customizer_url = add_query_arg(
array(
'autofocus[section]' => 'custom_css',
'return' => admin_url( 'nav-menus.php' ),
),
admin_url( 'customize.php' )
);
/**
* Allow plugins/themes to filter the settings' JS data
*
* @since 0.9.0
*
* @param array $js_data JS Data.
*/
$menu_current_theme = '';
$theme = wp_get_theme();
if ( ! empty( $theme ) ) {
if ( is_child_theme() ) {
$menu_current_theme = $theme->parent()->get( 'Name' );
} else {
$menu_current_theme = $theme->get( 'Name' );
}
}
$box_data = '<div id="menu-icons-sidebar">';
if ( ( $menu_current_theme != 'Neve' ) ) {
$menu_upgrade_hestia_box_text = '<h4>Check-out our latest fast and lightweight FREE theme - <strong>Neve</strong></h4>Neves mobile-first approach, compatibility with AMP and popular page-builders makes website building accessible for everyone.';
$menu_upgrade_hestia_url = add_query_arg(
array(
'theme' => 'Neve',
), admin_url( 'theme-install.php' )
);
$box_data .= '<div class="menu-icons-upgrade-hestia postbox new-card">';
$box_data .= '<p>' . wp_kses_post( $menu_upgrade_hestia_box_text ) . '</p>';
$box_data .= '<a class="button" href="' . $menu_upgrade_hestia_url . '" target="_blank">Preview Neve</a>';
$box_data .= '</div>';
}
$js_data = apply_filters(
'menu_icons_settings_js_data',
array(
'text' => array(
'title' => __( 'Select Icon', 'menu-icons' ),
'select' => __( 'Select', 'menu-icons' ),
'remove' => __( 'Remove', 'menu-icons' ),
'change' => __( 'Change', 'menu-icons' ),
'all' => __( 'All', 'menu-icons' ),
'preview' => __( 'Preview', 'menu-icons' ),
'settingsInfo' => sprintf(
'<div> %1$s <p>' . esc_html__( 'Please note that the actual look of the icons on the front-end will also be affected by the style of your active theme. You can add your own CSS using %2$s or a plugin such as %3$s if you need to override it.', 'menu-icons' ) . '</p></div>',
$box_data,
sprintf(
'<a href="%s">%s</a>',
esc_url( $customizer_url ),
esc_html__( 'the customizer', 'menu-icons' )
),
'<a target="_blank" href="https://wordpress.org/plugins/advanced-css-editor/">Advanced CSS Editor</a>'
),
),
'settingsFields' => self::get_settings_fields(),
'activeTypes' => self::get( 'global', 'icon_types' ),
'ajaxUrls' => array(
'update' => add_query_arg( 'action', 'menu_icons_update_settings', admin_url( '/admin-ajax.php' ) ),
),
'menuSettings' => self::get_menu_settings( self::get_current_menu_id() ),
)
);
wp_localize_script( 'menu-icons', 'menuIcons', $js_data );
}
}

View File

@ -0,0 +1,24 @@
<?php
/**
* Icon fonts handler
*
* @package Menu_Icons
* @author Dzikri Aziz <kvcrvt@gmail.com>
*/
require_once dirname( __FILE__ ) . '/type.php';
/**
* Generic handler for icon fonts
*
*/
abstract class Menu_Icons_Type_Fonts extends Menu_Icons_Type {
/**
* Constructor
*
* @since 0.9.0
*/
public function __construct() {
_deprecated_function( __CLASS__, '0.9.0', 'Icon_Picker_Type_Font' );
}
}

View File

@ -0,0 +1,107 @@
<?php
/**
* Icon type handler
*
* @package Menu_Icons
* @version 0.1.0
* @author Dzikri Aziz <kvcrvt@gmail.com>
*/
/**
* Generic handler for icon type
*
* @since 0.1.0
*/
abstract class Menu_Icons_Type {
/**
* Holds icon type
*
* @since 0.1.0
* @access protected
* @var string
*/
protected $type;
/**
* Holds icon label
*
* @since 0.1.0
* @access protected
* @var string
*/
protected $label;
/**
* Holds icon stylesheet URL
*
* @since 0.1.0
* @access protected
* @var string
*/
protected $stylesheet;
/**
* Custom stylesheet ID
*
* @since 0.8.0
* @access protected
* @var string
*/
protected $stylesheet_id;
/**
* Holds icon version
*
* @since 0.1.0
* @access protected
* @var string
*/
protected $version;
/**
* Holds array key for icon value
*
* @since 0.1.0
* @access protected
* @var string
*/
protected $key;
/**
* Holds menu settings
*
* @since 0.3.0
* @access protected
* @var array
*/
protected $menu_setttings = array();
/**
* Class constructor
*
* This simply sets $key
*
* @since 0.1.0
* @since 0.9.0 Deprecated.
*/
function __construct() {
_deprecated_function( __CLASS__, '0.9.0', 'Icon_Picker_Type' );
}
/**
* Register our type
*
* @since 0.1.0
* @since 0.9.0 Deprecated. This simply returns the $types.
* @param array $types Icon Types
* @uses apply_filters() Calls 'menu_icons_{type}_props' on type properties.
* @return array
*/
public function register( $types ) {
return $types;
}
}