css/post-preview.php 0000644 00000002375 14720727354 0010533 0 ustar 00 post_id_for_data = $post_id;
$parent_id = wp_get_post_parent_id( $post_id );
parent::__construct( $parent_id );
}
protected function get_post_id_for_data() {
return $this->post_id_for_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->get_post_id_for_data();
}
}
css/global-css.php 0000644 00000007670 14720727354 0010120 0 ustar 00 render_schemes_and_globals_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() {
return $this->get_meta( 'time' ) < get_option( Settings::UPDATE_TIME_FIELD );
}
/**
* 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_and_globals_css() {
$elementor = Plugin::$instance;
/** @var Manager $module */
$kits_manager = Plugin::$instance->kits_manager;
$custom_colors_enabled = $kits_manager->is_custom_colors_enabled();
$custom_typography_enabled = $kits_manager->is_custom_typography_enabled();
// If both default colors and typography are disabled, there is no need to render schemes and default global css.
if ( ! $custom_colors_enabled && ! $custom_typography_enabled ) {
return;
}
foreach ( $elementor->widgets_manager->get_widget_types() as $widget ) {
$controls = $widget->get_controls();
$global_controls = [];
$global_values['__globals__'] = [];
foreach ( $controls as $control ) {
$is_color_control = 'color' === $control['type'];
$is_typography_control = isset( $control['groupType'] ) && 'typography' === $control['groupType'];
// If it is a color/typography control and default colors/typography are disabled,
// don't add the default CSS.
if ( ( $is_color_control && ! $custom_colors_enabled ) || ( $is_typography_control && ! $custom_typography_enabled ) ) {
continue;
}
$global_control = $control;
// Handle group controls that don't have a default global property.
if ( ! empty( $control['groupType'] ) ) {
$global_control = $controls[ $control['groupPrefix'] . $control['groupType'] ];
}
// If the control has a default global defined, add it to the globals array
// that is used in add_control_rules.
if ( ! empty( $control['global']['default'] ) ) {
$global_values['__globals__'][ $control['name'] ] = $global_control['global']['default'];
}
if ( ! empty( $global_control['global']['default'] ) ) {
$global_controls[] = $control;
}
}
foreach ( $global_controls as $control ) {
$this->add_control_rules( $control, $controls, function( $control ) {}, [ '{{WRAPPER}}' ], [ '.elementor-widget-' . $widget->get_name() ], $global_values );
}
}
}
}
css/base.php 0000644 00000066175 14720727354 0007011 0 ustar 00 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;
}
}
$meta['dynamic_elements_ids'] = $this->dynamic_elements_ids;
$this->update_meta( $meta );
}
/**
* @since 2.1.0
* @access public
*/
public function write() {
if ( $this->use_external_file() ) {
parent::write();
}
}
/**
* @since 3.0.0
* @access public
*/
public function delete() {
if ( $this->use_external_file() ) {
parent::delete();
} else {
$this->delete_meta();
}
}
/**
* Get Responsive Control Duplication Mode
*
* @since 3.4.0
*
* @return string
*/
protected function get_responsive_control_duplication_mode() {
return 'on';
}
/**
* 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;
}
/**
* Enqueue CSS file.
*
* Fires before enqueuing a CSS file.
*
* @param Base $this The current CSS file.
*/
do_action( 'elementor/css-file/before_enqueue', $this );
// 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( '', $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 2.0.0
*
* @param Base $this The current CSS file.
*/
do_action( "elementor/css-file/{$name}/enqueue", $this );
/**
* Enqueue CSS file.
*
* Fires after enqueuing a CSS file.
*
* @param Base $this The current CSS file.
*/
do_action( 'elementor/css-file/after_enqueue', $this );
}
/**
* Print CSS.
*
* Output the final CSS inside the `'; // 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.
* @param array $values Global Values.
*/
public function add_control_rules( array $control, array $controls_stack, callable $value_callback, array $placeholders, array $replacements, array $values = [] ) {
if ( empty( $control['selectors'] ) ) {
return;
}
$control_global_key = $control['name'];
if ( ! empty( $control['groupType'] ) ) {
$control_global_key = $control['groupPrefix'] . $control['groupType'];
}
$global_values = [];
$global_key = '';
if ( ! empty( $values['__globals__'] ) ) {
$global_values = $values['__globals__'];
}
if ( ! empty( $global_values[ $control_global_key ] ) ) {
$global_key = $global_values[ $control_global_key ];
}
if ( ! $global_key ) {
$value = call_user_func( $value_callback, $control );
if ( null === $value ) {
return;
}
}
$stylesheet = $this->get_stylesheet();
$control = apply_filters( 'elementor/files/css/selectors', $control, $value ?? [], $this );
foreach ( $control['selectors'] as $selector => $css_property ) {
$output_css_property = '';
if ( $global_key ) {
$selector_global_value = $this->get_selector_global_value( $control, $global_key );
if ( $selector_global_value ) {
$output_css_property = preg_replace( '/(:)[^;]+(;?)/', '$1' . $selector_global_value . '$2', $css_property );
}
} else {
try {
if ( $this->unit_has_custom_selector( $control, $value ) ) {
$css_property = $control['unit_selectors_dictionary'][ $value['unit'] ];
}
$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 = '';
$value = apply_filters( 'elementor/files/css/property', $value, $css_property, $matches, $control );
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();
}
}
if ( '__EMPTY__' === $parsed_value ) {
$parsed_value = '';
}
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 ( Breakpoints_Manager::BREAKPOINT_KEY_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'] ) && Breakpoints_Manager::BREAKPOINT_KEY_DESKTOP === $query['max'] ) {
unset( $query['max'] );
}
}
$stylesheet->add_rules( $parsed_selector, $output_css_property, $query );
}
}
protected function unit_has_custom_selector( $control, $value ) {
return isset( $control['unit_selectors_dictionary'] ) && isset( $control['unit_selectors_dictionary'][ $value['unit'] ] );
}
/**
* @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 ) {
// If both the processed control and the control name found in the placeholder are responsive
if ( ! empty( $control['responsive'] ) && ! empty( $controls_stack[ $parser_control_name ]['responsive'] ) ) {
$device_suffix = Controls_Manager::get_responsive_control_device_suffix( $control );
$control = $controls_stack[ $parser_control_name . $device_suffix ] ?? $controls_stack[ $parser_control_name ];
} else {
$control = $controls_stack[ $parser_control_name ];
}
$value = call_user_func( $value_callback, $control );
}
// If the control value is empty, check for global default. `0` (integer, string) are falsy but are valid values.
if ( empty( $value ) && '0' !== $value && 0 !== $value ) {
$value = $this->get_control_global_default_value( $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 stylesheet.
*
* Retrieve the CSS file stylesheet instance.
*
* @since 1.2.0
* @access public
*
* @return Stylesheet The stylesheet object.
*/
public function get_stylesheet() {
if ( ! $this->stylesheet_obj ) {
$this->init_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'] ] );
$this->dynamic_elements_ids[] = $controls_stack->get_id();
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 ),
'dynamic_elements_ids' => [],
'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() {
Performance::set_use_style_controls( true );
$initial_responsive_controls_duplication_mode = Plugin::$instance->breakpoints->get_responsive_control_duplication_mode();
Plugin::$instance->breakpoints->set_responsive_control_duplication_mode( $this->get_responsive_control_duplication_mode() );
$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 2.0.0
*
* @param Base $this The current CSS file.
*/
do_action( "elementor/css-file/{$name}/parse", $this );
Plugin::$instance->breakpoints->set_responsive_control_duplication_mode( $initial_responsive_controls_duplication_mode );
Performance::set_use_style_controls( false );
return $this->get_stylesheet()->__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, $values
);
}
/**
* Get Control Global Default Value
*
* If the control has a global default value, and the corresponding global default setting is enabled, this method
* fetches and returns the global default value. Otherwise, it returns null.
*
* @since 3.7.0
* @access private
*
* @param $control
* @return string|null
*/
private function get_control_global_default_value( $control ) {
if ( empty( $control['global']['default'] ) ) {
return null;
}
// If the control value is empty, and the control has a global default set, fetch the global value and use it.
$global_enabled = false;
if ( 'color' === $control['type'] ) {
$global_enabled = Plugin::$instance->kits_manager->is_custom_colors_enabled();
} elseif ( isset( $control['groupType'] ) && 'typography' === $control['groupType'] ) {
$global_enabled = Plugin::$instance->kits_manager->is_custom_typography_enabled();
}
$value = null;
// Only apply the global default if Global Colors are enabled.
if ( $global_enabled ) {
$value = $this->get_selector_global_value( $control, $control['global']['default'] );
}
return $value;
}
/**
* 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 ) {
if ( ! empty( $values['__globals__'][ $control['name'] ] ) ) {
// When the control itself has no global value, but it refers to another control global value
return $this->get_selector_global_value( $control, $values['__globals__'][ $control['name'] ] );
}
$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();
$active_breakpoints = Plugin::$instance->breakpoints->get_active_breakpoints();
foreach ( $active_breakpoints as $breakpoint_name => $breakpoint ) {
$this->stylesheet_obj->add_device( $breakpoint_name, $breakpoint->get_value() );
}
}
/**
* 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, $this->get_style_controls( $tag ), $tag->get_active_settings(), [ '{{WRAPPER}}' ], [ '#elementor-tag-' . $id ] );
} );
}
private function get_selector_global_value( $control, $global_key ) {
$data = Plugin::$instance->data_manager_v2->run( $global_key );
if ( empty( $data['value'] ) ) {
return null;
}
$global_args = explode( '?id=', $global_key );
$id = $global_args[1];
if ( ! empty( $control['groupType'] ) ) {
$strings_to_replace = [ $control['groupPrefix'] ];
$active_breakpoint_keys = array_keys( Plugin::$instance->breakpoints->get_active_breakpoints() );
foreach ( $active_breakpoint_keys as $breakpoint ) {
$strings_to_replace[] = '_' . $breakpoint;
}
$property_name = str_replace( $strings_to_replace, '', $control['name'] );
// TODO: This check won't retrieve the proper answer for array values (multiple controls).
if ( empty( $data['value'][ Global_Typography::TYPOGRAPHY_GROUP_PREFIX . $property_name ] ) ) {
return null;
}
$property_name = str_replace( '_', '-', $property_name );
$value = "var( --e-global-$control[groupType]-$id-$property_name )";
if ( $control['groupPrefix'] . 'font_family' === $control['name'] ) {
$default_generic_fonts = Plugin::$instance->kits_manager->get_current_settings( 'default_generic_fonts' );
if ( $default_generic_fonts ) {
$value .= ", $default_generic_fonts";
}
}
} else {
$value = "var( --e-global-$control[type]-$id )";
}
return $value;
}
final protected function get_active_controls( Controls_Stack $controls_stack, array $controls = null, array $settings = null ) {
if ( ! $controls ) {
$controls = $controls_stack->get_controls();
}
if ( ! $settings ) {
$settings = $controls_stack->get_controls_settings();
}
if ( $this->is_global_parsing_supported() ) {
$settings = $this->parse_global_settings( $settings, $controls );
}
$active_controls = array_reduce(
array_keys( $controls ), function( $active_controls, $control_key ) use ( $controls_stack, $controls, $settings ) {
$control = $controls[ $control_key ];
if ( $controls_stack->is_control_visible( $control, $settings, $controls ) ) {
$active_controls[ $control_key ] = $control;
}
return $active_controls;
}, []
);
return $active_controls;
}
final public function get_style_controls( Controls_Stack $controls_stack, array $controls = null, array $settings = null ) {
$controls = $this->get_active_controls( $controls_stack, $controls, $settings );
$style_controls = [];
foreach ( $controls as $control_name => $control ) {
$control_obj = Plugin::$instance->controls_manager->get_control( $control['type'] );
if ( ! $control_obj instanceof Base_Data_Control ) {
continue;
}
$control = array_merge( $control_obj->get_settings(), $control );
if ( $control_obj instanceof Control_Repeater ) {
$style_fields = [];
foreach ( $controls_stack->get_settings( $control_name ) as $item ) {
$style_fields[] = $this->get_style_controls( $controls_stack, $control['fields'], $item );
}
$control['style_fields'] = $style_fields;
}
if ( ! empty( $control['selectors'] ) || ! empty( $control['dynamic'] ) || $this->is_global_control( $controls_stack, $control_name, $controls ) || ! empty( $control['style_fields'] ) ) {
$style_controls[ $control_name ] = $control;
}
}
return $style_controls;
}
private function parse_global_settings( array $settings, array $controls ) {
foreach ( $controls as $control ) {
$control_name = $control['name'];
$control_obj = Plugin::$instance->controls_manager->get_control( $control['type'] );
if ( ! $control_obj instanceof Base_Data_Control ) {
continue;
}
if ( $control_obj instanceof Control_Repeater ) {
foreach ( $settings[ $control_name ] as & $field ) {
$field = $this->parse_global_settings( $field, $control['fields'] );
}
continue;
}
if ( empty( $control['global']['active'] ) ) {
continue;
}
if ( empty( $settings['__globals__'][ $control_name ] ) ) {
continue;
}
$settings[ $control_name ] = 'global';
}
return $settings;
}
private function is_global_control( Controls_Stack $controls_stack, $control_name, $controls ) {
$control = $controls[ $control_name ];
$control_global_key = $control_name;
if ( ! empty( $control['groupType'] ) ) {
$control_global_key = $control['groupPrefix'] . $control['groupType'];
}
if ( empty( $controls[ $control_global_key ]['global']['active'] ) ) {
return false;
}
$globals = $controls_stack->get_settings( '__globals__' );
return ! empty( $globals[ $control_global_key ] );
}
}
css/post-local-cache.php 0000644 00000001366 14720727354 0011204 0 ustar 00 meta_cache;
}
protected function delete_meta() {
$this->meta_cache = [];
}
protected function update_meta( $meta ) {
$this->meta_cache = $meta;
}
protected function get_data() {
$document = Plugin::$instance->documents->get( $this->get_post_id_for_data() );
return $document ? $document->get_elements_data() : [];
}
}
css/post.php 0000644 00000017050 14720727354 0007050 0 ustar 00 post_id = $post_id;
parent::__construct( static::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 );
}
public function write() {
parent::write();
if ( ! empty( $this->additional_style_dependencies ) ) {
$meta = $this->get_meta();
$meta['additional_style_dependencies'] = $this->additional_style_dependencies;
$this->update_meta( $meta );
}
}
/**
* 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() {
$document = Plugin::$instance->documents->get( $this->post_id );
if ( ! $document || ! $document->is_built_with_elementor() ) {
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() {
$enqueue_dependencies = [ 'elementor-frontend' ];
$additional_style_dependencies = $this->get_meta( 'additional_style_dependencies' );
if ( ! empty( $additional_style_dependencies ) ) {
$enqueue_dependencies = array_merge( $enqueue_dependencies, $additional_style_dependencies );
}
return $enqueue_dependencies;
}
/**
* 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, $this->get_style_controls( $element, null, $element->get_parsed_dynamic_settings() ), $element_settings, [ '{{ID}}', '{{WRAPPER}}' ], [ $element->get_id(), $this->get_element_unique_selector( $element ) ] );
$element_style_depend = $element->get_style_depends();
if ( ! empty( $element_style_depend ) ) {
$this->additional_style_dependencies = array_unique( array_merge( $this->additional_style_dependencies, $element_style_depend ) );
}
/**
* 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 );
}
}
file-types/svg.php 0000644 00000013230 14720727354 0010147 0 ustar 00 sanitize_file( $filename );
}
/**
* Validate File
*
* @since 3.3.0
* @access public
*
* @param $file
* @return bool|\WP_Error
*/
public function validate_file( $file ) {
if ( ! $this->sanitize_svg( $file['tmp_name'] ) ) {
return new \WP_Error( Exceptions::FORBIDDEN, esc_html__( 'This file is not allowed for security reasons.', 'elementor' ) );
}
return true;
}
/**
* Sanitizer
*
* @since 3.5.0
* @access public
*
* @param $content
* @return bool|string
*/
public function sanitizer( $content ) {
return ( new SVG_Sanitizer() )->sanitize( $content );
}
/**
* WP Prepare Attachment For J
*
* Runs on the `wp_prepare_attachment_for_js` filter.
*
* @since 3.5.0
* @access public
*
* @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;
}
/**
* Set Svg Meta Data
*
* Adds dimensions metadata to uploaded SVG files, since WordPress doesn't do it.
*
* @since 3.5.0
* @access public
*
* @return mixed
*/
public function set_svg_meta_data( $data, $id ) {
$attachment = get_post( $id ); // Filter makes sure that the post is an attachment.
$mime_type = $attachment->post_mime_type;
// If the attachment is an svg
if ( 'image/svg+xml' === $mime_type ) {
// If the svg metadata are empty or the width is empty or the height is empty.
// then get the attributes from xml.
if ( empty( $data ) || empty( $data['width'] ) || empty( $data['height'] ) ) {
$attachment = wp_get_attachment_url( $id );
$xml = simplexml_load_file( $attachment );
if ( ! empty( $xml ) ) {
$attr = $xml->attributes();
$view_box = explode( ' ', $attr->viewBox );// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
$data['width'] = isset( $attr->width ) && preg_match( '/\d+/', $attr->width, $value ) ? (int) $value[0] : ( 4 === count( $view_box ) ? (int) $view_box[2] : null );
$data['height'] = isset( $attr->height ) && preg_match( '/\d+/', $attr->height, $value ) ? (int) $value[0] : ( 4 === count( $view_box ) ? (int) $view_box[3] : null );
}
}
}
return $data;
}
/**
* Delete Meta Cache
*
* Deletes the Inline SVG post meta entry.
*
* @since 3.5.0
* @access public
*/
public function delete_meta_cache() {
delete_post_meta_by_key( self::META_KEY );
}
/**
* File Sanitizer Can Run
*
* Checks if the classes required for the file sanitizer are in memory.
*
* @since 3.5.0
* @access public
* @static
*
* @return bool
*/
public static function file_sanitizer_can_run() {
return class_exists( 'DOMDocument' ) && class_exists( 'SimpleXMLElement' );
}
/**
* Get Inline SVG
*
* @since 3.5.0
* @access public
* @static
*
* @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 ) ) {
$valid_svg = ( new SVG_Sanitizer() )->sanitize( $svg );
return ( false === $valid_svg ) ? '' : $valid_svg;
}
$attachment_file = get_attached_file( $attachment_id );
if ( ! file_exists( $attachment_file ) ) {
return '';
}
$svg = Utils::file_get_contents( $attachment_file );
$valid_svg = ( new SVG_Sanitizer() )->sanitize( $svg );
if ( false === $valid_svg ) {
return '';
}
if ( ! empty( $valid_svg ) ) {
update_post_meta( $attachment_id, self::META_KEY, $valid_svg );
}
return $valid_svg;
}
public function __construct() {
add_filter( 'wp_update_attachment_metadata', [ $this, 'set_svg_meta_data' ], 10, 2 );
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' ] );
}
}
file-types/base.php 0000644 00000002503 14720727354 0010263 0 ustar 00 uploads_manager->create_unique_dir();
}
$zip->open( $file_path );
// if an array of allowed file types is provided, get the filtered file list to extract.
$allowed_files = $allowed_file_types ? $this->get_allowed_files( $zip, $allowed_file_types ) : null;
$zip->extractTo( $extraction_directory, $allowed_files );
$zip->close();
return [
'extraction_directory' => $extraction_directory,
'files' => $this->find_temp_files( $extraction_directory ),
];
}
/**
* Get Allowed Files
*
* Accepts a zipArchive instance and an array of allowed file types. Iterates over the zip archive's files and
* checks if their extensions are in the list of allowed file types. Returns an array containing all valid files.
*
* @since 3.3.0
*
* @param \ZipArchive $zip
* @param array $allowed_file_types
* @return array
*/
private function get_allowed_files( $zip, $allowed_file_types ) {
$allowed_files = [];
// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
for ( $i = 0; $i < $zip->numFiles; $i++ ) {
$filename = $zip->getNameIndex( $i );
$extension = pathinfo( $filename, PATHINFO_EXTENSION );
// Skip files with transversal paths.
if ( strpos( $filename, '..' ) !== false ) {
continue;
}
if ( in_array( $extension, $allowed_file_types, true ) ) {
$allowed_files[] = $filename;
}
}
return $allowed_files;
}
/**
* Find temporary files.
*
* Recursively finds a list of temporary files from the extracted zip file.
*
* Example return data:
*
* [
* 0 => '/www/wp-content/uploads/elementor/tmp/5eb3a7a411d44/templates/block-2-col-marble-title.json',
* 1 => '/www/wp-content/uploads/elementor/tmp/5eb3a7a411d44/templates/block-2-col-text-and-photo.json',
* ]
*
* @since 2.9.8
* @access private
*
* @param string $temp_path - The temporary file path to scan for template files
*
* @return array An array of temporary files on the filesystem
*/
private function find_temp_files( $temp_path ) {
$file_names = [];
$possible_file_names = array_diff( scandir( $temp_path ), [ '.', '..' ] );
// Find nested files in the unzipped path. This happens for example when the user imports a Website Kit.
foreach ( $possible_file_names as $possible_file_name ) {
$full_possible_file_name = $temp_path . $possible_file_name;
if ( is_dir( $full_possible_file_name ) ) {
$file_names = array_merge( $file_names, $this->find_temp_files( $full_possible_file_name . '/' ) );
} else {
$file_names[] = $full_possible_file_name;
}
}
return $file_names;
}
}
base.php 0000644 00000013135 14720727354 0006205 0 ustar 00 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 );
}
/**
* Get Path
*
* Returns the local path of the generated file.
*
* @since 3.5.0
* @access public
*
* @return string
*/
public function get_path() {
return set_url_scheme( self::get_base_uploads_dir() . $this->files_dir . $this->file_name );
}
/**
* @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 ) {
$meta = array_merge( $this->get_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;
}
}
uploads-manager.php 0000644 00000044242 14720727354 0010355 0 ustar 00 new Json(),
'zip' => new Zip(),
'svg' => new Svg(),
];
foreach ( $file_types as $file_type => $file_handler ) {
$this->file_type_handlers[ $file_type ] = $file_handler;
}
}
/**
* Extract and Validate Zip
*
* This method accepts a $file array (which minimally should include a 'tmp_name')
*
* @since 3.3.0
* @access public
*
* @param string $file_path
* @param array $allowed_file_types
* @return array|\WP_Error
*/
public function extract_and_validate_zip( $file_path, $allowed_file_types = null ) {
$result = [];
/** @var Zip $zip_handler - File Type */
$zip_handler = $this->file_type_handlers['zip'];
// Returns an array of file paths.
$extracted = $zip_handler->extract( $file_path, $allowed_file_types );
if ( is_wp_error( $extracted ) ) {
return $extracted;
}
// If there are no extracted file names, no files passed the extraction validation.
if ( empty( $extracted['files'] ) ) {
// TODO: Decide what to do if no files passed the extraction validation
return new \WP_Error( 'file_error', self::INVALID_FILE_CONTENT );
}
$result['extraction_directory'] = $extracted['extraction_directory'];
foreach ( $extracted['files'] as $extracted_file_path ) {
// Each file is an array with a 'name' (file path) property.
if ( ! is_wp_error( $this->validate_file( [ 'tmp_name' => $extracted_file_path ] ) ) ) {
$result['files'][] = $extracted_file_path;
}
}
return $result;
}
/**
* Handle Elementor Upload
*
* This method receives a $file array. If the received file is a Base64 string, the $file array should include a
* 'fileData' property containing the string, which is decoded and has its contents stored in a temporary file.
* If the $file parameter passed is a standard $file array, the 'name' and 'tmp_name' properties are used for
* validation.
*
* The file goes through validation; if it passes validation, the file is returned. Otherwise, an error is returned.
*
* @since 3.3.0
* @access public
*
* @param array $data
* @param array $allowed_file_extensions Optional. an array of file types that are allowed to pass validation for each
* upload.
* @return array|\WP_Error
*/
public function handle_elementor_upload( array $data, $allowed_file_extensions = null ) {
// If $file['fileData'] is set, it signals that the passed file is a Base64 string that needs to be decoded and
// saved to a temporary file.
if ( isset( $data['fileData'] ) ) {
$data = $this->save_base64_to_tmp_file( $data, $allowed_file_extensions );
}
if ( is_wp_error( $data ) ) {
return $data;
}
$validation_result = $this->validate_file( $data, $allowed_file_extensions );
if ( is_wp_error( $validation_result ) ) {
return $validation_result;
}
return $data;
}
/**
* are Unfiltered Uploads Enabled
*
* @since 3.5.0
* @access public
*
* @return bool
*/
final public static function are_unfiltered_uploads_enabled() {
$enabled = ! ! get_option( self::UNFILTERED_FILE_UPLOADS_KEY )
&& Svg::file_sanitizer_can_run()
&& User::is_current_user_can_upload_json();
/**
* Allow Unfiltered Files Upload.
*
* Determines whether to enable unfiltered file uploads.
*
* @since 3.0.0
*
* @param bool $enabled Whether upload is enabled or not.
*/
$enabled = apply_filters( 'elementor/files/allow_unfiltered_upload', $enabled );
return $enabled;
}
/**
* Handle Elementor WP Media Upload
*
* Runs on the 'wp_handle_upload_prefilter' filter.
*
* @since 3.2.0
* @access public
*
* @param $file
* @return mixed
*/
public function handle_elementor_wp_media_upload( $file ) {
// If it isn't a file uploaded by Elementor, we do not intervene.
if ( ! $this->is_elementor_wp_media_upload() ) {
return $file;
}
$result = $this->validate_file( $file );
if ( is_wp_error( $result ) ) {
$file['error'] = $result->get_error_message();
}
return $file;
}
/**
* Get File Type Handler
*
* Initialize the proper file type handler according to the file extension
* and assign it to the file type handlers array.
*
* @since 3.3.0
* @access public
*
* @param string|null $file_extension - file extension
* @return File_Type_Base[]|File_Type_Base
*/
public function get_file_type_handlers( $file_extension = null ) {
return self::get_items( $this->file_type_handlers, $file_extension );
}
/**
* 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
*
* @since 3.5.0
* @access public
*
* @param $data
* @param $file
* @param $filename
* @param $mimes
*
* @return mixed
*/
public function check_filetype_and_ext( $data, $file, $filename, $mimes ) {
if ( ! empty( $data['ext'] ) && ! empty( $data['type'] ) ) {
return $data;
}
$wp_file_type = wp_check_filetype( $filename, $mimes );
$file_type_handlers = $this->get_file_type_handlers();
if ( isset( $file_type_handlers[ $wp_file_type['ext'] ] ) ) {
$file_type_handler = $file_type_handlers[ $wp_file_type['ext'] ];
$data['ext'] = $file_type_handler->get_file_extension();
$data['type'] = $file_type_handler->get_mime_type();
}
return $data;
}
/**
* Remove File Or Directory
*
* Directory is deleted recursively with all of its contents (subdirectories and files).
*
* @since 3.3.0
* @access public
*
* @param string $path
*/
public function remove_file_or_dir( $path ) {
if ( is_dir( $path ) ) {
$this->remove_directory_with_files( $path );
} elseif ( is_file( $path ) ) {
unlink( $path );
}
}
/**
* Create Temp File
*
* Create a random temporary file.
*
* @since 3.3.0
* @access public
*
* @param string $file_content
* @param string $file_name
* @return string|\WP_Error
*/
public function create_temp_file( $file_content, $file_name ) {
$file_name = str_replace( ' ', '', sanitize_file_name( $file_name ) );
if ( empty( $file_name ) ) {
return new \WP_Error( 'invalid_file_name', esc_html__( 'Invalid file name.', 'elementor' ) );
}
$temp_filename = $this->create_unique_dir() . $file_name;
/**
* Temp File Path
*
* Allows modifying the full path of the temporary file.
*
* @since 3.7.0
*
* @param string full path to file
*/
$temp_filename = apply_filters( 'elementor/files/temp-file-path', $temp_filename );
file_put_contents( $temp_filename, $file_content ); // phpcs:ignore
return $temp_filename;
}
/**
* Get Temp Directory
*
* Get the temporary files directory path. If the directory does not exist, this method creates it.
*
* @since 3.3.0
* @access public
*
* @return string $temp_dir
*/
public function get_temp_dir() {
if ( ! $this->temp_dir ) {
$wp_upload_dir = wp_upload_dir();
$temp_dir = implode( DIRECTORY_SEPARATOR, [ $wp_upload_dir['basedir'], 'elementor', 'tmp' ] ) . DIRECTORY_SEPARATOR;
/**
* Temp File Path
*
* Allows modifying the full path of the temporary file.
*
* @since 3.7.0
*
* @param string temporary directory
*/
$this->temp_dir = apply_filters( 'elementor/files/temp-dir', $temp_dir );
if ( ! is_dir( $this->temp_dir ) ) {
wp_mkdir_p( $this->temp_dir );
}
}
return $this->temp_dir;
}
/**
* Create Unique Temp Dir
*
* Create a unique temporary directory
*
* @since 3.3.0
* @access public
*
* @return string the new directory path
*/
public function create_unique_dir() {
$unique_dir_path = $this->get_temp_dir() . uniqid() . DIRECTORY_SEPARATOR;
wp_mkdir_p( $unique_dir_path );
return $unique_dir_path;
}
/**
* Register Ajax Actions
*
* Runs on the 'elementor/ajax/register_actions' hook. Receives the AJAX module as a parameter and registers
* callbacks for specified action IDs.
*
* @since 3.5.0
* @access public
*
* @param Ajax $ajax
*/
public function register_ajax_actions( Ajax $ajax ) {
$ajax->register_ajax_action( 'enable_unfiltered_files_upload', [ $this, 'enable_unfiltered_files_upload' ] );
}
/**
* Set Unfiltered Files Upload
*
* @since 3.5.0
* @access public
*/
public function enable_unfiltered_files_upload() {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
update_option( self::UNFILTERED_FILE_UPLOADS_KEY, 1 );
}
/**
* Support Unfiltered File Uploads
*
* When uploading a file within Elementor, this method adds the registered
* file types to WordPress' allowed mimes list. This will only happen if the user allowed unfiltered file uploads
* in Elementor's settings in the admin dashboard.
*
* @since 3.5.0
* @access public
*
* @param array $allowed_mimes
* @return array allowed mime types
*/
final public function support_unfiltered_elementor_file_uploads( $allowed_mimes ) {
if ( $this->is_elementor_upload() && $this->are_unfiltered_uploads_enabled() ) {
foreach ( $this->file_type_handlers as $file_type_handler ) {
$allowed_mimes[ $file_type_handler->get_file_extension() ] = $file_type_handler->get_mime_type();
}
}
return $allowed_mimes;
}
/**
* Set Elementor Upload State
*
* @since 3.5.0
* @access public
*
* @param $state
*/
public function set_elementor_upload_state( $state ) {
$this->is_elementor_upload = $state;
}
/**
* Is Elementor Upload
*
* This method checks if the current session includes a request to upload files made via Elementor.
*
* @since 3.5.0
* @access private
*
* @return bool
*/
private function is_elementor_upload() {
return $this->is_elementor_upload || $this->is_elementor_media_upload() || $this->is_elementor_wp_media_upload();
}
/**
* Is Elementor Media Upload
*
* Checks whether the current request includes uploading files via Elementor which are not destined for the Media
* Library.
*
* @since 3.5.0
* @access public
*
* @return bool
*/
public function is_elementor_media_upload() {
// Sometimes `uploadTypeCaller` passed as a GET parameter when using the WP Media Library REST API, where the
// whole request body is occupied by the uploaded file.
return isset( $_REQUEST['uploadTypeCaller'] ) && 'elementor-media-upload' === $_REQUEST['uploadTypeCaller']; // phpcs:ignore
}
/**
* Is Elementor WP Media Upload
*
* Checks whether the current request is a request to upload files into the WP Media Library via Elementor.
*
* @since 3.3.0
* @access private
*
* @return bool
*/
private function is_elementor_wp_media_upload() {
return isset( $_REQUEST['uploadTypeCaller'] ) && 'elementor-wp-media-upload' === $_REQUEST['uploadTypeCaller']; // phpcs:ignore
}
/**
* Add File Extension To Allowed Extensions List
*
* @since 3.3.0
* @access private
*
* @param string $file_type
*/
private function add_file_extension_to_allowed_extensions_list( $file_type ) {
$file_handler = $this->file_type_handlers[ $file_type ];
$file_extension = $file_handler->get_file_extension();
// Only add the file extension to the list if it doesn't already exist in it.
if ( ! in_array( $file_extension, $this->allowed_file_extensions, true ) ) {
$this->allowed_file_extensions[] = $file_extension;
}
}
/**
* Save Base64 as File
*
* Saves a Base64 string as a .tmp file in Elementor's temporary files directory.
*
* @since 3.3.0
* @access private
*
* @param $file
* @param array|null $allowed_file_extensions
*
* @return array|\WP_Error
*/
private function save_base64_to_tmp_file( $file, $allowed_file_extensions = null ) {
if ( empty( $file['fileName'] ) || empty( $file['fileData'] ) ) {
return new \WP_Error( 'file_error', self::INVALID_FILE_CONTENT );
}
$file_extension = pathinfo( $file['fileName'], PATHINFO_EXTENSION );
$is_file_type_allowed = $this->is_file_type_allowed( $file_extension, $allowed_file_extensions );
if ( is_wp_error( $is_file_type_allowed ) ) {
return $is_file_type_allowed;
}
$file_content = base64_decode( $file['fileData'] ); // phpcs:ignore
// If the decode fails
if ( ! $file_content ) {
return new \WP_Error( 'file_error', self::INVALID_FILE_CONTENT );
}
$temp_filename = $this->create_temp_file( $file_content, $file['fileName'] );
if ( is_wp_error( $temp_filename ) ) {
return $temp_filename;
}
return [
// the original uploaded file name
'name' => $file['fileName'],
// The path to the temporary file
'tmp_name' => $temp_filename,
];
}
/**
* Validate File
*
* @since 3.3.0
* @access private
*
* @param array $file
* @param array $file_extensions Optional
* @return bool|\WP_Error
*/
private function validate_file( array $file, $file_extensions = [] ) {
$uploaded_file_name = isset( $file['name'] ) ? $file['name'] : $file['tmp_name'];
$file_extension = pathinfo( $uploaded_file_name, PATHINFO_EXTENSION );
if ( ! $this->is_elementor_wp_media_upload() ) {
$is_file_type_allowed = $this->is_file_type_allowed( $file_extension, $file_extensions );
if ( is_wp_error( $is_file_type_allowed ) ) {
return $is_file_type_allowed;
}
}
$file_type_handler = $this->get_file_type_handlers( $file_extension );
// If Elementor does not have a handler for this file type, don't block it.
if ( ! $file_type_handler ) {
return true;
}
// If there is a File Type Handler for the uploaded file, it means it is a non-standard file type. In this case,
// we check if unfiltered file uploads are enabled or not before allowing it.
if ( ! self::are_unfiltered_uploads_enabled() ) {
$error = 'json' === $file_extension
? esc_html__( 'You do not have permission to upload JSON files.', 'elementor' )
: esc_html__( 'This file is not allowed for security reasons.', 'elementor' );
return new \WP_Error( Exceptions::FORBIDDEN, $error );
}
// Here is each file type handler's chance to run its own specific validations
return $file_type_handler->validate_file( $file );
}
/**
* Is File Type Allowed
*
* Checks whether the passed file extension is allowed for upload.
*
* @since 3.5.0
* @access private
*
* @param $file_extension
* @param $filtered_file_extensions
* @return bool|\WP_Error
*/
private function is_file_type_allowed( $file_extension, $filtered_file_extensions ) {
$allowed_file_extensions = $this->get_allowed_file_extensions();
if ( $filtered_file_extensions ) {
$allowed_file_extensions = array_intersect( $allowed_file_extensions, $filtered_file_extensions );
}
$is_allowed = false;
// Check if the file type (extension) is in the allowed extensions list. If it is a non-standard file type (not
// enabled by default in WordPress) and unfiltered file uploads are not enabled, it will not be in the allowed
// file extensions list.
foreach ( $allowed_file_extensions as $allowed_extension ) {
if ( preg_match( '/' . $allowed_extension . '/', $file_extension ) ) {
$is_allowed = true;
break;
}
}
if ( ! $is_allowed ) {
$is_allowed = new \WP_Error( Exceptions::FORBIDDEN, 'Uploading this file type is not allowed.' );
}
/**
* Elementor File Type Allowed
*
* Allows setting file types
*
* @since 3.5.0
*
* @param bool|\WP_Error $is_allowed
*/
return apply_filters( 'elementor/files/allow-file-type/' . $file_extension, $is_allowed );
}
/**
* Remove Directory with Files
*
* @since 3.3.0
* @access private
*
* @param string $dir
* @return bool
*/
private function remove_directory_with_files( $dir ) {
$dir_iterator = new \RecursiveDirectoryIterator( $dir, \RecursiveDirectoryIterator::SKIP_DOTS );
foreach ( new \RecursiveIteratorIterator( $dir_iterator, \RecursiveIteratorIterator::CHILD_FIRST ) as $name => $item ) {
if ( is_dir( $name ) ) {
rmdir( $name );
} elseif ( is_file( $name ) ) {
unlink( $name );
}
}
return rmdir( $dir );
}
/**
* Get Allowed File Extensions
*
* Retrieve an array containing the list of file extensions allowed for upload.
*
* @since 3.3.0
* @access private
*
* @return array file extension/s
*/
private function get_allowed_file_extensions() {
if ( ! $this->allowed_file_extensions ) {
$this->allowed_file_extensions = array_keys( get_allowed_mime_types() );
foreach ( $this->get_file_type_handlers() as $file_type => $handler ) {
if ( $handler->is_upload_allowed() ) {
// Add the file extension to the allowed extensions list only if unfiltered files upload is enabled.
$this->add_file_extension_to_allowed_extensions_list( $file_type );
}
}
}
return $this->allowed_file_extensions;
}
public function __construct() {
$this->register_file_types();
add_filter( 'upload_mimes', [ $this, 'support_unfiltered_elementor_file_uploads' ] );
add_filter( 'wp_handle_upload_prefilter', [ $this, 'handle_elementor_wp_media_upload' ] );
add_filter( 'wp_check_filetype_and_ext', [ $this, 'check_filetype_and_ext' ], 10, 4 );
// Ajax.
add_action( 'elementor/ajax/register_actions', [ $this, 'register_ajax_actions' ] );
}
}
manager.php 0000644 00000011412 14720727354 0006701 0 ustar 00 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 files.
$path = Base::get_base_uploads_dir() . Base::DEFAULT_FILES_DIR . '*';
foreach ( glob( $path ) as $file_path ) {
unlink( $file_path );
}
delete_post_meta_by_key( Post_CSS::META_KEY );
delete_post_meta_by_key( Document_Base::CACHE_META_KEY );
delete_post_meta_by_key( Assets::ASSETS_META_KEY );
delete_option( Global_CSS::META_KEY );
delete_option( Frontend::META_KEY );
$this->reset_assets_data();
/**
* Elementor clear files.
*
* Fires after Elementor clears files
*
* @since 2.1.0
*/
do_action( 'elementor/core/files/clear_cache' );
}
public function clear_custom_image_sizes() {
if ( ! defined( 'BFITHUMB_UPLOAD_DIR' ) ) {
return;
}
$upload_info = wp_upload_dir();
$upload_dir = $upload_info['basedir'] . '/' . BFITHUMB_UPLOAD_DIR;
$path = $upload_dir . '/*';
foreach ( glob( $path ) as $file_path ) {
unlink( $file_path );
}
}
/**
* Register Ajax Actions
*
* Deprecated - use the Uploads Manager instead.
*
* @deprecated 3.5.0
*
* @param Ajax $ajax
*/
public function register_ajax_actions( Ajax $ajax ) {
Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.5.0' );
Plugin::$instance->uploads_manager->register_ajax_actions( $ajax );
}
/**
* Ajax Unfiltered Files Upload
*
* Deprecated - use the Uploads Manager instead.
*
* @deprecated 3.5.0
*/
public function ajax_unfiltered_files_upload() {
Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.5.0' );
Plugin::$instance->uploads_manager->enable_unfiltered_files_upload();
}
/**
* 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 );
add_action( 'update_option_home', function () {
$this->reset_assets_data();
} );
add_action( 'update_option_siteurl', function () {
$this->reset_assets_data();
} );
}
/**
* Reset Assets Data.
*
* Reset the page assets data.
*
* @since 3.3.0
* @access private
*/
private function reset_assets_data() {
delete_option( Page_Assets_Data_Manager::ASSETS_DATA_KEY );
}
}
assets/svg/svg-handler.php 0000644 00000015541 14720727354 0011611 0 ustar 00 uploads_manager->get_file_type_handlers( 'svg' );`
*/
class Svg_Handler extends Files_Upload_Handler {
/**
* Inline svg attachment meta key
*
* @deprecated 3.5.0
*/
const META_KEY = '_elementor_inline_svg';
/**
* @deprecated 3.5.0
*/
const SCRIPT_REGEX = '/(?:\w+script|data):/xi';
/**
* Attachment ID.
*
* Holds the current attachment ID.
*
* @deprecated 3.5.0
*
* @var int
*/
private $attachment_id;
/**
* @deprecated 3.5.0
*/
public static function get_name() {
return 'svg-handler';
}
/**
* get_meta
*
* @deprecated 3.5.0
*
* @return mixed
*/
protected function get_meta() {
Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.5.0' );
return get_post_meta( $this->attachment_id, self::META_KEY, true );
}
/**
* update_meta
*
* @deprecated 3.5.0
*
* @param $meta
*/
protected function update_meta( $meta ) {
Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.5.0' );
update_post_meta( $this->attachment_id, self::META_KEY, $meta );
}
/**
* delete_meta
*
* @deprecated 3.5.0
*/
protected function delete_meta() {
Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.5.0' );
delete_post_meta( $this->attachment_id, self::META_KEY );
}
/**
* @deprecated 3.5.0
*/
public function get_mime_type() {
return 'image/svg+xml';
}
/**
* @deprecated 3.5.0
*/
public function get_file_type() {
return 'svg';
}
/**
* delete_meta_cache
*
* @deprecated 3.5.0 Use `Plugin::$instance->uploads_manager->get_file_type_handlers( 'svg' )->delete_meta_cache()` instead.
*/
public function delete_meta_cache() {
Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.5.0', 'Plugin::$instance->uploads_manager->get_file_type_handlers( \'svg\' )->delete_meta_cache()' );
/** @var Svg $svg_handler */
$svg_handler = Plugin::$instance->uploads_manager->get_file_type_handlers( 'svg' );
$svg_handler->delete_meta_cache();
}
/**
* get_inline_svg
*
* @deprecated 3.5.0 Use `Elementor\Core\Files\File_Types\Svg::get_inline_svg()` instead.
*
* @param $attachment_id
*
* @return bool|mixed|string
*/
public static function get_inline_svg( $attachment_id ) {
Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.5.0', 'Elementor\Core\Files\File_Types\Svg::get_inline_svg()' );
return Svg::get_inline_svg( $attachment_id );
}
/**
* sanitize_svg
*
* @deprecated 3.5.0 Use `Plugin::$instance->uploads_manager->get_file_type_handlers( 'svg' )->delete_meta_cache()->sanitize_svg()` instead.
*
* @param $filename
*
* @return bool
*/
public function sanitize_svg( $filename ) {
Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.5.0', 'Plugin::$instance->uploads_manager->get_file_type_handlers( \'svg\' )->delete_meta_cache()->sanitize_svg()' );
/** @var Svg $svg_handler */
$svg_handler = Plugin::$instance->uploads_manager->get_file_type_handlers( 'svg' );
return $svg_handler->sanitize_svg( $filename );
}
/**
* sanitizer
*
* @deprecated 3.5.0 Use `Plugin::$instance->uploads_manager->get_file_type_handlers( 'svg' )->sanitizer()` instead.
*
* @param $content
*
* @return bool|string
*/
public function sanitizer( $content ) {
Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.5.0', 'Plugin::$instance->uploads_manager->get_file_type_handlers( \'svg\' )->sanitizer()' );
/** @var Svg $svg_handler */
$svg_handler = Plugin::$instance->uploads_manager->get_file_type_handlers( 'svg' );
return $svg_handler->sanitizer( $content );
}
/**
* wp_prepare_attachment_for_js
*
* @deprecated 3.5.0 Use `Plugin::$instance->uploads_manager->get_file_type_handlers( 'svg' )->wp_prepare_attachment_for_js()` instead.
*
* @param $attachment_data
* @param $attachment
* @param $meta
*
* @return mixed
*/
public function wp_prepare_attachment_for_js( $attachment_data, $attachment, $meta ) {
Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.5.0', 'Plugin::$instance->uploads_manager->get_file_type_handlers( \'svg\' )->wp_prepare_attachment_for_js()' );
/** @var Svg $svg_handler */
$svg_handler = Plugin::$instance->uploads_manager->get_file_type_handlers( 'svg' );
return $svg_handler->wp_prepare_attachment_for_js( $attachment_data, $attachment, $meta );
}
/**
* set_attachment_id
*
* @deprecated 3.5.0
*
* @param $attachment_id
*
* @return int
*/
public function set_attachment_id( $attachment_id ) {
Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.5.0' );
$this->attachment_id = $attachment_id;
return $this->attachment_id;
}
/**
* get_attachment_id
*
* @deprecated 3.5.0
*
* @return int
*/
public function get_attachment_id() {
Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.5.0' );
return $this->attachment_id;
}
/**
* set_svg_meta_data
*
* @deprecated 3.5.0 Use `Plugin::$instance->uploads_manager->get_file_type_handlers( 'svg' )->set_svg_meta_data()` instead.
*
* @return mixed
*/
public function set_svg_meta_data( $data, $id ) {
Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.5.0', 'Plugin::$instance->uploads_manager->get_file_type_handlers( \'svg\' )->set_svg_meta_data()' );
/** @var Svg $svg_handler */
$svg_handler = Plugin::$instance->uploads_manager->get_file_type_handlers( 'svg' );
return $svg_handler->set_svg_meta_data( $data, $id );
}
/**
* handle_upload_prefilter
*
* @deprecated 3.5.0 Use `Elementor\Plugin::$instance->uploads_manager->handle_elementor_wp_media_upload()` instead.
*
* @param $file
*
* @return mixed
*/
public function handle_upload_prefilter( $file ) {
Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.5.0', 'Elementor\Plugin::$instance->uploads_manager->handle_elementor_wp_media_upload()' );
return Plugin::$instance->uploads_manager->handle_elementor_wp_media_upload( $file );
}
}
assets/files-upload-handler.php 0000644 00000010527 14720727354 0012576 0 ustar 00 uploads_manager->are_unfiltered_uploads_enabled()` instead.
*
* @return bool
*/
private function is_elementor_media_upload() {
Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.5.0', 'Elementor\Plugin::$instance->uploads_manager->are_unfiltered_uploads_enabled()' );
return Plugin::$instance->uploads_manager->is_elementor_media_upload();
}
/**
* Is Enabled
*
* @deprecated 3.5.0 Use `Elementor\Plugin::$instance->uploads_manager->are_unfiltered_uploads_enabled()` instead.
*
* @return bool
*/
final public static function is_enabled() {
Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.5.0', 'Elementor\Plugin::$instance->uploads_manager->are_unfiltered_uploads_enabled()' );
return Plugin::$instance->uploads_manager->are_unfiltered_uploads_enabled();
}
/**
* @deprecated 3.5.0 Use `Elementor\Plugin::$instance->uploads_manager->are_unfiltered_uploads_enabled()` instead.
*/
final public function support_unfiltered_files_upload( $existing_mimes ) {
Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.5.0', 'Elementor\Plugin::$instance->uploads_manager->support_unfiltered_file_uploads()' );
return Plugin::$instance->uploads_manager->support_unfiltered_elementor_file_uploads( $existing_mimes );
}
/**
* handle_upload_prefilter
*
* @deprecated 3.5.0 Use `Elementor\Plugin::$instance->uploads_manager->handle_elementor_wp_media_upload()` instead.
*
* @param $file
*
* @return mixed
*/
public function handle_upload_prefilter( $file ) {
Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.5.0', 'Elementor\Plugin::$instance->uploads_manager->handle_elementor_wp_media_upload()' );
return Plugin::$instance->uploads_manager->handle_elementor_wp_media_upload( $file );
}
/**
* is_file_should_handled
*
* @deprecated 3.5.0
*
* @param $file
*
* @return bool
*/
protected function is_file_should_handled( $file ) {
Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.5.0' );
$ext = pathinfo( $file['name'], PATHINFO_EXTENSION );
return $this->is_elementor_media_upload() && $this->get_file_type() === $ext;
}
/**
* file_sanitizer_can_run
*
* @deprecated 3.5.0 Use `Elementor\Core\Files\File_Types\Svg::file_sanitizer_can_run()` instead.
*
* @return bool
*/
public static function file_sanitizer_can_run() {
Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.5.0', 'Elementor\Core\Files\File_Types\Svg::file_sanitizer_can_run()' );
return Svg::file_sanitizer_can_run();
}
/**
* 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
*
* @deprecated 3.5.0 Use `Elementor\Plugin::$instance->uploads_manager->check_filetype_and_ext()` instead.
*
* @param $data
* @param $file
* @param $filename
* @param $mimes
*
* @return mixed
*/
public function check_filetype_and_ext( $data, $file, $filename, $mimes ) {
Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.5.0', 'Elementor\Plugin::$instance->uploads_manager->check_filetype_and_ext()' );
Plugin::$instance->uploads_manager->check_filetype_and_ext( $data, $file, $filename, $mimes );
}
}
assets/manager.php 0000644 00000002325 14720727354 0010206 0 ustar 00 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() );
}
}
assets/json/json-handler.php 0000644 00000001302 14720727354 0012123 0 ustar 00 uploads_manager->get_file_type_handlers( 'svg' );`
*/
class Json_Handler extends Files_Upload_Handler {
/**
* @deprecated 3.5.0
*/
public static function get_name() {
return 'json-handler';
}
/**
* @deprecated 3.5.0
*/
public function get_mime_type() {
return 'application/json';
}
/**
* @deprecated 3.5.0
*/
public function get_file_type() {
return 'json';
}
}