File manager - Edit - /home/theblueo/tv/fb4e3b/files.tar
Back
base.php 0000666 00000012562 15214027777 0006215 0 ustar 00 <?php namespace Elementor\Core\Files; use Elementor\Plugin; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly } abstract class Base { const UPLOADS_DIR = 'elementor/'; const DEFAULT_FILES_DIR = 'css/'; const META_KEY = ''; private static $wp_uploads_dir = []; private $files_dir; private $file_name; /** * File path. * * Holds the file path. * * @access private * * @var string */ private $path; /** * Content. * * Holds the file content. * * @access private * * @var string */ private $content; /** * @since 2.1.0 * @access public * @static */ public static function get_base_uploads_dir() { $wp_upload_dir = self::get_wp_uploads_dir(); return $wp_upload_dir['basedir'] . '/' . self::UPLOADS_DIR; } /** * @since 2.1.0 * @access public * @static */ public static function get_base_uploads_url() { $wp_upload_dir = self::get_wp_uploads_dir(); return $wp_upload_dir['baseurl'] . '/' . self::UPLOADS_DIR; } /** * Use a create function for PhpDoc (@return static). * * @return static */ public static function create() { return Plugin::$instance->files_manager->get( get_called_class(), func_get_args() ); } /** * @since 2.1.0 * @access public */ public function __construct( $file_name ) { /** * Elementor File Name * * Filters the File name * * @since 2.3.0 * * @param string $file_name * @param object $this The file instance, which inherits Elementor\Core\Files */ $file_name = apply_filters( 'elementor/files/file_name', $file_name, $this ); $this->set_file_name( $file_name ); $this->set_files_dir( static::DEFAULT_FILES_DIR ); $this->set_path(); } /** * @since 2.1.0 * @access public */ public function set_files_dir( $files_dir ) { $this->files_dir = $files_dir; } /** * @since 2.1.0 * @access public */ public function set_file_name( $file_name ) { $this->file_name = $file_name; } /** * @since 2.1.0 * @access public */ public function get_file_name() { return $this->file_name; } /** * @since 2.1.0 * @access public */ public function get_url() { $url = set_url_scheme( self::get_base_uploads_url() . $this->files_dir . $this->file_name ); return add_query_arg( [ 'ver' => $this->get_meta( 'time' ) ], $url ); } /** * @since 2.1.0 * @access public */ public function get_content() { if ( ! $this->content ) { $this->content = $this->parse_content(); } return $this->content; } /** * @since 2.1.0 * @access public */ public function update() { $this->update_file(); $meta = $this->get_meta(); $meta['time'] = time(); $this->update_meta( $meta ); } /** * @since 2.1.0 * @access public */ public function update_file() { $this->content = $this->parse_content(); if ( $this->content ) { $this->write(); } else { $this->delete(); } } /** * @since 2.1.0 * @access public */ public function write() { return file_put_contents( $this->path, $this->content ); } /** * @since 2.1.0 * @access public */ public function delete() { if ( file_exists( $this->path ) ) { unlink( $this->path ); } $this->delete_meta(); } /** * Get meta data. * * Retrieve the CSS file meta data. Returns an array of all the data, or if * custom property is given it will return the property value, or `null` if * the property does not exist. * * @since 2.1.0 * @access public * * @param string $property Optional. Custom meta data property. Default is * null. * * @return array|null An array of all the data, or if custom property is * given it will return the property value, or `null` if * the property does not exist. */ public function get_meta( $property = null ) { $default_meta = $this->get_default_meta(); $meta = array_merge( $default_meta, (array) $this->load_meta() ); if ( $property ) { return isset( $meta[ $property ] ) ? $meta[ $property ] : null; } return $meta; } /** * @since 2.1.0 * @access protected * @abstract */ abstract protected function parse_content(); /** * Load meta. * * Retrieve the file meta data. * * @since 2.1.0 * @access protected */ protected function load_meta() { return get_option( static::META_KEY ); } /** * Update meta. * * Update the file meta data. * * @since 2.1.0 * @access protected * * @param array $meta New meta data. */ protected function update_meta( $meta ) { update_option( static::META_KEY, $meta ); } /** * Delete meta. * * Delete the file meta data. * * @since 2.1.0 * @access protected */ protected function delete_meta() { delete_option( static::META_KEY ); } /** * @since 2.1.0 * @access protected */ protected function get_default_meta() { return [ 'time' => 0, ]; } /** * @since 2.1.0 * @access private * @static */ private static function get_wp_uploads_dir() { global $blog_id; if ( empty( self::$wp_uploads_dir[ $blog_id ] ) ) { self::$wp_uploads_dir[ $blog_id ] = wp_upload_dir( null, false ); } return self::$wp_uploads_dir[ $blog_id ]; } /** * @since 2.1.0 * @access private */ private function set_path() { $dir_path = self::get_base_uploads_dir() . $this->files_dir; if ( ! is_dir( $dir_path ) ) { wp_mkdir_p( $dir_path ); } $this->path = $dir_path . $this->file_name; } } manager.php 0000666 00000005714 15214027777 0006716 0 ustar 00 <?php namespace Elementor\Core\Files; use Elementor\Core\Files\CSS\Global_CSS; use Elementor\Core\Files\CSS\Post as Post_CSS; use Elementor\Core\Files\Svg\Svg_Handler; use Elementor\Core\Responsive\Files\Frontend; use Elementor\Utils; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } /** * Elementor files manager. * * Elementor files manager handler class is responsible for creating files. * * @since 1.2.0 */ class Manager { private $files = []; /** * Files manager constructor. * * Initializing the Elementor files manager. * * @since 1.2.0 * @access public */ public function __construct() { $this->register_actions(); } public function get( $class, $args ) { $id = $class . '-' . wp_json_encode( $args ); if ( ! isset( $this->files[ $id ] ) ) { // Create an instance from dynamic args length. $reflection_class = new \ReflectionClass( $class ); $this->files[ $id ] = $reflection_class->newInstanceArgs( $args ); } return $this->files[ $id ]; } /** * On post delete. * * Delete post CSS immediately after a post is deleted from the database. * * Fired by `deleted_post` action. * * @since 1.2.0 * @access public * * @param string $post_id Post ID. */ public function on_delete_post( $post_id ) { if ( ! Utils::is_post_support( $post_id ) ) { return; } $css_file = Post_CSS::create( $post_id ); $css_file->delete(); } /** * On export post meta. * * When exporting data using WXR, skip post CSS file meta key. This way the * export won't contain the post CSS file data used by Elementor. * * Fired by `wxr_export_skip_postmeta` filter. * * @since 1.2.0 * @access public * * @param bool $skip Whether to skip the current post meta. * @param string $meta_key Current meta key. * * @return bool Whether to skip the post CSS meta. */ public function on_export_post_meta( $skip, $meta_key ) { if ( Post_CSS::META_KEY === $meta_key ) { $skip = true; } return $skip; } /** * Clear cache. * * Delete all meta containing files data. And delete the actual * files from the upload directory. * * @since 1.2.0 * @access public */ public function clear_cache() { delete_post_meta_by_key( Post_CSS::META_KEY ); delete_option( Global_CSS::META_KEY ); delete_option( Frontend::META_KEY ); // Delete files. $path = Base::get_base_uploads_dir() . Base::DEFAULT_FILES_DIR . '*'; foreach ( glob( $path ) as $file_path ) { unlink( $file_path ); } /** * Elementor clear files. * * Fires after Elementor clears files * * @since 2.1.0 */ do_action( 'elementor/core/files/clear_cache' ); } /** * Register actions. * * Register filters and actions for the files manager. * * @since 1.2.0 * @access private */ private function register_actions() { add_action( 'deleted_post', [ $this, 'on_delete_post' ] ); add_filter( 'wxr_export_skip_postmeta', [ $this, 'on_export_post_meta' ], 10, 2 ); } } assets/svg/svg-handler.php 0000666 00000040775 15214027777 0011625 0 ustar 00 <?php namespace Elementor\Core\Files\Assets\Svg; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } class Svg_Handler { /** * Inline svg attachment meta key */ const META_KEY = '_elementor_inline_svg'; const MIME_TYPE = 'image/svg+xml'; const SCRIPT_REGEX = '/(?:\w+script|data):/xi'; /** * @var \DOMDocument */ private $svg_dom = null; /** * Attachment ID. * * Holds the current attachment ID. * * @var int */ private $attachment_id; public static function get_name() { return 'svg-handler'; } /** * @return bool */ public static function is_svg_uploads_enabled() { return ! ! get_option( 'elementor_allow_svg', false ); } /** * svg_sanitizer_can_run * @return bool */ public static function svg_sanitizer_can_run() { return class_exists( 'DOMDocument' ) && class_exists( 'SimpleXMLElement' ); } /** * set_attachment_id * @param $attachment_id * * @return int */ public function set_attachment_id( $attachment_id ) { $this->attachment_id = $attachment_id; return $this->attachment_id; } /** * get_attachment_id * @return int */ public function get_attachment_id() { return $this->attachment_id; } /** * get_meta * @return mixed */ protected function get_meta() { return get_post_meta( $this->attachment_id, self::META_KEY, true ); } /** * update_meta * @param $meta */ protected function update_meta( $meta ) { update_post_meta( $this->attachment_id, self::META_KEY, $meta ); } /** * delete_meta */ protected function delete_meta() { delete_post_meta( $this->attachment_id, self::META_KEY ); } /** * delete_meta_cache */ public function delete_meta_cache() { delete_post_meta_by_key( self::META_KEY ); } /** * read_from_file * @return bool|string */ public function read_from_file() { return file_get_contents( get_attached_file( $this->attachment_id ) ); } /** * get_inline_svg * @param $attachment_id * * @return bool|mixed|string */ public static function get_inline_svg( $attachment_id ) { $svg = get_post_meta( $attachment_id, self::META_KEY, true ); if ( ! empty( $svg ) ) { return $svg; } $attachment_file = get_attached_file( $attachment_id ); if ( ! $attachment_file ) { return ''; } $svg = file_get_contents( $attachment_file ); if ( ! empty( $svg ) ) { update_post_meta( $attachment_id, self::META_KEY, $svg ); } return $svg; } public function upload_mimes( $allowed_types ) { if ( $this->is_elementor_media_upload() ) { $allowed_types['svg'] = self::MIME_TYPE; } return $allowed_types; } /** * wp_handle_upload_prefilter * @param $file * * @return mixed */ public function wp_handle_upload_prefilter( $file ) { if ( ! $this->is_elementor_media_upload() || self::MIME_TYPE !== $file['type'] ) { return $file; } $ext = pathinfo( $file['name'], PATHINFO_EXTENSION ); if ( 'svg' !== $ext ) { $file['error'] = sprintf( __( 'The uploaded %s file is not supported. Please upload a valid SVG file', 'elementor' ), $ext ); return $file; } if ( ! self::is_enabled() ) { $file['error'] = __( 'SVG file is not allowed for security reasons', 'elementor' ); return $file; } if ( self::svg_sanitizer_can_run() && ! $this->sanitize_svg( $file['tmp_name'] ) ) { $file['error'] = __( 'Invalid SVG Format, file not uploaded for security reasons', 'elementor' ); } return $file; } /** * is_elementor_media_upload * @return bool */ private function is_elementor_media_upload() { return isset( $_POST['uploadTypeCaller'] ) && 'elementor-editor-upload' === $_POST['uploadTypeCaller']; // phpcs:ignore } /** * wp_check_filetype_and_ext * A workaround for upload validation which relies on a PHP extension (fileinfo) * with inconsistent reporting behaviour. * ref: https://core.trac.wordpress.org/ticket/39550 * ref: https://core.trac.wordpress.org/ticket/40175 * * @param $data * @param $file * @param $filename * @param $mimes * * @return mixed */ public function wp_check_filetype_and_ext( $data, $file, $filename, $mimes ) { if ( ! empty( $data['ext'] ) && ! empty( $data['type'] ) ) { return $data; } $filetype = wp_check_filetype( $filename, $mimes ); if ( 'svg' === $filetype['ext'] ) { $data['ext'] = 'svg'; $data['type'] = self::MIME_TYPE; } return $data; } /** * Check if the contents are gzipped * @see http://www.gzip.org/zlib/rfc-gzip.html#member-format * * @param $contents * @return bool */ private function is_encoded( $contents ) { $needle = "\x1f\x8b\x08"; if ( function_exists( 'mb_strpos' ) ) { return 0 === mb_strpos( $contents, $needle ); } else { return 0 === strpos( $contents, $needle ); } } /** * decode_svg * @param $content * * @return string */ private function decode_svg( $content ) { return gzdecode( $content ); } /** * encode_svg * @param $content * * @return string */ private function encode_svg( $content ) { return gzencode( $content ); } /** * sanitize_svg * @param $filename * * @return bool */ public function sanitize_svg( $filename ) { $original_content = file_get_contents( $filename ); $is_encoded = $this->is_encoded( $original_content ); if ( $is_encoded ) { $decoded = $this->decode_svg( $original_content ); if ( false === $decoded ) { return false; } $original_content = $decoded; } $valid_svg = $this->sanitizer( $original_content ); if ( false === $valid_svg ) { return false; } // If we were gzipped, we need to re-zip if ( $is_encoded ) { $valid_svg = $this->encode_svg( $valid_svg ); } file_put_contents( $filename, $valid_svg ); return true; } /** * is_allowed_tag * @param $element * * @return bool */ private function is_allowed_tag( $element ) { static $allowed_tags = false; if ( false === $allowed_tags ) { $allowed_tags = $this->get_allowed_elements(); } $tag_name = $element->tagName; // phpcs:ignore -- php DomDocument if ( ! in_array( strtolower( $tag_name ), $allowed_tags ) ) { $this->remove_element( $element ); return false; } return true; } private function remove_element( $element ) { $element->parentNode->removeChild( $element ); // phpcs:ignore -- php DomDocument } /** * is_a_attribute * @param $name * @param $check * * @return bool */ private function is_a_attribute( $name, $check ) { return 0 === strpos( $name, $check . '-' ); } /** * is_remote_value * @param $value * * @return string */ private function is_remote_value( $value ) { $value = trim( preg_replace( '/[^ -~]/xu', '', $value ) ); $wrapped_in_url = preg_match( '~^url\(\s*[\'"]\s*(.*)\s*[\'"]\s*\)$~xi', $value, $match ); if ( ! $wrapped_in_url ) { return false; } $value = trim( $match[1], '\'"' ); return preg_match( '~^((https?|ftp|file):)?//~xi', $value ); } /** * has_js_value * @param $value * * @return false|int */ private function has_js_value( $value ) { return preg_match( '/base64|data|(?:java)?script|alert\(|window\.|document/i', $value ); } /** * get_allowed_attributes * @return array */ private function get_allowed_attributes() { $allowed_attributes = [ 'class', 'clip-path', 'clip-rule', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'id', 'mask', 'opacity', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'style', 'systemlanguage', 'transform', 'href', 'xlink:href', 'xlink:title', 'cx', 'cy', 'r', 'requiredfeatures', 'clippathunits', 'type', 'rx', 'ry', 'color-interpolation-filters', 'stddeviation', 'filterres', 'filterunits', 'height', 'primitiveunits', 'width', 'x', 'y', 'font-size', 'display', 'font-family', 'font-style', 'font-weight', 'text-anchor', 'marker-end', 'marker-mid', 'marker-start', 'x1', 'x2', 'y1', 'y2', 'gradienttransform', 'gradientunits', 'spreadmethod', 'markerheight', 'markerunits', 'markerwidth', 'orient', 'preserveaspectratio', 'refx', 'refy', 'viewbox', 'maskcontentunits', 'maskunits', 'd', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'fx', 'fy', 'offset', 'stop-color', 'stop-opacity', 'xmlns', 'xmlns:se', 'xmlns:xlink', 'xml:space', 'method', 'spacing', 'startoffset', 'dx', 'dy', 'rotate', 'textlength', ]; return apply_filters( 'elementor/files/svg/allowed_attributes', $allowed_attributes ); } /** * get_allowed_elements * @return array */ private function get_allowed_elements() { $allowed_elements = [ 'a', 'circle', 'clippath', 'defs', 'style', 'desc', 'ellipse', 'fegaussianblur', 'filter', 'foreignobject', 'g', 'image', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'svg', 'switch', 'symbol', 'text', 'textpath', 'title', 'tspan', 'use', ]; return apply_filters( 'elementor/files/svg/allowed_elements', $allowed_elements ); } /** * validate_allowed_attributes * @param \DOMElement $element */ private function validate_allowed_attributes( $element ) { static $allowed_attributes = false; if ( false === $allowed_attributes ) { $allowed_attributes = $this->get_allowed_attributes(); } for ( $index = $element->attributes->length - 1; $index >= 0; $index-- ) { // get attribute name $attr_name = $element->attributes->item( $index )->name; $attr_name_lowercase = strtolower( $attr_name ); // Remove attribute if not in whitelist if ( ! in_array( $attr_name_lowercase, $allowed_attributes ) && ! $this->is_a_attribute( $attr_name_lowercase, 'aria' ) && ! $this->is_a_attribute( $attr_name_lowercase, 'data' ) ) { $element->removeAttribute( $attr_name ); continue; } $attr_value = $element->attributes->item( $index )->value; // Remove attribute if it has a remote reference or js or data-URI/base64 if ( ! empty( $attr_value ) && ( $this->is_remote_value( $attr_value ) || $this->has_js_value( $attr_value ) ) ) { $element->removeAttribute( $attr_name ); continue; } } } /** * strip_xlinks * @param \DOMElement $element */ private function strip_xlinks( $element ) { $xlinks = $element->getAttributeNS( 'http://www.w3.org/1999/xlink', 'href' ); if ( ! $xlinks ) { return; } $allowed_links = [ 'data:image/png', // PNG 'data:image/gif', // GIF 'data:image/jpg', // JPG 'data:image/jpe', // JPEG 'data:image/pjp', // PJPEG ]; if ( 1 === preg_match( self::SCRIPT_REGEX, $xlinks ) ) { if ( ! in_array( substr( $xlinks, 0, 14 ), $allowed_links ) ) { $element->removeAttributeNS( 'http://www.w3.org/1999/xlink', 'href' ); } } } /** * validate_use_tag * @param $element */ private function validate_use_tag( $element ) { $xlinks = $element->getAttributeNS( 'http://www.w3.org/1999/xlink', 'href' ); if ( $xlinks && '#' !== substr( $xlinks, 0, 1 ) ) { $element->parentNode->removeChild( $element ); // phpcs:ignore -- php DomNode } } /** * strip_docktype */ private function strip_doctype() { foreach ( $this->svg_dom->childNodes as $child ) { if ( XML_DOCUMENT_TYPE_NODE === $child->nodeType ) { // phpcs:ignore -- php DomDocument $child->parentNode->removeChild( $child ); // phpcs:ignore -- php DomDocument } } } /** * strip_php_tags * @param $string * * @return string */ private function strip_php_tags( $string ) { $string = preg_replace( '/<\?(=|php)(.+?)\?>/i', '', $string ); // Remove XML, ASP, etc. $string = preg_replace( '/<\?(.*)\?>/Us', '', $string ); $string = preg_replace( '/<\%(.*)\%>/Us', '', $string ); if ( ( false !== strpos( $string, '<?' ) ) || ( false !== strpos( $string, '<%' ) ) ) { return ''; } return $string; } /** * strip_comments * @param $string * * @return string */ private function strip_comments( $string ) { // Remove comments. $string = preg_replace( '/<!--(.*)-->/Us', '', $string ); $string = preg_replace( '/\/\*(.*)\*\//Us', '', $string ); if ( ( false !== strpos( $string, '<!--' ) ) || ( false !== strpos( $string, '/*' ) ) ) { return ''; } return $string; } /** * sanitize_elements */ private function sanitize_elements() { $elements = $this->svg_dom->getElementsByTagName( '*' ); // loop through all elements // we do this backwards so we don't skip anything if we delete a node // see comments at: http://php.net/manual/en/class.domnamednodemap.php for ( $index = $elements->length - 1; $index >= 0; $index-- ) { /** * @var \DOMElement $current_element */ $current_element = $elements->item( $index ); // If the tag isn't in the whitelist, remove it and continue with next iteration if ( ! $this->is_allowed_tag( $current_element ) ) { continue; } //validate element attributes $this->validate_allowed_attributes( $current_element ); $this->strip_xlinks( $current_element ); if ( 'use' === strtolower( $current_element->tagName ) ) { // phpcs:ignore -- php DomDocument $this->validate_use_tag( $current_element ); } } } /** * sanitizer * @param $content * * @return bool|string */ public function sanitizer( $content ) { // Strip php tags $content = $this->strip_comments( $content ); $content = $this->strip_php_tags( $content ); // Find the start and end tags so we can cut out miscellaneous garbage. $start = strpos( $content, '<svg' ); $end = strrpos( $content, '</svg>' ); if ( false === $start || false === $end ) { return false; } $content = substr( $content, $start, ( $end - $start + 6 ) ); // Make sure to Disable the ability to load external entities $libxml_disable_entity_loader = libxml_disable_entity_loader( true ); // Suppress the errors $libxml_use_internal_errors = libxml_use_internal_errors( true ); // Create DomDocument instance $this->svg_dom = new \DOMDocument(); $this->svg_dom->formatOutput = false; $this->svg_dom->preserveWhiteSpace = false; $this->svg_dom->strictErrorChecking = false; $open_svg = $this->svg_dom->loadXML( $content ); if ( ! $open_svg ) { return false; } $this->strip_doctype(); $this->sanitize_elements(); // Export sanitized svg to string // Using documentElement to strip out <?xml version="1.0" encoding="UTF-8"... $sanitized = $this->svg_dom->saveXML( $this->svg_dom->documentElement, LIBXML_NOEMPTYTAG ); // Restore defaults libxml_disable_entity_loader( $libxml_disable_entity_loader ); libxml_use_internal_errors( $libxml_use_internal_errors ); return $sanitized; } /** * wp_prepare_attachment_for_js * @param $attachment_data * @param $attachment * @param $meta * * @return mixed */ public function wp_prepare_attachment_for_js( $attachment_data, $attachment, $meta ) { if ( 'image' !== $attachment_data['type'] || 'svg+xml' !== $attachment_data['subtype'] || ! class_exists( 'SimpleXMLElement' ) ) { return $attachment_data; } $svg = self::get_inline_svg( $attachment->ID ); if ( ! $svg ) { return $attachment_data; } try { $svg = new \SimpleXMLElement( $svg ); } catch ( \Exception $e ) { return $attachment_data; } $src = $attachment_data['url']; $width = (int) $svg['width']; $height = (int) $svg['height']; // Media Gallery $attachment_data['image'] = compact( 'src', 'width', 'height' ); $attachment_data['thumb'] = compact( 'src', 'width', 'height' ); // Single Details of Image $attachment_data['sizes']['full'] = [ 'height' => $height, 'width' => $width, 'url' => $src, 'orientation' => $height > $width ? 'portrait' : 'landscape', ]; return $attachment_data; } public static function is_enabled() { static $enabled = null; if ( null === $enabled ) { $enabled = self::is_svg_uploads_enabled() && self::svg_sanitizer_can_run(); $enabled = apply_filters( 'elementor/files/svg/enabled', $enabled ); } return $enabled; } /** * Svg_Handler constructor. */ public function __construct() { add_filter( 'upload_mimes', [ $this, 'upload_mimes' ] ); add_filter( 'wp_handle_upload_prefilter', [ $this, 'wp_handle_upload_prefilter' ] ); add_filter( 'wp_check_filetype_and_ext', [ $this, 'wp_check_filetype_and_ext' ], 10, 4 ); add_filter( 'wp_prepare_attachment_for_js', [ $this, 'wp_prepare_attachment_for_js' ], 10, 3 ); add_action( 'elementor/core/files/clear_cache', [ $this, 'delete_meta_cache' ] ); } } assets/manager.php 0000666 00000002325 15214027777 0010213 0 ustar 00 <?php namespace Elementor\Core\Files\Assets; use Elementor\Core\Files\Assets\Svg\Svg_Handler; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } /** * Elementor files manager. * * Elementor files manager handler class is responsible for creating files. * * @since 2.6.0 */ class Manager { /** * Holds registered asset types * @var array */ protected $asset_types = []; /** * Assets manager constructor. * * Initializing the Elementor assets manager. * * @access public */ public function __construct() { $this->register_asset_types(); /** * Elementor files assets registered. * * Fires after Elementor registers assets types * * @since 2.6.0 */ do_action( 'elementor/core/files/assets/assets_registered', $this ); } public function get_asset( $name ) { return isset( $this->asset_types[ $name ] ) ? $this->asset_types[ $name ] : false; } /** * Add Asset * @param $instance */ public function add_asset( $instance ) { $this->asset_types[ $instance::get_name() ] = $instance; } /** * Register Asset Types * * Registers Elementor Asset Types */ private function register_asset_types() { $this->add_asset( new Svg_Handler() ); } } css/post-preview.php 0000666 00000004267 15214027777 0010542 0 ustar 00 <?php namespace Elementor\Core\Files\CSS; use Elementor\Plugin; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } /** * Elementor post preview CSS file. * * Elementor CSS file handler class is responsible for generating the post * preview CSS file. * * @since 1.9.0 */ class Post_Preview extends Post { /** * Preview ID. * * Holds the ID of the current post being previewed. * * @var int */ private $preview_id; /** * Post preview CSS file constructor. * * Initializing the CSS file of the post preview. Set the post ID and the * parent ID and initiate the stylesheet. * * @since 1.9.0 * @access public * * @param int $post_id Post ID. */ public function __construct( $post_id ) { $this->preview_id = $post_id; $parent_id = wp_get_post_parent_id( $post_id ); parent::__construct( $parent_id ); } /** * @since 2.1.0 * @access public */ public function get_preview_id() { return $this->preview_id; } /** * Get data. * * Retrieve raw post data from the database. * * @since 1.9.0 * @access protected * * @return array Post data. */ protected function get_data() { $document = Plugin::$instance->documents->get( $this->preview_id ); return $document ? $document->get_elements_data() : []; } /** * Get file handle ID. * * Retrieve the handle ID for the previewed post CSS file. * * @since 1.9.0 * @access protected * * @return string CSS file handle ID. */ protected function get_file_handle_id() { return 'elementor-preview-' . $this->preview_id; } /** * Get meta data. * * Retrieve the previewed post CSS file meta data. * * @since 1.9.0 * @access public * * @param string $property Optional. Custom meta data property. Default is * null. * * @return array Previewed post CSS file meta data. */ public function get_meta( $property = null ) { // Parse CSS first, to get the fonts list. $css = $this->get_content(); $meta = [ 'status' => self::CSS_STATUS_INLINE, 'fonts' => $this->get_fonts(), 'css' => $css, ]; if ( $property ) { return isset( $meta[ $property ] ) ? $meta[ $property ] : null; } return $meta; } } css/base.php 0000666 00000045515 15214027777 0007011 0 ustar 00 <?php namespace Elementor\Core\Files\CSS; use Elementor\Base_Data_Control; use Elementor\Controls_Manager; use Elementor\Controls_Stack; use Elementor\Core\Files\Base as Base_File; use Elementor\Core\DynamicTags\Manager; use Elementor\Core\DynamicTags\Tag; use Elementor\Element_Base; use Elementor\Plugin; use Elementor\Core\Responsive\Responsive; use Elementor\Stylesheet; use Elementor\Icons_Manager; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } /** * Elementor CSS file. * * Elementor CSS file handler class is responsible for generating CSS files. * * @since 1.2.0 * @abstract */ abstract class Base extends Base_File { /** * Elementor CSS file generated status. * * The parsing result after generating CSS file. */ const CSS_STATUS_FILE = 'file'; /** * Elementor inline CSS status. * * The parsing result after generating inline CSS. */ const CSS_STATUS_INLINE = 'inline'; /** * Elementor CSS empty status. * * The parsing result when an empty CSS returned. */ const CSS_STATUS_EMPTY = 'empty'; /** * Fonts. * * Holds the list of fonts. * * @access private * * @var array */ private $fonts = []; private $icons_fonts = []; /** * Stylesheet object. * * Holds the CSS file stylesheet instance. * * @access protected * * @var Stylesheet */ protected $stylesheet_obj; /** * Printed. * * Holds the list of printed files. * * @access protected * * @var array */ private static $printed = []; /** * Get CSS file name. * * Retrieve the CSS file name. * * @since 1.6.0 * @access public * @abstract */ abstract public function get_name(); /** * CSS file constructor. * * Initializing Elementor CSS file. * * @since 1.2.0 * @access public */ public function __construct( $file_name ) { parent::__construct( $file_name ); $this->init_stylesheet(); } /** * Use external file. * * Whether to use external CSS file of not. When there are new schemes or settings * updates. * * @since 1.9.0 * @access protected * * @return bool True if the CSS requires an update, False otherwise. */ protected function use_external_file() { return 'internal' !== get_option( 'elementor_css_print_method' ); } /** * Update the CSS file. * * Delete old CSS, parse the CSS, save the new file and update the database. * * This method also sets the CSS status to be used later on in the render posses. * * @since 1.2.0 * @access public */ public function update() { $this->update_file(); $meta = $this->get_meta(); $meta['time'] = time(); $content = $this->get_content(); if ( empty( $content ) ) { $meta['status'] = self::CSS_STATUS_EMPTY; $meta['css'] = ''; } else { $use_external_file = $this->use_external_file(); if ( $use_external_file ) { $meta['status'] = self::CSS_STATUS_FILE; } else { $meta['status'] = self::CSS_STATUS_INLINE; $meta['css'] = $content; } } $this->update_meta( $meta ); } /** * @since 2.1.0 * @access public */ public function write() { if ( $this->use_external_file() ) { parent::write(); } } /** * Enqueue CSS. * * Either enqueue the CSS file in Elementor or add inline style. * * This method is also responsible for loading the fonts. * * @since 1.2.0 * @access public */ public function enqueue() { $handle_id = $this->get_file_handle_id(); if ( isset( self::$printed[ $handle_id ] ) ) { return; } self::$printed[ $handle_id ] = true; $meta = $this->get_meta(); if ( self::CSS_STATUS_EMPTY === $meta['status'] ) { return; } // First time after clear cache and etc. if ( '' === $meta['status'] || $this->is_update_required() ) { $this->update(); $meta = $this->get_meta(); } if ( self::CSS_STATUS_INLINE === $meta['status'] ) { $dep = $this->get_inline_dependency(); // If the dependency has already been printed ( like a template in footer ) if ( wp_styles()->query( $dep, 'done' ) ) { printf( '<style id="%1$s">%2$s</style>', $this->get_file_handle_id(), $meta['css'] ); // XSS ok. } else { wp_add_inline_style( $dep, $meta['css'] ); } } elseif ( self::CSS_STATUS_FILE === $meta['status'] ) { // Re-check if it's not empty after CSS update. wp_enqueue_style( $this->get_file_handle_id(), $this->get_url(), $this->get_enqueue_dependencies(), null ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion } // Handle fonts. if ( ! empty( $meta['fonts'] ) ) { foreach ( $meta['fonts'] as $font ) { Plugin::$instance->frontend->enqueue_font( $font ); } } if ( ! empty( $meta['icons'] ) ) { $icons_types = Icons_Manager::get_icon_manager_tabs(); foreach ( $meta['icons'] as $icon_font ) { if ( ! isset( $icons_types[ $icon_font ] ) ) { continue; } Plugin::$instance->frontend->enqueue_font( $icon_font ); } } $name = $this->get_name(); /** * Enqueue CSS file. * * Fires when CSS file is enqueued on Elementor. * * The dynamic portion of the hook name, `$name`, refers to the CSS file name. * * @since 1.9.0 * @deprecated 2.0.0 Use `elementor/css-file/{$name}/enqueue` action instead. * * @param Base $this The current CSS file. */ do_action_deprecated( "elementor/{$name}-css-file/enqueue", [ $this ], '2.0.0', "elementor/css-file/{$name}/enqueue" ); /** * Enqueue CSS file. * * Fires when CSS file is enqueued on Elementor. * * The dynamic portion of the hook name, `$name`, refers to the CSS file name. * * @since 2.0.0 * * @param Base $this The current CSS file. */ do_action( "elementor/css-file/{$name}/enqueue", $this ); } /** * Print CSS. * * Output the final CSS inside the `<style>` tags and all the frontend fonts in * use. * * @since 1.9.4 * @access public */ public function print_css() { echo '<style>' . $this->get_content() . '</style>'; // XSS ok. Plugin::$instance->frontend->print_fonts_links(); } /** * Add control rules. * * Parse the CSS for all the elements inside any given control. * * This method recursively renders the CSS for all the selectors in the control. * * @since 1.2.0 * @access public * * @param array $control The controls. * @param array $controls_stack The controls stack. * @param callable $value_callback Callback function for the value. * @param array $placeholders Placeholders. * @param array $replacements Replacements. */ public function add_control_rules( array $control, array $controls_stack, callable $value_callback, array $placeholders, array $replacements ) { $value = call_user_func( $value_callback, $control ); if ( null === $value || empty( $control['selectors'] ) ) { return; } foreach ( $control['selectors'] as $selector => $css_property ) { try { $output_css_property = preg_replace_callback( '/\{\{(?:([^.}]+)\.)?([^}| ]*)(?: *\|\| *(?:([^.}]+)\.)?([^}| ]*) *)*}}/', function( $matches ) use ( $control, $value_callback, $controls_stack, $value, $css_property ) { $external_control_missing = $matches[1] && ! isset( $controls_stack[ $matches[1] ] ); $parsed_value = ''; if ( ! $external_control_missing ) { $parsed_value = $this->parse_property_placeholder( $control, $value, $controls_stack, $value_callback, $matches[2], $matches[1] ); } if ( '' === $parsed_value ) { if ( isset( $matches[4] ) ) { $parsed_value = $matches[4]; $is_string_value = preg_match( '/^([\'"])(.*)\1$/', $parsed_value, $string_matches ); if ( $is_string_value ) { $parsed_value = $string_matches[2]; } elseif ( ! is_numeric( $parsed_value ) ) { if ( $matches[3] && ! isset( $controls_stack[ $matches[3] ] ) ) { return ''; } $parsed_value = $this->parse_property_placeholder( $control, $value, $controls_stack, $value_callback, $matches[4], $matches[3] ); } } if ( '' === $parsed_value ) { if ( $external_control_missing ) { return ''; } throw new \Exception(); } } return $parsed_value; }, $css_property ); } catch ( \Exception $e ) { return; } if ( ! $output_css_property ) { continue; } $device_pattern = '/^(?:\([^\)]+\)){1,2}/'; preg_match( $device_pattern, $selector, $device_rules ); $query = []; if ( $device_rules ) { $selector = preg_replace( $device_pattern, '', $selector ); preg_match_all( '/\(([^\)]+)\)/', $device_rules[0], $pure_device_rules ); $pure_device_rules = $pure_device_rules[1]; foreach ( $pure_device_rules as $device_rule ) { if ( Element_Base::RESPONSIVE_DESKTOP === $device_rule ) { continue; } $device = preg_replace( '/\+$/', '', $device_rule ); $endpoint = $device === $device_rule ? 'max' : 'min'; $query[ $endpoint ] = $device; } } $parsed_selector = str_replace( $placeholders, $replacements, $selector ); if ( ! $query && ! empty( $control['responsive'] ) ) { $query = array_intersect_key( $control['responsive'], array_flip( [ 'min', 'max' ] ) ); if ( ! empty( $query['max'] ) && Element_Base::RESPONSIVE_DESKTOP === $query['max'] ) { unset( $query['max'] ); } } $this->stylesheet_obj->add_rules( $parsed_selector, $output_css_property, $query ); } } /** * @param array $control * @param mixed $value * @param array $controls_stack * @param callable $value_callback * @param string $placeholder * @param string $parser_control_name * * @return string */ public function parse_property_placeholder( array $control, $value, array $controls_stack, $value_callback, $placeholder, $parser_control_name = null ) { if ( $parser_control_name ) { $control = $controls_stack[ $parser_control_name ]; $value = call_user_func( $value_callback, $control ); } if ( Controls_Manager::FONT === $control['type'] ) { $this->fonts[] = $value; } /** @var Base_Data_Control $control_obj */ $control_obj = Plugin::$instance->controls_manager->get_control( $control['type'] ); return (string) $control_obj->get_style_value( $placeholder, $value, $control ); } /** * Get the fonts. * * Retrieve the list of fonts. * * @since 1.9.0 * @access public * * @return array Fonts. */ public function get_fonts() { return $this->fonts; } /** * Get CSS. * * Retrieve the CSS. If the CSS is empty, parse it again. * * @since 1.2.0 * @access public * @deprecated 2.1.0 Use `CSS_File::get_content()` method instead * * @return string The CSS. */ public function get_css() { _deprecated_function( __METHOD__, '2.1.0', __CLASS__ . '::get_content()' ); return $this->get_content(); } /** * Get stylesheet. * * Retrieve the CSS file stylesheet instance. * * @since 1.2.0 * @access public * * @return Stylesheet The stylesheet object. */ public function get_stylesheet() { return $this->stylesheet_obj; } /** * Add controls stack style rules. * * Parse the CSS for all the elements inside any given controls stack. * * This method recursively renders the CSS for all the child elements in the stack. * * @since 1.6.0 * @access public * * @param Controls_Stack $controls_stack The controls stack. * @param array $controls Controls array. * @param array $values Values array. * @param array $placeholders Placeholders. * @param array $replacements Replacements. * @param array $all_controls All controls. */ public function add_controls_stack_style_rules( Controls_Stack $controls_stack, array $controls, array $values, array $placeholders, array $replacements, array $all_controls = null ) { if ( ! $all_controls ) { $all_controls = $controls_stack->get_controls(); } $parsed_dynamic_settings = $controls_stack->parse_dynamic_settings( $values, $controls ); foreach ( $controls as $control ) { if ( ! empty( $control['style_fields'] ) ) { $this->add_repeater_control_style_rules( $controls_stack, $control, $values[ $control['name'] ], $placeholders, $replacements ); } if ( ! empty( $control[ Manager::DYNAMIC_SETTING_KEY ][ $control['name'] ] ) ) { $this->add_dynamic_control_style_rules( $control, $control[ Manager::DYNAMIC_SETTING_KEY ][ $control['name'] ] ); } if ( Controls_Manager::ICONS === $control['type'] ) { $this->icons_fonts[] = $values[ $control['name'] ]['library']; } if ( ! empty( $parsed_dynamic_settings[ Manager::DYNAMIC_SETTING_KEY ][ $control['name'] ] ) ) { // Dynamic CSS should not be added to the CSS files. // Instead it's handled by \Elementor\Core\DynamicTags\Dynamic_CSS // and printed in a style tag. unset( $parsed_dynamic_settings[ $control['name'] ] ); continue; } if ( empty( $control['selectors'] ) ) { continue; } $this->add_control_style_rules( $control, $parsed_dynamic_settings, $all_controls, $placeholders, $replacements ); } } /** * Get file handle ID. * * Retrieve the file handle ID. * * @since 1.2.0 * @access protected * @abstract * * @return string CSS file handle ID. */ abstract protected function get_file_handle_id(); /** * Render CSS. * * Parse the CSS. * * @since 1.2.0 * @access protected * @abstract */ abstract protected function render_css(); protected function get_default_meta() { return array_merge( parent::get_default_meta(), [ 'fonts' => array_unique( $this->fonts ), 'icons' => array_unique( $this->icons_fonts ), 'status' => '', ] ); } /** * Get enqueue dependencies. * * Retrieve the name of the stylesheet used by `wp_enqueue_style()`. * * @since 1.2.0 * @access protected * * @return array Name of the stylesheet. */ protected function get_enqueue_dependencies() { return []; } /** * Get inline dependency. * * Retrieve the name of the stylesheet used by `wp_add_inline_style()`. * * @since 1.2.0 * @access protected * * @return string Name of the stylesheet. */ protected function get_inline_dependency() { return ''; } /** * Is update required. * * Whether the CSS requires an update. When there are new schemes or settings * updates. * * @since 1.2.0 * @access protected * * @return bool True if the CSS requires an update, False otherwise. */ protected function is_update_required() { return false; } /** * Parse CSS. * * Parsing the CSS file. * * @since 1.2.0 * @access protected */ protected function parse_content() { $this->render_css(); $name = $this->get_name(); /** * Parse CSS file. * * Fires when CSS file is parsed on Elementor. * * The dynamic portion of the hook name, `$name`, refers to the CSS file name. * * @since 1.2.0 * @deprecated 2.0.0 Use `elementor/css-file/{$name}/parse` action instead. * * @param Base $this The current CSS file. */ do_action_deprecated( "elementor/{$name}-css-file/parse", [ $this ], '2.0.0', "elementor/css-file/{$name}/parse" ); /** * Parse CSS file. * * Fires when CSS file is parsed on Elementor. * * The dynamic portion of the hook name, `$name`, refers to the CSS file name. * * @since 2.0.0 * * @param Base $this The current CSS file. */ do_action( "elementor/css-file/{$name}/parse", $this ); return $this->stylesheet_obj->__toString(); } /** * Add control style rules. * * Register new style rules for the control. * * @since 1.6.0 * @access private * * @param array $control The control. * @param array $values Values array. * @param array $controls The controls stack. * @param array $placeholders Placeholders. * @param array $replacements Replacements. */ protected function add_control_style_rules( array $control, array $values, array $controls, array $placeholders, array $replacements ) { $this->add_control_rules( $control, $controls, function( $control ) use ( $values ) { return $this->get_style_control_value( $control, $values ); }, $placeholders, $replacements ); } /** * Get style control value. * * Retrieve the value of the style control for any give control and values. * * It will retrieve the control name and return the style value. * * @since 1.6.0 * @access private * * @param array $control The control. * @param array $values Values array. * * @return mixed Style control value. */ private function get_style_control_value( array $control, array $values ) { $value = $values[ $control['name'] ]; if ( isset( $control['selectors_dictionary'][ $value ] ) ) { $value = $control['selectors_dictionary'][ $value ]; } if ( ! is_numeric( $value ) && ! is_float( $value ) && empty( $value ) ) { return null; } return $value; } /** * Init stylesheet. * * Initialize CSS file stylesheet by creating a new `Stylesheet` object and register new * breakpoints for the stylesheet. * * @since 1.2.0 * @access private */ private function init_stylesheet() { $this->stylesheet_obj = new Stylesheet(); $breakpoints = Responsive::get_breakpoints(); $this->stylesheet_obj ->add_device( 'mobile', 0 ) ->add_device( 'tablet', $breakpoints['md'] ) ->add_device( 'desktop', $breakpoints['lg'] ); } /** * Add repeater control style rules. * * Register new style rules for the repeater control. * * @since 2.0.0 * @access private * * @param Controls_Stack $controls_stack The control stack. * @param array $repeater_control The repeater control. * @param array $repeater_values Repeater values array. * @param array $placeholders Placeholders. * @param array $replacements Replacements. */ protected function add_repeater_control_style_rules( Controls_Stack $controls_stack, array $repeater_control, array $repeater_values, array $placeholders, array $replacements ) { $placeholders = array_merge( $placeholders, [ '{{CURRENT_ITEM}}' ] ); foreach ( $repeater_control['style_fields'] as $index => $item ) { $this->add_controls_stack_style_rules( $controls_stack, $item, $repeater_values[ $index ], $placeholders, array_merge( $replacements, [ '.elementor-repeater-item-' . $repeater_values[ $index ]['_id'] ] ), $repeater_control['fields'] ); } } /** * Add dynamic control style rules. * * Register new style rules for the dynamic control. * * @since 2.0.0 * @access private * * @param array $control The control. * @param string $value The value. */ protected function add_dynamic_control_style_rules( array $control, $value ) { Plugin::$instance->dynamic_tags->parse_tags_text( $value, $control, function( $id, $name, $settings ) { $tag = Plugin::$instance->dynamic_tags->create_tag( $id, $name, $settings ); if ( ! $tag instanceof Tag ) { return; } $this->add_controls_stack_style_rules( $tag, $tag->get_style_controls(), $tag->get_active_settings(), [ '{{WRAPPER}}' ], [ '#elementor-tag-' . $id ] ); } ); } } css/post.php 0000666 00000015031 15214027777 0007052 0 ustar 00 <?php namespace Elementor\Core\Files\CSS; use Elementor\Controls_Stack; use Elementor\Element_Base; use Elementor\Plugin; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } /** * Elementor post CSS file. * * Elementor CSS file handler class is responsible for generating the single * post CSS file. * * @since 1.2.0 */ class Post extends Base { /** * Elementor post CSS file prefix. */ const FILE_PREFIX = 'post-'; const META_KEY = '_elementor_css'; /** * Post ID. * * Holds the current post ID. * * @var int */ private $post_id; /** * Post CSS file constructor. * * Initializing the CSS file of the post. Set the post ID and initiate the stylesheet. * * @since 1.2.0 * @access public * * @param int $post_id Post ID. */ public function __construct( $post_id ) { $this->post_id = $post_id; parent::__construct( self::FILE_PREFIX . $post_id . '.css' ); } /** * Get CSS file name. * * Retrieve the CSS file name. * * @since 1.6.0 * @access public * * @return string CSS file name. */ public function get_name() { return 'post'; } /** * Get post ID. * * Retrieve the ID of current post. * * @since 1.2.0 * @access public * * @return int Post ID. */ public function get_post_id() { return $this->post_id; } /** * Get unique element selector. * * Retrieve the unique selector for any given element. * * @since 1.2.0 * @access public * * @param Element_Base $element The element. * * @return string Unique element selector. */ public function get_element_unique_selector( Element_Base $element ) { return '.elementor-' . $this->post_id . ' .elementor-element' . $element->get_unique_selector(); } /** * Load meta data. * * Retrieve the post CSS file meta data. * * @since 1.2.0 * @access protected * * @return array Post CSS file meta data. */ protected function load_meta() { return get_post_meta( $this->post_id, static::META_KEY, true ); } /** * Update meta data. * * Update the global CSS file meta data. * * @since 1.2.0 * @access protected * * @param array $meta New meta data. */ protected function update_meta( $meta ) { update_post_meta( $this->post_id, static::META_KEY, $meta ); } /** * Delete meta. * * Delete the file meta data. * * @since 2.1.0 * @access protected */ protected function delete_meta() { delete_post_meta( $this->post_id, static::META_KEY ); } /** * Get post data. * * Retrieve raw post data from the database. * * @since 1.9.0 * @access protected * * @return array Post data. */ protected function get_data() { $document = Plugin::$instance->documents->get( $this->post_id ); return $document ? $document->get_elements_data() : []; } /** * Render CSS. * * Parse the CSS for all the elements. * * @since 1.2.0 * @access protected */ protected function render_css() { $data = $this->get_data(); if ( ! empty( $data ) ) { foreach ( $data as $element_data ) { $element = Plugin::$instance->elements_manager->create_element_instance( $element_data ); if ( ! $element ) { continue; } $this->render_styles( $element ); } } } /** * Enqueue CSS. * * Enqueue the post CSS file in Elementor. * * This method ensures that the post was actually built with elementor before * enqueueing the post CSS file. * * @since 1.2.2 * @access public */ public function enqueue() { if ( ! Plugin::$instance->db->is_built_with_elementor( $this->post_id ) ) { return; } parent::enqueue(); } /** * Add controls-stack style rules. * * Parse the CSS for all the elements inside any given controls stack. * * This method recursively renders the CSS for all the child elements in the stack. * * @since 1.6.0 * @access public * * @param Controls_Stack $controls_stack The controls stack. * @param array $controls Controls array. * @param array $values Values array. * @param array $placeholders Placeholders. * @param array $replacements Replacements. * @param array $all_controls All controls. */ public function add_controls_stack_style_rules( Controls_Stack $controls_stack, array $controls, array $values, array $placeholders, array $replacements, array $all_controls = null ) { parent::add_controls_stack_style_rules( $controls_stack, $controls, $values, $placeholders, $replacements, $all_controls ); if ( $controls_stack instanceof Element_Base ) { foreach ( $controls_stack->get_children() as $child_element ) { $this->render_styles( $child_element ); } } } /** * Get enqueue dependencies. * * Retrieve the name of the stylesheet used by `wp_enqueue_style()`. * * @since 1.2.0 * @access protected * * @return array Name of the stylesheet. */ protected function get_enqueue_dependencies() { return [ 'elementor-frontend' ]; } /** * Get inline dependency. * * Retrieve the name of the stylesheet used by `wp_add_inline_style()`. * * @since 1.2.0 * @access protected * * @return string Name of the stylesheet. */ protected function get_inline_dependency() { return 'elementor-frontend'; } /** * Get file handle ID. * * Retrieve the handle ID for the post CSS file. * * @since 1.2.0 * @access protected * * @return string CSS file handle ID. */ protected function get_file_handle_id() { return 'elementor-post-' . $this->post_id; } /** * Render styles. * * Parse the CSS for any given element. * * @since 1.2.0 * @access protected * * @param Element_Base $element The element. */ protected function render_styles( Element_Base $element ) { /** * Before element parse CSS. * * Fires before the CSS of the element is parsed. * * @since 1.2.0 * * @param Post $this The post CSS file. * @param Element_Base $element The element. */ do_action( 'elementor/element/before_parse_css', $this, $element ); $element_settings = $element->get_settings(); $this->add_controls_stack_style_rules( $element, $element->get_style_controls( null, $element->get_parsed_dynamic_settings() ), $element_settings, [ '{{ID}}', '{{WRAPPER}}' ], [ $element->get_id(), $this->get_element_unique_selector( $element ) ] ); /** * After element parse CSS. * * Fires after the CSS of the element is parsed. * * @since 1.2.0 * * @param Post $this The post CSS file. * @param Element_Base $element The element. */ do_action( 'elementor/element/parse_css', $this, $element ); } } css/global-css.php 0000666 00000006137 15214027777 0010122 0 ustar 00 <?php namespace Elementor\Core\Files\CSS; use Elementor\Plugin; use Elementor\Scheme_Base; use Elementor\Settings; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } /** * Elementor global CSS file. * * Elementor CSS file handler class is responsible for generating the global CSS * file. * * @since 1.2.0 */ class Global_CSS extends Base { /** * Elementor global CSS file handler ID. */ const FILE_HANDLER_ID = 'elementor-global'; const META_KEY = '_elementor_global_css'; /** * Get CSS file name. * * Retrieve the CSS file name. * * @since 1.6.0 * @access public * * @return string CSS file name. */ public function get_name() { return 'global'; } /** * Get file handle ID. * * Retrieve the handle ID for the global post CSS file. * * @since 1.2.0 * @access protected * * @return string CSS file handle ID. */ protected function get_file_handle_id() { return self::FILE_HANDLER_ID; } /** * Render CSS. * * Parse the CSS for all the widgets and all the scheme controls. * * @since 1.2.0 * @access protected */ protected function render_css() { $this->render_schemes_css(); } /** * Get inline dependency. * * Retrieve the name of the stylesheet used by `wp_add_inline_style()`. * * @since 1.2.0 * @access protected * * @return string Name of the stylesheet. */ protected function get_inline_dependency() { return 'elementor-frontend'; } /** * Is update required. * * Whether the CSS requires an update. When there are new schemes or settings * updates. * * @since 1.2.0 * @access protected * * @return bool True if the CSS requires an update, False otherwise. */ protected function is_update_required() { $file_last_updated = $this->get_meta( 'time' ); $schemes_last_update = get_option( Scheme_Base::LAST_UPDATED_META ); if ( $file_last_updated < $schemes_last_update ) { return true; } $elementor_settings_last_updated = get_option( Settings::UPDATE_TIME_FIELD ); if ( $file_last_updated < $elementor_settings_last_updated ) { return true; } return false; } /** * Render schemes CSS. * * Parse the CSS for all the widgets and all the scheme controls. * * @since 1.2.0 * @access private */ private function render_schemes_css() { $elementor = Plugin::$instance; foreach ( $elementor->widgets_manager->get_widget_types() as $widget ) { $scheme_controls = $widget->get_scheme_controls(); foreach ( $scheme_controls as $control ) { $this->add_control_rules( $control, $widget->get_controls(), function( $control ) use ( $elementor ) { $scheme_value = $elementor->schemes_manager->get_scheme_value( $control['scheme']['type'], $control['scheme']['value'] ); if ( empty( $scheme_value ) ) { return null; } if ( ! empty( $control['scheme']['key'] ) ) { $scheme_value = $scheme_value[ $control['scheme']['key'] ]; } if ( empty( $scheme_value ) ) { return null; } return $scheme_value; }, [ '{{WRAPPER}}' ], [ '.elementor-widget-' . $widget->get_name() ] ); } } } }
| ver. 1.4 |
Github
|
.
| PHP 7.0.33 | Generation time: 0 |
proxy
|
phpinfo
|
Settings