From 7204a811c37fc2941818fbf920dc4c2fe4b14e75 Mon Sep 17 00:00:00 2001 From: stiofan Date: Fri, 19 Nov 2021 11:25:22 +0000 Subject: [PATCH] revert master to 1.0.27 --- change-log.txt | 14 - hello-world.php | 22 +- map.php | 188 +- sd-functions.php | 6 +- sd-plugin.php | 6 +- type/block.php | 966 ----------- type/shortcode.php | 792 --------- type/widget.php | 210 --- wp-super-duper.php | 4090 ++++++++++++++++++++++++++++---------------- 9 files changed, 2682 insertions(+), 3612 deletions(-) delete mode 100644 type/block.php delete mode 100644 type/shortcode.php delete mode 100644 type/widget.php diff --git a/change-log.txt b/change-log.txt index 20379f9..858558a 100644 --- a/change-log.txt +++ b/change-log.txt @@ -1,17 +1,3 @@ -= 2.0.2 = -* Elementor Pro will cause fatal error if old style register_widget is calles - FIXED - -= 2.0.1 = -* Added missing static functions to main class for backwards comparability - FIXED - -= 2.0.0 = -* WARNING v2 is a breaking change, please see our migration guide in our github repo https://github.com/AyeCode/wp-super-duper/ - BREAKING CHANGE -* Widget, blocks and shortcodes classes separated our for better readability and memory usage - CHANGED -* 'output_types' => array( 'block', 'shortcode' ) argument added to be able to only load certain types of output - ADDED -* Legacy widgets can be converted to blocks on the fly - ADDED -* Widgets hidden from legacy selector to prevent double option in widgets area - CHANGED -* Option added to WordPress General settings to set if widgets are loaded - ADDED - = 1.0.27 = * Category settings loads only 10 categories on CPT change - FIXED * Hook added to filter class & attributes for Elementor widget output - ADDED diff --git a/hello-world.php b/hello-world.php index 6d167c7..2bfcab7 100644 --- a/hello-world.php +++ b/hello-world.php @@ -2,6 +2,7 @@ class SD_Hello_World extends WP_Super_Duper { + public $arguments; /** @@ -27,10 +28,7 @@ public function __construct() { 'content' => 'Hello: [%after_text%]' // block properties can be added by wrapping them in [%name%] ) ), - 'output_types' => array( 'block', 'shortcode' ), - // Sample showing how to disable widgets for a given SD instance. - 'block-wrap' => '', - // You can specify the type of element to wrap the block `div` or `span` etc.. Or blank for no wrap at all. + 'block-wrap' => '', // You can specify the type of element to wrap the block `div` or `span` etc.. Or blank for no wrap at all. 'class_name' => __CLASS__, // The calling class name 'base_id' => 'hello_world', @@ -42,12 +40,8 @@ public function __construct() { // widget class 'description' => esc_html__( 'This is an example that will take a text parameter and output it after `Hello:`.', 'hello-world' ), // widget description - 'output' => array( $this, 'output' ) ), - 'no_wrap' => true, - // This will prevent the widget being wrapped in the containing widget class div. - //'block-editor-style' => 'https://example.com/style.css', - // Lets you add a URL for styles that should be added to the block editor. + 'no_wrap' => true, // This will prevent the widget being wrapped in the containing widget class div. 'arguments' => array( // these are the arguments that will be used in the widget, shortcode and block settings. 'after_text' => array( // this is the input name='' 'title' => __( 'Text after hello:', 'hello-world' ), @@ -82,6 +76,7 @@ public function __construct() { * @return string */ public function output( $args = array(), $widget_args = array(), $content = '' ) { + /** * @var string $after_text * @var string $another_input This is added by filter below. @@ -96,11 +91,16 @@ public function output( $args = array(), $widget_args = array(), $content = '' ) } return "Hello: " . $after_text . "" . $another_input; + } } -new SD_Hello_World(); +// register it. +add_action( 'widgets_init', function () { + register_widget( 'SD_Hello_World' ); +} ); + /** * Extend the options via filter hook, this can be done via plugin/theme. @@ -133,4 +133,4 @@ function _my_extra_arguments( $options ) { return $options; } -//add_filter( 'wp_super_duper_options_hello_world', '_my_extra_arguments' ); +//add_filter( 'wp_super_duper_options_hello_world', '_my_extra_arguments' ); \ No newline at end of file diff --git a/map.php b/map.php index 9da492c..c96268e 100644 --- a/map.php +++ b/map.php @@ -21,44 +21,44 @@ public function __construct() { // used in the block search, MAX 3 'block-output' => array( // the block visual output elements as an array array( - 'element' => 'p', - 'content' => __( 'A Google API key is required to use this block, we recommend installing our plugin which makes it easy and sets it globally, or you can set a key in the block settings sidebar: ', 'super-duper' ), + 'element' => 'p', + 'content' => __('A Google API key is required to use this block, we recommend installing our plugin which makes it easy and sets it globally, or you can set a key in the block settings sidebar: ','super-duper'), //'element_require' => '"1"=='.get_option( 'rgmk_google_map_api_key', '"0"') ? '"0"' : '"1"', - 'element_require' => get_option( 'rgmk_google_map_api_key', false ) ? '1==0' : '1==1 && [%api_key%]==""', + 'element_require' => get_option( 'rgmk_google_map_api_key', false) ? '1==0' : '1==1 && [%api_key%]==""', ), array( - 'element' => 'a', - 'content' => __( 'API KEY for Google Maps', 'super-duper' ), - 'element_require' => get_option( 'rgmk_google_map_api_key', false ) ? '1==0' : '1==1 && [%api_key%]==""', - 'href' => 'https://wordpress.org/plugins/api-key-for-google-maps/', + 'element' => 'a', + 'content' => __('API KEY for Google Maps','super-duper'), + 'element_require' => get_option( 'rgmk_google_map_api_key', false) ? '1==0' : '1==1 && [%api_key%]==""', + 'href' => 'https://wordpress.org/plugins/api-key-for-google-maps/', ), array( - 'element' => 'img', - 'class' => '[%className%]', + 'element' => 'img', + 'class' => '[%className%]', //'content' => 'Hello: [%after_text%]' // block properties can be added by wrapping them in [%name%] 'element_require' => '[%type%]=="image"', - 'src' => get_option( 'rgmk_google_map_api_key', false ) ? "https://maps.googleapis.com/maps/api/staticmap?center=[%location%]&maptype=[%maptype%]&zoom=[%zoom%]&size=[%static_width%]x[%static_height%]&key=" . get_option( 'rgmk_google_map_api_key' ) : "https://maps.googleapis.com/maps/api/staticmap?center=[%location%]&maptype=[%maptype%]&zoom=[%zoom%]&size=[%static_width%]x[%static_height%]&key=[%api_key%]" + 'src' => get_option( 'rgmk_google_map_api_key', false) ? "https://maps.googleapis.com/maps/api/staticmap?center=[%location%]&maptype=[%maptype%]&zoom=[%zoom%]&size=[%static_width%]x[%static_height%]&key=".get_option( 'rgmk_google_map_api_key') : "https://maps.googleapis.com/maps/api/staticmap?center=[%location%]&maptype=[%maptype%]&zoom=[%zoom%]&size=[%static_width%]x[%static_height%]&key=[%api_key%]" ), array( 'element' => 'div', 'class' => 'sd-map-iframe-cover', 'style' => '{overflow:"hidden", position:"relative"}', array( - 'element' => 'iframe', - 'title' => __( 'Placeholderx', 'super-duper' ), - 'class' => '[%className%]', - 'width' => '[%width%]', - 'height' => '[%height%]', - 'frameborder' => '0', + 'element' => 'iframe', + 'title' => __( 'Placeholderx', 'super-duper' ), + 'class' => '[%className%]', + 'width' => '[%width%]', + 'height' => '[%height%]', + 'frameborder' => '0', 'allowfullscreen' => 'true', - 'style' => '{border:0}', + 'style' => '{border:0}', 'element_require' => '[%type%]!="image"', - 'src' => get_option( 'rgmk_google_map_api_key', false ) ? "https://www.google.com/maps/embed/v1/[%type%]?q=[%location%]&maptype=[%maptype%]&zoom=[%zoom%]&key=" . get_option( 'rgmk_google_map_api_key' ) : "https://www.google.com/maps/embed/v1/[%type%]?q=[%location%]&maptype=[%maptype%]&zoom=[%zoom%]&key=[%api_key%]" + 'src' => get_option( 'rgmk_google_map_api_key', false) ? "https://www.google.com/maps/embed/v1/[%type%]?q=[%location%]&maptype=[%maptype%]&zoom=[%zoom%]&key=".get_option( 'rgmk_google_map_api_key') : "https://www.google.com/maps/embed/v1/[%type%]?q=[%location%]&maptype=[%maptype%]&zoom=[%zoom%]&key=[%api_key%]" ), ), array( - 'element' => 'style', - 'content' => '.sd-map-iframe-cover:hover:before {background: #4a4a4a88; content: "' . __( "Click here, Settings are in the block settings sidebar", "super-duper" ) . '";} .sd-map-iframe-cover:before{cursor: pointer; content: ""; width: 100%; height: 100%; position: absolute; top: 0; bottom: 0;padding-top: 33%; text-align: center; color: #fff; font-size: 20px; font-weight: bold;}', + 'element' => 'style', + 'content' => '.sd-map-iframe-cover:hover:before {background: #4a4a4a88; content: "'.__("Click here, Settings are in the block settings sidebar","super-duper").'";} .sd-map-iframe-cover:before{cursor: pointer; content: ""; width: 100%; height: 100%; position: absolute; top: 0; bottom: 0;padding-top: 33%; text-align: center; color: #fff; font-size: 20px; font-weight: bold;}', 'element_require' => '[%type%]!="image"', ), ), @@ -73,16 +73,15 @@ public function __construct() { // widget class 'description' => esc_html__( 'This is an example that will take a text parameter and output it after `Hello:`.', 'hello-world' ), // widget description - 'output' => array( $this, 'output' ) ), 'arguments' => array( // these are the arguments that will be used in the widget, shortcode and block settings. - 'type' => array( - 'title' => __( 'Map Type:', 'geodirectory' ), - 'desc' => __( 'Select the map type to use.', 'geodirectory' ), - 'type' => 'select', - 'options' => array( - "image" => __( 'Static Image', 'geodirectory' ), - "place" => __( 'Place', 'geodirectory' ), + 'type' => array( + 'title' => __('Map Type:', 'geodirectory'), + 'desc' => __('Select the map type to use.', 'geodirectory'), + 'type' => 'select', + 'options' => array( + "image" => __('Static Image', 'geodirectory'), + "place" => __('Place', 'geodirectory'), // "directions" => __('Directions', 'geodirectory'), // "search" => __('Search', 'geodirectory'), // "view" => __('View', 'geodirectory'), @@ -92,7 +91,7 @@ public function __construct() { 'desc_tip' => true, 'advanced' => false ), - 'location' => array( + 'location' => array( 'type' => 'text', 'title' => __( 'Location:', 'geodirectory' ), 'desc' => __( 'Enter the location to show on the map, place, city, zip code or GPS.', 'geodirectory' ), @@ -101,56 +100,56 @@ public function __construct() { 'default' => 'Ireland', 'advanced' => false ), - 'static_width' => array( - 'type' => 'number', - 'title' => __( 'Width:', 'geodirectory' ), - 'desc' => __( 'This is the width of the map, for static maps you can only use px values.', 'geodirectory' ), - 'placeholder' => '600', - 'desc_tip' => true, - 'default' => '600', + 'static_width' => array( + 'type' => 'number', + 'title' => __( 'Width:', 'geodirectory' ), + 'desc' => __( 'This is the width of the map, for static maps you can only use px values.', 'geodirectory' ), + 'placeholder' => '600', + 'desc_tip' => true, + 'default' => '600', 'custom_attributes' => array( - 'max' => '2000', - 'min' => '100', + 'max' => '2000', + 'min' => '100', ), - 'element_require' => '[%type%]=="image"', - 'advanced' => false + 'element_require' => '[%type%]=="image"', + 'advanced' => false ), - 'static_height' => array( - 'type' => 'number', - 'title' => __( 'Height:', 'geodirectory' ), - 'desc' => __( 'This is the height of the map, for static maps you can only use px values.', 'geodirectory' ), - 'placeholder' => '400', - 'desc_tip' => true, - 'default' => '400', + 'static_height' => array( + 'type' => 'number', + 'title' => __( 'Height:', 'geodirectory' ), + 'desc' => __( 'This is the height of the map, for static maps you can only use px values.', 'geodirectory' ), + 'placeholder' => '400', + 'desc_tip' => true, + 'default' => '400', 'custom_attributes' => array( - 'max' => '2000', - 'min' => '100', - 'required' => 'required', + 'max' => '2000', + 'min' => '100', + 'required' => 'required', ), - 'element_require' => '[%type%]=="image"', - 'advanced' => false + 'element_require' => '[%type%]=="image"', + 'advanced' => false ), - 'width' => array( - 'type' => 'text', - 'title' => __( 'Width:', 'geodirectory' ), - 'desc' => __( 'This is the width of the map, you can use % or px here.', 'geodirectory' ), - 'placeholder' => '100%', - 'desc_tip' => true, - 'default' => '100%', + 'width' => array( + 'type' => 'text', + 'title' => __( 'Width:', 'geodirectory' ), + 'desc' => __( 'This is the width of the map, you can use % or px here.', 'geodirectory' ), + 'placeholder' => '100%', + 'desc_tip' => true, + 'default' => '100%', 'element_require' => '[%type%]!="image"', - 'advanced' => false + 'advanced' => false ), - 'height' => array( - 'type' => 'text', - 'title' => __( 'Height:', 'geodirectory' ), - 'desc' => __( 'This is the height of the map, you can use %, px or vh here.', 'geodirectory' ), - 'placeholder' => '425px', - 'desc_tip' => true, - 'default' => '425px', + 'height' => array( + 'type' => 'text', + 'title' => __( 'Height:', 'geodirectory' ), + 'desc' => __( 'This is the height of the map, you can use %, px or vh here.', 'geodirectory' ), + 'placeholder' => '425px', + 'desc_tip' => true, + 'default' => '425px', 'element_require' => '[%type%]!="image"', - 'advanced' => false + 'advanced' => false ), - 'maptype' => array( + 'maptype' => array( 'type' => 'select', 'title' => __( 'Mapview:', 'geodirectory' ), 'desc' => __( 'This is the type of map view that will be used by default.', 'geodirectory' ), @@ -164,7 +163,7 @@ public function __construct() { 'default' => 'roadmap', 'advanced' => true ), - 'zoom' => array( + 'zoom' => array( 'type' => 'select', 'title' => __( 'Zoom level:', 'geodirectory' ), 'desc' => __( 'This is the zoom level of the map, `auto` is recommended.', 'geodirectory' ), @@ -174,15 +173,15 @@ public function __construct() { 'default' => '7', 'advanced' => true ), - 'api_key' => array( - 'type' => 'text', - 'title' => __( 'Api Key:', 'geodirectory' ), - 'desc' => __( 'Enter your Google maps API key here.', 'geodirectory' ), - 'placeholder' => '', - 'desc_tip' => true, - 'default' => '', - 'element_require' => get_option( 'rgmk_google_map_api_key', false ) ? '1==0' : '1==1', - 'advanced' => false + 'api_key' => array( + 'type' => 'text', + 'title' => __( 'Api Key:', 'geodirectory' ), + 'desc' => __( 'This is the height of the map, you can use %, px or vh here.', 'geodirectory' ), + 'placeholder' => '', + 'desc_tip' => true, + 'default' => '', + 'element_require' => get_option( 'rgmk_google_map_api_key', false) ? '1==0' : '1==1', + 'advanced' => false ), ) ); @@ -204,21 +203,21 @@ public function output( $args = array(), $widget_args = array(), $content = '' ) // options $defaults = array( - 'type' => 'image', // image, place - 'location' => 'Ireland', - 'static_width' => '600', + 'type' => 'image', // image, place + 'location' => 'Ireland', + 'static_width' => '600', 'static_height' => '400', - 'width' => '100%', - 'height' => '425px', - 'maptype' => 'roadmap', - 'zoom' => '7', - 'api_key' => 'AIzaSyBK3ZcmK0ljxl5agNyJNQh_G24Thq1btuE', + 'width'=> '100%', + 'height'=> '425px', + 'maptype' => 'roadmap', + 'zoom' => '7', + 'api_key' => 'AIzaSyBK3ZcmK0ljxl5agNyJNQh_G24Thq1btuE', ); /** * Parse incoming $args into an array and merge it with $defaults */ - $args = wp_parse_args( $args, $defaults ); + $args = wp_parse_args($args, $defaults ); $output = ''; @@ -226,10 +225,10 @@ public function output( $args = array(), $widget_args = array(), $content = '' ) // check if we have a global API key $args['api_key'] = get_option( 'rgmk_google_map_api_key', false ) ? get_option( 'rgmk_google_map_api_key' ) : $args['api_key']; - if ( $args['type'] == 'image' ) { - $output .= ""; - } else { - $output .= " "; + if($args['type']=='image'){ + $output .= ""; + }else{ + $output .= " "; } return $output; @@ -238,4 +237,7 @@ public function output( $args = array(), $widget_args = array(), $content = '' ) } -new SD_Map(); +// register it. +add_action( 'widgets_init', function () { + register_widget( 'SD_Map' ); +} ); diff --git a/sd-functions.php b/sd-functions.php index 5df58c7..f2443fd 100644 --- a/sd-functions.php +++ b/sd-functions.php @@ -10,7 +10,7 @@ * * @return mixed|void */ -function sd_pagenow_exclude() { +function sd_pagenow_exclude(){ return apply_filters( 'sd_pagenow_exclude', array( 'upload.php', 'edit-comments.php', @@ -33,6 +33,6 @@ function sd_pagenow_exclude() { * * @return mixed|void */ -function sd_widget_exclude() { +function sd_widget_exclude(){ return apply_filters( 'sd_widget_exclude', array() ); -} +} \ No newline at end of file diff --git a/sd-plugin.php b/sd-plugin.php index d0677b3..8042e06 100644 --- a/sd-plugin.php +++ b/sd-plugin.php @@ -5,13 +5,13 @@ * @wordpress-plugin * Plugin Name: Super Duper - Examples * Description: This is a Hello World test plugin for WP Super Duper Class. - * Version: 2.0.1 + * Version: 1.0.6 * Author: AyeCode * Author URI: https://ayecode.io * Text Domain: super-duper * Domain Path: /languages * Requires at least: 4.2 - * Tested up to: 5.8 + * Tested up to: 5.3 */ if ( ! defined( 'ABSPATH' ) ) { @@ -31,4 +31,4 @@ /* * Map example. */ -include_once( dirname( __FILE__ ) . "/map.php" ); \ No newline at end of file +include_once( dirname( __FILE__ ) . "/map.php" ); diff --git a/type/block.php b/type/block.php deleted file mode 100644 index 2a38eb9..0000000 --- a/type/block.php +++ /dev/null @@ -1,966 +0,0 @@ -sd = $super_duper; - - // Process the SD shortcode preview. - add_action( 'wp_ajax_super_duper_output_shortcode', array( __CLASS__, 'render_shortcode' ) ); - add_action( 'admin_enqueue_scripts', array( $this, 'register_block' ) ); - add_action( 'admin_footer-post.php', array( $this, 'enqueue_editor_assets' ) ); - add_action( 'admin_footer-post-new.php', array( $this, 'enqueue_editor_assets' ) ); - } - - /** - * Render the shortcode via ajax so we can return it to Gutenberg. - * - * @since 1.0.0 - */ - public static function render_shortcode() { - - // Verify nonce. - check_ajax_referer( 'super_duper_output_shortcode', '_ajax_nonce', true ); - - // And permissions. - if ( ! current_user_can( 'manage_options' ) ) { - wp_die(); - } - - // Ensure a shortcode is provided. - if ( empty( $_POST['shortcode'] ) ) { - wp_die(); - } - - // We might need the $post value here so lets set it. - if ( isset( $_POST['post_id'] ) && $_POST['post_id'] ) { - $post_obj = get_post( absint( $_POST['post_id'] ) ); - if ( ! empty( $post_obj ) && empty( $post ) ) { - global $post; - $post = $post_obj; - } - } - - // Prepare args. - $shortcode_name = sanitize_title_with_dashes( $_POST['shortcode'] ); - $attributes_array = isset( $_POST['attributes'] ) && $_POST['attributes'] ? $_POST['attributes'] : array(); - $attributes = ''; - - // Convert attributes array into a string. - if ( ! empty( $attributes_array ) ) { - foreach ( $attributes_array as $key => $value ) { - if ( is_array( $value ) ) { - $value = implode( ',', $value ); - } - $key = sanitize_title_with_dashes( $key ); - $value = wp_slash( $value ); - $attributes .= " $key='$value' "; - } - } - - echo do_shortcode( "[$shortcode_name $attributes]" ); - exit; - - } - - /** - * Add the dynamic block code inline when the wp-block in enqueued. - */ - public function register_block() { - wp_add_inline_script( 'wp-blocks', $this->block() ); - if ( class_exists( 'SiteOrigin_Panels' ) ) { - wp_add_inline_script( 'wp-blocks', WP_Super_Duper::siteorigin_js() ); - } - } - - /** - * Output the JS for building the dynamic Guntenberg block. - * - * @since 1.0.4 Added block_wrap property which will set the block wrapping output element ie: div, span, p or empty for no wrap. - * @since 1.0.9 Save numbers as numbers and not strings. - * @since 1.1.0 Font Awesome classes can be used for icons. - * @return mixed - */ - public function block() { - ob_start(); - - $block_name = str_replace( '_', '-', sanitize_title_with_dashes( $this->sd->options['textdomain'] ) . '/' . sanitize_title_with_dashes( $this->sd->options['class_name'] ) ); - $show_advanced = $this->sd->block_show_advanced(); - $id = $this->sd->base_id . '-' . $this->sd->get_number(); - ?> - - tags for code highlighting, so we strip them from the output. - */ - - return str_replace( array( - '' - ), '', $output ); - } - - /** - * Generate the block icon. - * - * Enables the use of Font Awesome icons. - * - * @note xlink:href is actually deprecated but href is not supported by all so we use both. - * - * @param $icon - * - * @since 1.1.0 - * @return string - */ - public function get_block_icon( $icon ) { - - // check if we have a Font Awesome icon - $fa_type = ''; - if ( substr( $icon, 0, 7 ) === 'fas fa-' ) { - $fa_type = 'solid'; - } elseif ( substr( $icon, 0, 7 ) === 'far fa-' ) { - $fa_type = 'regular'; - } elseif ( substr( $icon, 0, 7 ) === 'fab fa-' ) { - $fa_type = 'brands'; - } else { - $icon = sprintf( "'%s'", esc_js( $icon ) ); - } - - // set the icon if we found one - if ( $fa_type ) { - $fa_icon = substr( $icon, 7 ); - $icon = "el('svg',{width: 20, height: 20, viewBox: '0 0 20 20'},el('use', {'xlink:href': '" . $this->sd->get_url() . "icons/" . $fa_type . ".svg#" . $fa_icon . "','href': '" . $this->sd->get_url() . "icons/" . $fa_type . ".svg#" . $fa_icon . "'}))"; - } - - return $icon; - } - - public function block_row_start( $key, $args ) { - // check for row - if ( ! empty( $args['row'] ) ) { - if ( ! empty( $args['row']['open'] ) ) { - // element require - $element_require = ! empty( $args['element_require'] ) ? $this->block_props_replace( $args['element_require'], true ) . " && " : ""; - echo $element_require; - if ( false ){ - ?> - - - sd->array_to_attributes( $args['custom_attributes'] ) : ''; - $options = ''; - $key = sanitize_key( $key ); - $extra = "key: '$key',"; - - // `content` is a protected and Gutenberg special argument - if ( $key == 'content' ) { - return; - } - - // icon - $icon = ''; - if ( ! empty( $args['icon'] ) ) { - $icon .= "el('div', {"; - $icon .= "dangerouslySetInnerHTML: {__html: '" . $this->sd->get_widget_icon( esc_attr( $args['icon'] ) ) . "'},"; - $icon .= "className: 'text-center',"; - $icon .= "title: '" . addslashes( $args['title'] ) . "',"; - $icon .= "}),"; - // blank title as its added to the icon. - $args['title'] = ''; - } - - // require advanced - $require_advanced = ! empty( $args['advanced'] ) ? "props.attributes.show_advanced && " : ""; - - // element require - $element_require = ! empty( $args['element_require'] ) ? $this->block_props_replace( $args['element_require'], true ) . " && " : ""; - $onchange = "props.setAttributes({ $key: $key } )"; - $onchangecomplete = ""; - $value = "props.attributes.$key"; - $text_type = array( 'text', 'password', 'number', 'email', 'tel', 'url', 'colorx' ); - if ( in_array( $args['type'], $text_type ) ) { - $type = 'TextControl'; - // Save numbers as numbers and not strings - if ( $args['type'] == 'number' ) { - $onchange = "props.setAttributes({ $key: Number($key) } )"; - } - } elseif ( $args['type'] == 'color' ) { - $type = 'ColorPicker'; - $onchange = ""; - $extra .= "color: $value,"; - if ( ! empty( $args['disable_alpha'] ) ) { - $extra .= "disableAlpha: true,"; - } - $onchangecomplete = "onChangeComplete: function($key) { - value = $key.rgb.a && $key.rgb.a < 1 ? \"rgba(\"+$key.rgb.r+\",\"+$key.rgb.g+\",\"+$key.rgb.b+\",\"+$key.rgb.a+\")\" : $key.hex; - props.setAttributes({ - $key: value - }); - },"; - } elseif ( $args['type'] == 'checkbox' ) { - $type = 'CheckboxControl'; - $extra .= "checked: props.attributes.$key,"; - $onchange = "props.setAttributes({ $key: ! props.attributes.$key } )"; - } elseif ( $args['type'] == 'textarea' ) { - $type = 'TextareaControl'; - } elseif ( $args['type'] == 'select' || $args['type'] == 'multiselect' ) { - $type = 'SelectControl'; - if ( $args['name'] == 'category' && ! empty( $args['post_type_linked'] ) ) { - $options .= "options: taxonomies_" . str_replace( "-", "_", $this->sd->base_id . '_' . $this->sd->get_number() ) . ","; - } elseif ( $args['name'] == 'sort_by' && ! empty( $args['post_type_linked'] ) ) { - $options .= "options: sort_by_" . str_replace( "-", "_", $this->sd->base_id . '_' . $this->sd->get_number() ) . ","; - } else { - if ( ! empty( $args['options'] ) ) { - $options .= "options: ["; - foreach ( $args['options'] as $option_val => $option_label ) { - $options .= "{ value: '" . esc_attr( $option_val ) . "', label: '" . addslashes( $option_label ) . "' },"; - } - $options .= "],"; - } - } - if ( isset( $args['multiple'] ) && $args['multiple'] ) { //@todo multiselect does not work at the moment: https://github.com/WordPress/gutenberg/issues/5550 - $extra .= ' multiple: true, '; - } - } elseif ( $args['type'] == 'alignment' ) { - $type = 'AlignmentToolbar'; // @todo this does not seem to work but cant find a example - } elseif ( $args['type'] == 'margins' ) { - } else { - return;// if we have not implemented the control then don't break the JS. - } - - // color input does not show the labels so we add them - if ( $args['type'] == 'color' ) { - // add show only if advanced - echo $require_advanced; - // add setting require if defined - echo $element_require; - echo "el('div', {style: {'marginBottom': '8px'}}, '" . addslashes( $args['title'] ) . "'),"; - } - - // add show only if advanced - echo $require_advanced; - // add setting require if defined - echo $element_require; - - // icon - echo $icon; - ?> - el( wp.components., { - label: '', - help: '', - value: , - - - onChange: function ( ) {} - } ), - $new_args ) { - - // Check if its an element. - if ( is_array( $new_args ) ) { - if ( isset( $new_args['element'] ) ) { - if ( isset( $new_args['element_require'] ) ) { - echo str_replace( array( - "'+", - "+'" - ), '', $this->block_props_replace( $new_args['element_require'] ) ) . " && "; - unset( $new_args['element_require'] ); - } - - echo "\n el( '" . $new_args['element'] . "', {"; - - // get the attributes - foreach ( $new_args as $new_key => $new_value ) { - if ( $new_key == 'element' || $new_key == 'content' || $new_key == 'element_require' || $new_key == 'element_repeat' || is_array( $new_value ) ) { - // do nothing - } else { - echo $this->block_element( array( $new_key => $new_value ) ); - } - } - - echo "key: '$element'},";// end attributes - - // get the content - $first_item = 0; - foreach ( $new_args as $new_key => $new_value ) { - if ( $new_key === 'content' || is_array( $new_value ) ) { - if ( $new_key === 'content' ) { - echo "'" . $this->block_props_replace( wp_slash( $new_value ) ) . "'"; - } - - if ( is_array( $new_value ) ) { - if ( isset( $new_value['element_require'] ) ) { - echo str_replace( array( - "'+", - "+'" - ), '', $this->block_props_replace( $new_value['element_require'] ) ) . " && "; - unset( $new_value['element_require'] ); - } - - if ( isset( $new_value['element_repeat'] ) ) { - $x = 1; - while ( $x <= absint( $new_value['element_repeat'] ) ) { - $this->block_element( array( '' => $new_value ) ); - $x ++; - } - } else { - $this->block_element( array( '' => $new_value ) ); - } - } - $first_item ++; - } - } - echo ")";// end content - echo ", \n"; - } - - // Or an attribute. - } else { - if ( substr( $element, 0, 3 ) === 'if_' ) { - echo str_replace( 'if_', '', $element ) . ": " . $this->block_props_replace( $new_args, true ) . ","; - } elseif ( $element == 'style' ) { - echo $element . ": " . $this->block_props_replace( $new_args ) . ","; - } else { - echo $element . ": '" . $this->block_props_replace( $new_args ) . "',"; - } - } - } - - } - } - - /** - * Enqueue CSS assets in the editor if defined - */ - public function enqueue_editor_assets() { - if ( isset( $this->sd->options['block-editor-style'] ) ) { - echo ""; - } - } - -} diff --git a/type/shortcode.php b/type/shortcode.php deleted file mode 100644 index 7a49921..0000000 --- a/type/shortcode.php +++ /dev/null @@ -1,792 +0,0 @@ -sd = $super_duper; - - // Registers the shortcode. - add_shortcode( $this->sd->base_id, array( $this, 'shortcode_output' ) ); - - // This makes the insert button work for cornerstone. - add_action( 'wp_print_footer_scripts', array( $this, 'maybe_cornerstone_builder' ) ); - - // Fusion Builder (avada) support - if ( function_exists( 'fusion_builder_map' ) ) { - add_action( 'init', array( $this, 'register_fusion_element' ) ); - } - - // Add shortcode insert button once - add_action( 'media_buttons', array( $this, 'shortcode_insert_button' ) ); - add_action( 'wp_ajax_super_duper_get_widget_settings', array( $this, 'get_widget_settings' ) ); - - // generatepress theme sections compatibility - if ( function_exists( 'generate_sections_sections_metabox' ) ) { - add_action( 'generate_sections_metabox', array( $this, 'shortcode_insert_button_script' ) ); - } - - if ( $this->sd->is_preview() ) { - add_action( 'wp_footer', array( $this, 'shortcode_insert_button_script' ) ); - // this makes the insert button work for elementor - add_action( 'elementor/editor/after_enqueue_scripts', array( - $this, - 'shortcode_insert_button_script' - ) ); // for elementor - } - - } - - /** - * Insert shortcode builder button to classic editor (not inside Gutenberg, not needed). - * - * @since 1.0.0 - * - * @param string $editor_id Optional. Shortcode editor id. Default null. - * @param string $insert_shortcode_function Optional. Insert shortcode function. Default null. - */ - public static function shortcode_insert_button( $editor_id = '', $insert_shortcode_function = '' ) { - global $shortcode_insert_button_once; - if ( $shortcode_insert_button_once ) { - return; - } - add_thickbox(); - - /** - * Cornerstone makes us play dirty tricks :/ - * All media_buttons are removed via JS unless they are two specific id's so we wrap our content in this ID so it is not removed. - */ - if ( function_exists( 'cornerstone_plugin_init' ) && ! is_admin() ) { - echo ''; - } - - echo self::shortcode_button( 'this', 'true' ); - - // see opening note - if ( function_exists( 'cornerstone_plugin_init' ) && ! is_admin() ) { - echo ''; // end #insert-media-button - } - - // Add separate script for generatepress theme sections - if ( function_exists( 'generate_sections_sections_metabox' ) && did_action( 'generate_sections_metabox' ) ) { - } else { - self::shortcode_insert_button_script( $editor_id, $insert_shortcode_function ); - } - - $shortcode_insert_button_once = true; - } - - /** - * Output the shortcode. - * - * @param array $args - * @param string $content - * - * @return string - */ - public function shortcode_output( $args = array(), $content = '' ) { - $args = $this->sd->argument_values( $args ); - - // Clean booleans. - $args = $this->sd->string_to_bool( $args ); - - // if we have a enclosed shortcode we add it to the special `html` argument - if ( ! empty( $content ) ) { - $args['html'] = $content; - } - - $class = isset( $this->sd->options['widget_ops']['classname'] ) ? esc_attr( $this->sd->options['widget_ops']['classname'] ) : ''; - $class .= " sdel-" . $this->sd->get_instance_hash(); - - $class = apply_filters( 'wp_super_duper_div_classname', $class, $args, $this->sd, $this ); - $class = apply_filters( 'wp_super_duper_div_classname_' . $this->sd->base_id, $class, $args, $this->sd, $this ); - - $attrs = apply_filters( 'wp_super_duper_div_attrs', '', $args, $this->sd, $this ); - $attrs = apply_filters( 'wp_super_duper_div_attrs_' . $this->sd->base_id, $attrs, $args, $this->sd, $this ); - - $shortcode_args = array(); - $output = ''; - $no_wrap = ! empty( $this->sd->options['no_wrap'] ) || ! empty( $args['no_wrap'] ); - - $main_content = $this->sd->output( $args, $shortcode_args, $content ); - - if ( $main_content && ! $no_wrap ) { - // wrap the shortcode in a div with the same class as the widget - $output .= '
'; - if ( ! empty( $args['title'] ) ) { - // if its a shortcode and there is a title try to grab the title wrappers - $shortcode_args = array( 'before_title' => '', 'after_title' => '' ); - if ( empty( $instance ) ) { - global $wp_registered_sidebars; - if ( ! empty( $wp_registered_sidebars ) ) { - foreach ( $wp_registered_sidebars as $sidebar ) { - if ( ! empty( $sidebar['before_title'] ) ) { - $shortcode_args['before_title'] = $sidebar['before_title']; - $shortcode_args['after_title'] = $sidebar['after_title']; - break; - } - } - } - } - $output .= $this->sd->output_title( $shortcode_args, $args ); - } - $output .= $main_content; - $output .= '
'; - } elseif ( $main_content && $no_wrap ) { - $output .= $main_content; - } - - // if preview, show a placeholder if empty - if ( $this->sd->is_preview() && $output == '' ) { - $output = $this->sd->preview_placeholder_text( "{{" . $this->sd->base_id . "}}" ); - } - - return apply_filters( 'wp_super_duper_widget_output', $output, $args, $shortcode_args, $this ); - } - - public function register_fusion_element() { - $options = $this->sd->options; - - if ( $this->sd->base_id ) { - - $params = $this->get_fusion_params(); - - $args = array( - 'name' => $options['name'], - 'shortcode' => $this->sd->base_id, - 'icon' => $options['block-icon'] ? $options['block-icon'] : 'far fa-square', - 'allow_generator' => true, - ); - - if ( ! empty( $params ) ) { - $args['params'] = $params; - } - - fusion_builder_map( $args ); - } - } - - protected function get_fusion_params() { - $params = array(); - $arguments = $this->sd->get_arguments(); - - if ( ! empty( $arguments ) ) { - foreach ( $arguments as $key => $val ) { - $param = array(); - // type - $param['type'] = str_replace( - array( - "text", - "number", - "email", - "color", - "checkbox" - ), - array( - "textfield", - "textfield", - "textfield", - "colorpicker", - "select", - ), - $val['type'] ); - - // multiselect - if ( $val['type'] == 'multiselect' || ( ( $param['type'] == 'select' || $val['type'] == 'select' ) && ! empty( $val['multiple'] ) ) ) { - $param['type'] = 'multiple_select'; - $param['multiple'] = true; - } - - // heading - $param['heading'] = $val['title']; - - // description - $param['description'] = isset( $val['desc'] ) ? $val['desc'] : ''; - - // param_name - $param['param_name'] = $key; - - // Default - $param['default'] = isset( $val['default'] ) ? $val['default'] : ''; - - // Group - if ( isset( $val['group'] ) ) { - $param['group'] = $val['group']; - } - - // value - if ( $val['type'] == 'checkbox' ) { - if ( isset( $val['default'] ) && $val['default'] == '0' ) { - unset( $param['default'] ); - } - $param['value'] = array( '' => __( "No" ), '1' => __( "Yes" ) ); - } elseif ( $param['type'] == 'select' || $param['type'] == 'multiple_select' ) { - $param['value'] = isset( $val['options'] ) ? $val['options'] : array(); - } else { - $param['value'] = isset( $val['default'] ) ? $val['default'] : ''; - } - - // setup the param - $params[] = $param; - - } - } - - return $params; - } - - /** - * Maybe insert the shortcode inserter button in the footer if we are in the cornerstone builder - */ - public function maybe_cornerstone_builder() { - if ( did_action( 'cornerstone_before_boot_app' ) ) { - self::shortcode_insert_button_script(); - } - } - - /** - * Output the JS and CSS for the shortcode insert button. - * - * @since 1.0.6 - * - * @param string $editor_id - * @param string $insert_shortcode_function - */ - public static function shortcode_insert_button_script( $editor_id = '', $insert_shortcode_function = '' ) { - ?> - - " . WP_Super_Duper::siteorigin_js() . ""; - } - ?> - - - - );" href="#TB_inline?width=100%&height=550&inlineId=super-duper-content-ajaxed" - class="thickbox button super-duper-content-open" title="Add Shortcode"> - - - - - - sd->base_id == sanitize_title_with_dashes( $_REQUEST['shortcode'] ) ) { - - $shortcode = sanitize_title_with_dashes( $_REQUEST['shortcode'] ); - - ob_start(); - $this->sd->form( array() ); - $form = ob_get_clean(); - - echo "
" . $form . "
"; - echo ""; - echo ""; - exit; - - } - - } - -} diff --git a/type/widget.php b/type/widget.php deleted file mode 100644 index fa456b1..0000000 --- a/type/widget.php +++ /dev/null @@ -1,210 +0,0 @@ -sd = $super_duper; - - // Register widget. - $widget_ops = $super_duper->options['widget_ops']; - - // Only overwrite if not set already. - if ( ! isset( $widget_ops['show_instance_in_rest'] ) ) { - $widget_ops['show_instance_in_rest'] = true; - } - - parent::__construct( $super_duper->options['base_id'], $super_duper->options['name'], $widget_ops ); - - if ( did_action( 'widgets_init' ) || doing_action( 'widgets_init' ) ) { - $this->register_widget(); - } else { - add_action( 'widgets_init', array( $this, 'register_widget' ) ); - } - - add_action( 'wp_enqueue_scripts', array( __CLASS__, 'enqueue_scripts' ) ); - add_action( 'elementor/editor/after_enqueue_styles', array( __CLASS__, 'elementor_editor_styles' ) ); - add_filter( 'widget_types_to_hide_from_legacy_widget_block', array( $this, 'hide_widget' ) ); - - } - - /** - * Registers the widget. - */ - public function register_widget() { - register_widget( $this ); - } - - /** - * Enqeues scripts. - * - * @param WP_Super_Duper $super_duper - */ - public static function enqueue_scripts() { - wp_add_inline_script( 'admin-widgets', WP_Super_Duper::widget_js() ); - wp_add_inline_script( 'customize-controls', WP_Super_Duper::widget_js() ); - wp_add_inline_style( 'widgets', WP_Super_Duper::widget_css() ); - } - - /** - * Add our widget CSS to elementor editor. - */ - public static function elementor_editor_styles() { - wp_add_inline_style( 'elementor-editor', WP_Super_Duper::widget_css( false ) ); - } - - /** - * Outputs the content of the widget - * - * @param array $args - * @param array $instance - */ - public function widget( $args, $instance ) { - - // Prepare output args. - $argument_values = $this->sd->argument_values( $instance ); - $argument_values = $this->sd->string_to_bool( $argument_values ); - $output = $this->sd->output( $argument_values, $args ); - $no_wrap = ! empty( $argument_values['no_wrap'] ); - - ob_start(); - if ( $output && ! $no_wrap ) { - - $class_original = $this->sd->options['widget_ops']['classname']; - $class = $this->sd->options['widget_ops']['classname'] . ' sdel-' . $this->sd->get_instance_hash(); - - // Before widget - $before_widget = $args['before_widget']; - $before_widget = str_replace( $class_original, $class, $before_widget ); - $before_widget = apply_filters( 'wp_super_duper_before_widget', $before_widget, $args, $instance, $this ); - $before_widget = apply_filters( 'wp_super_duper_before_widget_' . $this->sd->base_id, $before_widget, $args, $instance, $this ); - - // After widget - $after_widget = $args['after_widget']; - $after_widget = apply_filters( 'wp_super_duper_after_widget', $after_widget, $args, $instance, $this ); - $after_widget = apply_filters( 'wp_super_duper_after_widget_' . $this->sd->base_id, $after_widget, $args, $instance, $this ); - - echo $before_widget; - - // elementor strips the widget wrapping div so we check for and add it back if needed - if ( $this->is_elementor_widget_output() ) { - // Filter class & attrs for elementor widget output. - $class = apply_filters( 'wp_super_duper_div_classname', $class, $args, $this->sd, $this ); - $class = apply_filters( 'wp_super_duper_div_classname_' . $this->sd->base_id, $class, $args, $this->sd, $this ); - - $attrs = apply_filters( 'wp_super_duper_div_attrs', '', $args, $this->sd, $this ); - $attrs = apply_filters( 'wp_super_duper_div_attrs_' . $this->sd->base_id, $attrs, $args, $this->sd, $this ); - - echo ""; - } - - echo $this->sd->output_title( $args, $instance ); - echo $output; - if ( $this->is_elementor_widget_output() ) { - echo ""; - } - - echo $after_widget; - } elseif ( $this->sd->is_preview() && $output == '' ) {// if preview show a placeholder if empty - $output = $this->sd->preview_placeholder_text( "{{" . $this->base_id . "}}" ); - echo $output; - } elseif ( $output && $no_wrap ) { - echo $output; - } - $output = ob_get_clean(); - - $output = apply_filters( 'wp_super_duper_widget_output', $output, $instance, $args, $this ); - - echo $output; - } - - /** - * Tests if the current output is inside a elementor container. - * - * @since 1.0.4 - * @return bool - */ - public function is_elementor_widget_output() { - return defined( 'ELEMENTOR_VERSION' ) && isset( $this->number ) && $this->number == 'REPLACE_TO_ID'; - } - - /** - * Outputs the options form inputs for the widget. - * - * @param array $instance The widget options. - */ - public function form( $instance ) { - $this->sd->form( $instance ); - } - - /** - * Processing widget options on save - * - * @param array $new_instance The new options - * @param array $old_instance The previous options - * - * @return array - * @todo we should add some sanitation here. - */ - public function update( $new_instance, $old_instance ) { - - // Save the widget. - $instance = array_merge( (array) $old_instance, (array) $new_instance ); - - // set widget instance - $this->sd->instance = $instance; - - if ( empty( $this->arguments ) ) { - $this->sd->get_arguments(); - } - - // check for checkboxes - if ( ! empty( $this->sd->arguments ) ) { - foreach ( $this->sd->arguments as $argument ) { - if ( isset( $argument['type'] ) && $argument['type'] == 'checkbox' && ! isset( $new_instance[ $argument['name'] ] ) ) { - $instance[ $argument['name'] ] = '0'; - } - } - } - - return $instance; - } - - /** - * Hides this widget from the block widgets inserter function. - * - * @param array $widget_types List of hidden widgets. - * - * @return array - */ - public function hide_widget( $widget_types ) { - $widget_types[] = $this->id_base; - - return $widget_types; - } - -} diff --git a/wp-super-duper.php b/wp-super-duper.php index 6615e03..1f3014f 100755 --- a/wp-super-duper.php +++ b/wp-super-duper.php @@ -1,294 +1,425 @@ $options['name'], 'class_name' => $options['class_name'] ); - $this->base_id = $options['base_id']; - - // Lets filter the options before we do anything. - $options = apply_filters( 'wp_super_duper_options', $options, $this ); - $options = apply_filters( "wp_super_duper_options_{$this->base_id}", $options, $this ); - $options = $this->add_name_from_key( $options ); - - // Set args. - $this->options = $options; + $this->base_id = $options['base_id']; + // lets filter the options before we do anything + $options = apply_filters( "wp_super_duper_options", $options ); + $options = apply_filters( "wp_super_duper_options_{$this->base_id}", $options ); + $options = $this->add_name_from_key( $options ); + $this->options = $options; + $this->base_id = $options['base_id']; $this->arguments = isset( $options['arguments'] ) ? $options['arguments'] : array(); - - // Load output types. - $this->load_output_types(); - - // add generator text to admin head - add_action( 'admin_head', array( $this, 'generator' ) ); - - add_action( 'admin_init', array( __CLASS__, 'load_widgets_setting' ) ); - - add_action( 'wp_ajax_super_duper_get_picker', array( __CLASS__, 'get_picker' ) ); - + + // init parent + parent::__construct( $options['base_id'], $options['name'], $options['widget_ops'] ); + + if ( isset( $options['class_name'] ) ) { + // register widget + $this->class_name = $options['class_name']; + + // register shortcode + $this->register_shortcode(); + + // Fusion Builder (avada) support + if ( function_exists( 'fusion_builder_map' ) ) { + add_action( 'init', array( $this, 'register_fusion_element' ) ); + } + + // register block + add_action( 'admin_enqueue_scripts', array( $this, 'register_block' ) ); + } + + // add the CSS and JS we need ONCE + global $sd_widget_scripts; + + if ( ! $sd_widget_scripts ) { + wp_add_inline_script( 'admin-widgets', $this->widget_js() ); + wp_add_inline_script( 'customize-controls', $this->widget_js() ); + wp_add_inline_style( 'widgets', $this->widget_css() ); + + // maybe add elementor editor styles + add_action( 'elementor/editor/after_enqueue_styles', array( $this, 'elementor_editor_styles' ) ); + + $sd_widget_scripts = true; + + // add shortcode insert button once + add_action( 'media_buttons', array( $this, 'shortcode_insert_button' ) ); + // generatepress theme sections compatibility + if ( function_exists( 'generate_sections_sections_metabox' ) ) { + add_action( 'generate_sections_metabox', array( $this, 'shortcode_insert_button_script' ) ); + } + if ( $this->is_preview() ) { + add_action( 'wp_footer', array( $this, 'shortcode_insert_button_script' ) ); + // this makes the insert button work for elementor + add_action( 'elementor/editor/after_enqueue_scripts', array( + $this, + 'shortcode_insert_button_script' + ) ); // for elementor + } + // this makes the insert button work for cornerstone + add_action( 'wp_print_footer_scripts', array( __CLASS__, 'maybe_cornerstone_builder' ) ); + + add_action( 'wp_ajax_super_duper_get_widget_settings', array( __CLASS__, 'get_widget_settings' ) ); + add_action( 'wp_ajax_super_duper_get_picker', array( __CLASS__, 'get_picker' ) ); + + // add generator text to admin head + add_action( 'admin_head', array( $this, 'generator' ) ); + } + do_action( 'wp_super_duper_widget_init', $options, $this ); - } - + /** - * Set the name from the argument key. - * - * @param array $options - * @param bool $arguments - * - * @return mixed + * Add our widget CSS to elementor editor. */ - protected function add_name_from_key( $options, $arguments = false ) { - if ( ! empty( $options['arguments'] ) ) { - foreach ( $options['arguments'] as $key => $val ) { - $options['arguments'][ $key ]['name'] = $key; - } - } elseif ( $arguments && is_array( $options ) && ! empty( $options ) ) { - foreach ( $options as $key => $val ) { - $options[ $key ]['name'] = $key; + public function elementor_editor_styles() { + wp_add_inline_style( 'elementor-editor', $this->widget_css( false ) ); + } + + public function register_fusion_element() { + + $options = $this->options; + + if ( $this->base_id ) { + + $params = $this->get_fusion_params(); + + $args = array( + 'name' => $options['name'], + 'shortcode' => $this->base_id, + 'icon' => $options['block-icon'] ? $options['block-icon'] : 'far fa-square', + 'allow_generator' => true, + ); + + if ( ! empty( $params ) ) { + $args['params'] = $params; } + + fusion_builder_map( $args ); } - - return $options; + } - - /** - * Output the version in the admin header. - */ - public function load_output_types() { - - $allowed_types = $this->get_output_types(); - $output_types = array( 'block', 'shortcode', 'widget' ); - - // Check if this is being overidden by the widget. - $args = $this->get_arguments(); - if ( isset( $args['output_types'] ) && is_array( $args['output_types'] ) ) { - $output_types = $args['output_types'] ; - } - - if ( isset( $this->options['output_types'] ) && is_array( $this->options['output_types'] ) ) { - $output_types = $this->options['output_types'] ; - } - - // Load each output type. - foreach ( $output_types as $output_type ) { - - // Ensure this is an allowed type. - if ( ! isset( $allowed_types[ $output_type ] ) ) { - continue; - } - - // If the class does not exist, try loading it. - if ( ! class_exists( $allowed_types[ $output_type ] ) ) { - - if ( file_exists( plugin_dir_path( __FILE__ ) . "type/$output_type.php" ) ) { - require_once( plugin_dir_path( __FILE__ ) . "type/$output_type.php" ); + + public function get_fusion_params() { + $params = array(); + $arguments = $this->get_arguments(); + + if ( ! empty( $arguments ) ) { + foreach ( $arguments as $key => $val ) { + $param = array(); + // type + $param['type'] = str_replace( + array( + "text", + "number", + "email", + "color", + "checkbox" + ), + array( + "textfield", + "textfield", + "textfield", + "colorpicker", + "select", + + ), + $val['type'] ); + + // multiselect + if ( $val['type'] == 'multiselect' || ( ( $param['type'] == 'select' || $val['type'] == 'select' ) && ! empty( $val['multiple'] ) ) ) { + $param['type'] = 'multiple_select'; + $param['multiple'] = true; + } + + // heading + $param['heading'] = $val['title']; + + // description + $param['description'] = isset( $val['desc'] ) ? $val['desc'] : ''; + + // param_name + $param['param_name'] = $key; + + // Default + $param['default'] = isset( $val['default'] ) ? $val['default'] : ''; + + // Group + if ( isset( $val['group'] ) ) { + $param['group'] = $val['group']; + } + + // value + if ( $val['type'] == 'checkbox' ) { + if ( isset( $val['default'] ) && $val['default'] == '0' ) { + unset( $param['default'] ); + } + $param['value'] = array( '' => __( "No" ), '1' => __( "Yes" ) ); + } elseif ( $param['type'] == 'select' || $param['type'] == 'multiple_select' ) { + $param['value'] = isset( $val['options'] ) ? $val['options'] : array(); } else { - continue; + $param['value'] = isset( $val['default'] ) ? $val['default'] : ''; } - + + // setup the param + $params[] = $param; + } - - $output_class = $allowed_types[ $output_type ]; - $this->output_types[ $output_type ] = new $output_class( $this ); } - + + + return $params; + } + + /** + * Maybe insert the shortcode inserter button in the footer if we are in the cornerstone builder + */ + public static function maybe_cornerstone_builder() { + if ( did_action( 'cornerstone_before_boot_app' ) ) { + self::shortcode_insert_button_script(); + } } - + /** - * Retrieves an array of available SD types. + * A function to ge the shortcode builder picker html. * - * @return array + * @param string $editor_id + * + * @return string */ - protected function get_output_types() { - - // Output type id and class. - $types = array( - 'block' => 'WP_Super_Duper_Block', - 'shortcode' => 'WP_Super_Duper_Shortcode', - 'widget' => 'WP_Super_Duper_Widget', - ); - - // Maybe disable widgets. - $disable_widget = get_option( 'sd_load_widgets', 'auto' ); - - if ( 'auto' === $disable_widget ) { - if ( !$this->widgets_required() ) { - unset( $types['widget'] ); - } + public static function get_picker( $editor_id = '' ) { + + ob_start(); + if ( isset( $_POST['editor_id'] ) ) { + $editor_id = esc_attr( $_POST['editor_id'] ); + } elseif ( isset( $_REQUEST['et_fb'] ) ) { + $editor_id = 'main_content_content_vb_tiny_mce'; } - - if ( 'no' === $disable_widget ) { - unset( $types['widget'] ); + + global $sd_widgets; + ?> + +
+ '; + echo ""; + foreach ( $sd_widgets as $shortcode => $class ) { + echo ""; + } + echo ""; + + } + ?> +
+ +
+ +
+ +
+ + + + +
+
+ has_active_widgets() ) ){ - $required = true; - } - - - return apply_filters( 'sd_widgets_required' , $required ); + public function generator() { + echo ''; } - + /** - * Check if the current site has any active old style widgets. + * Get widget settings. * - * @return bool + * @since 1.0.0 */ - protected function has_active_widgets(){ - global $sd_has_active_widgets; - - // have we already done this? - if(!is_null($sd_has_active_widgets)){ - return $sd_has_active_widgets; - } - - $result = false; - $sidebars_widgets = get_option('sidebars_widgets'); - - if(is_array($sidebars_widgets)){ - - foreach ($sidebars_widgets as $key => $value) { - - - - if( $key != 'wp_inactive_widgets' ) { - - if(!empty($value) && is_array($value)){ - foreach($value as $widget){ - if($widget && substr( $widget, 0, 6 ) !== "block-"){ - $result = true; - } - } - } - - } - } + public static function get_widget_settings() { + global $sd_widgets; + + $shortcode = isset( $_REQUEST['shortcode'] ) && $_REQUEST['shortcode'] ? sanitize_title_with_dashes( $_REQUEST['shortcode'] ) : ''; + if ( ! $shortcode ) { + wp_die(); } - - $sd_has_active_widgets = $result; - - return $result; + $widget_args = isset( $sd_widgets[ $shortcode ] ) ? $sd_widgets[ $shortcode ] : ''; + if ( ! $widget_args ) { + wp_die(); + } + $class_name = isset( $widget_args['class_name'] ) && $widget_args['class_name'] ? $widget_args['class_name'] : ''; + if ( ! $class_name ) { + wp_die(); + } + + // invoke an instance method + $widget = new $class_name; + + ob_start(); + $widget->form( array() ); + $form = ob_get_clean(); + echo "
" . $form . "
"; + echo ""; + echo ""; + ?> + arguments ) ) { - $this->arguments = $this->set_arguments(); + public static function shortcode_insert_button( $editor_id = '', $insert_shortcode_function = '' ) { + global $sd_widgets, $shortcode_insert_button_once; + if ( $shortcode_insert_button_once ) { + return; } - - $this->arguments = apply_filters( 'wp_super_duper_arguments', $this->arguments, $this->options, $this->instance ); - $this->arguments = $this->add_name_from_key( $this->arguments, true ); - - return $this->arguments; + add_thickbox(); + + + /** + * Cornerstone makes us play dirty tricks :/ + * All media_buttons are removed via JS unless they are two specific id's so we wrap our content in this ID so it is not removed. + */ + if ( function_exists( 'cornerstone_plugin_init' ) && ! is_admin() ) { + echo ''; + } + + echo self::shortcode_button( 'this', 'true' ); + + // see opening note + if ( function_exists( 'cornerstone_plugin_init' ) && ! is_admin() ) { + echo ''; // end #insert-media-button + } + + // Add separate script for generatepress theme sections + if ( function_exists( 'generate_sections_sections_metabox' ) && did_action( 'generate_sections_metabox' ) ) { + } else { + self::shortcode_insert_button_script( $editor_id, $insert_shortcode_function ); + } + + $shortcode_insert_button_once = true; } - + /** - * Set arguments in super duper. + * Gets the shortcode insert button html. * - * @since 1.0.0 + * @param string $id + * @param string $search_for_id * - * @return array Set arguments. + * @return mixed */ - public function set_arguments() { - return $this->arguments; + public static function shortcode_button( $id = '', $search_for_id = '' ) { + ob_start(); + ?> + + );" href="#TB_inline?width=100%&height=550&inlineId=super-duper-content-ajaxed" + class="thickbox button super-duper-content-open" title="Add Shortcode"> + + + + + + " class="button button-primary right sd-advanced-button" onclick="sd_so_toggle_advanced(this);return false;">'; var form = jQuery($this).parents('' + $selector + ''); - + if (jQuery($this).val() == '1' && jQuery(form).find('.sd-advanced-button').length == 0) { jQuery(form).append($button); } - + // show hide on form change jQuery(form).on("change", function () { sd_so_show_hide(form); }); - + // show hide on load sd_so_show_hide(form); } - + jQuery(function () { jQuery(document).on('open_dialog', function (w, e) { setTimeout(function () { @@ -376,131 +507,600 @@ function sd_so_init_widget($this, $selector) { tags for code highlighting, so we strip them from the output. */ + return str_replace( array( '' ), '', $output ); } - + /** - * A function to ge the shortcode builder picker html. + * Output the JS and CSS for the shortcode insert button. * - * @param string $editor_id + * @since 1.0.6 * - * @return string + * @param string $editor_id + * @param string $insert_shortcode_function */ - public static function get_picker( $editor_id = '' ) { - - ob_start(); - if ( isset( $_POST['editor_id'] ) ) { - $editor_id = esc_attr( $_POST['editor_id'] ); - } elseif ( isset( $_REQUEST['et_fb'] ) ) { - $editor_id = 'main_content_content_vb_tiny_mce'; - } - - global $sd_widgets; + public static function shortcode_insert_button_script( $editor_id = '', $insert_shortcode_function = '' ) { ?> - -
- '; - echo ""; - foreach ( $sd_widgets as $shortcode => $class ) { - echo ""; - } - echo ""; - + " . self::siteorigin_js() . ""; + } + ?> + + + + tags for code highlighting, so we strip them from the output. + */ + + return str_replace( array( + '' + ), '', $output ); } - + /** - * Returns the JS used to render the widget/shortcode settings form. + * Gets some JS for the widgets screen. * - * @return string + * @return mixed */ - public static function widget_js() { + public function widget_js() { ob_start(); ?> - tags for code highlighting, so we strip them from the output. - */ - - return str_replace( array( - '' - ), '', $output ); + $output = ob_get_clean(); + + /* + * We only add the ' + ), '', $output ); } - + + /** - * Returns the CSS used to render the widget/shortcode settings form. + * Set the name from the argument key. * - * @param bool $advanced If we should include advanced CSS. + * @param $options * * @return mixed */ - public static function widget_css( $advanced = true ) { - ob_start(); - ?> - - - - tags for code highlighting, so we strip them from the output. - */ - - return str_replace( array( - '' - ), '', $output ); - } - - /** - * Registers the widgets loading settings. - */ - public static function load_widgets_setting() { - register_setting( 'general', 'sd_load_widgets', 'esc_attr' ); - - add_settings_field( - 'sd_load_widgets', - '', - 'WP_Super_Duper::load_widgets_setting_html', - 'general' - ); - - } - - /** - * Displays the widgets settings HTML. - */ - public static function load_widgets_setting_html() { - $available_options = array( - 'yes' => __( 'Yes' ), - 'no' => __( 'No' ), - 'auto' => __( 'Auto' ), - ); - $selected_option = get_option( 'sd_load_widgets', 'auto' ); - - ?> - -

- $val ) { + $options[ $key ]['name'] = $key; + } + } + + return $options; } /** - * Prevents elementor errors if called the SDv1 way. + * Register the parent shortcode. + * + * @since 1.0.0 */ - public function _set(){ - // backwards compatibility for elementor pro + public function register_shortcode() { + add_shortcode( $this->base_id, array( $this, 'shortcode_output' ) ); + add_action( 'wp_ajax_super_duper_output_shortcode', array( __CLASS__, 'render_shortcode' ) ); } - + /** - * Output the version in the admin header. + * Render the shortcode via ajax so we can return it to Gutenberg. + * + * @since 1.0.0 */ - public function generator() { - - // We want to set this once. - if ( empty( $GLOBALS['SD_SET_GENERATOR'] ) ) { - echo ''; - $GLOBALS['SD_SET_GENERATOR'] = 1; + public static function render_shortcode() { + + check_ajax_referer( 'super_duper_output_shortcode', '_ajax_nonce', true ); + if ( ! current_user_can( 'manage_options' ) ) { + wp_die(); + } + + // we might need the $post value here so lets set it. + if ( isset( $_POST['post_id'] ) && $_POST['post_id'] ) { + $post_obj = get_post( absint( $_POST['post_id'] ) ); + if ( ! empty( $post_obj ) && empty( $post ) ) { + global $post; + $post = $post_obj; + } + } + + if ( isset( $_POST['shortcode'] ) && $_POST['shortcode'] ) { + $shortcode_name = sanitize_title_with_dashes( $_POST['shortcode'] ); + $attributes_array = isset( $_POST['attributes'] ) && $_POST['attributes'] ? $_POST['attributes'] : array(); + $attributes = ''; + if ( ! empty( $attributes_array ) ) { + foreach ( $attributes_array as $key => $value ) { + if ( is_array( $value ) ) { + $value = implode( ",", $value ); + } + $attributes .= " " . sanitize_title_with_dashes( $key ) . "='" . wp_slash( $value ) . "' "; + } + } + + $shortcode = "[" . $shortcode_name . " " . $attributes . "]"; + + echo do_shortcode( $shortcode ); + } - + wp_die(); } - + /** - * This is the main output class for all 3 items, widget, shortcode and block, it is extended in the calling class. + * Output the shortcode. * * @param array $args - * @param array $widget_args * @param string $content + * + * @return string */ - public function output( $args = array(), $widget_args = array(), $content = '' ) { - echo call_user_func( $this->options['widget_ops']['output'], $args, $widget_args, $content ); + public function shortcode_output( $args = array(), $content = '' ) { + $args = $this->argument_values( $args ); + + // add extra argument so we know its a output to gutenberg + //$args + $args = $this->string_to_bool( $args ); + + // if we have a enclosed shortcode we add it to the special `html` argument + if ( ! empty( $content ) ) { + $args['html'] = $content; + } + + $class = isset( $this->options['widget_ops']['classname'] ) ? esc_attr( $this->options['widget_ops']['classname'] ) : ''; + $class .= " sdel-".$this->get_instance_hash(); + + $class = apply_filters( 'wp_super_duper_div_classname', $class, $args, $this ); + $class = apply_filters( 'wp_super_duper_div_classname_' . $this->base_id, $class, $args, $this ); + + $attrs = apply_filters( 'wp_super_duper_div_attrs', '', $args, $this ); + $attrs = apply_filters( 'wp_super_duper_div_attrs_' . $this->base_id, '', $args, $this ); + + $shortcode_args = array(); + $output = ''; + $no_wrap = isset( $this->options['no_wrap'] ) && $this->options['no_wrap'] ? true : false; + if ( isset( $args['no_wrap'] ) && $args['no_wrap'] ) { + $no_wrap = true; + } + $main_content = $this->output( $args, $shortcode_args, $content ); + if ( $main_content && ! $no_wrap ) { + // wrap the shortcode in a div with the same class as the widget + $output .= '
'; + if ( ! empty( $args['title'] ) ) { + // if its a shortcode and there is a title try to grab the title wrappers + $shortcode_args = array( 'before_title' => '', 'after_title' => '' ); + if ( empty( $instance ) ) { + global $wp_registered_sidebars; + if ( ! empty( $wp_registered_sidebars ) ) { + foreach ( $wp_registered_sidebars as $sidebar ) { + if ( ! empty( $sidebar['before_title'] ) ) { + $shortcode_args['before_title'] = $sidebar['before_title']; + $shortcode_args['after_title'] = $sidebar['after_title']; + break; + } + } + } + } + $output .= $this->output_title( $shortcode_args, $args ); + } + $output .= $main_content; + $output .= '
'; + } elseif ( $main_content && $no_wrap ) { + $output .= $main_content; + } + + // if preview show a placeholder if empty + if ( $this->is_preview() && $output == '' ) { + $output = $this->preview_placeholder_text( "{{" . $this->base_id . "}}" ); + } + + return apply_filters( 'wp_super_duper_widget_output', $output, $args, $shortcode_args, $this ); } - + /** * Placeholder text to show if output is empty and we are on a preview/builder page. * @@ -791,7 +1399,7 @@ public function output( $args = array(), $widget_args = array(), $content = '' ) public function preview_placeholder_text( $name = '' ) { return "
" . sprintf( __( 'Placeholder for: %s' ), $name ) . "
"; } - + /** * Sometimes booleans values can be turned to strings, so we fix that. * @@ -808,10 +1416,10 @@ public function string_to_bool( $options ) { $options[ $key ] = true; } } - + return $options; } - + /** * Get the argument values that are also filterable. * @@ -823,14 +1431,14 @@ public function string_to_bool( $options ) { */ public function argument_values( $instance ) { $argument_values = array(); - + // set widget instance $this->instance = $instance; - + if ( empty( $this->arguments ) ) { $this->arguments = $this->get_arguments(); } - + if ( ! empty( $this->arguments ) ) { foreach ( $this->arguments as $key => $args ) { // set the input name from the key @@ -844,119 +1452,1190 @@ public function argument_values( $instance ) { } } } - + return $argument_values; } - + /** - * Get the url path to the current folder. + * Set arguments in super duper. * - * @return string - */ - public function get_url() { - $url = $this->url; - - if ( ! $url ) { - // check if we are inside a plugin - $file_dir = str_replace( "/includes", "", dirname( __FILE__ ) ); - - $dir_parts = explode( "/wp-content/", $file_dir ); - $url_parts = explode( "/wp-content/", plugins_url() ); - - if ( ! empty( $url_parts[0] ) && ! empty( $dir_parts[1] ) ) { - $url = trailingslashit( $url_parts[0] . "/wp-content/" . $dir_parts[1] ); - $this->url = $url; - } - } - - return $url; - } - - /** - * General function to check if we are in a preview situation. + * @since 1.0.0 * - * @since 1.0.6 - * @return bool + * @return array Set arguments. */ - public function is_preview() { - return $this->is_divi_preview() || $this->is_elementor_preview() || $this->is_beaver_preview() || $this->is_siteorigin_preview() || $this->is_cornerstone_preview() || $this->is_fusion_preview() || $this->is_oxygen_preview() || $this->is_block_content_call(); + public function set_arguments() { + return $this->arguments; } - + /** - * Tests if the current output is inside a Divi preview. + * Get arguments in super duper. * - * @since 1.0.6 - * @return bool + * @since 1.0.0 + * + * @return array Get arguments. */ - public function is_divi_preview() { - $result = false; - if ( isset( $_REQUEST['et_fb'] ) || isset( $_REQUEST['et_pb_preview'] ) || ( is_admin() && isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'elementor' ) ) { - $result = true; + public function get_arguments() { + if ( empty( $this->arguments ) ) { + $this->arguments = $this->set_arguments(); } - - return $result; + + $this->arguments = apply_filters( 'wp_super_duper_arguments', $this->arguments, $this->options, $this->instance ); + $this->arguments = $this->add_name_from_key( $this->arguments, true ); + + return $this->arguments; } - + /** - * Tests if the current output is inside a elementor preview. + * This is the main output class for all 3 items, widget, shortcode and block, it is extended in the calling class. * - * @since 1.0.4 - * @return bool + * @param array $args + * @param array $widget_args + * @param string $content */ - public function is_elementor_preview() { - $result = false; - if ( isset( $_REQUEST['elementor-preview'] ) || ( is_admin() && isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'elementor' ) || ( isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'elementor_ajax' ) ) { - $result = true; - } - - return $result; + public function output( $args = array(), $widget_args = array(), $content = '' ) { + } - + /** - * Tests if the current output is inside a Beaver builder preview. - * - * @since 1.0.6 - * @return bool + * Add the dynamic block code inline when the wp-block in enqueued. */ - public function is_beaver_preview() { - $result = false; - if ( isset( $_REQUEST['fl_builder'] ) ) { - $result = true; + public function register_block() { + wp_add_inline_script( 'wp-blocks', $this->block() ); + if ( class_exists( 'SiteOrigin_Panels' ) ) { + wp_add_inline_script( 'wp-blocks', $this->siteorigin_js() ); } - - return $result; } - + /** - * Tests if the current output is inside a siteorigin builder preview. + * Check if we need to show advanced options. * - * @since 1.0.6 * @return bool */ - public function is_siteorigin_preview() { - $result = false; - if ( ! empty( $_REQUEST['siteorigin_panels_live_editor'] ) ) { - $result = true; + public function block_show_advanced() { + + $show = false; + $arguments = $this->arguments; + + if ( empty( $arguments ) ) { + $arguments = $this->get_arguments(); } - - return $result; + + if ( ! empty( $arguments ) ) { + foreach ( $arguments as $argument ) { + if ( isset( $argument['advanced'] ) && $argument['advanced'] ) { + $show = true; + break; // no need to continue if we know we have it + } + } + } + + return $show; } - + /** - * Tests if the current output is inside a cornerstone builder preview. + * Get the url path to the current folder. * - * @since 1.0.8 - * @return bool + * @return string + */ + public function get_url() { + + $url = $this->url; + + if ( ! $url ) { + // check if we are inside a plugin + $file_dir = str_replace( "/includes", "", dirname( __FILE__ ) ); + + $dir_parts = explode( "/wp-content/", $file_dir ); + $url_parts = explode( "/wp-content/", plugins_url() ); + + if ( ! empty( $url_parts[0] ) && ! empty( $dir_parts[1] ) ) { + $url = trailingslashit( $url_parts[0] . "/wp-content/" . $dir_parts[1] ); + $this->url = $url; + } + } + + + return $url; + } + + /** + * Generate the block icon. + * + * Enables the use of Font Awesome icons. + * + * @note xlink:href is actually deprecated but href is not supported by all so we use both. + * + * @param $icon + * + * @since 1.1.0 + * @return string + */ + public function get_block_icon( $icon ) { + + // check if we have a Font Awesome icon + $fa_type = ''; + if ( substr( $icon, 0, 7 ) === "fas fa-" ) { + $fa_type = 'solid'; + } elseif ( substr( $icon, 0, 7 ) === "far fa-" ) { + $fa_type = 'regular'; + } elseif ( substr( $icon, 0, 7 ) === "fab fa-" ) { + $fa_type = 'brands'; + } else { + $icon = "'" . $icon . "'"; + } + + // set the icon if we found one + if ( $fa_type ) { + $fa_icon = str_replace( array( "fas fa-", "far fa-", "fab fa-" ), "", $icon ); + $icon = "el('svg',{width: 20, height: 20, viewBox: '0 0 20 20'},el('use', {'xlink:href': '" . $this->get_url() . "icons/" . $fa_type . ".svg#" . $fa_icon . "','href': '" . $this->get_url() . "icons/" . $fa_type . ".svg#" . $fa_icon . "'}))"; + } + + return $icon; + } + + public function group_arguments( $arguments ) { +// echo '###';print_r($arguments); + if ( ! empty( $arguments ) ) { + $temp_arguments = array(); + $general = __( "General" ); + $add_sections = false; + foreach ( $arguments as $key => $args ) { + if ( isset( $args['group'] ) ) { + $temp_arguments[ $args['group'] ][ $key ] = $args; + $add_sections = true; + } else { + $temp_arguments[ $general ][ $key ] = $args; + } + } + + // only add sections if more than one + if ( $add_sections ) { + $arguments = $temp_arguments; + } + } + +// echo '###';print_r($arguments); + return $arguments; + } + + + /** + * Output the JS for building the dynamic Guntenberg block. + * + * @since 1.0.4 Added block_wrap property which will set the block wrapping output element ie: div, span, p or empty for no wrap. + * @since 1.0.9 Save numbers as numbers and not strings. + * @since 1.1.0 Font Awesome classes can be used for icons. + * @return mixed + */ + public function block() { + ob_start(); + + $show_advanced = $this->block_show_advanced(); + ?> + + tags for code highlighting, so we strip them from the output. + */ + + return str_replace( array( + '' + ), '', $output ); + } + + public function block_row_start($key, $args){ + + // check for row + if(!empty($args['row'])){ + + if(!empty($args['row']['open'])){ + + // element require + $element_require = ! empty( $args['element_require'] ) ? $this->block_props_replace( $args['element_require'], true ) . " && " : ""; + echo $element_require; + + if(false){?>array_to_attributes( $args['custom_attributes'] ) : ''; + $options = ''; + $extra = ''; + $require = ''; + + // `content` is a protected and special argument + if ( $key == 'content' ) { + return; + } + + + // icon + $icon = ''; + if( !empty( $args['icon'] ) ){ + $icon .= "el('div', {"; + $icon .= "dangerouslySetInnerHTML: {__html: '".self::get_widget_icon( esc_attr($args['icon']))."'},"; + $icon .= "className: 'text-center',"; + $icon .= "title: '".addslashes( $args['title'] )."',"; + $icon .= "}),"; + + // blank title as its added to the icon. + $args['title'] = ''; + } + + // require advanced + $require_advanced = ! empty( $args['advanced'] ) ? "props.attributes.show_advanced && " : ""; + + // element require + $element_require = ! empty( $args['element_require'] ) ? $this->block_props_replace( $args['element_require'], true ) . " && " : ""; + + + $onchange = "props.setAttributes({ $key: $key } )"; + $onchangecomplete = ""; + $value = "props.attributes.$key"; + $text_type = array( 'text', 'password', 'number', 'email', 'tel', 'url', 'colorx' ); + if ( in_array( $args['type'], $text_type ) ) { + $type = 'TextControl'; + // Save numbers as numbers and not strings + if ( $args['type'] == 'number' ) { + $onchange = "props.setAttributes({ $key: Number($key) } )"; + } + } + /* + * https://www.wptricks.com/question/set-current-tab-on-a-gutenberg-tabpanel-component-from-outside-that-component/ es5 layout + elseif($args['type']=='tabs'){ + ?> + + id).","; + }elseif($args['name'] == 'sort_by' && !empty($args['post_type_linked'])){ + $options .= "options: sort_by_".str_replace("-","_", $this->id).","; + }else { + + if ( ! empty( $args['options'] ) ) { + $options .= "options: ["; + foreach ( $args['options'] as $option_val => $option_label ) { + $options .= "{ value: '" . esc_attr( $option_val ) . "', label: '" . addslashes( $option_label ) . "' },"; + } + $options .= "],"; + } + } + if ( isset( $args['multiple'] ) && $args['multiple'] ) { //@todo multiselect does not work at the moment: https://github.com/WordPress/gutenberg/issues/5550 + $extra .= ' multiple: true, '; + } + } elseif ( $args['type'] == 'alignment' ) { + $type = 'AlignmentToolbar'; // @todo this does not seem to work but cant find a example + }elseif ( $args['type'] == 'margins' ) { + + } else { + return;// if we have not implemented the control then don't break the JS. + } + + + + // color input does not show the labels so we add them + if($args['type']=='color'){ + // add show only if advanced + echo $require_advanced; + // add setting require if defined + echo $element_require; + echo "el('div', {style: {'marginBottom': '8px'}}, '".addslashes( $args['title'] )."'),"; + } + + // add show only if advanced + echo $require_advanced; + // add setting require if defined + echo $element_require; + + // icon + echo $icon; + ?> + el( wp.components., { + label: '', + help: '', + value: , + + + + + + + onChange: function ( ) { + + } + } ), + $val ) { + $attributes .= " $key='$val' "; + } + } else { + foreach ( $custom_attributes as $key => $val ) { + $attributes .= "'$key': '$val',"; + } + } + } + + return $attributes; + } + + /** + * A self looping function to create the output for JS block elements. + * + * This is what is output in the WP Editor visual view. + * + * @param $args + */ + public function block_element( $args ) { + + + if ( ! empty( $args ) ) { + foreach ( $args as $element => $new_args ) { + + if ( is_array( $new_args ) ) { // its an element + + + if ( isset( $new_args['element'] ) ) { + + if ( isset( $new_args['element_require'] ) ) { + echo str_replace( array( + "'+", + "+'" + ), '', $this->block_props_replace( $new_args['element_require'] ) ) . " && "; + unset( $new_args['element_require'] ); + } + + echo "\n el( '" . $new_args['element'] . "', {"; + + // get the attributes + foreach ( $new_args as $new_key => $new_value ) { + + + if ( $new_key == 'element' || $new_key == 'content' || $new_key == 'element_require' || $new_key == 'element_repeat' || is_array( $new_value ) ) { + // do nothing + } else { + echo $this->block_element( array( $new_key => $new_value ) ); + } + } + + echo "},";// end attributes + + // get the content + $first_item = 0; + foreach ( $new_args as $new_key => $new_value ) { + if ( $new_key === 'content' || is_array( $new_value ) ) { + + if ( $new_key === 'content' ) { + echo "'" . $this->block_props_replace( wp_slash( $new_value ) ) . "'"; + } + + if ( is_array( $new_value ) ) { + + if ( isset( $new_value['element_require'] ) ) { + echo str_replace( array( + "'+", + "+'" + ), '', $this->block_props_replace( $new_value['element_require'] ) ) . " && "; + unset( $new_value['element_require'] ); + } + + if ( isset( $new_value['element_repeat'] ) ) { + $x = 1; + while ( $x <= absint( $new_value['element_repeat'] ) ) { + $this->block_element( array( '' => $new_value ) ); + $x ++; + } + } else { + $this->block_element( array( '' => $new_value ) ); + } + } + $first_item ++; + } + } + + echo ")";// end content + + echo ", \n"; + + } + } else { + + if ( substr( $element, 0, 3 ) === "if_" ) { + echo str_replace( "if_", "", $element ) . ": " . $this->block_props_replace( $new_args, true ) . ","; + } elseif ( $element == 'style' ) { + echo $element . ": " . $this->block_props_replace( $new_args ) . ","; + } else { + echo $element . ": '" . $this->block_props_replace( $new_args ) . "',"; + } + + } + } + } + } + + /** + * Replace block attributes placeholders with the proper naming. + * + * @param $string + * + * @return mixed + */ + public function block_props_replace( $string, $no_wrap = false ) { + + if ( $no_wrap ) { + $string = str_replace( array( "[%", "%]" ), array( "props.attributes.", "" ), $string ); + } else { + $string = str_replace( array( "[%", "%]" ), array( "'+props.attributes.", "+'" ), $string ); + } + + return $string; + } + + /** + * Outputs the content of the widget + * + * @param array $args + * @param array $instance + */ + public function widget( $args, $instance ) { + + // get the filtered values + $argument_values = $this->argument_values( $instance ); + $argument_values = $this->string_to_bool( $argument_values ); + $output = $this->output( $argument_values, $args ); + + $no_wrap = false; + if ( isset( $argument_values['no_wrap'] ) && $argument_values['no_wrap'] ) { + $no_wrap = true; + } + + ob_start(); + if ( $output && ! $no_wrap ) { + + $class_original = $this->options['widget_ops']['classname']; + $class = $this->options['widget_ops']['classname']." sdel-".$this->get_instance_hash(); + + // Before widget + $before_widget = $args['before_widget']; + $before_widget = str_replace($class_original,$class,$before_widget); + $before_widget = apply_filters( 'wp_super_duper_before_widget', $before_widget, $args, $instance, $this ); + $before_widget = apply_filters( 'wp_super_duper_before_widget_' . $this->base_id, $before_widget, $args, $instance, $this ); + + // After widget + $after_widget = $args['after_widget']; + $after_widget = apply_filters( 'wp_super_duper_after_widget', $after_widget, $args, $instance, $this ); + $after_widget = apply_filters( 'wp_super_duper_after_widget_' . $this->base_id, $after_widget, $args, $instance, $this ); + + echo $before_widget; + // elementor strips the widget wrapping div so we check for and add it back if needed + if ( $this->is_elementor_widget_output() ) { + // Filter class & attrs for elementor widget output. + $class = apply_filters( 'wp_super_duper_div_classname', $class, $args, $this ); + $class = apply_filters( 'wp_super_duper_div_classname_' . $this->base_id, $class, $args, $this ); + + $attrs = apply_filters( 'wp_super_duper_div_attrs', '', $args, $this ); + $attrs = apply_filters( 'wp_super_duper_div_attrs_' . $this->base_id, '', $args, $this ); + + echo ""; + } + echo $this->output_title( $args, $instance ); + echo $output; + if ( $this->is_elementor_widget_output() ) { + echo ""; + } + echo $after_widget; + } elseif ( $this->is_preview() && $output == '' ) {// if preview show a placeholder if empty + $output = $this->preview_placeholder_text( "{{" . $this->base_id . "}}" ); + echo $output; + } elseif ( $output && $no_wrap ) { + echo $output; + } + $output = ob_get_clean(); + + $output = apply_filters( 'wp_super_duper_widget_output', $output, $instance, $args, $this ); + + echo $output; + } + + /** + * Tests if the current output is inside a elementor container. + * + * @since 1.0.4 + * @return bool + */ + public function is_elementor_widget_output() { + $result = false; + if ( defined( 'ELEMENTOR_VERSION' ) && isset( $this->number ) && $this->number == 'REPLACE_TO_ID' ) { + $result = true; + } + + return $result; + } + + /** + * Tests if the current output is inside a elementor preview. + * + * @since 1.0.4 + * @return bool + */ + public function is_elementor_preview() { + $result = false; + if ( isset( $_REQUEST['elementor-preview'] ) || ( is_admin() && isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'elementor' ) || ( isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'elementor_ajax' ) ) { + $result = true; + } + + return $result; + } + + /** + * Tests if the current output is inside a Divi preview. + * + * @since 1.0.6 + * @return bool + */ + public function is_divi_preview() { + $result = false; + if ( isset( $_REQUEST['et_fb'] ) || isset( $_REQUEST['et_pb_preview'] ) || ( is_admin() && isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'elementor' ) ) { + $result = true; + } + + return $result; + } + + /** + * Tests if the current output is inside a Beaver builder preview. + * + * @since 1.0.6 + * @return bool + */ + public function is_beaver_preview() { + $result = false; + if ( isset( $_REQUEST['fl_builder'] ) ) { + $result = true; + } + + return $result; + } + + /** + * Tests if the current output is inside a siteorigin builder preview. + * + * @since 1.0.6 + * @return bool + */ + public function is_siteorigin_preview() { + $result = false; + if ( ! empty( $_REQUEST['siteorigin_panels_live_editor'] ) ) { + $result = true; + } + + return $result; + } + + /** + * Tests if the current output is inside a cornerstone builder preview. + * + * @since 1.0.8 + * @return bool */ public function is_cornerstone_preview() { $result = false; if ( ! empty( $_REQUEST['cornerstone_preview'] ) || basename( $_SERVER['REQUEST_URI'] ) == 'cornerstone-endpoint' ) { $result = true; } - + return $result; } - + /** * Tests if the current output is inside a fusion builder preview. * @@ -968,10 +2647,10 @@ public function is_fusion_preview() { if ( ! empty( $_REQUEST['fb-edit'] ) || ! empty( $_REQUEST['fusion_load_nonce'] ) ) { $result = true; } - + return $result; } - + /** * Tests if the current output is inside a Oxygen builder preview. * @@ -983,154 +2662,146 @@ public function is_oxygen_preview() { if ( ! empty( $_REQUEST['ct_builder'] ) || ( ! empty( $_REQUEST['action'] ) && ( substr( $_REQUEST['action'], 0, 11 ) === "oxy_render_" || substr( $_REQUEST['action'], 0, 10 ) === "ct_render_" ) ) ) { $result = true; } - + return $result; } - + /** - * Checks if the current call is a ajax call to get the block content. - * - * This can be used in your widget to return different content as the block content. - * - * @since 1.0.3 - * @return bool - */ - public function is_block_content_call() { - $result = false; - if ( wp_doing_ajax() && isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'super_duper_output_shortcode' ) { - $result = true; + * General function to check if we are in a preview situation. + * + * @since 1.0.6 + * @return bool + */ + public function is_preview() { + $preview = false; + if ( $this->is_divi_preview() ) { + $preview = true; + } elseif ( $this->is_elementor_preview() ) { + $preview = true; + } elseif ( $this->is_beaver_preview() ) { + $preview = true; + } elseif ( $this->is_siteorigin_preview() ) { + $preview = true; + } elseif ( $this->is_cornerstone_preview() ) { + $preview = true; + } elseif ( $this->is_fusion_preview() ) { + $preview = true; + } elseif ( $this->is_oxygen_preview() ) { + $preview = true; + } elseif( $this->is_block_content_call() ) { + $preview = true; + } + + return $preview; + } + + /** + * Output the super title. + * + * @param $args + * @param array $instance + * + * @return string + */ + public function output_title( $args, $instance = array() ) { + $output = ''; + if ( ! empty( $instance['title'] ) ) { + /** This filter is documented in wp-includes/widgets/class-wp-widget-pages.php */ + $title = apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base ); + + if(empty($instance['widget_title_tag'])){ + $output = $args['before_title'] . $title . $args['after_title']; + }else{ + $title_tag = esc_attr( $instance['widget_title_tag'] ); + + // classes + $title_classes = array(); + $title_classes[] = !empty( $instance['widget_title_size_class'] ) ? sanitize_html_class( $instance['widget_title_size_class'] ) : ''; + $title_classes[] = !empty( $instance['widget_title_align_class'] ) ? sanitize_html_class( $instance['widget_title_align_class'] ) : ''; + $title_classes[] = !empty( $instance['widget_title_color_class'] ) ? "text-".sanitize_html_class( $instance['widget_title_color_class'] ) : ''; + $title_classes[] = !empty( $instance['widget_title_border_class'] ) ? sanitize_html_class( $instance['widget_title_border_class'] ) : ''; + $title_classes[] = !empty( $instance['widget_title_border_color_class'] ) ? "border-".sanitize_html_class( $instance['widget_title_border_color_class'] ) : ''; + $title_classes[] = !empty( $instance['widget_title_mt_class'] ) ? "mt-".absint( $instance['widget_title_mt_class'] ) : ''; + $title_classes[] = !empty( $instance['widget_title_mr_class'] ) ? "mr-".absint( $instance['widget_title_mr_class'] ) : ''; + $title_classes[] = !empty( $instance['widget_title_mb_class'] ) ? "mb-".absint( $instance['widget_title_mb_class'] ) : ''; + $title_classes[] = !empty( $instance['widget_title_ml_class'] ) ? "ml-".absint( $instance['widget_title_ml_class'] ) : ''; + $title_classes[] = !empty( $instance['widget_title_pt_class'] ) ? "pt-".absint( $instance['widget_title_pt_class'] ) : ''; + $title_classes[] = !empty( $instance['widget_title_pr_class'] ) ? "pr-".absint( $instance['widget_title_pr_class'] ) : ''; + $title_classes[] = !empty( $instance['widget_title_pb_class'] ) ? "pb-".absint( $instance['widget_title_pb_class'] ) : ''; + $title_classes[] = !empty( $instance['widget_title_pl_class'] ) ? "pl-".absint( $instance['widget_title_pl_class'] ) : ''; + + $class = !empty( $title_classes ) ? implode(" ",$title_classes) : ''; + $output = "<$title_tag class='$class' >$title"; + } + } - - return $result; + + return $output; } - + /** - * Outputs the options form inputs for the widget/shortcode. + * Outputs the options form inputs for the widget. * * @param array $instance The widget options. */ public function form( $instance ) { - - // Set widget instance. + + // set widget instance $this->instance = $instance; - - // Set it as a SD widget. + + // set it as a SD widget echo $this->widget_advanced_toggle(); - - // Display description. - printf( '

%s

', esc_html( $this->options['widget_ops']['description'] ) ); - - // Prepare arguments. + + echo "

" . esc_attr( $this->options['widget_ops']['description'] ) . "

"; $arguments_raw = $this->get_arguments(); - - if ( is_array( $arguments_raw ) ) { - - $arguments = $this->group_arguments( $arguments_raw ); - - // Do we have sections? - if ( $arguments != $arguments_raw ) { - + + if ( is_array( $arguments_raw ) ) { + + $arguments = $this->group_arguments( $arguments_raw ); + + // Do we have sections? + $has_sections = $arguments == $arguments_raw ? false : true; + + + if ( $has_sections ) { $panel_count = 0; foreach ( $arguments as $key => $args ) { - + + ?> + + " . esc_attr( $key ) . " "; + echo ""; echo "
"; - + foreach ( $args as $k => $a ) { - + $this->widget_inputs_row_start($k, $a); $this->widget_inputs( $a, $instance ); $this->widget_inputs_row_end($k, $a); - + } - + echo "
"; - + $panel_count ++; - + } - } else { - foreach ( $arguments as $key => $args ) { $this->widget_inputs_row_start($key, $args); $this->widget_inputs( $args, $instance ); $this->widget_inputs_row_end($key, $args); } - - } - - } - } - - /** - * Get the hidden input that when added makes the advanced button show on widget settings. - * - * @return string - */ - public function widget_advanced_toggle() { - - return sprintf( - '', - (int) $this->block_show_advanced() - ); - - } - - /** - * Check if we need to show advanced options. - * - * @return bool - */ - public function block_show_advanced() { - $show = false; - $arguments = $this->get_arguments(); - - if ( ! empty( $arguments ) ) { - foreach ( $arguments as $argument ) { - if ( isset( $argument['advanced'] ) && $argument['advanced'] ) { - $show = true; - break; // no need to continue if we know we have it - } - } - } - - return $show; - } - - /** - * Groups widget arguments. - * - * @param array $arguments - * - * @return array - */ - public function group_arguments( $arguments ) { - - if ( ! empty( $arguments ) ) { - $temp_arguments = array(); - $general = __( "General" ); - $add_sections = false; - foreach ( $arguments as $key => $args ) { - if ( isset( $args['group'] ) ) { - $temp_arguments[ $args['group'] ][ $key ] = $args; - $add_sections = true; - } else { - $temp_arguments[ $general ][ $key ] = $args; - } - } - - // only add sections if more than one - if ( $add_sections ) { - $arguments = $temp_arguments; } + } - - return $arguments; } - + public function widget_inputs_row_start($key, $args){ if(!empty($args['row'])){ // maybe open @@ -1152,7 +2823,38 @@ public function widget_inputs_row_start($key, $args){ } } } - + + public function widget_inputs_row_end($key, $args){ + + if(!empty($args['row'])){ + // maybe close + if(!empty($args['row']['close'])){ + echo "
"; + } + + echo ""; + } + } + + /** + * Get the hidden input that when added makes the advanced button show on widget settings. + * + * @return string + */ + public function widget_advanced_toggle() { + + $output = ''; + if ( $this->block_show_advanced() ) { + $val = 1; + } else { + $val = 0; + } + + $output .= ""; + + return $output; + } + /** * Convert require element. * @@ -1163,78 +2865,17 @@ public function widget_inputs_row_start($key, $args){ * @return string $output */ public function convert_element_require( $input ) { - + $input = str_replace( "'", '"', $input );// we only want double quotes - + $output = esc_attr( str_replace( array( "[%", "%]" ), array( "jQuery(form).find('[data-argument=\"", "\"]').find('input,select,textarea').val()" ), $input ) ); - + return $output; } - - /** - * Get the widget input description html. - * - * @param $args - * - * @return string - * @todo, need to make its own tooltip script - */ - public function widget_field_desc( $args ) { - - $description = ''; - if ( isset( $args['desc'] ) && $args['desc'] ) { - if ( isset( $args['desc_tip'] ) && $args['desc_tip'] ) { - $description = $this->desc_tip( $args['desc'] ); - } else { - $description = '' . wp_kses_post( $args['desc'] ) . ''; - } - } - - return $description; - } - - /** - * Get the tool tip html. - * - * @param $tip - * @param bool $allow_html - * - * @return string - */ - public function desc_tip( $tip, $allow_html = false ) { - if ( $allow_html ) { - $tip = $this->sanitize_tooltip( $tip ); - } else { - $tip = esc_attr( $tip ); - } - - return ''; - } - - /** - * Sanitize a string destined to be a tooltip. - * - * @param string $var - * - * @return string - */ - public function sanitize_tooltip( $var ) { - return htmlspecialchars( wp_kses( html_entity_decode( $var ), array( - 'br' => array(), - 'em' => array(), - 'strong' => array(), - 'small' => array(), - 'span' => array(), - 'ul' => array(), - 'li' => array(), - 'ol' => array(), - 'p' => array(), - ) ) ); - } - + /** * Builds the inputs for the widget options. * @@ -1242,11 +2883,11 @@ public function sanitize_tooltip( $var ) { * @param $instance */ public function widget_inputs( $args, $instance ) { - + $class = ""; $element_require = ""; $custom_attributes = ""; - + // get value if ( isset( $instance[ $args['name'] ] ) ) { $value = $instance[ $args['name'] ]; @@ -1255,30 +2896,30 @@ public function widget_inputs( $args, $instance ) { } else { $value = ''; } - + // get placeholder if ( ! empty( $args['placeholder'] ) ) { $placeholder = "placeholder='" . esc_html( $args['placeholder'] ) . "'"; } else { $placeholder = ''; } - + // get if advanced if ( isset( $args['advanced'] ) && $args['advanced'] ) { $class .= " sd-advanced-setting "; } - + // element_require if ( isset( $args['element_require'] ) && $args['element_require'] ) { $element_require = $args['element_require']; } - + // custom_attributes if ( isset( $args['custom_attributes'] ) && $args['custom_attributes'] ) { $custom_attributes = $this->array_to_attributes( $args['custom_attributes'], true ); } - - + + // before wrapper ?>

' > get_field_id( $args['name'] ) ); ?>">widget_field_title( $args );?>widget_field_desc( $args ); ?> class="widefat" - id="get_field_id( $args['name'] ) ); ?>" - name="get_field_name( $args['name'] ) ); ?>" - type="" - value=""> + id="get_field_id( $args['name'] ) ); ?>" + name="get_field_name( $args['name'] ) ); ?>" + type="" + value=""> get_field_id( $args['name'] ) ); ?>">widget_field_title( $args ); ?>widget_field_desc( $args ); ?> + name="get_field_name( $args['name'] ) ); ?>" type="hidden" + value="">

'; + }elseif($icon=='box-right'){ + return ''; + }elseif($icon=='box-bottom'){ + return ''; + }elseif($icon=='box-left'){ + return ''; + } } - + /** - * Convert an array of attributes to JS object or HTML attributes string. - * - * @todo there is prob a faster way to do this, also we could add some validation here. + * Get the widget input description html. * - * @param $attributes + * @param $args * * @return string + * @todo, need to make its own tooltip script */ - public function array_to_attributes( $attributes, $html = false ) { - - if ( ! is_array( $attributes ) ) { - return ''; - } - - $output = ''; - foreach ( $attributes as $name => $value ) { - - if ( $html ) { - - if ( true === $value ) { - $output .= esc_html( $name ) . ' '; - } else if ( false !== $value ) { - $output .= sprintf( '%s="%s" ', esc_html( $name ), trim( esc_attr( $value ) ) ); - } - + public function widget_field_desc( $args ) { + + $description = ''; + if ( isset( $args['desc'] ) && $args['desc'] ) { + if ( isset( $args['desc_tip'] ) && $args['desc_tip'] ) { + $description = $this->desc_tip( $args['desc'] ); } else { - $output .= sprintf( "'%s': '%s',", esc_js( $name ), is_bool( $value ) ? $value : trim( esc_js( $value ) ) ); + $description = '' . wp_kses_post( $args['desc'] ) . ''; } - } - - return $output; + + return $description; } - + /** - * Constructs id attributes for use in WP_Widget::form() fields. + * Get the widget input title html. * - * This function should be used in form() methods to create id attributes - * for fields to be saved by WP_Widget::update(). + * @param $args * - * @since 2.8.0 - * @since 4.4.0 Array format field IDs are now accepted. + * @return string + */ + public function widget_field_title( $args ) { + + $title = ''; + if ( isset( $args['title'] ) && $args['title'] ) { + if ( isset( $args['icon'] ) && $args['icon'] ) { + $title = self::get_widget_icon( $args['icon'], $args['title'] ); + } else { + $title = esc_attr($args['title']); + } + } + + return $title; + } + + /** + * Get the tool tip html. * - * @param string $field_name Field name. + * @param $tip + * @param bool $allow_html * - * @return string ID attribute for `$field_name`. + * @return string */ - public function get_field_id( $field_name ) { - - $field_name = str_replace( array( '[]', '[', ']' ), array( '', '-', '' ), $field_name ); - $field_name = trim( $field_name, '-' ); - - return 'widget-' . $this->base_id . '-' . $this->get_number() . '-' . $field_name; + function desc_tip( $tip, $allow_html = false ) { + if ( $allow_html ) { + $tip = $this->sanitize_tooltip( $tip ); + } else { + $tip = esc_attr( $tip ); + } + + return ''; } - + /** - * Returns the instance number. + * Sanitize a string destined to be a tooltip. + * + * @param string $var * - * @return int + * @return string */ - public function get_number() { - static $number = 1; - - if ( isset( $this->output_types['widget'] ) ) { - return $this->output_types['widget']->number; - } - - if ( empty( $this->number ) ) { - $this->number = $number; - $number ++; - } - - return $this->number; + public function sanitize_tooltip( $var ) { + return htmlspecialchars( wp_kses( html_entity_decode( $var ), array( + 'br' => array(), + 'em' => array(), + 'strong' => array(), + 'small' => array(), + 'span' => array(), + 'ul' => array(), + 'li' => array(), + 'ol' => array(), + 'p' => array(), + ) ) ); } - + /** - * Get the widget input title html. + * Processing widget options on save * - * @param $args + * @param array $new_instance The new options + * @param array $old_instance The previous options * - * @return string + * @return array + * @todo we should add some sanitation here. */ - public function widget_field_title( $args ) { - - $title = ''; - if ( isset( $args['title'] ) && $args['title'] ) { - if ( isset( $args['icon'] ) && $args['icon'] ) { - $title = $this->get_widget_icon( $args['icon'], $args['title'] ); - } else { - $title = esc_attr($args['title']); + public function update( $new_instance, $old_instance ) { + + //save the widget + $instance = array_merge( (array) $old_instance, (array) $new_instance ); + + // set widget instance + $this->instance = $instance; + + if ( empty( $this->arguments ) ) { + $this->get_arguments(); + } + + // check for checkboxes + if ( ! empty( $this->arguments ) ) { + foreach ( $this->arguments as $argument ) { + if ( isset( $argument['type'] ) && $argument['type'] == 'checkbox' && ! isset( $new_instance[ $argument['name'] ] ) ) { + $instance[ $argument['name'] ] = '0'; + } } } - - return $title; + + return $instance; } - + /** - * Retrieves the icon to use for widgets / blocks. + * Checks if the current call is a ajax call to get the block content. * - * @return array + * This can be used in your widget to return different content as the block content. + * + * @since 1.0.3 + * @return bool */ - public function get_widget_icon( $icon = 'box-top', $title = '' ) { - if($icon=='box-top'){ - return ''; - }elseif($icon=='box-right'){ - return ''; - }elseif($icon=='box-bottom'){ - return ''; - }elseif($icon=='box-left'){ - return ''; + public function is_block_content_call() { + $result = false; + if ( wp_doing_ajax() && isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'super_duper_output_shortcode' ) { + $result = true; } + + return $result; } - + /** - * Constructs name attributes for use in form() fields - * - * This function should be used in form() methods to create name attributes for fields - * to be saved by update() - * - * @since 2.8.0 - * @since 4.4.0 Array format field names are now accepted. - * - * @param string $field_name Field name. + * Get an instance hash that will be unique to the type and settings. * - * @return string Name attribute for `$field_name`. + * @since 1.0.20 + * @return string */ - public function get_field_name( $field_name ) { - $pos = strpos( $field_name, '[' ); - - if ( false !== $pos ) { - // Replace the first occurrence of '[' with ']['. - $field_name = '[' . substr_replace( $field_name, '][', $pos, strlen( '[' ) ); - } else { - $field_name = '[' . $field_name . ']'; - } - - return 'widget-' . $this->base_id . '[' . $this->get_number() . ']' . $field_name; - } - - public function widget_inputs_row_end($key, $args){ - if(!empty($args['row'])){ - // maybe close - if(!empty($args['row']['close'])){ - echo ""; - } - - echo ""; - } + public function get_instance_hash(){ + $instance_string = $this->base_id.serialize($this->instance); + return hash('crc32b',$instance_string); } - + /** * Generate and return inline styles from CSS rules that will match the unique class of the instance. * @@ -1551,7 +3198,7 @@ public function widget_inputs_row_end($key, $args){ */ public function get_instance_style($rules = array()){ $css = ''; - + if(!empty($rules)){ $rules = array_unique($rules); $instance_hash = $this->get_instance_hash(); @@ -1561,605 +3208,8 @@ public function get_instance_style($rules = array()){ } $css .= ""; } - - return $css; - } - - /** - * Get an instance hash that will be unique to the type and settings. - * - * @since 1.0.20 - * @return string - */ - public function get_instance_hash(){ - $instance_string = $this->base_id . serialize( $this->instance ); - return hash( 'crc32b', $instance_string ); - } - - /** - * Get the conditional fields JavaScript. - * - * @return mixed - */ - public function conditional_fields_js() { - ob_start(); - ?> - - ', '' ), '', trim( $output ) ); - } - - /** - * Output the super title. - * - * @param $args - * @param array $instance - * - * @return string - */ - public function output_title( $args, $instance = array() ) { - $output = ''; - - if ( ! empty( $instance['title'] ) ) { - /** This filter is documented in wp-includes/widgets/class-wp-widget-pages.php */ - $title = apply_filters( 'widget_title', $instance['title'], $instance, $this->base_id ); - - if ( empty( $instance['widget_title_tag'] ) ) { - $output = $args['before_title'] . $title . $args['after_title']; - } else { - $title_tag = esc_attr( $instance['widget_title_tag'] ); - - // classes - $title_classes = array(); - $title_classes[] = !empty( $instance['widget_title_size_class'] ) ? sanitize_html_class( $instance['widget_title_size_class'] ) : ''; - $title_classes[] = !empty( $instance['widget_title_align_class'] ) ? sanitize_html_class( $instance['widget_title_align_class'] ) : ''; - $title_classes[] = !empty( $instance['widget_title_color_class'] ) ? "text-".sanitize_html_class( $instance['widget_title_color_class'] ) : ''; - $title_classes[] = !empty( $instance['widget_title_border_class'] ) ? sanitize_html_class( $instance['widget_title_border_class'] ) : ''; - $title_classes[] = !empty( $instance['widget_title_border_color_class'] ) ? "border-".sanitize_html_class( $instance['widget_title_border_color_class'] ) : ''; - $title_classes[] = !empty( $instance['widget_title_mt_class'] ) ? "mt-".absint( $instance['widget_title_mt_class'] ) : ''; - $title_classes[] = !empty( $instance['widget_title_mr_class'] ) ? "mr-".absint( $instance['widget_title_mr_class'] ) : ''; - $title_classes[] = !empty( $instance['widget_title_mb_class'] ) ? "mb-".absint( $instance['widget_title_mb_class'] ) : ''; - $title_classes[] = !empty( $instance['widget_title_ml_class'] ) ? "ml-".absint( $instance['widget_title_ml_class'] ) : ''; - $title_classes[] = !empty( $instance['widget_title_pt_class'] ) ? "pt-".absint( $instance['widget_title_pt_class'] ) : ''; - $title_classes[] = !empty( $instance['widget_title_pr_class'] ) ? "pr-".absint( $instance['widget_title_pr_class'] ) : ''; - $title_classes[] = !empty( $instance['widget_title_pb_class'] ) ? "pb-".absint( $instance['widget_title_pb_class'] ) : ''; - $title_classes[] = !empty( $instance['widget_title_pl_class'] ) ? "pl-".absint( $instance['widget_title_pl_class'] ) : ''; - $title_classes = array_filter( $title_classes ); - - $class = ! empty( $title_classes ) ? implode( ' ', $title_classes ) : ''; - $output = "<$title_tag class='$class' >$title"; - } - - } - - return $output; - } - - /** - * Backwards compatibility for SDv1 - * - * @param string $editor_id - * @param string $insert_shortcode_function - * - * @return string|void - */ - public static function shortcode_insert_button( $editor_id = '', $insert_shortcode_function = '' ) { - return class_exists('WP_Super_Duper_Shortcode') ? WP_Super_Duper_Shortcode::shortcode_insert_button( $editor_id, $insert_shortcode_function ) : ''; - } - /** - * Backwards compatibility for SDv1 - * - * @param string $id - * @param string $search_for_id - * - * @return mixed|string - */ - public static function shortcode_button( $id = '', $search_for_id = '') { - return class_exists('WP_Super_Duper_Shortcode') ? WP_Super_Duper_Shortcode::shortcode_button( $id, $search_for_id ) : ''; + return $css; } - } - }