<?php namespace ElementorPro\Modules\AssetsManager\Classes; use Elementor\Utils; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } abstract class Assets_Base { abstract public function get_name(); abstract public function get_type(); protected function actions() { } public function print_metabox( $fields ) { ?> <div class="elementor-metabox-content"> <?php foreach ( $fields as $field ) : $field['saved'] = isset( $field['saved'] ) ? $field['saved'] : ''; // PHPCS - admin fields echo $this->get_metabox_field_html( $field, $field['saved'] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped endforeach; ?> </div> <?php } public function get_metabox_field_html( $field, $saved ) { $html = ''; switch ( $field['field_type'] ) { case 'html': $html = $this->get_html_field( $field ); return $html; break; case 'html_tag': $html = $this->get_html_tag( $field ); return $html; break; case 'toolbar': $html = $this->get_repeater_tools( $field ); break; case 'input': $html = $this->get_input_field( $field ); break; case 'select': $html = $this->get_select_field( $field, $saved ); break; case 'textarea': $html = $this->get_textarea_field( $field, $saved ); break; case 'file': $html = $this->get_file_field( $field, $saved ); break; case 'repeater': $html = $this->get_repeater_field( $field, $saved ); break; case 'dropzone': $html = $this->get_dropzone_field( $field, $saved ); break; case 'checkbox': return $this->get_checkbox_field( $field, $saved ); default: $method = 'get_' . $field['field_type'] . 'field'; if ( method_exists( $this, $method ) ) { $html = call_user_func( [ $this, $method ], $field, $saved ); } break; } return $this->get_field_row( $field, $html ); } public function get_field_label( $field ) { if ( ! isset( $field['label'] ) || false === $field['label'] ) { return ''; } $id = $field['id']; if ( 'file' === $field['field_type'] ) { $id .= $field['field_type']; } return '<p class="elementor-field-label"><label for="' . esc_attr( $id ) . '">' . $field['label'] . '</label></p>'; } public function get_input_field( $attributes ) { if ( isset( $attributes['input_type'] ) ) { $attributes['type'] = $attributes['input_type']; unset( $attributes['input_type'] ); } $input = '<input ' . $this->get_attribute_string( $attributes ) . '>'; return $input; } public function get_attribute_string( $attributes, $field = [] ) { if ( isset( $field['extra_attributes'] ) && is_array( $field['extra_attributes'] ) ) { $attributes = array_merge( $attributes, $field['extra_attributes'] ); } $attributes_array = []; foreach ( $attributes as $name => $value ) { $attributes_array[] = sprintf( '%s="%s"', $name, esc_attr( $value ) ); } return implode( ' ', $attributes_array ); } public function get_select_field( $field, $selected = '' ) { $input = '<select '; $input .= $this->get_attribute_string( [ 'name' => $field['id'], 'id' => $field['id'], ], $field ); $input .= '>' . "\n"; foreach ( $field['options'] as $value => $label ) { $input .= '<option value="' . $value . '" ' . selected( $selected, $value, false ) . '>' . esc_attr( $label ) . '</option>' . PHP_EOL; } return $input . '</select>'; } public function get_textarea_field( $field, $html ) { $input = '<textarea '; $input .= $this->get_attribute_string( [ 'name' => $field['id'], 'id' => $field['id'], ], $field ); $input .= '>' . esc_textarea( $html ) . '</textarea>'; return $input; } public function get_file_field( $field, $saved ) { $value = [ 'id' => '', 'url' => '', ]; if ( isset( $saved['id'] ) && isset( $saved['url'] ) ) { $value = $saved; } $html = '<ul></ul>'; $html .= $this->get_input_field( [ 'type' => 'hidden', 'name' => $field['id'] . '[id]', 'value' => $value['id'], ] ); $html .= $this->get_input_field( [ 'type' => 'text', 'name' => $field['id'] . '[url]', 'value' => $value['url'], 'placeholder' => $field['description'], 'class' => 'elementor-field-input', ] ); $html .= $this->get_input_field( [ 'type' => 'button', 'class' => 'button elementor-button elementor-upload-btn', 'name' => $field['id'], 'id' => $field['id'], 'value' => '', 'data-preview_anchor' => isset( $field['preview_anchor'] ) ? $field['preview_anchor'] : 'none', 'data-mime_type' => isset( $field['mine'] ) ? $field['mine'] : '', 'data-ext' => isset( $field['ext'] ) ? $field['ext'] : '', 'data-upload_text' => esc_html__( 'Upload', 'elementor-pro' ), 'data-remove_text' => esc_html__( 'Delete', 'elementor-pro' ), 'data-box_title' => isset( $field['box_title'] ) ? $field['box_title'] : '', 'data-box_action' => isset( $field['box_action'] ) ? $field['box_action'] : '', ] ); return $html; } public function get_html_field( $field ) { return $field['raw_html']; } public function get_dropzone_field( $field ) { ob_start(); $input_attributes = [ 'type' => 'file', 'name' => $field['id'], 'id' => $field['id'], 'accept' => $field['accept'], 'class' => 'box__file', ]; if ( ! empty( $field['multiple'] ) ) { $input_attributes['multiple'] = true; } $input_html = $this->get_input_field( $input_attributes ); $field['label'] = '<h4><span class="box__dragndrop">' . esc_html__( 'Drag & Drop to Upload', 'elementor-pro' ) . '</span></h4>'; if ( ! empty( $field['sub-label'] ) ) { $field['label'] .= '<h5>' . $field['sub-label'] . '</h5>'; } ?> <div class="elementor-dropzone-field"> <div class="box__input"> <div class="elementor--dropzone--upload__icon"> <i class="eicon-library-upload"></i> </div> <?php echo $input_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> <?php echo $this->get_field_label( $field ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> <div class="elementor-button elementor--dropzone--upload__browse"> <span><?php esc_html_e( 'Click here to browse', 'elementor-pro' ); ?></span> </div> </div> <div class="box__uploading"><?php esc_html_e( 'Uploading&hellip;', 'elementor-pro' ); ?></div> <div class="box__success"><?php esc_html_e( 'Done!', 'elementor-pro' ); ?></div> <div class="box__error"><?php esc_html_e( 'Error!', 'elementor-pro' ); ?> <span></span>.</div> </div> <?php return ob_get_clean(); } public function get_repeater_field( $field, $saved ) { $id = $field['id']; $js_id = 'repeater_' . Utils::generate_random_string(); $add_label = isset( $field['add_label'] ) ? $field['add_label'] : esc_html__( 'Add item', 'elementor-pro' ); $row_label = isset( $field['row_label'] ) ? $field['row_label'] : esc_html__( 'Row', 'elementor-pro' ); $row_label_html_args = [ 'id' => 'row_label_' . $js_id, 'class' => 'repeater-title hidden', ]; if ( is_array( $row_label ) ) { $label = $row_label['default']; $row_label_html_args['data-default'] = $row_label['default']; $row_label_html_args['data-selector'] = $row_label['selector']; } else { $label = $row_label; $row_label_html_args['data-default'] = $row_label; } $row_label_html = '<span ' . $this->get_attribute_string( $row_label_html_args ) . '>' . $label . '</span>'; ob_start(); ?> <script type="text/template" id="<?php echo esc_attr( $js_id . '_block' ); ?>"> <div class="repeater-block block-visible"> <?php echo $row_label_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo $this->get_repeater_tools( $field ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> <div class="repeater-content form-table"> <?php foreach ( $field['fields'] as $sub_field ) { $sub_field['real_id'] = $id; $sub_field['id'] = $id . '[__counter__][' . $sub_field['id'] . ']'; echo $this->get_metabox_field_html( $sub_field, '' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } ?> </div> </div> </script> <?php $counter = 0; $row_label_html_args['class'] = 'repeater-title'; $row_label_html = '<span ' . $this->get_attribute_string( $row_label_html_args ) . '>' . $label . '</span>'; if ( is_array( $saved ) && count( $saved ) > 0 ) { foreach ( (array) $saved as $key => $item ) { echo '<div class="repeater-block">'; echo $row_label_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo $this->get_repeater_tools( $field ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo '<div class="repeater-content hidden form-table">'; foreach ( $field['fields'] as $sub_field ) { $default = isset( $sub_field['default'] ) ? $sub_field['default'] : ''; $item_meta = isset( $item[ $sub_field['id'] ] ) ? $item[ $sub_field['id'] ] : $default; $sub_field['real_id'] = $sub_field['id']; $sub_field['id'] = $id . '[' . $counter . '][' . $sub_field['id'] . ']'; echo $this->get_metabox_field_html( $sub_field, $item_meta ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped } echo '</div>'; // end table echo '</div>'; $counter++; } } echo '<input type="button" class="button elementor-button add-repeater-row" value="' . esc_attr( $add_label ) . '" data-template-id="' . esc_html( $js_id ) . '_block">'; return ob_get_clean(); } public function get_checkbox_field( $field, $saved ) { Utils::print_unescaped_internal_string( $this->get_field_row( $field, '' ) ); echo '<div id="' . esc_attr( $field['id'] ) . '" class="elementor-field-checkboxes">'; foreach ( $field['options'] as $checkbox_key => $label ) { $name = $field['id'] . '_' . $checkbox_key; $checked = ! empty( $saved ) && in_array( $checkbox_key, $saved, true ) ? 'checked' : ''; echo '<input name="' . esc_attr( $name ) . '" type="checkbox" ' . esc_attr( $checked ) . '><span class="label">' . esc_html( $label ) . '</span></input>'; } echo '</div>'; } private function get_html_tag( $field ) { $tag = isset( $field['tag'] ) ? $field['tag'] : 'div'; if ( isset( $field['close'] ) && true === $field['close'] ) { return '</' . $tag . '>'; } return '<' . $tag . ' ' . $this->get_attribute_string( $field['attributes'] ) . '>'; } private function get_repeater_tools( $field ) { $confirm = isset( $field['confirm'] ) ? $field['confirm'] : esc_html__( 'Are you sure?', 'elementor-pro' ); $remove_title = isset( $field['remove_title'] ) ? $field['remove_title'] : esc_html__( 'Delete', 'elementor-pro' ); $toggle_title = isset( $field['toggle_title'] ) ? $field['toggle_title'] : esc_html__( 'Edit', 'elementor-pro' ); $close_title = isset( $field['close_title'] ) ? $field['close_title'] : esc_html__( 'Close', 'elementor-pro' ); return '<span class="elementor-repeater-tool-btn close-repeater-row" title="' . esc_attr( $close_title ) . '"> <i class="eicon-times" aria-hidden="true"></i>' . $close_title . ' </span> <span class="elementor-repeater-tool-btn toggle-repeater-row" title="' . esc_attr( $toggle_title ) . '"> <i class="eicon-edit" aria-hidden="true"></i>' . $toggle_title . ' </span> <span class="elementor-repeater-tool-btn remove-repeater-row" data-confirm="' . $confirm . '" title="' . esc_attr( $remove_title ) . '"> <i class="eicon-trash" aria-hidden="true"></i>' . $remove_title . ' </span>'; } public function get_field_row( $field, $field_html ) { $description = ''; $css_id = isset( $field['id'] ) ? ' ' . $field['id'] : ''; if ( isset( $field['real_id'] ) ) { $css_id = ' ' . $field['real_id']; } $css_id .= ' elementor-field-' . $field['field_type']; return '<div class="elementor-field' . $css_id . '">' . $this->get_field_label( $field ) . $field_html . $description . '</div>'; } public function sanitize_text_field_recursive( $data ) { if ( is_array( $data ) ) { foreach ( $data as $key => $value ) { $data[ $key ] = $this->sanitize_text_field_recursive( $value ); } return $data; } return sanitize_text_field( $data ); } public function __construct() { $this->actions(); } }