38217-vm/wp-content/themes/Avada/includes/lib/inc/custom-icons/class-fusion-custom-icon-set.php
2026-02-05 17:08:59 +03:00

964 lines
28 KiB
PHP

<?php
/**
* Main Custom Icons class.
*
* @author ThemeFusion
* @copyright (c) Copyright by ThemeFusion
* @link https://avada.com
* @package Fusion-Library
* @since 2.2
*/
/**
* Adds Custom Icons feature.
*/
class Fusion_Custom_Icon_Set {
/**
* The one, true instance of this object.
*
* @static
* @access private
* @since 6.2
* @var object
*/
private static $instance;
/**
* WP Filesystem object.
*
* @access private
* @since 6.2
* @var object
*/
private $wp_filesystem;
/**
* Icons post type handle.
*
* @access private
* @since 6.2
* @var string
*/
private $post_type = 'fusion_icons';
/**
* Used to cache configs.
*
* @access private
* @since 6.2
* @var array
*/
private $package_config = [];
/**
* Default post meta values.
*
* @access private
* @since 6.2
* @var array
*/
private $post_meta_defaults = [
'attachment_id' => '',
'icon_set_dir_name' => '',
'service' => 'icomoon',
'css_prefix' => '',
'icons' => [],
];
/**
* Reserved CSS prefixes.
*
* @access private
* @since 6.2
* @var array
*/
private $reserved_css_prefixes = [
'fusiona-',
];
/**
* The class constructor.
*
* @access private
* @since 6.2
* @return void
*/
private function __construct() {
$this->wp_filesystem = Fusion_Helper::init_filesystem();
// Register custom post type.
add_action( 'init', [ $this, 'register_post_type' ] );
// Front end styles.
add_filter( 'fusion_dynamic_css_final', [ $this, 'combine_stylesheets' ] );
// Live Builders scripts.
add_action( 'fusion_enqueue_live_scripts', [ $this, 'enqueue_scripts' ] );
// Dashboard scripts.
add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_admin_scripts' ] );
add_action( 'admin_head', [ $this, 'admin_head' ] );
add_action( 'wp_ajax_fusion-icons-uploader-action', [ $this, 'handle_upload' ] );
if ( is_admin() ) {
// Add meta box.
add_action( 'add_meta_boxes_' . $this->post_type, [ $this, 'add_meta_box' ] );
// Save post meta.
add_action( 'save_post_' . $this->post_type, [ $this, 'save_post_meta' ], 10, 3 );
// Cleanup when post is deleted (trash emptied).
add_action( 'before_delete_post', [ $this, 'delete_icon_set' ], 10, 1 );
add_action( 'do_meta_boxes', [ $this, 'remove_revolution_slider_meta_box' ], 10, 3 );
// Display 'duplicate css prefix note' if needed.
add_action( 'admin_notices', [ $this, 'add_duplicate_prefix_notice' ], 1, 1 );
// Process icon package when post is saved.
add_action( $this->post_type . '_post_saved', [ $this, 'process_upload' ], 10, 1 );
// Add admin page.
add_action( 'admin_action_fusion_custom_icons_new', [ $this, 'add_new_custom_icon_set' ] );
}
}
/**
* Creates or returns an instance of this class.
*
* @static
* @access public
* @since 6.2
*/
public static function get_instance() {
// If an instance hasn't been created and set to $instance create an instance and set it to $instance.
if ( null === self::$instance ) {
self::$instance = new Fusion_Custom_Icon_Set();
}
return self::$instance;
}
/**
* Register custom post type.
*
* @since 6.2
* @return void
*/
public function register_post_type() {
$labels = [
'name' => _x( 'Custom Icons', 'Avada Icon', 'Avada' ),
'singular_name' => _x( 'Icon Set', 'Avada Icon', 'Avada' ),
'add_new' => _x( 'Add New', 'Avada Icon', 'Avada' ),
'add_new_item' => _x( 'Add New Icon Set', 'Avada Icon', 'Avada' ),
'edit_item' => _x( 'Edit Icon Set', 'Avada Icon', 'Avada' ),
'new_item' => _x( 'New Icon Set', 'Avada Icon', 'Avada' ),
'all_items' => _x( 'All Icon Sets', 'Avada Icon', 'Avada' ),
'view_item' => _x( 'View Icon Set', 'Avada Icon', 'Avada' ),
'search_items' => _x( 'Search Icon Sets', 'Avada Icon', 'Avada' ),
'not_found' => _x( 'No Icon Sets found', 'Avada Icon', 'Avada' ),
'not_found_in_trash' => _x( 'No Icon Sets found in Trash', 'Avada Icon', 'Avada' ),
'parent_item_colon' => '',
'menu_name' => _x( 'Custom Icons', 'Avada Icon', 'Avada' ),
];
$args = [
'labels' => $labels,
'public' => false,
'rewrite' => false,
'show_ui' => true,
'show_in_menu' => false,
'show_in_nav_menus' => false,
'exclude_from_search' => true,
'capability_type' => 'post',
'hierarchical' => false,
'supports' => [ 'title' ],
];
register_post_type( $this->post_type, apply_filters( 'fusion_custom_icons_args', $args ) ); // phpcs:ignore WPThemeReview.PluginTerritory.ForbiddenFunctions.plugin_territory_register_post_type
}
/**
* Removes Slider Revolution metabox from new / edit screen.
*
* @access public
* @since 6.2
*
* @param string $screen Screen identifier.
* @param string $context The screen context for which to display meta boxes.
* @param object $post Post object.
* @return void
*/
public function remove_revolution_slider_meta_box( $screen, $context, $post ) {
if ( 'normal' !== $context ) {
return;
}
remove_meta_box( 'mymetabox_revslider_0', $this->post_type, 'normal' );
}
/**
* Adds assets to the compiled CSS.
*
* @access public
* @since 3.4
* @param string $original_styles The compiled styles.
* @return string The compiled styles with any additional CSS appended.
*/
public function combine_stylesheets( $original_styles ) {
$icon_style = '';
$icon_styles = '';
$icon_sets = fusion_get_custom_icons_array();
foreach ( $icon_sets as $key => $icon_set ) {
if ( isset( $icon_set['icon_set_dir_name'] ) && '' !== $icon_set['icon_set_dir_name'] ) {
$icon_style_path = FUSION_ICONS_BASE_DIR . $icon_set['icon_set_dir_name'] . '/style.css';
if ( file_exists( $icon_style_path ) ) {
$icon_style = fusion_file_get_contents( $icon_style_path );
$icon_style = str_replace( 'fonts/', FUSION_ICONS_BASE_URL . $icon_set['icon_set_dir_name'] . '/fonts/', $icon_style );
$icon_styles .= $icon_style;
}
}
}
if ( 'swap-all' === fusion_library()->get_option( 'font_face_display' ) ) {
$icon_styles = str_replace( 'font-display: block', 'font-display: swap', $icon_styles );
}
return $icon_styles . $original_styles;
}
/**
* Enqueue front end scripts, used in Live Editor.
*
* @since 2.2.0
* @return void
*/
public function enqueue_scripts() {
global $fusion_library_latest_version;
$icon_sets = fusion_get_custom_icons_array();
foreach ( $icon_sets as $key => $icon_set ) {
if ( isset( $icon_set['css_url'] ) && '' !== $icon_set['css_url'] ) {
wp_enqueue_style( 'fusion-custom-icons-' . $key, $icon_set['css_url'], [], $fusion_library_latest_version, 'all' );
}
}
}
/**
* Enqueue admin scripts.
*
* @since 2.2.0
* @param string $hook_suffix The current admin page.
* @return void
*/
public function enqueue_admin_scripts( $hook_suffix ) {
global $fusion_library_latest_version, $typenow, $post;
$current_screen_id = null;
$allowed_screens = [ 'nav-menus', 'appearance_page_avada_options' ];
if ( function_exists( 'get_current_screen' ) ) {
$current_screen = get_current_screen();
$current_screen_id = $current_screen->id;
}
if ( 'post-new.php' !== $hook_suffix && 'post.php' !== $hook_suffix && ! in_array( $current_screen_id, $allowed_screens, true ) ) {
return;
}
if ( get_post_type() === $this->post_type ) {
$min = '';
if ( ( ! defined( 'FUSION_LIBRARY_DEV_MODE' ) || ! FUSION_LIBRARY_DEV_MODE ) ) {
$min = 'min/';
}
// Enqueue WP media.
wp_enqueue_media();
// Scripts.
wp_enqueue_script( 'fusion-custom-icons', trailingslashit( FUSION_LIBRARY_URL ) . 'assets/' . $min . 'js/general/fusion-custom-icons.js', [ 'jquery' ], $fusion_library_latest_version, false );
wp_enqueue_script( 'plupload-handlers' );
// Styles.
wp_enqueue_style( 'fusion-custom-icons', trailingslashit( FUSION_LIBRARY_URL ) . 'assets/css/fusion-custom-icons.css', [], $fusion_library_latest_version, 'all' );
// Icon set is already saved.
if ( 'post.php' === $hook_suffix ) {
$css_url = fusion_get_custom_icons_css_url();
if ( $css_url ) {
wp_enqueue_style( 'fusion-custom-icons-style', $css_url, [], get_the_ID(), 'all' );
}
}
}
// Enqueue custom icon's styles.
if ( isset( $typenow ) && class_exists( 'FusionBuilder' ) && in_array( $typenow, FusionBuilder::allowed_post_types(), true ) || in_array( $current_screen_id, $allowed_screens, true ) ) {
$icon_sets = fusion_get_custom_icons_array();
foreach ( $icon_sets as $key => $icon_set ) {
if ( isset( $icon_set['css_url'] ) && '' !== $icon_set['css_url'] ) {
wp_enqueue_style( 'fusion-custom-icons-' . $key, $icon_set['css_url'], [], $fusion_library_latest_version, 'all' );
}
}
}
}
/**
* Adds the fusionUploaderOptions global var.
*
* @access public
* @since 2.2.0
* @return void
*/
public function admin_head() {
$uploader_options = [
'runtimes' => 'html5,silverlight,flash,html4',
'browse_button' => 'fusion-icons-uploader-button',
'container' => 'fusion-icons-uploader-wrapper',
'drop_element' => 'fusion-icons-uploader-drop-zone',
'file_data_name' => 'async-upload',
'multiple_queues' => true,
'max_file_size' => wp_max_upload_size() . 'b',
'url' => admin_url( 'admin-ajax.php' ),
'flash_swf_url' => includes_url( 'js/plupload/plupload.flash.swf' ),
'silverlight_xap_url' => includes_url( 'js/plupload/plupload.silverlight.xap' ),
'filters' => [
[
'title' => __( 'Allowed Files' ),
'extensions' => 'zip',
],
],
'multipart' => true,
'urlstream_upload' => true,
'multi_selection' => true,
'multipart_params' => [
'_ajax_nonce' => '',
'action' => 'fusion-icons-uploader-action',
],
];
?>
<script type="text/javascript">
var fusionUploaderOptions=<?php echo wp_json_encode( $uploader_options ); ?>;
</script>
<?php
}
/**
* Handles uploads.
*
* @access public
* @since 2.2.0
* @return void
*/
public function handle_upload() {
// Check ajax nonce.
check_ajax_referer( 'fusion-custom-icon-set' );
if ( current_user_can( 'upload_files' ) ) {
$response = [];
// Handle file upload.
$id = media_handle_upload(
'async-upload',
0,
[
'test_form' => true,
'action' => 'fusion-icons-uploader-action',
]
);
// Send the file' url as response.
if ( is_wp_error( $id ) ) {
$response['status'] = 'error';
$response['error'] = $id->get_error_messages();
} else {
$response['status'] = 'success';
$response['attachment'] = [];
$response['attachment']['id'] = $id;
}
}
echo wp_json_encode( $response );
die();
}
/**
* Display 'duplicate css prefix note' if needed.
*
* @since 6.2
* @return void
*/
public function add_duplicate_prefix_notice() {
global $post, $pagenow;
if ( ! is_admin() || 'post.php' !== $pagenow || $post->post_type !== $this->post_type ) {
return;
}
$icon_set = fusion_data()->post_meta( $post->ID )->get( 'custom_icon_set' );
if ( isset( $icon_set['css_prefix'] ) && true === $this->is_duplicate_prefix( $icon_set['css_prefix'] ) && class_exists( 'Fusion_Admin_Notice' ) ) {
new Fusion_Admin_Notice(
'fusion-custom-icons-notice',
'<h2>' . esc_html__( 'Icon set with same CSS prefix already exists!', 'Avada' ) . '</h2><p>' . esc_html__( 'Icon set with same CSS prefix already exists! Please use unique prefix in order to avoid conflicts.', 'Avada' ) . '</p>',
true,
'error',
true,
'user_meta',
'the-meta-custom-icons',
[ 'fusion_icons' ]
);
}
}
/**
* Display 'duplicate css prefix note' if needed.
*
* @since 6.2
* @param int $post_id The post-ID.
* @return void
*/
protected function change_post_status_to_draft( $post_id ) {
$duplicate_prefix = fusion_data()->post_meta( $post_id )->get( 'duplicate_css_prefix' );
if ( true === $duplicate_prefix ) {
wp_update_post(
[
'ID' => $post_id,
'post_status' => 'draft',
]
);
}
}
/**
* Add metaboxes.
*
* @since 6.2
* @return void
*/
public function add_meta_box() {
add_meta_box(
'fusion-custom-icons-metabox',
__( 'Icon Set', 'Avada' ),
[ $this, 'render_metabox' ],
$this->post_type,
'normal',
'default'
);
}
/**
* Meta box callback, outputs metabox content.
*
* @since 6.2
* @return void
*/
public function render_metabox() {
global $post;
$icon_set = fusion_data()->post_meta( $post->ID )->get( 'custom_icon_set' );
$icon_set = wp_parse_args( $icon_set, $this->post_meta_defaults );
$is_new_icon_set = empty( $icon_set['icon_set_dir_name'] ) ? true : false;
$buton_label = $is_new_icon_set ? __( 'Browse Files', 'Avada' ) : __( 'Update Custom Icon Set', 'Avada' );
$wrapper_class = $is_new_icon_set ? 'fusion-no-custom-icons-uploaded' : 'fusion-custom-icons-uploaded';
?>
<div class="fusion-custom-icons-wrapper <?php echo esc_attr( $wrapper_class ); ?>">
<div class="fusion-custom-icons-inner">
<input type="hidden" id="fusion-custom-icons-attachment-id" name="fusion-custom-icons[attachment_id]" value="<?php echo esc_attr( $icon_set['attachment_id'] ); ?>">
<input type="hidden" name="fusion-custom-icons-nonce" id="fusion-custom-icons-nonce" value="<?php echo esc_attr( wp_create_nonce( 'fusion-custom-icon-set' ) ); ?>">
<?php if ( $is_new_icon_set ) : ?>
<div id="fusion-icons-uploader-wrapper" class="fusion-icons-uploader multiple">
<div id="fusion-icons-uploader-drop-zone">
<div>
<span class="fusiona-file-upload-solid fusion-icon-upload"></span>
<h3>
<?php esc_html_e( 'Drop zip file to upload', 'Avada' ); ?>
</h3>
<p>
<?php
printf(
/* translators: %1$s: Link to Icomoon site. %2$s <br>. %3$s Note: */
esc_html__(
'Supported Icon Tool - %1$s %2$s %3$s Every uploaded custom icon set needs a unique font name and CSS class prefix.
For more info, see the %4$s.',
'Avada'
),
'<a href="https://icomoon.io/app/" target="_blank" rel="noreferrer">Icomoon</a>',
'<br>',
'<strong>' . esc_html__( 'NOTE:', 'Avada' ) . '</strong>',
'<a href="https://avada.com/documentation/how-to-upload-and-use-custom-icons-in-avada/" target="_blank" rel="noreferrer">Custom Icon documentation</a>'
);
?>
</p>
<input id="fusion-icons-uploader-button" type="button" value="<?php esc_attr_e( 'Select File' ); ?>" class="fusion-icons-uploader-button button">
<div class="fusion-icons-spinner-wrapper">
<span class="spinner"></span>
</div>
<div id="fusion-icons-error">
</div>
</div>
</div>
</div>
<?php else : ?>
<input type="hidden" id="fusion-custom-icons-update" name="fusion-custom-icons[icon_set_update]" value="">
<div class="fusion-custom-icons-top-bar">
<a href="#" id="fusion-custom-icons-upload" data-title="<?php echo esc_attr( $buton_label ); ?>">
<i class="fusiona-file-upload-solid" aria-hidden="true"></i>
<?php echo esc_html( $buton_label ); ?>
</a>
<?php
$json_exists = method_exists( $this->wp_filesystem, 'exists' ) && $this->wp_filesystem->exists( FUSION_ICONS_BASE_DIR . $icon_set['icon_set_dir_name'] . '/selection.json' );
if ( $json_exists ) :
?>
<a href="<?php echo FUSION_ICONS_BASE_URL . $icon_set['icon_set_dir_name'] . '/selection.json'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>" id="fusion-custom-icons-json" target="_blank" data-title="<?php echo esc_attr( __( 'JSON', 'Avada' ) ); ?>">
<?php echo esc_html( __( 'Download', 'Avada' ) ); ?>
</a>
<?php endif; ?>
<div class="fusion-custom-icons-info">
<span>
<?php esc_html_e( 'CSS Prefix:', 'Avada' ); ?>
<span class="fusion-custom-icons-value">
<?php echo esc_html( '.' . $icon_set['css_prefix'] ); ?>
</span>
</span>
<span>
<?php esc_html_e( 'Icons Count:', 'Avada' ); ?>
<span class="fusion-custom-icons-value">
<?php echo esc_html( count( $icon_set['icons'] ) ); ?>
</span>
</span>
</div>
</div>
<div class="fusion-custom-icons-preview">
<?php
// Print icons' markup.
echo $this->get_icons_html(); // phpcs:ignore WordPress.Security.EscapeOutput
?>
</div>
<?php
endif;
?>
</div>
</div>
<?php
}
/**
* Save post meta.
*
* @since 6.2
* @param int $post_id Post ID.
* @param object $post Post Object.
* @param bool $update Whether this is an existing post being updated or not.
* @return void|int
*/
public function save_post_meta( $post_id, $post, $update ) {
// Early exit if it is autosave.
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return $post_id;
}
if ( wp_is_post_revision( $post_id ) || wp_is_post_autosave( $post_id ) ) {
return $post_id;
}
// Check user's permissions.
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return $post_id;
}
// Check nonce.
if ( ! isset( $_POST['fusion-custom-icons-nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['fusion-custom-icons-nonce'] ) ), 'fusion-custom-icon-set' ) ) {
return $post_id;
}
// Process package.
do_action( $this->post_type . '_post_saved', $post_id );
}
/**
* Processes icon package, exctracts files and saves post meta.
* Separate method as it might be needed to be called as AJAX callback.
*
* @since 6.2
* @param int $post_id Post ID.
* @return void
*/
public function process_upload( $post_id ) {
// Early exit if post ID is not valid.
if ( ! $post_id || ( isset( $_POST['fusion-custom-icons']['icon_set_update'] ) && 'true' !== $_POST['fusion-custom-icons']['icon_set_update'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
return;
}
// Remove icon set files if we're updating.
if ( isset( $_POST['fusion-custom-icons']['icon_set_update'] ) && 'true' === $_POST['fusion-custom-icons']['icon_set_update'] ) { // phpcs:ignore WordPress.Security.NonceVerification
$this->delete_icon_set( $post_id );
}
$icon_set = [];
// Get $_POST values and set defaults.
foreach ( $this->post_meta_defaults as $key => $value ) {
$icon_set[ $key ] = isset( $_POST['fusion-custom-icons'][ $key ] ) ? sanitize_text_field( wp_unslash( $_POST['fusion-custom-icons'][ $key ] ) ) : $this->post_meta_defaults[ $key ]; // phpcs:ignore WordPress.Security.NonceVerification
}
// Return if attachment ID is not set.
if ( empty( $icon_set['attachment_id'] ) ) {
return;
}
// Create base directory if it's not there.
if ( ! file_exists( FUSION_ICONS_BASE_DIR ) ) {
wp_mkdir_p( FUSION_ICONS_BASE_DIR );
}
// Get package path.
$package_path = get_attached_file( $icon_set['attachment_id'] );
$status = false;
if ( $package_path && file_exists( $package_path ) ) {
// Create icon set path.
$icon_set_dir_name = $this->get_unique_dir_name( pathinfo( $package_path, PATHINFO_FILENAME ), FUSION_ICONS_BASE_DIR );
$icon_set_path = FUSION_ICONS_BASE_DIR . $icon_set_dir_name;
// Attempt to manually extract the zip file first. Required for fptext method.
if ( class_exists( 'ZipArchive' ) ) {
$zip = new ZipArchive();
$to_extract = [];
if ( true === $zip->open( $package_path ) ) {
// Check if icomoon file extensions are allowed.
for ( $i = 0; $i < $zip->numFiles; $i++ ) {
$filename = $zip->getNameIndex( $i );
if ( preg_match( '/(\.json$|\.js$|\.css$|\.txt$|\.ttf$|\.woff$|\.woff2$|\.otf$|\.eot$|\.scss$|\.less$|\.styl$|\/$)/', $filename ) ) {
$to_extract[] = $filename;
}
}
if ( ! empty( $to_extract ) ) {
wp_mkdir_p( $icon_set_path ); // Create icon set directory.
$status = $zip->extractTo( $icon_set_path, $to_extract );
}
$zip->close();
}
}
}
// Update post meta if extract didn't fail.
if ( true === $status ) {
$icon_set['icon_set_dir_name'] = $icon_set_dir_name;
// Parse package.
$parsed_package = $this->parse_icons_package( $icon_set_dir_name );
// Update post meta with package data.
foreach ( $parsed_package as $key => $value ) {
$icon_set[ $key ] = $parsed_package[ $key ];
}
$icon_set['icon_set_id'] = md5( $post_id . $icon_set['attachment_id'] );
// Finally save post meta.
fusion_data()->post_meta( $post_id )->set( 'custom_icon_set', $icon_set );
// Add icon set id to attachment as well.
update_post_meta( $icon_set['attachment_id'], '_fusion_icon_set_id', $icon_set['icon_set_id'] );
}
}
/**
* Processes icon package, extracts files and saves post meta.
* Separate method as it might be needed to be called as AJAX callback.
*
* @since 6.2
* @param int $post_id Post ID.
* @return void
*/
public function regenerate_icon_files( $post_id ) {
// Early exit if post ID is not valid.
if ( ! $post_id ) {
return;
}
// Remove icon set files.
$this->delete_icon_set( $post_id );
$icon_set = fusion_data()->post_meta( $post_id )->get( 'custom_icon_set' );
// Return if attachment ID is not set.
if ( empty( $icon_set['attachment_id'] ) ) {
return;
}
// Create base directory if it's not there.
if ( ! file_exists( FUSION_ICONS_BASE_DIR ) ) {
wp_mkdir_p( FUSION_ICONS_BASE_DIR );
}
// Get package path.
$package_path = get_attached_file( $icon_set['attachment_id'] );
$status = false;
if ( $package_path && file_exists( $package_path ) ) {
// Create icon set path.
$icon_set_dir_name = $this->get_unique_dir_name( pathinfo( $package_path, PATHINFO_FILENAME ), FUSION_ICONS_BASE_DIR );
$icon_set_path = FUSION_ICONS_BASE_DIR . $icon_set_dir_name;
// Attempt to manually extract the zip file first. Required for fptext method.
if ( class_exists( 'ZipArchive' ) ) {
$zip = new ZipArchive();
$to_extract = [];
if ( true === $zip->open( $package_path ) ) {
// Check if icomoon file extensions are allowed.
for ( $i = 0; $i < $zip->numFiles; $i++ ) {
$filename = $zip->getNameIndex( $i );
if ( preg_match( '/(\.json$|\.js$|\.css$|\.txt$|\.ttf$|\.woff$|\.woff2$|\.otf$|\.eot$|\.scss$|\.less$|\.styl$|\/$)/', $filename ) ) {
$to_extract[] = $filename;
}
}
if ( ! empty( $to_extract ) ) {
wp_mkdir_p( $icon_set_path ); // Create icon set directory.
$status = $zip->extractTo( $icon_set_path, $to_extract );
}
$zip->close();
}
}
}
// Update post meta if extract didn't fail.
if ( true === $status ) {
$icon_set['icon_set_dir_name'] = $icon_set_dir_name;
// Parse package.
$parsed_package = $this->parse_icons_package( $icon_set_dir_name );
// Update post meta with package data.
foreach ( $parsed_package as $key => $value ) {
$icon_set[ $key ] = $parsed_package[ $key ];
}
// Update post meta.
fusion_data()->post_meta( $post_id )->set( 'custom_icon_set', $icon_set );
}
}
/**
* Checks if icon set with same prefix already exists.
*
* @since 6.2
* @param string $css_prefix Icon set prefix.
* @return bool
*/
protected function is_duplicate_prefix( $css_prefix ) {
global $post;
if ( $css_prefix ) {
// Check if there is conflict with our icon fonts.
if ( in_array( $css_prefix, $this->reserved_css_prefixes, true ) ) {
return true;
}
// Exclude currently edited post.
$custom_icon_sets = fusion_get_custom_icons_array( [ 'post__not_in' => [ $post->ID ] ] );
foreach ( $custom_icon_sets as $custom_set ) {
if ( $css_prefix === $custom_set['css_prefix'] ) {
return true;
}
}
}
return false;
}
/**
* Delete icon set directory and do general cleanup.
*
* @since 6.2
* @param int $post_id Post ID.
* @return void
*/
public function delete_icon_set( $post_id ) {
if ( get_post_type( $post_id ) !== $this->post_type ) {
return;
}
$icon_set = fusion_data()->post_meta( $post_id )->get( 'custom_icon_set' );
if ( isset( $icon_set['icon_set_dir_name'] ) ) {
$icon_set_path = FUSION_ICONS_BASE_DIR . $icon_set['icon_set_dir_name'];
// Delete directory.
$this->wp_filesystem->rmdir( $icon_set_path, true );
}
}
/**
* Get unique directory name for passed parent directory.
*
* @since 6.2
* @param string $dir_name Name of the directory.
* @param string $parent_dir_path Path of the parent directory.
* @return string Unique directory name.
*/
protected function get_unique_dir_name( $dir_name, $parent_dir_path ) {
$parent_dir_path = trailingslashit( $parent_dir_path );
$dir_path = $parent_dir_path . $dir_name;
$counter = 0;
$tmp_name = $dir_name;
while ( file_exists( $dir_path ) ) {
$counter++;
$dir_name = $tmp_name . '-' . $counter;
$dir_path = $parent_dir_path . $dir_name;
}
return $dir_name;
}
/**
* Get package config.
*
* @since 6.2
* @param string $icon_set_dir_name Icon set dir name.
* @return array Config array.
*/
protected function get_package_config( $icon_set_dir_name ) {
if ( ! isset( $this->package_config[ $icon_set_dir_name ] ) ) {
$json_file = $this->wp_filesystem->get_contents( FUSION_ICONS_BASE_DIR . '/' . $icon_set_dir_name . '/selection.json' );
$this->package_config[ $icon_set_dir_name ] = json_decode( $json_file, true );
}
return $this->package_config[ $icon_set_dir_name ];
}
/**
* Parse package.
*
* @since 6.2
* @param string $icon_set_dir_name Icon set dir name.
* @return array Post meta array.
*/
protected function parse_icons_package( $icon_set_dir_name ) {
// Get icons config file.
$icons_config = $this->get_package_config( $icon_set_dir_name );
$parsed_package = [];
$parsed_package['icons'] = [];
// Add icons.
foreach ( $icons_config['icons'] as $icon ) {
$parsed_package['icons'][] = $icon['properties']['name'];
}
// Set icon prefix.
$parsed_package['css_prefix'] = $icons_config['preferences']['fontPref']['prefix'];
// Set icon count.
$parsed_package['icon_count'] = count( $parsed_package['icons'] );
return $parsed_package;
}
/**
* Get icon HTML code, for example to be used in a meta box.
*
* @since 6.2
* @param int $post_id Post ID.
* @return string HTML code.
*/
public function get_icons_html( $post_id = 0 ) {
if ( ! $post_id ) {
$post_id = get_the_ID();
}
$icon_set = fusion_data()->post_meta( $post_id )->get( 'custom_icon_set' );
$html = '';
foreach ( $icon_set['icons'] as $icon ) {
$html .= '<span class="fusion-custom-icon-preview" title="' . esc_attr( $icon ) . '"><i class="' . esc_attr( $icon_set['css_prefix'] . $icon ) . '" aria-hidden="true"></i><span class="fusion-custom-icon-preview-name">' . esc_html( $icon ) . '</span></span>';
}
return $html;
}
/**
* Create a new library element, fired from library page.
*/
public function add_new_custom_icon_set() {
check_admin_referer( 'fusion_new_custom_icon_set' );
if ( ! current_user_can( apply_filters( 'awb_role_manager_access_capability', 'edit_posts', 'fusion_icons' ) ) ) {
return;
}
$custom_icon_set = [
'post_title' => isset( $_GET['name'] ) ? sanitize_text_field( wp_unslash( $_GET['name'] ) ) : '',
'post_status' => current_user_can( 'publish_posts' ) ? 'publish' : 'pending',
'post_type' => $this->post_type,
];
$set_id = wp_insert_post( $custom_icon_set, true );
if ( is_wp_error( $set_id ) ) {
$error_string = $set_id->get_error_message();
wp_die( esc_html( $error_string ) );
}
// Just redirect to back-end editor. In future tie it to default editor option.
wp_safe_redirect( get_edit_post_link( $set_id, false ) );
die();
}
}
/* Omit closing PHP tag to avoid "Headers already sent" issues. */