Changeset 3230461
- Timestamp:
- 01/28/2025 11:57:25 AM (14 months ago)
- Location:
- borderless
- Files:
-
- 210 added
- 3 edited
-
tags/1.6.0 (added)
-
tags/1.6.0/assets (added)
-
tags/1.6.0/assets/fonts (added)
-
tags/1.6.0/assets/fonts/bootstrap-icons.woff (added)
-
tags/1.6.0/assets/fonts/bootstrap-icons.woff2 (added)
-
tags/1.6.0/assets/fonts/borderless-icon-font.svg (added)
-
tags/1.6.0/assets/fonts/borderless-icon-font.ttf (added)
-
tags/1.6.0/assets/fonts/borderless-icon-font.woff (added)
-
tags/1.6.0/assets/img (added)
-
tags/1.6.0/assets/img/borderless.svg (added)
-
tags/1.6.0/assets/img/library.svg (added)
-
tags/1.6.0/assets/img/post-type.svg (added)
-
tags/1.6.0/assets/lib (added)
-
tags/1.6.0/assets/lib/appear.js (added)
-
tags/1.6.0/assets/lib/countto.js (added)
-
tags/1.6.0/assets/lib/flickity (added)
-
tags/1.6.0/assets/lib/flickity/flickity-as-nav-for.js (added)
-
tags/1.6.0/assets/lib/flickity/flickity-fade.css (added)
-
tags/1.6.0/assets/lib/flickity/flickity-fade.js (added)
-
tags/1.6.0/assets/lib/flickity/flickity-fullscreen.css (added)
-
tags/1.6.0/assets/lib/flickity/flickity-fullscreen.js (added)
-
tags/1.6.0/assets/lib/flickity/flickity.css (added)
-
tags/1.6.0/assets/lib/flickity/flickity.js (added)
-
tags/1.6.0/assets/lib/images-loaded.js (added)
-
tags/1.6.0/assets/lib/isotope.js (added)
-
tags/1.6.0/assets/lib/marquee.js (added)
-
tags/1.6.0/assets/lib/progressbar.js (added)
-
tags/1.6.0/assets/lib/typewriterjs.js (added)
-
tags/1.6.0/assets/scripts (added)
-
tags/1.6.0/assets/scripts/ai-button.js (added)
-
tags/1.6.0/assets/scripts/bootstrap.js (added)
-
tags/1.6.0/assets/scripts/borderless-elementor.min.js (added)
-
tags/1.6.0/assets/scripts/borderless-wpbakery.min.js (added)
-
tags/1.6.0/assets/scripts/borderless.js (added)
-
tags/1.6.0/assets/scripts/borderless.min.js (added)
-
tags/1.6.0/assets/scripts/library.js (added)
-
tags/1.6.0/assets/styles (added)
-
tags/1.6.0/assets/styles/bootstrap-icons.css (added)
-
tags/1.6.0/assets/styles/bootstrap.css (added)
-
tags/1.6.0/assets/styles/borderless-icon-font.css (added)
-
tags/1.6.0/assets/styles/borderless.css (added)
-
tags/1.6.0/assets/styles/borderless.min.css (added)
-
tags/1.6.0/assets/styles/dashboard.css (added)
-
tags/1.6.0/assets/styles/dashboard.min.css (added)
-
tags/1.6.0/assets/styles/elementor (added)
-
tags/1.6.0/assets/styles/elementor.css (added)
-
tags/1.6.0/assets/styles/elementor.min.css (added)
-
tags/1.6.0/assets/styles/elementor/elementor-widget-animated-text.css (added)
-
tags/1.6.0/assets/styles/elementor/elementor-widget-hero.css (added)
-
tags/1.6.0/assets/styles/elementor/elementor-widget-portfolio.css (added)
-
tags/1.6.0/assets/styles/elementor/elementor-widget-slider.css (added)
-
tags/1.6.0/assets/styles/elementor/elementor-widget-split-hero.css (added)
-
tags/1.6.0/assets/styles/library.css (added)
-
tags/1.6.0/assets/styles/wpbakery (added)
-
tags/1.6.0/assets/styles/wpbakery.css (added)
-
tags/1.6.0/assets/styles/wpbakery.min.css (added)
-
tags/1.6.0/assets/styles/wpbakery/wpbakery-icon-fonts.css (added)
-
tags/1.6.0/borderless.php (added)
-
tags/1.6.0/includes (added)
-
tags/1.6.0/includes/class-borderless-loader.php (added)
-
tags/1.6.0/includes/class-borderless-public.php (added)
-
tags/1.6.0/includes/class-borderless.php (added)
-
tags/1.6.0/includes/custom-post-types (added)
-
tags/1.6.0/includes/custom-post-types/custom-post-types.php (added)
-
tags/1.6.0/includes/custom-post-types/templates.php (added)
-
tags/1.6.0/includes/helper.php (added)
-
tags/1.6.0/includes/icon-manager (added)
-
tags/1.6.0/includes/icon-manager/assets (added)
-
tags/1.6.0/includes/icon-manager/assets/css (added)
-
tags/1.6.0/includes/icon-manager/assets/css/icon-manager.css (added)
-
tags/1.6.0/includes/icon-manager/assets/css/icon-manager.min.css (added)
-
tags/1.6.0/includes/icon-manager/assets/css/icon-manager.scss (added)
-
tags/1.6.0/includes/icon-manager/assets/js (added)
-
tags/1.6.0/includes/icon-manager/assets/js/icon-manager.js (added)
-
tags/1.6.0/includes/icon-manager/assets/js/icon-manager.min.js (added)
-
tags/1.6.0/includes/icon-manager/icon-manager.php (added)
-
tags/1.6.0/includes/index.php (added)
-
tags/1.6.0/includes/library (added)
-
tags/1.6.0/includes/library/importer.php (added)
-
tags/1.6.0/includes/library/inc (added)
-
tags/1.6.0/includes/library/inc/BorderlessLibraryImporter.php (added)
-
tags/1.6.0/includes/library/inc/CustomizerImporter.php (added)
-
tags/1.6.0/includes/library/inc/CustomizerOption.php (added)
-
tags/1.6.0/includes/library/inc/Downloader.php (added)
-
tags/1.6.0/includes/library/inc/Helpers.php (added)
-
tags/1.6.0/includes/library/inc/ImportActions.php (added)
-
tags/1.6.0/includes/library/inc/Importer.php (added)
-
tags/1.6.0/includes/library/inc/Logger.php (added)
-
tags/1.6.0/includes/library/inc/PluginInstaller.php (added)
-
tags/1.6.0/includes/library/inc/PluginInstallerSkin.php (added)
-
tags/1.6.0/includes/library/inc/PluginInstallerSkinSilent.php (added)
-
tags/1.6.0/includes/library/inc/ReduxImporter.php (added)
-
tags/1.6.0/includes/library/inc/ViewHelpers.php (added)
-
tags/1.6.0/includes/library/inc/WPCLICommands.php (added)
-
tags/1.6.0/includes/library/inc/WXRImporter.php (added)
-
tags/1.6.0/includes/library/inc/WidgetImporter.php (added)
-
tags/1.6.0/includes/library/templates (added)
-
tags/1.6.0/includes/library/templates/borderless-templates-after.php (added)
-
tags/1.6.0/includes/library/templates/borderless-templates.php (added)
-
tags/1.6.0/includes/library/templates/classic-templates-after.php (added)
-
tags/1.6.0/includes/library/templates/classic-templates-plugins.php (added)
-
tags/1.6.0/includes/library/templates/classic-templates.php (added)
-
tags/1.6.0/includes/library/templates/templates.php (added)
-
tags/1.6.0/includes/library/vendor (added)
-
tags/1.6.0/includes/library/vendor/autoload.php (added)
-
tags/1.6.0/includes/library/vendor/awesomemotive (added)
-
tags/1.6.0/includes/library/vendor/awesomemotive/wp-content-importer-v2 (added)
-
tags/1.6.0/includes/library/vendor/awesomemotive/wp-content-importer-v2/src (added)
-
tags/1.6.0/includes/library/vendor/awesomemotive/wp-content-importer-v2/src/Importer.php (added)
-
tags/1.6.0/includes/library/vendor/awesomemotive/wp-content-importer-v2/src/WPImporterLogger.php (added)
-
tags/1.6.0/includes/library/vendor/awesomemotive/wp-content-importer-v2/src/WPImporterLoggerCLI.php (added)
-
tags/1.6.0/includes/library/vendor/awesomemotive/wp-content-importer-v2/src/WXRImportInfo.php (added)
-
tags/1.6.0/includes/library/vendor/awesomemotive/wp-content-importer-v2/src/WXRImporter.php (added)
-
tags/1.6.0/includes/library/vendor/composer (added)
-
tags/1.6.0/includes/library/vendor/composer/ClassLoader.php (added)
-
tags/1.6.0/includes/library/vendor/composer/autoload_classmap.php (added)
-
tags/1.6.0/includes/library/vendor/composer/autoload_namespaces.php (added)
-
tags/1.6.0/includes/library/vendor/composer/autoload_psr4.php (added)
-
tags/1.6.0/includes/library/vendor/composer/autoload_real.php (added)
-
tags/1.6.0/includes/library/vendor/composer/autoload_static.php (added)
-
tags/1.6.0/includes/library/views (added)
-
tags/1.6.0/includes/library/views/import.php (added)
-
tags/1.6.0/includes/library/views/install-plugins.php (added)
-
tags/1.6.0/includes/library/views/plugin-page.php (added)
-
tags/1.6.0/includes/svg (added)
-
tags/1.6.0/includes/svg/sanitizer.php (added)
-
tags/1.6.0/includes/svg/svg.min.js (added)
-
tags/1.6.0/includes/svg/svg.php (added)
-
tags/1.6.0/includes/svg/whitelist.php (added)
-
tags/1.6.0/includes/templates (added)
-
tags/1.6.0/includes/templates/dashboard.php (added)
-
tags/1.6.0/includes/templates/license.php (added)
-
tags/1.6.0/includes/templates/system-info.php (added)
-
tags/1.6.0/languages (added)
-
tags/1.6.0/languages/borderless.pot (added)
-
tags/1.6.0/license.txt (added)
-
tags/1.6.0/modules (added)
-
tags/1.6.0/modules/block-editor (added)
-
tags/1.6.0/modules/block-editor/contact-information (added)
-
tags/1.6.0/modules/block-editor/contact-information/contact-information-frontend.css (added)
-
tags/1.6.0/modules/block-editor/contact-information/contact-information.css (added)
-
tags/1.6.0/modules/block-editor/contact-information/contact-information.js (added)
-
tags/1.6.0/modules/block-editor/contact-information/contact-information.php (added)
-
tags/1.6.0/modules/block-editor/social-icons (added)
-
tags/1.6.0/modules/block-editor/social-icons/social-icons-backend.css (added)
-
tags/1.6.0/modules/block-editor/social-icons/social-icons-frontend.css (added)
-
tags/1.6.0/modules/block-editor/social-icons/social-icons.js (added)
-
tags/1.6.0/modules/block-editor/social-icons/social-icons.php (added)
-
tags/1.6.0/modules/block-editor/spacer (added)
-
tags/1.6.0/modules/block-editor/spacer/spacer-backend.css (added)
-
tags/1.6.0/modules/block-editor/spacer/spacer.js (added)
-
tags/1.6.0/modules/block-editor/spacer/spacer.php (added)
-
tags/1.6.0/modules/elementor (added)
-
tags/1.6.0/modules/elementor/assets.php (added)
-
tags/1.6.0/modules/elementor/elementor.php (added)
-
tags/1.6.0/modules/elementor/helper.php (added)
-
tags/1.6.0/modules/elementor/widgets (added)
-
tags/1.6.0/modules/elementor/widgets/animated-text.php (added)
-
tags/1.6.0/modules/elementor/widgets/circular-progress-bar.php (added)
-
tags/1.6.0/modules/elementor/widgets/contact-form-7.php (added)
-
tags/1.6.0/modules/elementor/widgets/hero.php (added)
-
tags/1.6.0/modules/elementor/widgets/marquee-text.php (added)
-
tags/1.6.0/modules/elementor/widgets/portfolio.php (added)
-
tags/1.6.0/modules/elementor/widgets/progress-bar.php (added)
-
tags/1.6.0/modules/elementor/widgets/semi-circular-progress-bar.php (added)
-
tags/1.6.0/modules/elementor/widgets/slider.php (added)
-
tags/1.6.0/modules/elementor/widgets/split-hero.php (added)
-
tags/1.6.0/modules/elementor/widgets/team-member.php (added)
-
tags/1.6.0/modules/elementor/widgets/testimonial.php (added)
-
tags/1.6.0/modules/related-posts (added)
-
tags/1.6.0/modules/related-posts/related-posts.php (added)
-
tags/1.6.0/modules/wpbakery (added)
-
tags/1.6.0/modules/wpbakery/custom-default-elements.php (added)
-
tags/1.6.0/modules/wpbakery/elements (added)
-
tags/1.6.0/modules/wpbakery/elements/alert.php (added)
-
tags/1.6.0/modules/wpbakery/elements/circular-progress-bar.php (added)
-
tags/1.6.0/modules/wpbakery/elements/counter.php (added)
-
tags/1.6.0/modules/wpbakery/elements/icon-group.php (added)
-
tags/1.6.0/modules/wpbakery/elements/icon.php (added)
-
tags/1.6.0/modules/wpbakery/elements/infobox.php (added)
-
tags/1.6.0/modules/wpbakery/elements/list-group.php (added)
-
tags/1.6.0/modules/wpbakery/elements/modal.php (added)
-
tags/1.6.0/modules/wpbakery/elements/pricing.php (added)
-
tags/1.6.0/modules/wpbakery/elements/progress-bar.php (added)
-
tags/1.6.0/modules/wpbakery/elements/semi-circular-progress-bar.php (added)
-
tags/1.6.0/modules/wpbakery/elements/svg.php (added)
-
tags/1.6.0/modules/wpbakery/elements/team-member.php (added)
-
tags/1.6.0/modules/wpbakery/elements/testimonial.php (added)
-
tags/1.6.0/modules/wpbakery/images (added)
-
tags/1.6.0/modules/wpbakery/images/alert.png (added)
-
tags/1.6.0/modules/wpbakery/images/circular-progress-bar.png (added)
-
tags/1.6.0/modules/wpbakery/images/counter.png (added)
-
tags/1.6.0/modules/wpbakery/images/icon-group.png (added)
-
tags/1.6.0/modules/wpbakery/images/icon.png (added)
-
tags/1.6.0/modules/wpbakery/images/infobox.png (added)
-
tags/1.6.0/modules/wpbakery/images/list-group.png (added)
-
tags/1.6.0/modules/wpbakery/images/list-item.png (added)
-
tags/1.6.0/modules/wpbakery/images/modal.png (added)
-
tags/1.6.0/modules/wpbakery/images/pricing.png (added)
-
tags/1.6.0/modules/wpbakery/images/progress-bar.png (added)
-
tags/1.6.0/modules/wpbakery/images/semi-circular-progress-bar.png (added)
-
tags/1.6.0/modules/wpbakery/images/svg.png (added)
-
tags/1.6.0/modules/wpbakery/images/team-member.png (added)
-
tags/1.6.0/modules/wpbakery/images/testimonial-section.png (added)
-
tags/1.6.0/modules/wpbakery/images/testimonial.png (added)
-
tags/1.6.0/modules/wpbakery/lean-map.php (added)
-
tags/1.6.0/modules/wpbakery/paramns (added)
-
tags/1.6.0/modules/wpbakery/paramns/icon-manager-param.php (added)
-
tags/1.6.0/modules/wpbakery/wpbakery.php (added)
-
tags/1.6.0/readme.txt (added)
-
trunk/borderless.php (modified) (2 diffs)
-
trunk/includes/icon-manager/icon-manager.php (modified) (1 diff)
-
trunk/readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
borderless/trunk/borderless.php
r3209805 r3230461 5 5 Plugin URI: https://visualmodo.com/borderless/ 6 6 Description: One service packed with powerful tools to help you reach your purposes. 7 Version: 1. 5.97 Version: 1.6.0 8 8 Author: Visualmodo 9 9 Author URI: https://visualmodo.com … … 21 21 /*-----------------------------------------------------------------------------------*/ 22 22 23 define( 'BORDERLESS__VERSION', '1. 5.9' );23 define( 'BORDERLESS__VERSION', '1.6.0' ); 24 24 define( 'BORDERLESS__DIR', plugin_dir_path( __FILE__ ) ); 25 25 define( 'BORDERLESS__URL', plugins_url( '/', __FILE__ ) ); -
borderless/trunk/includes/icon-manager/icon-manager.php
r2483040 r3230461 1 1 <?php 2 2 if ( ! defined( 'ABSPATH' ) ) { 3 die( '-1' );3 die( '-1' ); 4 4 } 5 5 6 6 if ( ! class_exists( 'Borderless_IF' ) ) { 7 class Borderless_IF { 8 var $paths = array(); 9 var $svg_file; 10 var $json_file; 11 var $ip_name = 'unknown'; 12 var $svg_config = array(); 13 var $json_config = array(); 14 static $ip_list = array(); 15 16 function __construct() { 17 $this->paths = wp_upload_dir(); 18 $this->paths['fonts'] = 'borderless_icon_fonts'; 19 $this->paths['temp'] = trailingslashit( $this->paths['fonts'] ) . 'borderless_temp'; 20 $this->paths['fontdir'] = trailingslashit( $this->paths['basedir'] ) . $this->paths['fonts']; 21 $this->paths['tempdir'] = trailingslashit( $this->paths['basedir'] ) . $this->paths['temp']; 22 $this->paths['fonturl'] = set_url_scheme( trailingslashit( $this->paths['baseurl'] ) . $this->paths['fonts'] ); 23 $this->paths['tempurl'] = trailingslashit( $this->paths['baseurl'] ) . trailingslashit( $this->paths['temp'] ); 24 $this->paths['config'] = 'charmap.php'; 25 add_action( 'wp_ajax_borderless_ajax_add_zipped_font', array( $this, 'add_zipped_font' ) ); 26 add_action( 'wp_ajax_borderless_ajax_remove_zipped_font', array( $this, 'remove_zipped_font' ) ); 27 28 } 29 30 function admin_scripts() { 31 $upload_paths = wp_upload_dir(); 32 wp_enqueue_script( 'borderless-admin-media', plugin_dir_url( __FILE__ ) . 'assets/js/icon-manager.min.js', array( 'jquery' ) ); 33 wp_enqueue_script( 'media-upload' ); 34 wp_enqueue_media(); 35 wp_enqueue_style( 'borderless-wpbakery-icon-manager-admin', plugin_dir_url( __FILE__ ) . 'assets/css/icon-manager.css' ); 36 $custom_fonts = get_option( 'borderless_icon_fonts' ); 37 if ( is_array( $custom_fonts ) ) { 38 foreach ( $custom_fonts as $font => $info ) { 39 if ( strpos( $info['style'], 'http://' ) !== false ) { 40 wp_enqueue_style( 'borderless-' . $font, $info['style'], null, '1.0', 'all' ); 41 } else { 42 wp_enqueue_style( 'borderless-' . $font, trailingslashit( $upload_paths['baseurl'] . '/borderless_icon_fonts/' ) . $info['style'], null, '1.0', 'all' ); 43 } 44 } 45 } 46 } 47 48 /*-----------------------------------------------------------------------------------*/ 49 /* *. Icon Pack Manager On Page Edit 50 /*-----------------------------------------------------------------------------------*/ 51 52 public function get_icon_manager( $input_name, $icon ) { 53 $font_manager = self::get_font_manager( $id ); 54 $output = '<div class="my_param_block">'; 55 $output .= '<input name="' . $input_name . '" class="textinput ' . $input_name . ' text_field" type="text" value="' . $icon . '"/>'; 56 $output .= '</div>'; 57 $output .= '<script type="text/javascript"> 58 jQuery(document).ready(function(){ 59 60 //debugger; 61 //alert("' . $id . '"); 62 jQuery(".icon-manager-preview-icon-' . $id . '").html("<i class=\'' . $icon . '\'></i>"); 63 jQuery(".icons-list-' . $id . ' li[data-icons=\'' . $icon . '\']").addClass("selected"); 64 }); 65 jQuery(".icons-list-' . $id . ' li").click(function() { 66 jQuery(this).attr("class","selected").siblings().removeAttr("class"); 67 var icon = jQuery(this).attr("data-icons"); 68 jQuery("input[name=\'' . $input_name . '\']").val(icon); 69 jQuery(".icon-manager-preview-icon-' . $id . '").html("<i class=\'"+icon+"\'></i>"); 70 }); 71 </script>'; 72 $output .= $font_manager; 73 74 return $output; 75 } 76 77 public function get_font_manager( $id ) { 78 79 $fonts = get_option( 'borderless_icon_fonts' ); 80 $output = '<div class="icon-manager-preview"><div class="icon-manager-preview-icon preview-icon-' . $id . '"><i class=""></i></div><input class="icon-manager-search-icon" type="text" placeholder="Search for a suitable icon.." /></div>'; 81 $output .= '<div id="icon-manager-search-icon-inner">'; 82 $output .= '<ul class="icons-list borderless_icon icon-list-' . $id . '">'; 83 foreach ( $fonts as $font => $info ) { 84 $icon_set = array(); 85 $icons = array(); 86 $upload_dir = wp_upload_dir(); 87 $path = trailingslashit( $upload_dir['basedir'] ); 88 $file = $path . $info['include'] . '/' . $info['config']; 89 include( $file ); 90 if ( ! empty( $icons ) ) { 91 $icon_set = array_merge( $icon_set, $icons ); 92 } 93 94 $set_name = ucfirst( $font ); 95 96 if ( ! empty( $icon_set ) ) { 97 $output .= '<p><strong>' . $set_name . '</strong></p>'; 98 $output .= '<li title="no-icon" data-icons="none" data-icons-tag="none,blank" style="cursor: pointer;" id="' . $id . '"></li>'; 99 foreach ( $icon_set as $icons ) { 100 foreach ( $icons as $icon ) { 101 $output .= '<li title="' . $icon['class'] . '" data-icons="' . $font . '-' . $icon['class'] . '" data-icons-tag="' . $icon['tags'] . '" id="' . $id . '">'; 102 $output .= '<i class="icon-manager-icon ' . $font . '-' . $icon['class'] . '"></i><label class="icon">' . $icon['class'] . '</label></li>'; 103 } 104 } 105 } 106 } 107 $output . '</ul>'; 108 $output .= '<script type="text/javascript"> 109 jQuery(document).ready(function(){ 110 jQuery(".icon-manager-search-icon").keyup(function(){ 111 // Retrieve the input field text and reset the count to zero 112 var filter = jQuery(this).val(), count = 0; 113 // Loop through the icon list 114 jQuery(".icons-list li").each(function(){ 115 // If the list item does not contain the text phrase fade it out 116 if (jQuery(this).attr("data-icons-tag").search(new RegExp(filter, "i")) < 0) { 117 jQuery(this).fadeOut(); 118 } else { 119 jQuery(this).show(); 120 count++; 121 } 122 }); 123 }); 124 }); 125 </script>'; 126 $output .= '</div>'; 127 128 return $output; 129 } 130 131 /*-----------------------------------------------------------------------------------*/ 132 /* *. Icon Pack Manager 133 /*-----------------------------------------------------------------------------------*/ 134 135 function icon_pack_manager() { 136 ?> 137 <div class="wrap"> 138 <h2> 139 <?php esc_html_e( 'Icon Pack Manager', 'borderless' ); ?> 140 <a href="#borderless_upload_icon" class="button button-primary borderless-upload-icon" data-target="iconfont_upload" 141 data-title="<?php echo esc_html__( "Upload/Select Fontello Font Zip", "borderless" ) ?>" 142 data-type="application/octet-stream, application/zip" 143 data-button="<?php echo esc_html__( "Insert Fonts Zip File", "borderless" ); ?>" data-trigger="borderless_insert_zip" 144 data-class="media-frame "> 145 <?php esc_html_e( 'Add New Icon Pack', 'borderless' ); ?> 146 </a> <span class="spinner"></span></h2> 147 <div id="msg"></div> 148 <?php 149 $fonts = get_option( 'borderless_icon_fonts' ); 150 if ( is_array( $fonts ) ) : 151 ?> 152 <div class="metabox-holder meta-search"> 153 <div class="postbox borderless-postbox-search"> 154 <h2 class="hndle ui-sortable-handle"><span>Search for Icons</h2> 155 <div class="inside"> 156 <div class="search-area"> 157 <input class="search-icon" type="text" placeholder="<?php esc_attr_e( 'Start typing to search', 'borderless' ); ?>"/> 158 <span class="search-count"></span> 159 </div> 160 </div> 161 </div> 162 </div> 163 <?php self::get_ipm(); ?> 164 </div> 165 <?php else: ?> 166 <div class="error"> 167 <p> 168 <?php esc_html_e( 'No icon pack uploaded. Upload some icon pack to display here.', 'borderless' ); ?> 169 </p> 170 </div> 171 <?php 172 endif; 173 } 174 175 // Generate Icon Pack Preview and settings page 176 static function get_ipm() { 177 $fonts = get_option( 'borderless_icon_fonts' ); 178 $n = count( $fonts ); 179 foreach ( $fonts as $font => $info ) { 180 $icon_set = array(); 181 $icons = array(); 182 $upload_dir = wp_upload_dir(); 183 $path = trailingslashit( $upload_dir['basedir'] ); 184 $file = $path . $info['include'] . '/' . $info['config']; 185 $output = '<div class="icon_set-' . $font . ' metabox-holder">'; 186 $output .= '<div class="postbox borderless-postbox-icon-manager">'; 187 include( $file ); 188 if ( ! empty( $icons ) ) { 189 $icon_set = array_merge( $icon_set, $icons ); 190 } 191 if ( ! empty( $icon_set ) ) { 192 foreach ( $icon_set as $icons ) { 193 $count = count( $icons ); 194 } 195 196 $output .= '<h3 class="ip_name"><strong>' . esc_html( ucfirst( $font ) ) . '</strong>'; 197 198 $output .= '<span class="fonts-count wp-core-ui wp-ui-notification count-' . esc_attr( $font ) . '">' . esc_html( $count ) . '</span>'; 199 if ( $n != 1 ) { 200 $output .= '<button class="button button-primary button-small borderless_del_icon" data-delete=' . esc_attr( $font ) . ' data-title="' . esc_attr__( 'Remove Pack', 'borderless' ) . '">' . esc_html__( 'Remove Pack', 'borderless' ) . '</button>'; 201 } 202 $output .= '</h3>'; 203 $output .= '<div class="inside"><div class="icon_actions">'; 204 $output .= '</div>'; 205 $output .= '<div class="icon_search"><ul class="icons-list borderless_icon">'; 206 foreach ( $icon_set as $icons ) { 207 foreach ( $icons as $icon ) { 208 $output .= '<li " data-icons="' . esc_attr( $icon['class'] ) . '" data-icons-tag="' . esc_attr( $icon['tags'] ) . '">'; 209 $output .= '<i class="' . esc_attr( $font ) . '-' . esc_attr( $icon['class'] ) . '"></i><a class="tooltips" href="#"><span>' . esc_html( $icon['class'] ) . '</span></a></li>'; 210 } 211 } 212 $output . '</ul>'; 213 $output .= '</div><!-- .icon_search-->'; 214 $output .= '</div><!-- .inside-->'; 215 $output .= '</div><!-- .postbox-->'; 216 $output .= '</div><!-- .icon_set-' . esc_html( $font ) . ' -->'; 217 echo $output; 218 } 219 } 220 $script = '<script type="text/javascript"> 221 jQuery(document).ready(function(){ 222 jQuery(".search-icon").keyup(function(){ 223 jQuery(".fonts-count").hide(); 224 // Retrieve the input field text and reset the count to zero 225 var filter = jQuery(this).val(), count = 0; 226 // Loop through the icon list 227 jQuery(".icons-list li").each(function(){ 228 // If the list item does not contain the text phrase fade it out 229 if (jQuery(this).attr("data-icons-tag").search(new RegExp(filter, "i")) < 0) { 230 jQuery(this).fadeOut(); 231 } else { 232 jQuery(this).show(); 233 count++; 234 } 235 if(count == 0) 236 jQuery(".search-count").html(" ' . esc_js( __( 'Can\'t find the icon?', 'borderless' ) ) . ' <a href=\'#borderless_upload_icon\' class=\'button button-primary borderless_upload_icon\' data-target=\'iconfont_upload\' data-title=\' ' . esc_js( __( 'Upload/Select Fontello Font Zip', 'borderless' ) ) . ' \' data-type=\'application/octet-stream, application/zip\' data-button=\' ' . esc_js( __( 'Insert Fonts Zip File', 'borderless' ) ) . ' \' data-trigger=\'borderless_insert_zip\' data-class=\'media-frame\'>' . esc_js( __( 'Upload New Font Pack', 'borderless' ) ) . '</a>"); 237 else 238 jQuery(".search-count").html(count+" ' . esc_js( __( 'Icons found.', 'borderless' ) ) . '"); 239 jQuery( ".search-count" ).addClass( "search-count-open" ); 240 if(filter == "") 241 jQuery(".fonts-count").show(); 242 }); 243 }); 244 }); 245 </script>'; 246 echo $script; 247 } 248 249 function add_zipped_font() { 250 $cap = apply_filters( 'avf_file_upload_capability', 'update_plugins' ); 251 if ( ! current_user_can( $cap ) ) { 252 die( esc_html__( "Using this feature is reserved for Super Admins. You unfortunately don't have the necessary permissions.", "borderless" ) ); 253 } 254 //get the file path of the zip file 255 $attachment = $_POST['values']; 256 $path = realpath( get_attached_file( sanitize_text_field( $attachment['id'] ) ) ); 257 $unzipped = $this->zip_flatten( $path, array( '\.eot', '\.svg', '\.ttf', '\.woff', '\.json', '\.css' ) ); 258 // if we were able to unzip the file and save it to our temp folder extract the svg file 259 if ( $unzipped ) { 260 $this->create_config(); 261 } 262 //if we got no name for the font dont add it and delete the temp folder 263 if ( $this->ip_name == 'unknown' ) { 264 $this->delete_folder( $this->paths['tempdir'] ); 265 die( esc_html__( 'Was not able to retrieve the Icon Pack name from your Uploaded Folder', 'borderless' ) ); 266 } 267 die( esc_html__( 'borderless_font_added:', 'borderless' ) . $this->ip_name ); 268 } 269 270 function remove_zipped_font() { 271 //get the file path of the zip file 272 $font = sanitize_text_field( $_POST['del_font'] ); 273 $list = self::load_iconfont_list(); 274 $delete = isset( $list[ $font ] ) ? $list[ $font ] : false; 275 if ( $delete ) { 276 $this->delete_folder( $delete['include'] ); 277 $this->remove_font( $font ); 278 die( esc_html__( 'borderless_font_removed', 'borderless' ) ); 279 } 280 die( esc_html__( 'Was not able to remove Icon Pack', 'borderless' ) ); 281 } 282 283 //extract the zip file to a flat folder and remove the files that are not needed 284 function zip_flatten( $zipfile, $filter ) { 285 if ( is_dir( $this->paths['tempdir'] ) ) { 286 $this->delete_folder( $this->paths['tempdir'] ); 287 $tempdir = borderless_backend_create_folder( $this->paths['tempdir'], false ); 288 } else { 289 $tempdir = borderless_backend_create_folder( $this->paths['tempdir'], false ); 290 } 291 //$fontdir = borderless_backend_create_folder($this->paths['fontdir'], false); 292 if ( ! $tempdir ) { 293 die( esc_html__( 'Could not create temporary folder.', 'borderless' ) ); 294 } 295 $zip = new ZipArchive; 296 if ( $zip->open( $zipfile ) ) { 297 for ( $i = 0; $i < $zip->numFiles; $i ++ ) { 298 $entry = $zip->getNameIndex( $i ); 299 if ( ! empty( $filter ) ) { 300 $delete = true; 301 $matches = array(); 302 foreach ( $filter as $regex ) { 303 preg_match( "!" . $regex . "!", $entry, $matches ); 304 if ( ! empty( $matches ) ) { 305 $delete = false; 306 break; 307 } 308 } 309 } 310 if ( substr( $entry, - 1 ) == '/' || ! empty( $delete ) ) { 311 continue; 312 } // skip directories and non matching files 313 $fp = $zip->getStream( $entry ); 314 $ofp = fopen( $this->paths['tempdir'] . '/' . basename( $entry ), 'w' ); 315 if ( ! $fp ) { 316 die( esc_html__( 'Unable to unpack Icon Pack.', 'borderless' ) ); 317 } 318 while ( ! feof( $fp ) ) { 319 fwrite( $ofp, fread( $fp, 8192 ) ); 320 } 321 fclose( $fp ); 322 fclose( $ofp ); 323 } 324 $zip->close(); 325 } else { 326 die( esc_html__( "Icon Pack Zip file is corrupted.", 'borderless' ) ); 327 } 328 329 return true; 330 } 331 332 //iterate over xml file and extract the glyphs for the font 333 function create_config() { 334 $this->json_file = $this->find_json(); 335 $this->svg_file = $this->find_svg(); 336 if ( empty( $this->json_file ) || empty( $this->svg_file ) ) { 337 $this->delete_folder( $this->paths['tempdir'] ); 338 die( esc_html__( 'SVG file or selection.json not found. Please check the integrity of the Icon Pack files.', 'borderless' ) ); 339 } 340 //$response = wp_remote_get( $this->paths['tempurl'].$this->svg_file ); 341 $response = wp_remote_fopen( trailingslashit( $this->paths['tempurl'] ) . $this->svg_file ); 342 //if wordpress wasnt able to get the file which is unlikely try to fetch it old school 343 $json = file_get_contents( trailingslashit( $this->paths['tempdir'] ) . $this->json_file ); 344 if ( empty( $response ) ) { 345 $response = file_get_contents( trailingslashit( $this->paths['tempdir'] ) . $this->svg_file ); 346 } 347 if ( ! is_wp_error( $json ) && ! empty( $json ) ) { 348 $xml = simplexml_load_string( $response ); 349 $font_attr = $xml->defs->font->attributes(); 350 $glyphs = $xml->defs->font->children(); 351 $this->ip_name = (string) $font_attr['id']; 352 $font_folder = trailingslashit( $this->paths['fontdir'] ) . $this->ip_name; 353 if ( is_dir( $font_folder ) ) { 354 $this->delete_folder( $this->paths['tempdir'] ); 355 die( esc_html__( "There is already an Icon Pack with this name, add an icon with another name.", "borderless" ) ); 356 } 357 $file_contents = json_decode( $json ); 358 if ( ! isset( $file_contents->IcoMoonType ) ) { 359 $this->delete_folder( $this->paths['tempdir'] ); 360 die( esc_html__( "This Icon Pack does not belong to Icomoon. Use only Icomoon's Icon Pack.", 'borderless' ) ); 361 } 362 $icons = $file_contents->icons; 363 $n = 1; 364 foreach ( $icons as $icon ) { 365 $icon_name = $icon->properties->name; 366 $icon_class = str_replace( ' ', '', $icon_name ); 367 $icon_class = str_replace( ',', ' ', $icon_class ); 368 $tags = implode( ",", $icon->icon->tags ); 369 $this->json_config[ $this->ip_name ][ $icon_name ] = array( 370 "class" => $icon_class, 371 "tags" => $tags 372 ); 373 $n ++; 374 } 375 if ( ! empty( $this->json_config ) && $this->ip_name != 'unknown' ) { 376 $this->write_config(); 377 $this->re_write_css(); 378 $this->rename_files(); 379 $this->rename_folder(); 380 $this->add_font(); 381 } 382 } 383 384 return false; 385 } 386 387 //writes the php config file for the font 388 function write_config() { 389 $charmap = $this->paths['tempdir'] . '/' . $this->paths['config']; 390 $handle = @fopen( $charmap, 'w' ); 391 if ( $handle ) { 392 fwrite( $handle, '<?php $icons = array();' ); 393 foreach ( $this->json_config[ $this->ip_name ] as $icon => $info ) { 394 if ( ! empty( $info ) ) { 395 $delimiter = "'"; 396 fwrite( $handle, "\r\n" . '$icons[\'' . $this->ip_name . '\'][' . $delimiter . $icon . $delimiter . '] = array("class"=>' . $delimiter . $info["class"] . $delimiter . ',"tags"=>' . $delimiter . $info["tags"] . $delimiter . ');' ); 397 } else { 398 $this->delete_folder( $this->paths['tempdir'] ); 399 die( esc_html__( 'Error generating configuration file.', 'borderless' ) ); 400 } 401 } 402 fclose( $handle ); 403 } else { 404 $this->delete_folder( $this->paths['tempdir'] ); 405 die( esc_html__( 'Error generating configuration file.', 'borderless' ) ); 406 } 407 } 408 409 //re-writes the php config file for the font 410 function re_write_css() { 411 $style = $this->paths['tempdir'] . '/style.css'; 412 $file = @file_get_contents( $style ); 413 if ( $file ) { 414 $str = str_replace( 'fonts/', '', $file ); 415 $str = str_replace( 'icon-', $this->ip_name . '-', $str ); 416 $str = str_replace( '.icon {', '[class^="' . $this->ip_name . '-"], [class*=" ' . $this->ip_name . '-"] {', $str ); 417 $str = str_replace( 'i {', '[class^="' . $this->ip_name . '-"], [class*=" ' . $this->ip_name . '-"] {', $str ); 418 419 /* remove comments */ 420 $str = preg_replace( '!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $str ); 421 422 /* remove tabs, spaces, newlines, etc. */ 423 $str = str_replace( array( "\r\n", "\r", "\n", "\t", ' ', ' ', ' ' ), '', $str ); 424 425 @file_put_contents( $style, $str ); 426 } else { 427 die( esc_html__( "Error generating CSS file. Use only Icomoon's Icon Pack.", 'borderless' ) ); 428 } 429 } 430 431 function rename_files() { 432 $extensions = array( 'eot', 'svg', 'ttf', 'woff', 'css' ); 433 $folder = trailingslashit( $this->paths['tempdir'] ); 434 foreach ( glob( $folder . '*' ) as $file ) { 435 $path_parts = pathinfo( $file ); 436 if ( strpos( $path_parts['filename'], '.dev' ) === false && in_array( $path_parts['extension'], $extensions ) ) { 437 if ( $path_parts['filename'] !== $this->ip_name ) { 438 rename( $file, trailingslashit( $path_parts['dirname'] ) . $this->ip_name . '.' . $path_parts['extension'] ); 439 } 440 } 441 } 442 } 443 444 //rename the temp folder and all its font files 445 function rename_folder() { 446 $new_name = trailingslashit( $this->paths['fontdir'] ) . $this->ip_name; 447 //delete folder and contents if they already exist 448 $this->delete_folder( $new_name ); 449 if ( rename( $this->paths['tempdir'], $new_name ) ) { 450 return true; 451 } else { 452 $this->delete_folder( $this->paths['tempdir'] ); 453 die( esc_html__( "This Icon Pack could not be added.", "borderless" ) ); 454 } 455 } 456 457 //delete a folder 458 function delete_folder( $new_name ) { 459 //delete folder and contents if they already exist 460 if ( is_dir( $new_name ) ) { 461 $objects = scandir( $new_name ); 462 foreach ( $objects as $object ) { 463 if ( $object != "." && $object != ".." ) { 464 unlink( $new_name . "/" . $object ); 465 } 466 } 467 reset( $objects ); 468 rmdir( $new_name ); 469 } else { 470 echo $new_name . ' no found<br/>'; 471 } 472 } 473 474 function add_font() { 475 $fonts = get_option( 'borderless_icon_fonts' ); 476 if ( empty( $fonts ) ) { 477 $fonts = array(); 478 } 479 $fonts[ $this->ip_name ] = array( 480 'include' => sanitize_text_field( trailingslashit( $this->paths['fonts'] ) ) . $this->ip_name, 481 'folder' => sanitize_text_field( trailingslashit( $this->paths['fonts'] ) ) . $this->ip_name, 482 'style' => $this->ip_name . '/' . $this->ip_name . '.css', 483 'config' => sanitize_text_field( $this->paths['config'] ) 484 ); 485 update_option( 'borderless_icon_fonts', $fonts ); 486 } 487 488 function remove_font( $font ) { 489 $fonts = get_option( 'borderless_icon_fonts' ); 490 if ( isset( $fonts[ $font ] ) ) { 491 unset( $fonts[ $font ] ); 492 update_option( 'borderless_icon_fonts', $fonts ); 493 } 494 } 495 496 //finds the json file we need to create the config 497 function find_json() { 498 $files = scandir( $this->paths['tempdir'] ); 499 foreach ( $files as $file ) { 500 if ( strpos( strtolower( $file ), '.json' ) !== false && $file[0] != '.' ) { 501 return $file; 502 } 503 } 504 } 505 506 //finds the svg file we need to create the config 507 function find_svg() { 508 $files = scandir( $this->paths['tempdir'] ); 509 foreach ( $files as $file ) { 510 if ( strpos( strtolower( $file ), '.svg' ) !== false && $file[0] != '.' ) { 511 return $file; 512 } 513 } 514 } 515 516 static function load_iconfont_list() { 517 if ( ! empty( self::$ip_list ) ) { 518 return self::$ip_list; 519 } 520 $extra_fonts = get_option( 'borderless_icon_fonts' ); 521 if ( empty( $extra_fonts ) ) { 522 $extra_fonts = array(); 523 } 524 $font_configs = $extra_fonts;//array_merge(borderlessBuilder::$default_iconfont, $extra_fonts); 525 //if we got any include the charmaps and add the chars to an array 526 $upload_dir = wp_upload_dir(); 527 $path = trailingslashit( $upload_dir['basedir'] ); 528 $url = trailingslashit( $upload_dir['baseurl'] ); 529 foreach ( $font_configs as $key => $config ) { 530 if ( empty( $config['full_path'] ) ) { 531 $font_configs[ $key ]['include'] = $path . $font_configs[ $key ]['include']; 532 $font_configs[ $key ]['folder'] = $url . $font_configs[ $key ]['folder']; 533 } 534 } 535 //cache the result 536 self::$ip_list = $font_configs; 537 538 return $font_configs; 539 } 540 }// End class 541 542 /* 543 * creates a folder for the theme framework 544 */ 545 546 if ( ! function_exists( 'borderless_backend_create_folder' ) ) { 547 function borderless_backend_create_folder( &$folder, $addindex = true ) { 548 if ( is_dir( $folder ) && $addindex == false ) { 549 return true; 550 } 551 $created = wp_mkdir_p( trailingslashit( $folder ) ); 552 @chmod( $folder, 0777 ); 553 if ( $addindex == false ) { 554 return $created; 555 } 556 $index_file = trailingslashit( $folder ) . 'index.php'; 557 if ( file_exists( $index_file ) ) { 558 return $created; 559 } 560 $handle = @fopen( $index_file, 'w' ); 561 if ( $handle ) { 562 fwrite( $handle, "<?php\r\necho 'We're sorry for the inconvenience, but you're not allowed to browse the directory.';\r\n?> 563 " ); 564 fclose( $handle ); 565 } 566 567 return $created; 568 } 569 } 570 // Instantiate the Icon Fonts 571 new Borderless_IF; 572 } 573 574 function borderless_custom_icons_menu() { 575 $Borderless_IF = new Borderless_IF; 576 $Borderless_IF->icon_pack_manager(); 577 } 578 579 function borderless_custom_icons() { 580 $upload_paths = wp_upload_dir(); 581 $custom_fonts = get_option( 'borderless_icon_fonts' ); 582 if ( is_array( $custom_fonts ) ) { 583 foreach ( $custom_fonts as $font => $info ) { 584 if ( strpos( $info['style'], 'http://' ) !== false ) { 585 wp_enqueue_style( 'borderless-' . $font, $info['style'], null, '1.0', 'all' ); 586 } else { 587 wp_enqueue_style( 'borderless-' . $font, trailingslashit( $upload_paths['baseurl'] . '/borderless_icon_fonts/' ) . $info['style'], null, '1.0', 'all' ); 588 } 589 } 590 } 591 } 592 593 add_action( 'wp_enqueue_scripts', 'borderless_custom_icons' ); 7 class Borderless_IF { 8 var $paths = array(); 9 var $svg_file; 10 var $json_file; 11 var $ip_name = 'unknown'; 12 var $svg_config = array(); 13 var $json_config = array(); 14 static $ip_list = array(); 15 16 function __construct() { 17 $this->paths = wp_upload_dir(); 18 $this->paths['fonts'] = 'borderless_icon_fonts'; 19 $this->paths['temp'] = trailingslashit( $this->paths['fonts'] ) . 'borderless_temp'; 20 $this->paths['fontdir'] = trailingslashit( $this->paths['basedir'] ) . $this->paths['fonts']; 21 $this->paths['tempdir'] = trailingslashit( $this->paths['basedir'] ) . $this->paths['temp']; 22 $this->paths['fonturl'] = set_url_scheme( trailingslashit( $this->paths['baseurl'] ) . $this->paths['fonts'] ); 23 $this->paths['tempurl'] = trailingslashit( $this->paths['baseurl'] ) . trailingslashit( $this->paths['temp'] ); 24 $this->paths['config'] = 'charmap.php'; 25 26 add_action( 'wp_ajax_borderless_ajax_add_zipped_font', array( $this, 'add_zipped_font' ) ); 27 add_action( 'wp_ajax_borderless_ajax_remove_zipped_font', array( $this, 'remove_zipped_font' ) ); 28 } 29 30 /** 31 * Loads admin scripts and styles 32 */ 33 function admin_scripts() { 34 $upload_paths = wp_upload_dir(); 35 wp_enqueue_script( 'borderless-admin-media', plugin_dir_url( __FILE__ ) . 'assets/js/icon-manager.min.js', array( 'jquery' ) ); 36 wp_enqueue_script( 'media-upload' ); 37 wp_enqueue_media(); 38 wp_enqueue_style( 'borderless-wpbakery-icon-manager-admin', plugin_dir_url( __FILE__ ) . 'assets/css/icon-manager.css' ); 39 $custom_fonts = get_option( 'borderless_icon_fonts' ); 40 if ( is_array( $custom_fonts ) ) { 41 foreach ( $custom_fonts as $font => $info ) { 42 if ( strpos( $info['style'], 'http://' ) !== false ) { 43 wp_enqueue_style( 'borderless-' . $font, $info['style'], null, '1.0', 'all' ); 44 } else { 45 wp_enqueue_style( 'borderless-' . $font, trailingslashit( $upload_paths['baseurl'] . '/borderless_icon_fonts/' ) . $info['style'], null, '1.0', 'all' ); 46 } 47 } 48 } 49 } 50 51 /** 52 * Creates an icon selector interface 53 */ 54 public function get_icon_manager( $input_name, $icon ) { 55 $font_manager = self::get_font_manager( $id ); 56 $output = '<div class="my_param_block">'; 57 $output .= '<input name="' . $input_name . '" class="textinput ' . $input_name . ' text_field" type="text" value="' . $icon . '"/>'; 58 $output .= '</div>'; 59 $output .= '<script type="text/javascript"> 60 jQuery(document).ready(function(){ 61 jQuery(".icon-manager-preview-icon-' . $id . '").html("<i class=\'' . $icon . '\'></i>"); 62 jQuery(".icons-list-' . $id . ' li[data-icons=\'' . $icon . '\']").addClass("selected"); 63 }); 64 jQuery(".icons-list-' . $id . ' li").click(function() { 65 jQuery(this).attr("class","selected").siblings().removeAttr("class"); 66 var icon = jQuery(this).attr("data-icons"); 67 jQuery("input[name=\'' . $input_name . '\']").val(icon); 68 jQuery(".icon-manager-preview-icon-' . $id . '").html("<i class=\'"+icon+"\'></i>"); 69 }); 70 </script>'; 71 $output .= $font_manager; 72 73 return $output; 74 } 75 76 /** 77 * Generates the list of icons in the manager 78 */ 79 public function get_font_manager( $id ) { 80 $fonts = get_option( 'borderless_icon_fonts' ); 81 $output = '<div class="icon-manager-preview"><div class="icon-manager-preview-icon preview-icon-' . $id . '"><i class=""></i></div><input class="icon-manager-search-icon" type="text" placeholder="Search for a suitable icon.." /></div>'; 82 $output .= '<div id="icon-manager-search-icon-inner">'; 83 $output .= '<ul class="icons-list borderless_icon icon-list-' . $id . '">'; 84 85 foreach ( $fonts as $font => $info ) { 86 $icon_set = array(); 87 $icons = array(); 88 $upload_dir = wp_upload_dir(); 89 $path = trailingslashit( $upload_dir['basedir'] ); 90 $file = $path . $info['include'] . '/' . $info['config']; 91 92 include( $file ); 93 if ( ! empty( $icons ) ) { 94 $icon_set = array_merge( $icon_set, $icons ); 95 } 96 97 $set_name = ucfirst( $font ); 98 99 if ( ! empty( $icon_set ) ) { 100 $output .= '<p><strong>' . $set_name . '</strong></p>'; 101 $output .= '<li title="no-icon" data-icons="none" data-icons-tag="none,blank" style="cursor: pointer;" id="' . $id . '"></li>'; 102 foreach ( $icon_set as $icons ) { 103 foreach ( $icons as $icon ) { 104 $output .= '<li title="' . $icon['class'] . '" data-icons="' . $font . '-' . $icon['class'] . '" data-icons-tag="' . $icon['tags'] . '" id="' . $id . '">'; 105 $output .= '<i class="icon-manager-icon ' . $font . '-' . $icon['class'] . '"></i><label class="icon">' . $icon['class'] . '</label></li>'; 106 } 107 } 108 } 109 } 110 $output .= '</ul>'; 111 $output .= '<script type="text/javascript"> 112 jQuery(document).ready(function(){ 113 jQuery(".icon-manager-search-icon").keyup(function(){ 114 var filter = jQuery(this).val(), count = 0; 115 jQuery(".icons-list li").each(function(){ 116 if ( jQuery(this).attr("data-icons-tag").search(new RegExp(filter, "i")) < 0 ) { 117 jQuery(this).fadeOut(); 118 } else { 119 jQuery(this).show(); 120 count++; 121 } 122 }); 123 }); 124 }); 125 </script>'; 126 $output .= '</div>'; 127 128 return $output; 129 } 130 131 /** 132 * Generates the Icon Pack Manager page 133 */ 134 function icon_pack_manager() { 135 ?> 136 <div class="wrap"> 137 <h2> 138 <?php esc_html_e( 'Icon Pack Manager', 'borderless' ); ?> 139 <a href="#borderless_upload_icon" class="button button-primary borderless-upload-icon" 140 data-target="iconfont_upload" 141 data-title="<?php echo esc_html__( "Upload or Select Fontello Font Zip", "borderless" ); ?>" 142 data-type="application/octet-stream, application/zip" 143 data-button="<?php echo esc_html__( "Insert Fonts Zip File", "borderless" ); ?>" 144 data-trigger="borderless_insert_zip" 145 data-class="media-frame "> 146 <?php esc_html_e( 'Add New Icon Pack', 'borderless' ); ?> 147 </a> <span class="spinner"></span> 148 </h2> 149 <div id="msg"></div> 150 <?php 151 $fonts = get_option( 'borderless_icon_fonts' ); 152 if ( is_array( $fonts ) ) : 153 ?> 154 <div class="metabox-holder meta-search"> 155 <div class="postbox borderless-postbox-search"> 156 <h2 class="hndle ui-sortable-handle"><span>Search for Icons</span></h2> 157 <div class="inside"> 158 <div class="search-area"> 159 <input class="search-icon" type="text" placeholder="<?php esc_attr_e( 'Start typing to search', 'borderless' ); ?>"/> 160 <span class="search-count"></span> 161 </div> 162 </div> 163 </div> 164 </div> 165 <?php self::get_ipm(); ?> 166 </div> 167 <?php else: ?> 168 <div class="error"> 169 <p> 170 <?php esc_html_e( 'No icon pack uploaded. Please upload at least one icon pack to display here.', 'borderless' ); ?> 171 </p> 172 </div> 173 <?php 174 endif; 175 } 176 177 /** 178 * Generates Icon Pack Preview and settings 179 */ 180 static function get_ipm() { 181 $fonts = get_option( 'borderless_icon_fonts' ); 182 $n = count( $fonts ); 183 foreach ( $fonts as $font => $info ) { 184 $icon_set = array(); 185 $icons = array(); 186 $upload_dir = wp_upload_dir(); 187 $path = trailingslashit( $upload_dir['basedir'] ); 188 $file = $path . $info['include'] . '/' . $info['config']; 189 $output = '<div class="icon_set-' . $font . ' metabox-holder">'; 190 $output .= '<div class="postbox borderless-postbox-icon-manager">'; 191 192 include( $file ); 193 if ( ! empty( $icons ) ) { 194 $icon_set = array_merge( $icon_set, $icons ); 195 } 196 197 if ( ! empty( $icon_set ) ) { 198 foreach ( $icon_set as $icons ) { 199 $count = count( $icons ); 200 } 201 202 $output .= '<h3 class="ip_name"><strong>' . esc_html( ucfirst( $font ) ) . '</strong>'; 203 $output .= '<span class="fonts-count wp-core-ui wp-ui-notification count-' . esc_attr( $font ) . '">' . esc_html( $count ) . '</span>'; 204 205 if ( $n != 1 ) { 206 $output .= '<button class="button button-primary button-small borderless_del_icon" data-delete=' . esc_attr( $font ) . ' data-title="' . esc_attr__( 'Remove Pack', 'borderless' ) . '">' . esc_html__( 'Remove Pack', 'borderless' ) . '</button>'; 207 } 208 $output .= '</h3>'; 209 $output .= '<div class="inside"><div class="icon_actions"></div>'; 210 $output .= '<div class="icon_search"><ul class="icons-list borderless_icon">'; 211 212 foreach ( $icon_set as $icons ) { 213 foreach ( $icons as $icon ) { 214 $output .= '<li data-icons="' . esc_attr( $icon['class'] ) . '" data-icons-tag="' . esc_attr( $icon['tags'] ) . '">'; 215 $output .= '<i class="' . esc_attr( $font ) . '-' . esc_attr( $icon['class'] ) . '"></i><a class="tooltips" href="#"><span>' . esc_html( $icon['class'] ) . '</span></a></li>'; 216 } 217 } 218 $output .= '</ul>'; 219 $output .= '</div><!-- .icon_search-->'; 220 $output .= '</div><!-- .inside-->'; 221 $output .= '</div><!-- .postbox-->'; 222 $output .= '</div><!-- .icon_set-' . esc_html( $font ) . ' -->'; 223 echo $output; 224 } 225 } 226 $script = '<script type="text/javascript"> 227 jQuery(document).ready(function(){ 228 jQuery(".search-icon").keyup(function(){ 229 jQuery(".fonts-count").hide(); 230 var filter = jQuery(this).val(), count = 0; 231 jQuery(".icons-list li").each(function(){ 232 if (jQuery(this).attr("data-icons-tag").search(new RegExp(filter, "i")) < 0) { 233 jQuery(this).fadeOut(); 234 } else { 235 jQuery(this).show(); 236 count++; 237 } 238 if(count === 0) { 239 jQuery(".search-count").html("Can\'t find the icon? <a href=\'#borderless_upload_icon\' class=\'button button-primary borderless_upload_icon\' data-target=\'iconfont_upload\' data-title=\'Upload or Select Fontello Font Zip\' data-type=\'application/octet-stream, application/zip\' data-button=\'Insert Fonts Zip File\' data-trigger=\'borderless_insert_zip\' data-class=\'media-frame\'>Upload New Font Pack</a>"); 240 } else { 241 jQuery(".search-count").html(count + " Icons found."); 242 } 243 jQuery(".search-count").addClass("search-count-open"); 244 if(filter === "") { 245 jQuery(".fonts-count").show(); 246 } 247 }); 248 }); 249 }); 250 </script>'; 251 echo $script; 252 } 253 254 /** 255 * Handles the Ajax call for adding a zipped font 256 */ 257 function add_zipped_font() { 258 $cap = apply_filters( 'avf_file_upload_capability', 'update_plugins' ); 259 if ( ! current_user_can( $cap ) ) { 260 die( esc_html__( "You do not have sufficient permissions to use this feature.", "borderless" ) ); 261 } 262 // Retrieve the file path of the zip file 263 $attachment = $_POST['values']; 264 $path = realpath( get_attached_file( sanitize_text_field( $attachment['id'] ) ) ); 265 $unzipped = $this->zip_flatten( $path, array( '\.eot', '\.svg', '\.ttf', '\.woff', '\.json', '\.css' ) ); 266 267 // If we managed to unzip the file and save it, extract the SVG file 268 if ( $unzipped ) { 269 $this->create_config(); 270 } 271 272 // If we did not get a name for the font, do not add it and remove the temp folder 273 if ( $this->ip_name == 'unknown' ) { 274 $this->delete_folder( $this->paths['tempdir'] ); 275 die( esc_html__( 'Unable to retrieve the Icon Pack name from your uploaded folder.', 'borderless' ) ); 276 } 277 die( esc_html__( 'borderless_font_added:', 'borderless' ) . $this->ip_name ); 278 } 279 280 /** 281 * Handles the Ajax call for removing a zipped font 282 */ 283 function remove_zipped_font() { 284 // Nonce verification for CSRF protection 285 check_ajax_referer( 'borderless_remove_zipped_font_nonce', 'security' ); 286 287 // Capability check to ensure only authorized users can delete 288 $cap = apply_filters( 'avf_file_upload_capability', 'update_plugins' ); 289 if ( ! current_user_can( $cap ) ) { 290 die( esc_html__( "You do not have sufficient permissions to use this feature.", "borderless" ) ); 291 } 292 293 // Retrieve the font to be deleted 294 $font = sanitize_text_field( $_POST['del_font'] ); 295 $list = self::load_iconfont_list(); 296 $delete = isset( $list[ $font ] ) ? $list[ $font ] : false; 297 if ( $delete ) { 298 $this->delete_folder( $delete['include'] ); 299 $this->remove_font( $font ); 300 die( esc_html__( 'borderless_font_removed', 'borderless' ) ); 301 } 302 die( esc_html__( 'Unable to remove Icon Pack', 'borderless' ) ); 303 } 304 305 /** 306 * Unzips a font file to a flat folder and removes unneeded files 307 */ 308 function zip_flatten( $zipfile, $filter ) { 309 if ( is_dir( $this->paths['tempdir'] ) ) { 310 $this->delete_folder( $this->paths['tempdir'] ); 311 $tempdir = borderless_backend_create_folder( $this->paths['tempdir'], false ); 312 } else { 313 $tempdir = borderless_backend_create_folder( $this->paths['tempdir'], false ); 314 } 315 if ( ! $tempdir ) { 316 die( esc_html__( 'Could not create the temporary folder.', 'borderless' ) ); 317 } 318 319 $zip = new ZipArchive; 320 if ( $zip->open( $zipfile ) ) { 321 for ( $i = 0; $i < $zip->numFiles; $i++ ) { 322 $entry = $zip->getNameIndex( $i ); 323 if ( ! empty( $filter ) ) { 324 $delete = true; 325 $matches = array(); 326 foreach ( $filter as $regex ) { 327 preg_match( "!" . $regex . "!", $entry, $matches ); 328 if ( ! empty( $matches ) ) { 329 $delete = false; 330 break; 331 } 332 } 333 } 334 // Skip directories and non-matching files 335 if ( substr( $entry, -1 ) == '/' || ! empty( $delete ) ) { 336 continue; 337 } 338 $fp = $zip->getStream( $entry ); 339 $ofp = fopen( $this->paths['tempdir'] . '/' . basename( $entry ), 'w' ); 340 if ( ! $fp ) { 341 die( esc_html__( 'Unable to unpack the Icon Pack.', 'borderless' ) ); 342 } 343 while ( ! feof( $fp ) ) { 344 fwrite( $ofp, fread( $fp, 8192 ) ); 345 } 346 fclose( $fp ); 347 fclose( $ofp ); 348 } 349 $zip->close(); 350 } else { 351 die( esc_html__( "The Icon Pack zip file is corrupted.", 'borderless' ) ); 352 } 353 354 return true; 355 } 356 357 /** 358 * Reads JSON and SVG files, sanitizes them, and prepares the config 359 */ 360 function create_config() { 361 $this->json_file = $this->find_json(); 362 $this->svg_file = $this->find_svg(); 363 if ( empty( $this->json_file ) || empty( $this->svg_file ) ) { 364 $this->delete_folder( $this->paths['tempdir'] ); 365 die( esc_html__( 'SVG file or selection.json not found. Please check the integrity of the Icon Pack files.', 'borderless' ) ); 366 } 367 368 // Attempt to read the SVG file 369 $response = wp_remote_fopen( trailingslashit( $this->paths['tempurl'] ) . $this->svg_file ); 370 $json = file_get_contents( trailingslashit( $this->paths['tempdir'] ) . $this->json_file ); 371 372 if ( empty( $response ) ) { 373 $response = file_get_contents( trailingslashit( $this->paths['tempdir'] ) . $this->svg_file ); 374 } 375 376 if ( ! is_wp_error( $json ) && ! empty( $json ) ) { 377 // Load and parse the SVG 378 $xml = simplexml_load_string( $response ); 379 $font_attr = $xml->defs->font->attributes(); 380 $glyphs = $xml->defs->font->children(); 381 382 // Sanitize the font name (ip_name) 383 $this->ip_name = (string) $font_attr['id']; 384 $this->ip_name = sanitize_text_field( $this->ip_name ); 385 386 $font_folder = trailingslashit( $this->paths['fontdir'] ) . $this->ip_name; 387 if ( is_dir( $font_folder ) ) { 388 $this->delete_folder( $this->paths['tempdir'] ); 389 die( esc_html__( "There is already an Icon Pack with this name. Please upload with another name.", "borderless" ) ); 390 } 391 392 // Decode JSON content 393 $file_contents = json_decode( $json ); 394 if ( ! isset( $file_contents->IcoMoonType ) ) { 395 $this->delete_folder( $this->paths['tempdir'] ); 396 die( esc_html__( "This Icon Pack is not an Icomoon pack. Use only Icomoon Icon Pack files.", 'borderless' ) ); 397 } 398 399 // Iterate over icons to build $this->json_config 400 $icons = $file_contents->icons; 401 foreach ( $icons as $icon ) { 402 // Sanitize each piece of data to prevent injection 403 $raw_name = isset( $icon->properties->name ) ? $icon->properties->name : 'unknown'; 404 $icon_name = sanitize_text_field( $raw_name ); 405 406 // Create a "class" by removing spaces and sanitizing further 407 $icon_class = str_replace( ' ', '', $icon_name ); 408 // Remove any other characters that are not typical in a CSS class 409 $icon_class = preg_replace( '/[^A-Za-z0-9\-_]/', '', $icon_class ); 410 411 $raw_tags = isset( $icon->icon->tags ) ? $icon->icon->tags : array(); 412 // Sanitize each tag 413 $safe_tags = array_map( 'sanitize_text_field', $raw_tags ); 414 $tags = implode( ",", $safe_tags ); 415 416 $this->json_config[ $this->ip_name ][ $icon_name ] = array( 417 "class" => $icon_class, 418 "tags" => $tags 419 ); 420 } 421 422 if ( ! empty( $this->json_config ) && $this->ip_name != 'unknown' ) { 423 $this->write_config(); 424 $this->re_write_css(); 425 $this->rename_files(); 426 $this->rename_folder(); 427 $this->add_font(); 428 } 429 } 430 431 return false; 432 } 433 434 /** 435 * Writes the charmap.php config file with sanitized data 436 */ 437 function write_config() { 438 $charmap = $this->paths['tempdir'] . '/' . $this->paths['config']; 439 $handle = @fopen( $charmap, 'w' ); 440 if ( $handle ) { 441 fwrite( $handle, '<?php $icons = array();' ); 442 443 // Safely build the PHP array with sanitized content 444 foreach ( $this->json_config[ $this->ip_name ] as $icon => $info ) { 445 if ( ! empty( $info ) ) { 446 $delimiter = "'"; 447 $safe_icon = esc_attr( $icon ); 448 $safe_class = esc_attr( $info["class"] ); 449 $safe_tags = esc_attr( $info["tags"] ); 450 451 fwrite( $handle, "\r\n" . '$icons[\'' . $this->ip_name . '\'][' . $delimiter . $safe_icon . $delimiter . '] = array("class"=>' . $delimiter . $safe_class . $delimiter . ',"tags"=>' . $delimiter . $safe_tags . $delimiter . ');' ); 452 } else { 453 $this->delete_folder( $this->paths['tempdir'] ); 454 die( esc_html__( 'Error generating the configuration file.', 'borderless' ) ); 455 } 456 } 457 fclose( $handle ); 458 } else { 459 $this->delete_folder( $this->paths['tempdir'] ); 460 die( esc_html__( 'Error generating the configuration file.', 'borderless' ) ); 461 } 462 } 463 464 /** 465 * Rewrites the CSS file to replace paths and standardize classes 466 */ 467 function re_write_css() { 468 $style = $this->paths['tempdir'] . '/style.css'; 469 $file = @file_get_contents( $style ); 470 if ( $file ) { 471 $str = str_replace( 'fonts/', '', $file ); 472 $str = str_replace( 'icon-', $this->ip_name . '-', $str ); 473 $str = str_replace( '.icon {', '[class^="' . $this->ip_name . '-"], [class*=" ' . $this->ip_name . '-"] {', $str ); 474 $str = str_replace( 'i {', '[class^="' . $this->ip_name . '-"], [class*=" ' . $this->ip_name . '-"] {', $str ); 475 476 // Remove comments 477 $str = preg_replace( '!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $str ); 478 // Remove tabs, spaces, newlines, etc. 479 $str = str_replace( array( "\r\n", "\r", "\n", "\t", ' ', ' ', ' ' ), '', $str ); 480 481 @file_put_contents( $style, $str ); 482 } else { 483 die( esc_html__( "Error generating the CSS file. Make sure you are using Icomoon's Icon Pack.", 'borderless' ) ); 484 } 485 } 486 487 /** 488 * Renames font files to match the sanitized ip_name 489 */ 490 function rename_files() { 491 $extensions = array( 'eot', 'svg', 'ttf', 'woff', 'css' ); 492 $folder = trailingslashit( $this->paths['tempdir'] ); 493 foreach ( glob( $folder . '*' ) as $file ) { 494 $path_parts = pathinfo( $file ); 495 if ( strpos( $path_parts['filename'], '.dev' ) === false && in_array( $path_parts['extension'], $extensions ) ) { 496 if ( $path_parts['filename'] !== $this->ip_name ) { 497 rename( $file, trailingslashit( $path_parts['dirname'] ) . $this->ip_name . '.' . $path_parts['extension'] ); 498 } 499 } 500 } 501 } 502 503 /** 504 * Renames the temporary folder to a final folder 505 */ 506 function rename_folder() { 507 $new_name = trailingslashit( $this->paths['fontdir'] ) . $this->ip_name; 508 // Delete folder if it already exists 509 $this->delete_folder( $new_name ); 510 if ( rename( $this->paths['tempdir'], $new_name ) ) { 511 return true; 512 } else { 513 $this->delete_folder( $this->paths['tempdir'] ); 514 die( esc_html__( "This Icon Pack could not be added.", "borderless" ) ); 515 } 516 } 517 518 /** 519 * Deletes a given folder and its contents 520 */ 521 function delete_folder( $new_name ) { 522 if ( is_dir( $new_name ) ) { 523 $objects = scandir( $new_name ); 524 foreach ( $objects as $object ) { 525 if ( $object != "." && $object != ".." ) { 526 @unlink( $new_name . "/" . $object ); 527 } 528 } 529 reset( $objects ); 530 @rmdir( $new_name ); 531 } 532 } 533 534 /** 535 * Adds new font info to the WP option 'borderless_icon_fonts' 536 */ 537 function add_font() { 538 $fonts = get_option( 'borderless_icon_fonts' ); 539 if ( empty( $fonts ) ) { 540 $fonts = array(); 541 } 542 $fonts[ $this->ip_name ] = array( 543 'include' => sanitize_text_field( trailingslashit( $this->paths['fonts'] ) ) . $this->ip_name, 544 'folder' => sanitize_text_field( trailingslashit( $this->paths['fonts'] ) ) . $this->ip_name, 545 'style' => $this->ip_name . '/' . $this->ip_name . '.css', 546 'config' => sanitize_text_field( $this->paths['config'] ) 547 ); 548 update_option( 'borderless_icon_fonts', $fonts ); 549 } 550 551 /** 552 * Removes specified font info from the WP option 553 */ 554 function remove_font( $font ) { 555 $fonts = get_option( 'borderless_icon_fonts' ); 556 if ( isset( $fonts[ $font ] ) ) { 557 unset( $fonts[ $font ] ); 558 update_option( 'borderless_icon_fonts', $fonts ); 559 } 560 } 561 562 /** 563 * Finds the first JSON file in the temp folder 564 */ 565 function find_json() { 566 $files = scandir( $this->paths['tempdir'] ); 567 foreach ( $files as $file ) { 568 if ( strpos( strtolower( $file ), '.json' ) !== false && $file[0] != '.' ) { 569 return $file; 570 } 571 } 572 return null; 573 } 574 575 /** 576 * Finds the first SVG file in the temp folder 577 */ 578 function find_svg() { 579 $files = scandir( $this->paths['tempdir'] ); 580 foreach ( $files as $file ) { 581 if ( strpos( strtolower( $file ), '.svg' ) !== false && $file[0] != '.' ) { 582 return $file; 583 } 584 } 585 return null; 586 } 587 588 /** 589 * Loads the list of iconfonts from the WP option (cached locally) 590 */ 591 static function load_iconfont_list() { 592 if ( ! empty( self::$ip_list ) ) { 593 return self::$ip_list; 594 } 595 $extra_fonts = get_option( 'borderless_icon_fonts' ); 596 if ( empty( $extra_fonts ) ) { 597 $extra_fonts = array(); 598 } 599 $font_configs = $extra_fonts; 600 $upload_dir = wp_upload_dir(); 601 $path = trailingslashit( $upload_dir['basedir'] ); 602 $url = trailingslashit( $upload_dir['baseurl'] ); 603 604 foreach ( $font_configs as $key => $config ) { 605 if ( empty( $config['full_path'] ) ) { 606 $font_configs[ $key ]['include'] = $path . $font_configs[ $key ]['include']; 607 $font_configs[ $key ]['folder'] = $url . $font_configs[ $key ]['folder']; 608 } 609 } 610 self::$ip_list = $font_configs; 611 return $font_configs; 612 } 613 } // End class Borderless_IF 614 615 /** 616 * Creates a folder for the plugin framework 617 */ 618 if ( ! function_exists( 'borderless_backend_create_folder' ) ) { 619 function borderless_backend_create_folder( &$folder, $addindex = true ) { 620 if ( is_dir( $folder ) && $addindex == false ) { 621 return true; 622 } 623 $created = wp_mkdir_p( trailingslashit( $folder ) ); 624 @chmod( $folder, 0777 ); 625 if ( $addindex == false ) { 626 return $created; 627 } 628 $index_file = trailingslashit( $folder ) . 'index.php'; 629 if ( file_exists( $index_file ) ) { 630 return $created; 631 } 632 $handle = @fopen( $index_file, 'w' ); 633 if ( $handle ) { 634 fwrite( $handle, "<?php\r\necho 'We are sorry, but you are not allowed to browse this directory.';\r\n?>" ); 635 fclose( $handle ); 636 } 637 return $created; 638 } 639 } 640 641 // Instantiate the main Icon Fonts class 642 new Borderless_IF; 643 } 644 645 /** 646 * Adds the Icon Pack Manager to the WP admin menu 647 */ 648 function borderless_custom_icons_menu() { 649 $Borderless_IF = new Borderless_IF; 650 $Borderless_IF->icon_pack_manager(); 651 } 652 653 /** 654 * Enqueues the custom icon fonts on the frontend 655 */ 656 function borderless_custom_icons() { 657 $upload_paths = wp_upload_dir(); 658 $custom_fonts = get_option( 'borderless_icon_fonts' ); 659 if ( is_array( $custom_fonts ) ) { 660 foreach ( $custom_fonts as $font => $info ) { 661 if ( strpos( $info['style'], 'http://' ) !== false ) { 662 wp_enqueue_style( 'borderless-' . $font, $info['style'], null, '1.0', 'all' ); 663 } else { 664 wp_enqueue_style( 'borderless-' . $font, trailingslashit( $upload_paths['baseurl'] . '/borderless_icon_fonts/' ) . $info['style'], null, '1.0', 'all' ); 665 } 666 } 667 } 668 } 669 add_action( 'wp_enqueue_scripts', 'borderless_custom_icons' ); -
borderless/trunk/readme.txt
r3209805 r3230461 3 3 Tags: Gutenberg, Elementor, elements, widgets, templates 4 4 Requires at least: 5.0 5 Tested up to: 6. 6.15 Tested up to: 6.7.1 6 6 Requires PHP: 7.4 7 Stable tag: 1. 5.97 Stable tag: 1.6.0 8 8 License: GPLv3 9 9 License URI: https://www.gnu.org/licenses/gpl-3.0.html … … 82 82 == Changelog == 83 83 84 = 1. 5.9 -Dec 18 2024=84 = 1.6.0 - Jan 28 2025 = 85 85 * Fixed - General Vulnerabilities. 86 86 87 = 1.5.8 -Dec 06 2024 = 87 = 1.5.9 - Dec 18 2024 = 88 * Fixed - General Vulnerabilities. 89 90 = 1.5.8 - Dec 06 2024 = 88 91 * Fixed - General Vulnerabilities. 89 92
Note: See TracChangeset
for help on using the changeset viewer.