JezK
Edit File: skins.php
<?php namespace JET_SM\Elementor; use JET_SM\Plugin; /** * Skins manager class */ // If this file is called directly, abort. if ( ! defined( 'WPINC' ) ) { die; } /** * Define Skins class */ class Skins { private $rendered_skins = array(); /** * Public function */ public function __construct() { $this->editor(); add_action( 'elementor/element/common/_section_attributes/before_section_end', array( $this, 'register_skin_control' ) ); add_action( 'elementor/widget/before_render_content', array( $this, 'set_skin_class' ) ); add_action( 'elementor/editor/after_enqueue_scripts', array( $this, 'localize_skins' ) ); } /** * Print localized skins * * @return [type] [description] */ public function localize_skins() { $script = "var JetSMRenderedSkins = " . wp_json_encode( $this->rendered_skins ) . ';'; printf( "<script type='text/javascript'>\n%s\n</script>\n", $script ); } /** * Set skin class if is set and add widget info to renderd skins * * @param [type] $widget [description] */ public function set_skin_class( $widget ) { $skin_data = $this->add_skin_to_rendered( $widget ); if ( ! empty( $skin_data ) ) { $widget->add_render_attribute( '_wrapper', 'class', array( $skin_data['class_name'] ) ); } } /** * Check if element has skin and add this skin to processed skins * * @param [type] $element [description] */ public function add_skin_to_rendered( $element ) { $skin = $element->get_settings( 'jet_sm_skin' ); $data = array(); if ( $skin ) { $data = array( 'id' => $element->get_id(), 'skin' => $skin, 'widget' => $element->get_name(), 'class_name' => $this->get_skin_class_name( $skin, $element->get_name() ) ); $this->rendered_skins[] = $data; return $data; } else { return false; } } /** * Returns all rendered skins * * @return [type] [description] */ public function get_rendered_skins() { return array_map( 'unserialize', array_unique( array_map( 'serialize', $this->rendered_skins ) ) ); } /** * Register hidden control for skin * * @return [type] [description] */ public function register_skin_control( $widget ) { $widget->add_control( 'jet_sm_skin', array( 'label' => 'Skin', 'type' => \Elementor\Controls_Manager::HIDDEN, 'render_type' => 'none', ) ); } /** * Editor hooks * @return [type] [description] */ public function editor() { add_action( 'elementor/editor/before_enqueue_scripts', array( $this, 'editor_assets' ) ); add_action( 'wp_ajax_jet_sm_save_skin', array( $this, 'save_skin' ) ); add_action( 'wp_ajax_jet_sm_delete_skin', array( $this, 'delete_skin' ) ); add_action( 'wp_ajax_jet_sm_get_skins_for_widget', array( $this, 'get_skins_for_widget' ) ); add_action( 'wp_ajax_jet_sm_apply_skin', array( $this, 'apply_skin' ) ); add_action( 'wp_ajax_jet_sm_load_skins_css', array( $this, 'load_preview_skin_css' ) ); } /** * Load preview CSS * @return [type] [description] */ public function load_preview_skin_css() { if ( ! current_user_can( 'edit_posts' ) ) { wp_send_json_error( array( 'message' => 'You don\'t have permissions to do this' ) ); } $skins = $_REQUEST['skins'] ? $this->sanitize( json_decode( wp_unslash( $_REQUEST['skins'] ), true ) ) : array(); $skins = array_map( function( $item ) { $whitelisted_item = array( 'skin' => $item['skin'], 'widget' => $item['widget'], ); return $whitelisted_item; }, $skins ); $query_relation = 'OR'; $render = new CSS_Render(); ob_start(); $render->render_styles( $skins, false, true, $query_relation ); $render->enqueue_hidden_fonts( $skins, $query_relation ); $css = ob_get_clean(); //$css = str_replace( '.elementor .elementor-inner', '#elementor.elementor .elementor-inner', $css ); wp_send_json_success( array( 'css' => $css, ) ); } /** * Apply skin for selected widget * * @return [type] [description] */ public function apply_skin() { if ( ! current_user_can( 'edit_posts' ) ) { wp_send_json_error( array( 'message' => 'You don\'t have permissions to saving skins' ) ); } $widget = $_REQUEST['widget'] ? sanitize_key( $_REQUEST['widget'] ) : false; $skin = $_REQUEST['name'] ? sanitize_text_field( $_REQUEST['name'] ) : false; $render = new CSS_Render(); ob_start(); $render->render_styles( array( 'widget' => $widget, 'skin' => $skin ), null, true ); $render->enqueue_hidden_fonts( array( 'widget' => $widget, 'skin' => $skin ) ); \Elementor\Plugin::$instance->frontend->print_fonts_links(); $css = ob_get_clean(); wp_send_json_success( array( 'class_name' => $this->get_skin_class_name( $skin, $widget ), 'css' => $css, ) ); } public function get_skin_class_name( $skin, $widget ) { return 'elementor-element-' . $this->get_skin_id( $skin, $widget ); } /** * Returns available skins * * @return [type] [description] */ public function get_skins_for_widget() { if ( ! current_user_can( 'edit_posts' ) ) { wp_send_json_error( array( 'message' => 'You don\'t have permissions to saving skins' ) ); } $widget = $_REQUEST['widget'] ? sanitize_key( $_REQUEST['widget'] ) : false; if ( ! $widget ) { wp_send_json_error( array( 'message' => 'Widget type not found in request' ) ); } $skins = Plugin::instance()->db->query( array( '__select' => 'DISTINCT skin', 'widget' => $widget, ) ); wp_send_json_success( array( 'skins' => $skins ) ); } /** * Delete skin * * @return [type] [description] */ public function delete_skin() { if ( ! current_user_can( 'edit_posts' ) ) { wp_send_json_error( array( 'message' => 'You don\'t have permissions to deleting skins' ) ); } $widget = $_REQUEST['widget'] ? sanitize_key( $_REQUEST['widget'] ) : false; $skin = $_REQUEST['name'] ? sanitize_text_field( $_REQUEST['name'] ) : false; Plugin::instance()->db->delete_row( array( 'widget' => $widget, 'skin' => $skin, ) ); $this->get_skins_for_widget(); } /** * Save skin * * @return [type] [description] */ public function save_skin() { if ( ! current_user_can( 'edit_posts' ) ) { wp_send_json_error( array( 'message' => 'You don\'t have permissions to saving skins' ) ); } $widget = $_REQUEST['widget'] ? sanitize_key( $_REQUEST['widget'] ) : false; $name = $_REQUEST['name'] ? sanitize_text_field( $_REQUEST['name'] ) : false; $settings = $_REQUEST['values'] ? $this->sanitize( json_decode( wp_unslash( $_REQUEST['values'] ), true ) ) : array(); $element_type = \Elementor\Plugin::$instance->widgets_manager->get_widget_types( $widget ); if ( ! $element_type ) { wp_send_json_error( array( 'message' => 'Can\'t find element' ) ); } $element_class = $element_type->get_class_name(); $element_class = '\\' . $element_class; try { $args = array(); $element_data = array( 'id' => $this->get_skin_id( $name, $widget ), 'elType' => 'widget', 'settings' => $settings, 'elements' => array(), 'widgetType' => $widget ); $element = new $element_class( $element_data, $args ); } catch ( \Exception $e ) { wp_send_json_error( array( 'message' => 'Can\'t create element instance' ) ); } try { Plugin::instance()->css_stack->start_new_stack(); Plugin::instance()->css_stack->process_element( null, $element ); Plugin::instance()->css_stack->write_stack_to_db( null, $widget, $name ); } catch ( \Exception $e ) { wp_send_json_error( array( 'message' => 'Can\'t write skin style into database' ) ); } wp_send_json_success(); } public function sanitize( $source = null ) { if ( ! is_array( $source ) ) { return sanitize_textarea_field( $source ); } $result = array(); foreach ( $source as $key => $value ) { switch ( gettype( $value ) ) { case 'array': case 'object': if( ! empty( $value ) ){ $value = $this->sanitize( $value ); } break; default: $value = sanitize_text_field( $value ); break; } $result[ $key ] = $value; } return $result; } /** * Get unique skin ID * * @param [type] $name [description] * @param [type] $widget [description] * @return [type] [description] */ public function get_skin_id( $name, $widget ) { return 'skin-' . substr( md5( $name . $widget ), 0, 12 ); } /** * Load editor assets * * @return [type] [description] */ public function editor_assets() { wp_enqueue_script( 'jet-sm-editor', JET_SM_URL . 'assets/js/editor.js', array(), JET_SM_VERSION . time(), true ); wp_enqueue_style( 'jet-sm-editor', JET_SM_URL . 'assets/css/editor.css', array(), JET_SM_VERSION ); } }