= 0 ) ) ? true : false; if ( 'widgets.php' == $hook || $widgetload ): /* Enqueue Styles */ wp_enqueue_style( 'font-awesome' ); // hybridextend-font-awesome $style_uri = hybridextend_locate_style( HYBRIDEXTEND_CSS . 'admin-widgets' ); wp_enqueue_style( 'hybridext-admin-widgets', $style_uri, array(), HYBRIDEXTEND_VERSION ); /* Enqueue Color Picker Styles */ wp_enqueue_style( 'wp-color-picker' ); /* Enqueue Scripts including color-picker */ // Load admin-widgets in footer to maintain script hierarchy $script_uri = hybridextend_locate_script( HYBRIDEXTEND_JS . 'admin-widgets' ); wp_enqueue_script( 'hybridext-admin-widgets', $script_uri, array( 'jquery', 'wp-color-picker' ), HYBRIDEXTEND_VERSION, true ); /* Enqueues all scripts, styles, settings, and templates necessary to use all media JavaScript APIs. */ wp_enqueue_media(); endif; } add_action( 'admin_enqueue_scripts', 'hybridext_enqueue_admin_widget_styles_scripts' ); } /** * Abstract Widgets Class for creating and displaying widgets. This file is only loaded if the theme supports * the 'hybridextend-widgets' feature. * * @credit() Derived from Vantage theme code by Greg Priday http://SiteOrigin.com * Licensed under GPL * * @since 1.0.0 * @access public */ abstract class HybridExtend_WP_Widget extends WP_Widget { protected $form_options; protected $repeater_html; protected $repeater_html_widgetnumber; protected $is_so = false; protected $widgetid; /** * Register the widget and load the Widget options * * @since 1.0.0 */ function __construct( $id, $name, $widget_options = array(), $control_options = array(), $form_options = array() ) { $this->form_options = $form_options; $this->widgetid = $id; parent::__construct( $id, $name, $widget_options, $control_options ); $this->initialize(); } /** * Initialize this widget in whatever way we need to. Runs before rendering widget or form. * * @since 1.0.0 */ function initialize(){ add_action( 'siteorigin_panels_before_widget_form', array( $this, 'is_so' ), 10, 2 ); } function is_so( $the_widget, $instance ){ $this->is_so = true; } /** * Display the widget. * * @since 1.0.0 * @param array $args * @param array $instance */ function widget( $args, $instance ) { // Backend preview in Legacy_Widget_Block_WP5.8 // @ref https://github.com/WordPress/gutenberg/blob/trunk/docs/how-to-guides/widgets/legacy-widget-block.md // SiteOrigin Page Builder compatibility - Live Preview in backend (gutenberg SO Layout block preview mode) @6.21 if ( is_admin() ) { if ( !empty( $args['widget_name'] ) ) { // If Name (title) is available $widget_name = $args['widget_name']; } elseif ( !empty( $instance['panels_info']['class'] ) ) { // SO Layout block preview mode $widget_name = str_replace( '_', ' ', $instance['panels_info']['class'] ); } else { // Legacy_Widget_Block_WP5.8 $widget_name = ( !empty( $args['before_widget'] ) ) ? str_replace( array( '
' ), '', $args['before_widget'] ) : ''; $widget_name = ( strpos( $widget_name, 'hoot-' ) === 0 ) ? ucwords( str_replace( '-', ' ', $widget_name ) ) : ''; } $widget_name = ( !empty( $widget_name ) ) ? $widget_name : __( 'Hoot Theme Widget', 'hybrid-core' ); /* Translators: The %s are placeholders for HTML, so the order can't be changed. */ printf( esc_html__( '%1$s %3$s %4$sNo preview available.%5$s %2$s', 'hybrid-core' ), '
', '
', '

' . $widget_name . '

', '

', '

' ); return; } $args = wp_parse_args( $args, array( 'before_widget' => '', 'after_widget' => '', 'before_title' => '', 'after_title' => '', ) ); $defaults = array(); foreach( $this->form_options as $option ) { if ( isset( $option['id'] ) ) { $defaults[ $option['id'] ] = ( isset( $option['std'] ) ) ? $option['std'] : ''; } } $instance = wp_parse_args( $instance, $defaults ); global $hybridext_currentwidget; $hybridext_currentwidget = array( 'id' => $this->widgetid, 'widget' => $args, 'instance' => $instance, ); echo $args['before_widget']; $title = ( !empty( $instance['title'] ) ) ? apply_filters( 'widget_title', $instance['title'] ) : ''; $this->display_widget( $instance, $args['before_title'], $title, $args['after_title'] ); echo $args['after_widget']; } /** * Echo the widget content * Subclasses should over-ride this function to generate their widget code. * Convention: Subclasses should include the template from the theme/widgets folder. * * @since 1.0.0 * @param array $args */ function display_widget( $instance, $before_title = '', $title='', $after_title = '' ) { die('function HybridExtend_WP_Widget::display_widget() must be over-ridden in a sub-class.'); } /** * Update the widget instance. * * @param array $new_instance * @param array $old_instance * @return array|void */ public function update( $new_instance, $old_instance ) { $new_instance = $this->sanitize( $new_instance, $this->form_options ); return $new_instance; } /** * Display the widget form. * * @since 1.0.0 * @param array $instance * @return string|void */ public function form( $instance ) { $form_id = 'hybridext-widget-form-' . md5( uniqid( rand(), true ) ); $class_name = str_replace( '_', '-', strtolower( get_class($this) ) ); ?>
widget_options['help'] ) ) : ?>
widget_options['help']; ?>
form_options as $key => $field ) { $field = wp_parse_args( (array) $field, array( 'name' => '', 'desc' => '', 'id' => '', 'type' => '', 'settings' => array(), 'std' => '', 'options' => array(), 'fields' => array(), ) ); if ( empty( $field['id'] ) || empty( $field['type'] ) ) continue; $value = false; if ( isset( $instance[ $field['id'] ] ) ) $value = $instance[ $field['id'] ]; elseif ( !empty( $field['std'] ) ) $value = $field['std']; $this->render_field( $field, $value, false ); } ?> ( function($){ if (typeof window.hybridext_widget_helper == 'undefined') window.hybridext_widget_helper = {}; "] == 'undefined') */ /* // This creates unexpected results as the script is first instancized in template widget __i__ ?> window.hybridext_widget_helper[""] = repeater_html ) // JS receives this as an object ?>; if (typeof $.fn.hybridextSetupWidget != 'undefined') { // console.log('inline calls setup'); $('#').hybridextSetupWidget(); // Needed for Customizer AND when widget is saved in classic widgets screen : now Replaced with widget-added AND widget-updated event triggers respectively in JS } } )( jQuery ); */ ?> // However `hybridextSetupWidget` is still needed for SiteOrigin Page Buuilder if ( !empty( $this->is_so ) ) : ?>repeater_html ) ) : $grpdataset[ get_class($this) ] = true; $groupwgtnumber = ( !empty( $this->repeater_html_widgetnumber ) ) ? $this->repeater_html_widgetnumber : '__i__'; // replaced with widgetnumber ($this->number) passed to JS using data in add button div (fixes bug when groups added to fresh widget did not save) since [widgetnumber] values in input ids were incorrect ?>
repeater_html ) ) // $.data('grouphtml') converts < to < and so on... ?>' data-groupwgtnumber="" style="display:none;">
/>
{$name}"; break; case 'checkbox': ?>
$s_title ) { ?>

$i_class ) { $selected = ( $iconvalue == $i_class ) ? ' selected' : ''; ?>
>
/>

$v ) { $this->render_group( $k, $v, $fields, $item_name, $repeater ); if ( !empty( $maxlimitcheck ) && $groupcount >= $maxlimitcheck ) break; else $groupcount++; } } else $maxlimitcheck = 0; ?>
number; /** * replace with $this->number passed to JS (fixes bug when groups added to fresh widget did not save) * since [widgetnumber] values in input ids were incorrect * UPDATE: use $this->repeater_html_widgetnumber instead to be compatible with SiteOrigin * since SO "Convert the widget field naming into ones that Page Builder uses" in SiteOrigin_Panels_Admin::render_form * which makes the group items not save.. * Eg: SO changes `widget-hootkit-icon-list[14][items][1][text]` to `widgets[c39][items][1][text]` * 14 and c39 are dummy widget numbers - changing 14 to 246813579 wont let SO pregmatch * widget-hootkit-icon-list[14] (which gets converted to widgets[c39]) */ // $this->number = 246813579; $this->render_group( 975318642, array(), $fields, $item_name, $repeater ); // $this->number = $cache; $html = ob_get_clean(); $this->repeater_html[$id] = $html; $this->repeater_html_widgetnumber = $this->number; $maxlimit = ( isset( $options['maxlimit'] ) ) ? ' data-limit="' . absint( $options['maxlimit'] ) . '"' : ''; $limitmsg = ( isset( $options['limitmsg'] ) ) ? ' data-limitmsg="' . esc_attr( $options['limitmsg'] ) . '"' : ''; ?>
>

> '', 'desc' => '', 'id' => '', 'type' => '', 'settings' => array(), 'std' => '', 'options' => array(), 'fields' => array(), ) ); $fieldvalue = false; if ( isset( $value[ $field['id'] ] ) ) $fieldvalue = $value[ $field['id'] ]; elseif ( !empty( $field['std'] ) ) $fieldvalue = $field['std']; $this->render_field( $field, $fieldvalue, $repeater ); } ?>
hybridext_get_field_id( $id, $repeater ), 'hybridext-widget-input', $this->hybridext_get_field_name( $id, $repeater ), $value ), $type ); break; } if ( ! empty( $desc ) ) echo '
' . wp_kses_post( $desc ) . '
'; echo '
'; ?>
X

'', 'desc' => '', 'id' => '', 'type' => '', 'settings' => array(), 'std' => '', 'options' => array(), 'fields' => array(), ) ); $fieldvalue = isset( $value[ $field['id'] ] ) ? $value[ $field['id'] ] : false; $fieldvalue = ( !$fieldvalue && !empty( $field['std'] ) ) ? $field['std'] : $fieldvalue; $this->render_field( $field, $fieldvalue, $repeater ); } ?>
get_field_name( $id ); else { $repeater_extras = ''; foreach( $repeater as $r ) $repeater_extras .= '[' . $r . ']'; $repeater_extras .= '[' . esc_attr( $id ) . ']'; $name = $this->get_field_name('{{{FIELD_NAME}}}'); $name = str_replace( '[{{{FIELD_NAME}}}]', $repeater_extras, $name ); return $name; } } /** * Get the ID of this field. * * @since 1.0.0 * @param $id * @param array $repeater * @return string */ public function hybridext_get_field_id( $id, $repeater = array() ) { if ( empty( $repeater ) ) return $this->get_field_id( $id ); else { $ids = $repeater; $ids[] = $id; return $this->get_field_id( implode( '-', $ids ) ); } } /** * Sanitize field values to store in database * * @since 1.1.7 * @param $instance * @param $fields */ public function sanitize( $instance, $fields ) { foreach ( $fields as $field ) { /* Skip if the field does not have an id/type */ if ( !isset( $field['id'] ) || !isset( $field['type'] ) ) continue; /* Skip if instance value is not set (except for checkbox) */ $id = $field['id']; if ( !isset( $instance[ $id ] ) && $field['type'] != 'checkbox' ) continue; /* Sanitize field values */ switch ( $field['type'] ) { case 'textarea': global $allowedposttags; $instance[ $id ] = wp_kses( $instance[ $id ], $allowedposttags); break; case 'checkbox': $instance[ $id ] = ( !empty( $instance[ $id ] ) ) ? 1 : 0; break; case 'select': case 'radio': case 'images': $instance[ $id ] = ( isset( $field['options'][ $instance[ $id ] ] ) ) ? $instance[ $id ] : ''; break; case 'icon': $icons = hybridextend_enum_icons(); $instance[ $id ] = ( in_array( $instance[ $id ], $icons ) ) ? $instance[ $id ] : ''; break; case 'group': foreach ( $instance[ $id ] as $i => $subinstance ) { $instance[ $id ][ $i ] = $this->sanitize( $subinstance, $field['fields'] ); } break; case 'collapse': $instance[$id] = $this->sanitize( $instance[$id], $field['fields'] ); break; } /* Custom sanitizations for specific field. Example, a text input has a url */ if ( isset( $field['sanitize'] ) ) { switch( $field['sanitize'] ) { case 'url': $instance[ $id ] = esc_url_raw( $instance[ $id ] ); break; case 'integer': if ( $instance[ $id ] !== '0' && $instance[ $id ] !== 0 ) { $instance[ $id ] = intval( $instance[ $id ] ); $instance[ $id ] = ( !empty( $instance[ $id ] ) ) ? $instance[ $id ] : ''; } break; case 'absint': if ( $instance[ $id ] !== '0' && $instance[ $id ] !== 0 ) { $instance[ $id ] = absint( $instance[ $id ] ); $instance[ $id ] = ( !empty( $instance[ $id ] ) ) ? $instance[ $id ] : ''; } break; case 'email': $instance[ $id ] = ( is_email( $instance[ $id ] ) ) ? sanitize_email( $instance[ $id ] ) : ''; break; // Allow custom sanitization functions default: $instance[ $id ] = apply_filters( 'widget_admin_sanitize_field', $instance[ $id ], $field['sanitize'], $instance ); } } } return $instance; } /** * Helper function to get a list for option values * * @since 1.0.0 * @param $post_type * @param $number Set to -1 to show all * @see: http://codex.wordpress.org/Class_Reference/WP_Query#Pagination_Parameters * @return array */ // @todo more post types and taxonomies static function get_wp_list( $post_type = 'page', $number = false ) { $number = intval( $number ); if ( false === $number || empty( $number ) ) { $number = HYBRIDEXTEND_ADMIN_LIST_ITEM_COUNT; if ( $post_type == 'page' ) { static $options_pages = array(); // cache if ( empty( $options_pages ) ) $options_pages = self::get_pages( $number ); return $options_pages; } } else { if ( $post_type == 'page' ) { $pages = self::get_pages( $number ); return $pages; } } } /** * Helper function to get a list of taxonomies * * @since 1.1.1 * @param $taxonomy * @return array */ static function get_tax_list( $taxonomy = 'category' ) { static $options_tax = array(); // cache if ( empty( $options_tax[ $taxonomy ] ) ) { $options_tax[ $taxonomy ] = array(); $object = (array) get_terms( array( 'taxonomy' => $taxonomy ) ); foreach ( $object as $term ) $options_tax[ $taxonomy ][$term->term_id] = $term->name; } return $options_tax[ $taxonomy ]; } /** * Get pages array * * @since 1.0.0 * @param int $number Set to -1 for all pages * @param string $post_type for custom post types * @return array */ static function get_pages( $number, $post_type = 'page' ){ // Doesnt allow -1 as $number // $options_pages_obj = get_pages("sort_column=post_parent,menu_order&number=$number"); // $options_pages[''] = __( 'Select a page:', 'hybrid-core' ); $options_pages = array(); $number = intval( $number ); $the_query = new WP_Query( array( 'post_type' => $post_type, 'posts_per_page' => $number, 'orderby' => 'post_title', 'order' => 'ASC' ) ); // Prietable plugin (wpalchemy) bug compatibility: We cannot run a custom loop (with // $the_query->the_post() ) since this will set global $post (initially empty before looping // through custom query). Even wp_reset_postdata() doesnt set global $post back to empty // wpalchemy uses global $post->ID, and hence gets the ID of last page instead of empty (at // a later hook, it would have got its easy table's post ID) // All this happens in Metabox.php file in easy-pricing-tables (hooked to 'admin_init' at 10) // if ( $the_query->have_posts() ) : // while ( $the_query->have_posts() ) : $the_query->the_post(); // $options_pages[ get_the_ID() ] = get_the_title(); // endwhile; // wp_reset_postdata(); // endif; if ( !empty( $the_query->posts ) ) foreach ( $the_query->posts as $post ) if( !empty( $post->ID ) ) $options_pages[ $post->ID ] = ( empty( $post->post_title ) ) ? '' : apply_filters( 'the_title', $post->post_title, $post->ID ); return $options_pages; } } /* Loads all available widget classes for the theme. */ hybridext_load_widgets();