Plugin Directory

Changeset 3386622


Ignore:
Timestamp:
10/29/2025 07:05:29 PM (4 months ago)
Author:
Webilia
Message:

Released vertex 1.6.1

Location:
addons-for-elementor-builder
Files:
692 added
28 edited

Legend:

Unmodified
Added
Removed
  • addons-for-elementor-builder/trunk/addons-for-elementor-builder.php

    r3382971 r3386622  
    44 * Plugin URI: https://vertexaddons.com/
    55 * Description: Just one plugin instead of a lot!
    6  * Version: 1.6.0
     6 * Version: 1.6.1
    77 * Author: Webilia
    88 * Author URI: https://webilia.com/
  • addons-for-elementor-builder/trunk/afeb.php

    r3382971 r3386622  
    2323     * @var string
    2424     */
    25     public $version = '1.6.0';
     25    public $version = '1.6.1';
    2626
    2727    /**
  • addons-for-elementor-builder/trunk/app/Ajax.php

    r3382971 r3386622  
    1212use Plugin_Upgrader;
    1313use WP_Ajax_Upgrader_Skin;
     14use WP_Filesystem_Base;
    1415use WP_Query;
    15 
    16 if (!defined('ABSPATH')) {
    17     exit;
    18 }
    1916
    2017/**
    2118 * "Vertex Addons for Elementor" General Ajax Class
    22  * 
     19 *
    2320 * @class Ajax
    2421 * @version 1.0.4
     
    2825    /**
    2926     * Initialize "Vertex Addons for Elementor" Ajax
    30      * 
     27     *
    3128     * @since 1.0.4
    3229     */
     
    3835    /**
    3936     * Ajax Class Actions
    40      * 
     37     *
    4138     * @since 1.0.4
    4239     */
     
    6663        $data = isset($_POST['data']) && is_array($_POST['data']) ? map_deep($_POST['data'], 'sanitize_text_field') : [
    6764            'library' => 'fa-regular',
    68             'value' => "far fa-arrow-alt-circle-up"
     65            'value' => "far fa-arrow-alt-circle-up",
    6966        ];
    7067
     
    8784        $type = isset($_POST['data']['type']) ? sanitize_text_field(wp_unslash($_POST['data']['type'])) : '';
    8885
    89         if (!trim($type)) {
     86        if (!trim($type))
     87        {
    9088            wp_send_json_error(['message' => esc_html__('Please use a valid template type', 'addons-for-elementor-builder')]);
    9189        }
     
    9795            'post_title' => $name,
    9896            'post_type' => Builder::BUILDER_POST_TYPE,
    99             'post_name' => Builder::BUILDER_POST_TYPE
     97            'post_name' => Builder::BUILDER_POST_TYPE,
    10098        ]);
    10199
    102         if ($id) {
     100        if ($id)
     101        {
    103102            $template_name = '';
    104103            $page_settings = [
     
    106105                'display_condition' => [['_id' => 'ff0d1cf', 'conditon_group' => 'entire']],
    107106                'display_condition_temp' => [],
    108                 'activeItemIndex' => 1
     107                'activeItemIndex' => 1,
    109108            ];
    110109
    111             switch ($type) {
     110            switch ($type)
     111            {
    112112                case 'archive':
    113113                    $template_name = 'Archive';
     
    130130            }
    131131
    132             if ($name == '') {
     132            if ($name == '')
     133            {
    133134                $id = intval($id);
    134135                wp_update_post([
    135136                    'ID' => $id,
    136                     'post_title' => "Vertex {$template_name} Template_{$id}"
     137                    'post_title' => "Vertex $template_name Template_$id",
    137138                ]);
    138139            }
     
    146147            $redirect = get_edit_post_link($id, 'raw');
    147148
    148             if (did_action('elementor/loaded') && class_exists(Plugin::class)) {
     149            if (did_action('elementor/loaded') && class_exists(Plugin::class))
     150            {
    149151                $document = Plugin::instance()->documents->get($id);
    150                 if ($document) {
     152                if ($document)
     153                {
    151154                    $redirect = $document->get_edit_url();
    152155                }
     
    155158            wp_send_json_success([
    156159                'redirect' => $redirect,
    157                 'message' => esc_html__('The new template has been created', 'addons-for-elementor-builder')
     160                'message' => esc_html__('The new template has been created', 'addons-for-elementor-builder'),
    158161            ]);
    159162        }
     
    177180            'post_title' => $name,
    178181            'post_type' => Popup::POPUP_POST_TYPE,
    179             'post_name' => Popup::POPUP_POST_TYPE
     182            'post_name' => Popup::POPUP_POST_TYPE,
    180183        ]);
    181184
    182         if ($id) {
    183             if ($name == '') {
     185        if ($id)
     186        {
     187            if ($name == '')
     188            {
    184189                $id = intval($id);
    185190                wp_update_post([
    186191                    'ID' => $id,
    187                     'post_title' => "Vertex Popup_{$id}"
     192                    'post_title' => "Vertex Popup_$id",
    188193                ]);
    189194            }
     
    193198            $redirect = get_edit_post_link($id, 'raw');
    194199
    195             if (did_action('elementor/loaded') && class_exists(Plugin::class)) {
     200            if (did_action('elementor/loaded') && class_exists(Plugin::class))
     201            {
    196202                $document = Plugin::instance()->documents->get($id);
    197                 if ($document) {
     203                if ($document)
     204                {
    198205                    $redirect = $document->get_edit_url();
    199206                }
     
    202209            wp_send_json_success([
    203210                'redirect' => $redirect,
    204                 'message' => esc_html__('The new popup has been created', 'addons-for-elementor-builder')
     211                'message' => esc_html__('The new popup has been created', 'addons-for-elementor-builder'),
    205212            ]);
    206213        }
     
    211218    /**
    212219     * Activate Required Plugins
    213      * 
     220     *
    214221     * @since 1.4.0
    215222     */
     
    228235        set_time_limit(0);
    229236
    230         foreach ($plugins as $plugin_slug => $plugin_path) {
    231             if (Helper::is_plugin_installed($plugin_slug, $plugin_path)) {
    232                 if (!is_plugin_active($plugin_path)) {
     237        foreach ($plugins as $plugin_slug => $plugin_path)
     238        {
     239            if (Helper::is_plugin_installed($plugin_slug, $plugin_path))
     240            {
     241                if (!is_plugin_active($plugin_path))
     242                {
    233243                    activate_plugin($plugin_path);
    234244                }
    235             } else {
     245            }
     246            else
     247            {
    236248                require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
    237249                require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
     
    240252                    'plugin_information',
    241253                    [
    242                         'slug'   => $plugin_slug,
     254                        'slug' => $plugin_slug,
    243255                        'fields' => ['sections' => false],
    244256                    ]
     
    253265
    254266                if (is_wp_error($result)) $error = $result->get_error_message();
    255                 elseif (is_wp_error($skin->result)) $error = $skin->result->get_error_message();
    256                 elseif ($skin->get_errors()->has_errors()) $error = $skin->get_error_messages();
    257                 elseif (is_null($result)) {
     267                else if (is_wp_error($skin->result)) $error = $skin->result->get_error_message();
     268                else if ($skin->get_errors()->has_errors()) $error = $skin->get_error_messages();
     269                else if (is_null($result))
     270                {
    258271                    $error = esc_html__('Unable to connect to the filesystem. Please confirm your credentials.', 'addons-for-elementor-builder');
    259272
    260273                    global $wp_filesystem;
    261274                    if ($wp_filesystem instanceof WP_Filesystem_Base && is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->has_errors())
    262                         $error =  esc_html($wp_filesystem->errors->get_error_message());
     275                        $error = esc_html($wp_filesystem->errors->get_error_message());
    263276                }
    264277
     
    275288    /**
    276289     * Import Settings
    277      * 
     290     *
    278291     * @since 1.4.0
    279292     */
     
    284297        $time_limit = ini_get('max_execution_time');
    285298
    286         if (!did_action('elementor/loaded') || !class_exists(Plugin::class)) {
     299        if (!did_action('elementor/loaded') || !class_exists(Plugin::class))
     300        {
    287301            wp_send_json_error(['message' => esc_html__('Elementor must be active to import settings.', 'addons-for-elementor-builder')]);
    288302        }
     
    292306        $kit_id = isset($_POST['afeb_templates_kit']) ? sanitize_file_name(wp_unslash($_POST['afeb_templates_kit'])) : '';
    293307        $random_number = substr(str_shuffle('0123456789abcdefghijklmnopqrstvwxyzABCDEFGHIJKLMNOPQRSTVWXYZ'), 0, 7);
    294         $site_settings = @file_get_contents('https://cdn.webilia.com/u/c/vertex/' . $kit_id . '/site-settings.json?' . $random_number);
    295308        $error = '';
    296 
    297         if ($site_settings !== false) {
    298             $site_settings = json_decode($site_settings, true);
    299 
    300             if (!empty($site_settings['settings'])) {
    301                 $kit = Plugin::instance()->kits_manager->get_active_kit();
    302                 $active_kit_id = $kit->get_id();
    303 
    304                 if (!$active_kit_id) {
    305                     $created_default_kit = Plugin::instance()->kits_manager->create_default();
    306 
    307                     if (!$created_default_kit) {
     309        $site_settings_url = 'https://cdn.webilia.com/u/c/vertex/' . $kit_id . '/site-settings.json?' . $random_number;
     310
     311        $response = wp_remote_get($site_settings_url, ['timeout' => 20]);
     312
     313        if (is_wp_error($response))
     314        {
     315            $error = esc_html__('The site settings file could not be retrieved from the destination server. The file address may be incorrect or the destination server may be temporarily experiencing issues.', 'addons-for-elementor-builder');
     316        }
     317        else
     318        {
     319            $body = wp_remote_retrieve_body($response);
     320
     321            if (!empty($body))
     322            {
     323                $decoded_settings = json_decode($body, true);
     324
     325                if (json_last_error() === JSON_ERROR_NONE && is_array($decoded_settings) && !empty($decoded_settings['settings']))
     326                {
     327                    $site_settings = $decoded_settings;
     328
     329                    $kit = Plugin::instance()->kits_manager->get_active_kit();
     330                    $active_kit_id = $kit->get_id();
     331
     332                    if (!$active_kit_id)
     333                    {
     334                        $created_default_kit = Plugin::instance()->kits_manager->create_default();
     335
     336                        if (!$created_default_kit)
     337                        {
     338                            set_time_limit($time_limit);
     339                            wp_send_json_error(['message' => esc_html__('There was a problem creating the default Elementor kit, the default kit cannot be created.', 'addons-for-elementor-builder')]);
     340                        }
     341
     342                        update_option(Manager::OPTION_ACTIVE, $created_default_kit);
     343                        $active_kit_id = $created_default_kit;
     344                    }
     345
     346                    $default_kit = Plugin::instance()->documents->get_doc_for_frontend($active_kit_id);
     347                    $kit_settings = $default_kit->get_settings();
     348                    $new_settings = $site_settings['settings'];
     349                    $settings = array_merge($kit_settings, $new_settings);
     350                    $save_new_settings = $default_kit->save(['settings' => $settings]);
     351
     352                    if ($save_new_settings === true)
     353                    {
     354                        update_option('elementor_disable_color_schemes', 'yes');
     355                        update_option('elementor_disable_typography_schemes', 'yes');
     356
    308357                        set_time_limit($time_limit);
    309                         wp_send_json_error(['message' => esc_html__('There was a problem creating the default Elementor kit, the default kit cannot be created.', 'addons-for-elementor-builder')]);
    310                     }
    311 
    312                     update_option(Manager::OPTION_ACTIVE, $created_default_kit);
    313                     $active_kit_id = $created_default_kit;
    314                 }
    315 
    316                 $default_kit = Plugin::instance()->documents->get_doc_for_frontend($active_kit_id);
    317                 $kit_settings = $default_kit->get_settings();
    318                 $new_settings = $site_settings['settings'];
    319                 $settings = array_merge($kit_settings, $new_settings);
    320                 $save_new_settings = $default_kit->save(['settings' => $settings]);
    321 
    322                 if ($save_new_settings === true) {
    323                     update_option('elementor_disable_color_schemes', 'yes');
    324                     update_option('elementor_disable_typography_schemes', 'yes');
    325 
    326                     set_time_limit($time_limit);
    327                     wp_send_json_success();
    328                 }
    329             } else {
     358                        wp_send_json_success();
     359                    }
     360                }
     361                else
     362                {
     363                    $error = esc_html__('No settings exist. The site settings file may have been downloaded incompletely or it may be corrupted.', 'addons-for-elementor-builder');
     364                }
     365            }
     366            else
     367            {
    330368                $error = esc_html__('No settings exist. The site settings file may have been downloaded incompletely or it may be corrupted.', 'addons-for-elementor-builder');
    331369            }
    332         } else {
    333             $error = esc_html__('The site settings file could not be retrieved from the destination server. The file address may be incorrect or the destination server may be temporarily experiencing issues.', 'addons-for-elementor-builder');
    334370        }
    335371
    336372        set_time_limit($time_limit);
    337373
    338         if (!empty($error)) {
     374        if (!empty($error))
     375        {
    339376            wp_send_json_error(['message' => $error]);
    340377        }
     
    343380    /**
    344381     * Import Templates Kit
    345      * 
     382     *
    346383     * @since 1.4.0
    347384     */
     
    362399            'post_status' => 'any',
    363400            'posts_per_page' => '-1',
    364             'meta_key' => '_afeb_demo_import_item'
     401            'meta_key' => '_afeb_demo_import_item',
    365402        ];
    366403        $error = esc_html__('Previous imported files will not be reset.', 'addons-for-elementor-builder');
     
    371408        $imported_items = new WP_Query($args);
    372409
    373         if ($imported_items->have_posts()) {
    374             while ($imported_items->have_posts()) {
     410        if ($imported_items->have_posts())
     411        {
     412            while ($imported_items->have_posts())
     413            {
    375414                $imported_items->the_post();
    376415
     
    388427            ]);
    389428
    390             if (!empty($imported_terms)) {
     429            if (!empty($imported_terms))
     430            {
    391431                foreach ($imported_terms as $imported_term)
    392432                    wp_delete_term($imported_term->term_id, $imported_term->taxonomy);
    393433            }
    394 
    395             $error = '';
    396         } else {
    397             $error = '';
    398         }
    399 
    400         if (!empty($error)) {
    401             set_time_limit($time_limit);
    402             wp_send_json_error(['message' => $error]);
    403         }
    404 
    405         add_filter('upload_mimes', function ($mimes) {
     434        }
     435
     436        $error = '';
     437        add_filter('upload_mimes', function ($mimes)
     438        {
    406439            // Allow SVG files.
    407             $mimes['svg']  = 'image/svg+xml';
     440            $mimes['svg'] = 'image/svg+xml';
    408441            $mimes['svgz'] = 'image/svg+xml';
    409442
     
    417450        }, 99);
    418451
    419         add_filter('wp_handle_upload_prefilter', function ($file) {
    420             if ($file['type'] === 'image/svg+xml') {
     452        add_filter('wp_handle_upload_prefilter', function ($file)
     453        {
     454            if ($file['type'] === 'image/svg+xml')
     455            {
    421456                $file_content = file_get_contents($file['tmp_name']);
    422457                $sanitized_content = (new Security())->sanitize_svg($file_content);
     
    430465            define('WP_LOAD_IMPORTERS', true);
    431466
    432         if (!class_exists('WP_Import')) {
    433             $wp_importer =  AFEB_ABSPATH . '/app/Modules/WPImport/WPImporter.php';
     467        if (!class_exists('WP_Import'))
     468        {
     469            $wp_importer = AFEB_ABSPATH . '/app/Modules/WPImport/WPImporter.php';
    434470            if (file_exists($wp_importer)) require $wp_importer;
    435471        }
    436472
    437         if (class_exists('AFEB\Modules\WPImport\WPImport')) {
     473        if (class_exists('AFEB\Modules\WPImport\WPImport'))
     474        {
    438475            $kit_id = isset($_POST['afeb_templates_kit']) ? sanitize_file_name(wp_unslash($_POST['afeb_templates_kit'])) : '';
    439476
     
    452489            $result = serialize($wp_import);
    453490
    454             if (strpos($result, 'summary') !== false) {
     491            if (strpos($result, 'summary') !== false)
     492            {
    455493
    456494                $templates_kit->fix_elementor_images($kit_id);
    457 
    458495                $templates_kit->setup_templates($kit_id);
    459496
     
    465502                set_time_limit($time_limit);
    466503                wp_send_json_success();
    467             } else {
     504            }
     505            else
     506            {
    468507                $wp_import = array_values((array) $wp_import);
    469508
    470                 foreach ($wp_import as $key => $value) {
     509                foreach ($wp_import as $value)
     510                {
    471511                    if (
    472512                        isset($value['status']) &&
    473513                        isset($value['errors'])
    474                     ) {
     514                    )
     515                    {
    475516                        $error = isset($value['errors'][0]) ? esc_html($value['errors'][0]) : '';
    476517                    }
    477518                }
    478519            }
    479         } else {
     520        }
     521        else
     522        {
    480523            $error = esc_html__('Operation not completed, Class WPImport does not exist.', 'addons-for-elementor-builder');
    481524        }
     
    496539        $template_id = !empty($_POST['data']['template_id']) ? intval(wp_unslash($_POST['data']['template_id'])) : -1;
    497540
    498         if ($template_id !== -1) {
     541        if ($template_id !== -1)
     542        {
    499543            $post_type = !empty($_POST['data']['post_type']) ? sanitize_text_field(wp_unslash($_POST['data']['post_type'])) : '';
    500544            $number_of_items = !empty($_POST['data']['number_of_items']) ? intval(wp_unslash($_POST['data']['number_of_items'])) : 5;
     
    516560            $is_content = $helper->dynamic_loop_item($template_id, $query->posts);
    517561
    518             if (!$is_content) {
     562            if (!$is_content)
     563            {
    519564                echo -1;
    520565            }
     
    527572    }
    528573
    529     public function afeb_update_submission_handler() {
    530 
    531         if ( ! current_user_can( 'edit_posts' ) ) {
    532             wp_send_json_error( __( 'Permission denied.', 'addons-for-elementor-builder' ) );
    533         }
    534 
    535         $submission_id = intval( $_POST['post_id'] ?? 0 );
    536         if ( ! $submission_id ) {
    537             wp_send_json_error( __( 'Invalid submission ID.', 'addons-for-elementor-builder' ) );
     574    public function afeb_update_submission_handler()
     575    {
     576
     577        if (!current_user_can('edit_posts'))
     578        {
     579            wp_send_json_error(__('Permission denied.', 'addons-for-elementor-builder'));
     580        }
     581
     582        $submission_id = intval($_POST['post_id'] ?? 0);
     583        if (!$submission_id)
     584        {
     585            wp_send_json_error(__('Invalid submission ID.', 'addons-for-elementor-builder'));
    538586        }
    539587
    540588        // Get original form reference
    541         $page_id = intval( get_post_meta( $submission_id, 'afeb_page_id', true ) );
    542         $form_id = sanitize_text_field( get_post_meta( $submission_id, 'afeb_form_id', true ) );
    543 
    544         if ( ! $page_id || ! $form_id ) {
    545             wp_send_json_error( __( 'Parent form reference not found.', 'addons-for-elementor-builder' ) );
    546         }
    547 
    548         $current_meta = get_post_meta( $submission_id, 'afeb_form_fields', true );
    549         $current_meta = is_array( $current_meta ) ? $current_meta : [];
     589        $page_id = intval(get_post_meta($submission_id, 'afeb_page_id', true));
     590        $form_id = sanitize_text_field(get_post_meta($submission_id, 'afeb_form_id', true));
     591
     592        if (!$page_id || !$form_id)
     593        {
     594            wp_send_json_error(__('Parent form reference not found.', 'addons-for-elementor-builder'));
     595        }
     596
     597        $current_meta = get_post_meta($submission_id, 'afeb_form_fields', true);
     598        $current_meta = is_array($current_meta) ? $current_meta : [];
    550599
    551600        // Load Elementor widget settings
    552         $settings         = \AFEB\Widgets::get_widget_preview_settings( $page_id, $form_id );
    553         $original_fields  = $settings['form_fields'] ?? [];
     601        $settings = Widgets::get_widget_preview_settings($page_id, $form_id);
     602        $original_fields = $settings['form_fields'] ?? [];
    554603
    555604        // Posted values from admin editor
    556         $submitted_fields  = isset( $_POST['form_fields'] ) && is_array( $_POST['form_fields'] ) ? $_POST['form_fields'] : [];
    557 
    558         if ( empty( $submitted_fields ) ) {
    559             $fallback_fields = isset( $_POST['afeb-form-fields'] ) && is_array( $_POST['afeb-form-fields'] ) ? wp_unslash( $_POST['afeb-form-fields'] ) : [];
    560 
    561             if ( ! empty( $fallback_fields ) && ! empty( $current_meta ) ) {
    562                 foreach ( $current_meta as $index => $meta_field ) {
     605        $submitted_fields = isset($_POST['form_fields']) && is_array($_POST['form_fields']) ? $_POST['form_fields'] : [];
     606
     607        if (empty($submitted_fields))
     608        {
     609            $fallback_fields = isset($_POST['afeb-form-fields']) && is_array($_POST['afeb-form-fields']) ? wp_unslash($_POST['afeb-form-fields']) : [];
     610
     611            if (!empty($fallback_fields) && !empty($current_meta))
     612            {
     613                foreach ($current_meta as $index => $meta_field)
     614                {
    563615                    $raw_value = null;
    564616
    565                     if ( array_key_exists( $index, $fallback_fields ) ) {
    566                         $raw_value = $fallback_fields[ $index ];
    567                     } elseif ( isset( $meta_field['_id'] ) && array_key_exists( $meta_field['_id'], $fallback_fields ) ) {
    568                         $raw_value = $fallback_fields[ $meta_field['_id'] ];
    569                     }
    570 
    571                     if ( null === $raw_value ) {
     617                    if (array_key_exists($index, $fallback_fields))
     618                    {
     619                        $raw_value = $fallback_fields[$index];
     620                    }
     621                    else if (isset($meta_field['_id']) && array_key_exists($meta_field['_id'], $fallback_fields))
     622                    {
     623                        $raw_value = $fallback_fields[$meta_field['_id']];
     624                    }
     625
     626                    if (null === $raw_value)
     627                    {
    572628                        continue;
    573629                    }
    574630
    575                     if ( 'checkbox' === ( $meta_field['type'] ?? '' ) ) {
    576                         $raw_value = is_array( $raw_value )
    577                             ? array_values( array_filter( array_map( 'wp_unslash', $raw_value ), 'strlen' ) )
    578                             : (array) wp_unslash( $raw_value );
    579                     } elseif ( 'upload' === ( $meta_field['type'] ?? '' ) ) {
    580                         $raw_value = array_values( array_filter( (array) $raw_value ) );
    581                     }
    582 
    583                     $submitted_fields[] = array_merge( $meta_field, [ 'value' => $raw_value ] );
    584                 }
    585             }
    586         }
    587 
    588         if ( ! isset( $_FILES['form_files'] ) && isset( $_FILES['afeb-form-fields'] ) && ! empty( $current_meta ) ) {
     631                    if ('checkbox' === ($meta_field['type'] ?? ''))
     632                    {
     633                        $raw_value = is_array($raw_value)
     634                            ? array_values(array_filter(array_map('wp_unslash', $raw_value), 'strlen'))
     635                            : (array) wp_unslash($raw_value);
     636                    }
     637                    else if ('upload' === ($meta_field['type'] ?? ''))
     638                    {
     639                        $raw_value = array_values(array_filter((array) $raw_value));
     640                    }
     641
     642                    $submitted_fields[] = array_merge($meta_field, ['value' => $raw_value]);
     643                }
     644            }
     645        }
     646
     647        if (!isset($_FILES['form_files']) && isset($_FILES['afeb-form-fields']) && !empty($current_meta))
     648        {
    589649            $files = $_FILES['afeb-form-fields'];
    590650            $_FILES['form_files'] = [
    591                 'name'     => [],
    592                 'type'     => [],
     651                'name' => [],
     652                'type' => [],
    593653                'tmp_name' => [],
    594                 'error'    => [],
    595                 'size'     => [],
     654                'error' => [],
     655                'size' => [],
    596656            ];
    597657
    598             foreach ( $current_meta as $index => $meta_field ) {
     658            foreach ($current_meta as $index => $meta_field)
     659            {
    599660                $fid = $meta_field['_id'] ?? $index;
    600661
    601                 foreach ( [ 'name', 'type', 'tmp_name', 'error', 'size' ] as $prop ) {
    602                     if ( isset( $files[ $prop ][ $index ] ) ) {
    603                         $_FILES['form_files'][ $prop ][ $fid ] = $files[ $prop ][ $index ];
    604                     }
    605                 }
    606             }
    607         }
    608         $new_fields_meta   = [];
    609         $field_errors      = [];
    610 
    611         if ( ! empty( $submitted_fields ) && ! empty( $current_meta ) ) {
     662                foreach (['name', 'type', 'tmp_name', 'error', 'size'] as $prop)
     663                {
     664                    if (isset($files[$prop][$index]))
     665                    {
     666                        $_FILES['form_files'][$prop][$fid] = $files[$prop][$index];
     667                    }
     668                }
     669            }
     670        }
     671        $new_fields_meta = [];
     672        $field_errors = [];
     673
     674        if (!empty($submitted_fields) && !empty($current_meta))
     675        {
    612676            $current_meta_by_id = [];
    613             foreach ( $current_meta as $meta_field ) {
    614                 if ( empty( $meta_field['_id'] ) ) {
     677            foreach ($current_meta as $meta_field)
     678            {
     679                if (empty($meta_field['_id']))
     680                {
    615681                    continue;
    616682                }
    617                 $current_meta_by_id[ $meta_field['_id'] ] = $meta_field;
    618             }
    619 
    620             foreach ( $submitted_fields as $idx => $field ) {
     683                $current_meta_by_id[$meta_field['_id']] = $meta_field;
     684            }
     685
     686            foreach ($submitted_fields as $idx => $field)
     687            {
    621688                $fid = $field['_id'] ?? '';
    622689
    623                 if ( $fid && isset( $current_meta_by_id[ $fid ] ) ) {
    624                     $submitted_fields[ $idx ] = array_merge( $current_meta_by_id[ $fid ], $field );
    625                 } elseif ( isset( $current_meta[ $idx ] ) && is_array( $current_meta[ $idx ] ) ) {
    626                     $submitted_fields[ $idx ] = array_merge( $current_meta[ $idx ], $field );
    627                 }
    628             }
    629         }
    630 
    631         foreach ( $submitted_fields as $field ) {
    632             $fid   = $field['_id'] ?? '';
    633             $type  = $field['type'] ?? 'text';
     690                if ($fid && isset($current_meta_by_id[$fid]))
     691                {
     692                    $submitted_fields[$idx] = array_merge($current_meta_by_id[$fid], $field);
     693                }
     694                else if (isset($current_meta[$idx]) && is_array($current_meta[$idx]))
     695                {
     696                    $submitted_fields[$idx] = array_merge($current_meta[$idx], $field);
     697                }
     698            }
     699        }
     700
     701        foreach ($submitted_fields as $field)
     702        {
     703            $fid = $field['_id'] ?? '';
     704            $type = $field['type'] ?? 'text';
    634705            $value = $field['value'] ?? [];
    635706
    636707            // Match saved Elementor definition
    637708            $original = null;
    638             foreach ( $original_fields as $of ) {
    639                 if ( ! empty( $of['field_id'] ) && $of['field_id'] === $fid ) {
     709            foreach ($original_fields as $of)
     710            {
     711                if (!empty($of['field_id']) && $of['field_id'] === $fid)
     712                {
    640713                    $original = $of;
    641714                    break;
     
    643716            }
    644717
    645             if ( $type === 'upload' && $original ) {
     718            if ($type === 'upload' && $original)
     719            {
    646720                // Extract validation rules
    647                 $allowed_exts  = ! empty( $original['allowed_file_types'] )
    648                     ? array_map( 'strtolower', array_map( 'trim', explode( ',', $original['allowed_file_types'] ) ) )
     721                $allowed_exts = !empty($original['allowed_file_types'])
     722                    ? array_map('strtolower', array_map('trim', explode(',', $original['allowed_file_types'])))
    649723                    : [];
    650724                $allowed_mimes = wp_get_mime_types();
    651                 if ( ! empty( $allowed_exts ) ) {
    652                     $allowed_mimes = array_intersect_key( $allowed_mimes, array_flip( $allowed_exts ) );
    653                 }
    654                 $max_size    = ! empty( $original['max_file_size'] ) ? intval( $original['max_file_size'] ) * 1024 : 0; // KB → bytes
    655                 $is_required = ! empty( $original['required'] );
     725                if (!empty($allowed_exts))
     726                {
     727                    $allowed_mimes = array_intersect_key($allowed_mimes, array_flip($allowed_exts));
     728                }
     729                $max_size = !empty($original['max_file_size']) ? intval($original['max_file_size']) * 1024 : 0; // KB → bytes
     730                $is_required = !empty($original['required']);
    656731
    657732                // Normalize from $_FILES
    658733                $file_data = [];
    659                 if ( isset( $_FILES['form_files']['name'][ $fid ] ) ) {
    660                     foreach ( (array) $_FILES['form_files']['name'][ $fid ] as $idx => $name ) {
    661                         if ( ! $name ) {
     734                if (isset($_FILES['form_files']['name'][$fid]))
     735                {
     736                    foreach ((array) $_FILES['form_files']['name'][$fid] as $idx => $name)
     737                    {
     738                        if (!$name)
     739                        {
    662740                            continue;
    663741                        }
    664742                        $file_data[] = [
    665                             'name'     => $_FILES['form_files']['name'][ $fid ][ $idx ],
    666                             'type'     => $_FILES['form_files']['type'][ $fid ][ $idx ],
    667                             'tmp_name' => $_FILES['form_files']['tmp_name'][ $fid ][ $idx ],
    668                             'error'    => $_FILES['form_files']['error'][ $fid ][ $idx ],
    669                             'size'     => $_FILES['form_files']['size'][ $fid ][ $idx ],
     743                            'name' => $_FILES['form_files']['name'][$fid][$idx],
     744                            'type' => $_FILES['form_files']['type'][$fid][$idx],
     745                            'tmp_name' => $_FILES['form_files']['tmp_name'][$fid][$idx],
     746                            'error' => $_FILES['form_files']['error'][$fid][$idx],
     747                            'size' => $_FILES['form_files']['size'][$fid][$idx],
    670748                        ];
    671749                    }
     
    674752                // Validate
    675753                $validation = \AFEB\Widgets\FormBuilder\Helper::validate_uploaded_files(
    676                     ! empty( $file_data ) ? $file_data : (array) $value,
     754                    !empty($file_data) ? $file_data : (array) $value,
    677755                    [
    678756                        'mime_types' => $allowed_mimes,
    679                         'exts'       => $allowed_exts,
    680                         'max_size'   => $max_size,
     757                        'exts' => $allowed_exts,
     758                        'max_size' => $max_size,
    681759                    ],
    682760                    $is_required
    683761                );
    684762
    685                 if ( ! $validation['valid'] ) {
    686                     $field_errors[ $fid ] = $validation['errors'];
    687                 }
    688 
    689                 $new_fields_meta[] = array_merge( $field, [ 'value' => $validation['files'] ?? [] ] );
    690             }
    691             else {
     763                if (!$validation['valid'])
     764                {
     765                    $field_errors[$fid] = $validation['errors'];
     766                }
     767
     768                $new_fields_meta[] = array_merge($field, ['value' => $validation['files'] ?? []]);
     769            }
     770            else
     771            {
    692772                // Non-upload fields, keep sanitized value
    693                 if ( is_array( $value ) ) {
    694                     $sanitized = map_deep( $value, 'sanitize_text_field' );
    695                 } else {
    696                     $sanitized = sanitize_text_field( $value );
    697                 }
    698                 $new_fields_meta[] = array_merge( $field, [ 'value' => $sanitized ] );
    699             }
    700         }
    701 
    702         if ( ! empty( $field_errors ) ) {
    703             wp_send_json_error( [
    704                 'message' => __( 'Some fields have errors.', 'addons-for-elementor-builder' ),
    705                 'errors'  => $field_errors,
    706             ] );
     773                if (is_array($value))
     774                {
     775                    $sanitized = map_deep($value, 'sanitize_text_field');
     776                }
     777                else
     778                {
     779                    $sanitized = sanitize_text_field($value);
     780                }
     781                $new_fields_meta[] = array_merge($field, ['value' => $sanitized]);
     782            }
     783        }
     784
     785        if (!empty($field_errors))
     786        {
     787            wp_send_json_error([
     788                'message' => __('Some fields have errors.', 'addons-for-elementor-builder'),
     789                'errors' => $field_errors,
     790            ]);
    707791        }
    708792
    709793        // Save updated meta
    710         update_post_meta( $submission_id, 'afeb_form_fields', $new_fields_meta );
    711 
    712         wp_send_json_success( __( 'Submission updated successfully.', 'addons-for-elementor-builder' ) );
    713     }
    714 
     794        update_post_meta($submission_id, 'afeb_form_fields', $new_fields_meta);
     795
     796        wp_send_json_success(__('Submission updated successfully.', 'addons-for-elementor-builder'));
     797    }
    715798}
  • addons-for-elementor-builder/trunk/app/Assets.php

    r3382971 r3386622  
    8989        );
    9090
    91         // Swiper (rollback to afterInit-supporting version)
    92         wp_enqueue_style(
    93             'afeb-swiper',
    94             'https://unpkg.com/[email protected]/swiper-bundle.min.css',
    95             [],
    96             '7.4.1'
    97         );
    98 
    99         wp_enqueue_script(
    100             'afeb-swiper',
    101             'https://unpkg.com/[email protected]/swiper-bundle.min.js',
    102             [],
    103             '7.4.1',
    104             false
    105         );
     91        // Swiper
     92        $this->register_swiper_assets();
     93        wp_enqueue_style('swiper');
     94        wp_enqueue_script('swiper');
    10695
    10796        // Lightbox
    108         wp_enqueue_style(
    109             'afeb-lightbox',
    110             'https://cdnjs.cloudflare.com/ajax/libs/glightbox/3.2.0/css/glightbox.min.css',
    111             [],
    112             '3.2.0'
    113         );
    114 
    115         wp_enqueue_script(
    116             'afeb-lightbox',
    117             'https://cdnjs.cloudflare.com/ajax/libs/glightbox/3.2.0/js/glightbox.min.js',
    118             [],
    119             '3.2.0',
    120             true
    121         );
     97        $this->register_glightbox_assets();
     98        wp_enqueue_style('glightbox');
     99        wp_enqueue_script('glightbox');
    122100
    123101        // Widget JS
     
    125103            'afeb-woo-product-images',
    126104            $this->assets_url('js/afeb-woo-product-images.js'),
    127             ['jquery', 'afeb-swiper', 'afeb-lightbox'],
     105            ['jquery', 'swiper', 'glightbox'],
    128106            AFEB_VERSION,
    129107            true
     
    163141    {
    164142        $handle = 'afeb-woo-product-images';
     143        $this->register_swiper_assets();
     144        $this->register_glightbox_assets();
    165145        wp_register_script(
    166146            $handle,
    167147            $this->assets_url('js/afeb-woo-product-images.js'),
    168             ['jquery'],
     148            ['jquery', 'swiper', 'glightbox'],
    169149            AFEB_VERSION,
    170150            true
     
    14991479    }
    15001480
     1481    private function register_swiper_assets()
     1482    {
     1483        if (!wp_style_is('swiper', 'registered'))
     1484        {
     1485            wp_register_style(
     1486                'swiper',
     1487                $this->assets_url('packages/swiper/swiper-bundle.min.css'),
     1488                [],
     1489                '9.3.2'
     1490            );
     1491        }
     1492
     1493        if (!wp_script_is('swiper', 'registered'))
     1494        {
     1495            wp_register_script(
     1496                'swiper',
     1497                $this->assets_url('packages/swiper/swiper-bundle.min.js'),
     1498                [],
     1499                '9.3.2',
     1500                true
     1501            );
     1502        }
     1503    }
     1504
     1505    private function register_glightbox_assets()
     1506    {
     1507        if (!wp_style_is('glightbox', 'registered'))
     1508        {
     1509            wp_register_style(
     1510                'glightbox',
     1511                $this->assets_url('packages/glightbox/glightbox.min.css'),
     1512                [],
     1513                '3.2.0'
     1514            );
     1515        }
     1516
     1517        if (!wp_script_is('glightbox', 'registered'))
     1518        {
     1519            wp_register_script(
     1520                'glightbox',
     1521                $this->assets_url('packages/glightbox/glightbox.min.js'),
     1522                [],
     1523                '3.2.0',
     1524                true
     1525            );
     1526        }
     1527    }
     1528
    15011529    public function woo_add_to_cart_script()
    15021530    {
  • addons-for-elementor-builder/trunk/app/Base.php

    r3382971 r3386622  
    3131     */
    3232    const AFEB_URL = 'https://vertexaddons.com';
     33
     34    /**
     35     * "Vertex Addons for Elementor" Contact URL
     36     */
     37    const AFEB_CONTACT_URL = 'https://vertexaddons.com/contact';
    3338
    3439    /**
  • addons-for-elementor-builder/trunk/app/Documents/Builder.php

    r3297649 r3386622  
    6060
    6161        add_action('elementor/widgets/register', function ($widgets_manager) {
    62             $options = get_option('afeb-widgets-status', []);
     62            $options = array_merge(
     63                (array) get_option('afeb-widgets-status', []),
     64                (array) get_option('afeb-3rdpt-widgets-status', [])
     65            );
    6366            $widgets = $this->widgets->get_template_builder_widgets();
    6467            $widgets = array_replace_recursive($widgets, $options);
  • addons-for-elementor-builder/trunk/app/Handler/Widgets/FormBuilderHandler.php

    r3382971 r3386622  
    368368            'post_title'  => $form_title ?: "Vertex Submission",
    369369            'post_type'   => Submissions::SUBMISSIONS_POST_TYPE,
    370         ]);
    371 
    372         if (!$id) return false;
     370        ], true);
     371
     372        if (is_wp_error($id) || !$id) return false;
    373373
    374374        if (trim($form_title)) update_post_meta($id, 'afeb_form_name', $form_title);
  • addons-for-elementor-builder/trunk/app/I18n.php

    r3297649 r3386622  
    4242            load_textdomain('addons-for-elementor-builder', $language_file_path);
    4343        }
    44         else
    45         {
    46             // Otherwise use plugin directory /path/to/plugin/i18n/languages/addons-for-elementor-builder-en_US.mo
    47             load_plugin_textdomain('addons-for-elementor-builder', false, dirname(AFEB_BASENAME) . '/i18n/languages/');
    48         }
    4944    }
    5045}
  • addons-for-elementor-builder/trunk/app/Modules/DynamicTags/Tags/Author/AuthorURL.php

    r3297649 r3386622  
    7777    public function get_value(array $options = [])
    7878    {
    79         return get_author_posts_url(get_the_author_ID());
     79        return get_author_posts_url(get_the_author_meta('ID'));
    8080    }
    8181}
  • addons-for-elementor-builder/trunk/app/Widgets.php

    r3382971 r3386622  
    225225                'image' => 'search-form.svg',
    226226            ],
    227             'Woo_MyAccount' => [
    228                 'title' => esc_html__('Woo My Account', 'addons-for-elementor-builder'),
    229                 'status' => 1,
    230                 'class' => 'MyAccount',
    231                 'nsp' => 'Woo',
    232                 'image' => 'myacc.svg',
    233             ],
    234227            'Site_Logo' => [
    235228                'title' => esc_html__('Site Logo', 'addons-for-elementor-builder'),
     
    268261                'nsp' => 1,
    269262                'image' => 'timeline.svg',
    270             ],
    271             'Woo_Checkout' => [
    272                 'title' => esc_html__('Woo Checkout', 'addons-for-elementor-builder'),
    273                 'status' => 1,
    274                 'class' => 'Checkout',
    275                 'nsp' => 'Woo',
    276                 'image' => 'checkout.svg',
    277             ],
    278             'ProductCategory' => [
    279                 'title' => esc_html__('Woo Product Category', 'addons-for-elementor-builder'),
    280                 'status' => class_exists('WooCommerce') ? 1 : 0,
    281                 'nsp' => 'Woo',
    282                 'image' => 'products-category.svg',
    283             ],
    284             'ProductTags' => [
    285                 'title' => esc_html__('Woo Product Tags', 'addons-for-elementor-builder'),
    286                 'status' => 1,
    287                 'categories' => 'single, woocommerce-elements-single',
    288                 'nsp' => 'Woo',
    289                 'image' => 'product-tags.svg',
    290263            ],
    291264        ];
     
    393366                'image' => 'site-title.svg',
    394367            ],
    395             'ProductImage' => [
    396                 'title' => esc_html__('Product Image', 'addons-for-elementor-builder'),
    397                 'status' => 1,
    398                 'categories' => 'single, woocommerce-elements-single',
    399                 'nsp' => 'Woo',
    400                 'image' => 'product-img.svg',
    401             ],
    402             'Add_To_Cart' => [
    403                 'title' => esc_html__('Woo Add To Cart', 'addons-for-elementor-builder'),
    404                 'status' => 1,
    405                 'nsp' => 'Woo',
    406                 'image' => 'add-to-cart.svg',
    407             ],
    408             'ProductExcerpt' => [
    409                 'title' => esc_html__('Product Excerpt', 'addons-for-elementor-builder'),
    410                 'status' => 1,
    411                 'categories' => 'single, woocommerce-elements-single',
    412                 'nsp' => 'Woo',
    413                 'image' => 'product-excerpt.svg',
    414             ],
    415             'ProductContent' => [
    416                 'title' => esc_html__('Product Content', 'addons-for-elementor-builder'),
    417                 'status' => 1,
    418                 'categories' => 'single, woocommerce-elements-single',
    419                 'nsp' => 'Woo',
    420                 'image' => 'product-content.svg',
    421             ]
    422368        ];
    423369        return $widgets;
     
    440386        foreach ($template_builder_widgets as $widget_key => $widget)
    441387            $widgets[$widget_key] = $widget;
     388
     389        foreach ($this->trdpt_widgets() as $widget_key => $widget) {
     390            if (!empty($widget['template_builder'])) {
     391                $widgets[$widget_key] = $widget;
     392            }
     393        }
    442394
    443395        return $widgets;
     
    543495    public function trdpt_widgets()
    544496    {
    545         $output = [];
     497        $woo_status = class_exists('WooCommerce') ? 1 : 0;
     498
     499        $output = [
     500            'Woo_MyAccount' => [
     501                'title' => esc_html__('Woo My Account', 'addons-for-elementor-builder'),
     502                'status' => $woo_status,
     503                'class' => 'MyAccount',
     504                'nsp' => 'Woo',
     505                'image' => 'myacc.svg',
     506            ],
     507            'Woo_Checkout' => [
     508                'title' => esc_html__('Woo Checkout', 'addons-for-elementor-builder'),
     509                'status' => $woo_status,
     510                'class' => 'Checkout',
     511                'nsp' => 'Woo',
     512                'image' => 'checkout.svg',
     513            ],
     514            'ProductCategory' => [
     515                'title' => esc_html__('Woo Product Category', 'addons-for-elementor-builder'),
     516                'status' => $woo_status,
     517                'nsp' => 'Woo',
     518                'image' => 'products-category.svg',
     519            ],
     520            'ProductTags' => [
     521                'title' => esc_html__('Woo Product Tags', 'addons-for-elementor-builder'),
     522                'status' => $woo_status,
     523                'categories' => 'single, woocommerce-elements-single',
     524                'nsp' => 'Woo',
     525                'image' => 'product-tags.svg',
     526            ],
     527            'ProductImage' => [
     528                'title' => esc_html__('Product Image', 'addons-for-elementor-builder'),
     529                'status' => $woo_status,
     530                'categories' => 'single, woocommerce-elements-single',
     531                'nsp' => 'Woo',
     532                'image' => 'product-img.svg',
     533                'template_builder' => true,
     534            ],
     535            'Add_To_Cart' => [
     536                'title' => esc_html__('Woo Add To Cart', 'addons-for-elementor-builder'),
     537                'status' => $woo_status,
     538                'nsp' => 'Woo',
     539                'image' => 'add-to-cart.svg',
     540                'template_builder' => true,
     541            ],
     542            'ProductExcerpt' => [
     543                'title' => esc_html__('Product Excerpt', 'addons-for-elementor-builder'),
     544                'status' => $woo_status,
     545                'categories' => 'single, woocommerce-elements-single',
     546                'nsp' => 'Woo',
     547                'image' => 'product-excerpt.svg',
     548                'template_builder' => true,
     549            ],
     550            'ProductContent' => [
     551                'title' => esc_html__('Product Content', 'addons-for-elementor-builder'),
     552                'status' => $woo_status,
     553                'categories' => 'single, woocommerce-elements-single',
     554                'nsp' => 'Woo',
     555                'image' => 'product-content.svg',
     556                'template_builder' => true,
     557            ],
     558        ];
     559
    546560        return apply_filters('afeb/widgets/trdpt_widgets', $output);
    547561    }
     
    559573    {
    560574        $output = ['pname' => '', 'ppath' => ''];
     575
     576        $woocommerce_widgets = [
     577            'Woo_MyAccount',
     578            'Woo_Checkout',
     579            'ProductCategory',
     580            'ProductTags',
     581            'ProductImage',
     582            'Add_To_Cart',
     583            'ProductExcerpt',
     584            'ProductContent',
     585        ];
     586
     587        if (strpos($widgets_key, 'Woo') !== false || in_array($widgets_key, $woocommerce_widgets, true)) {
     588            $output['pname'] = 'woocommerce';
     589            $output['ppath'] = $output['pname'] . '/woocommerce.php';
     590        }
     591
    561592        return apply_filters('afeb/widgets/trdpt_plugins', $output, $widgets_key);
    562593    }
     
    574605    {
    575606        foreach ($widgets as $widget_key => $widget) {
     607            if (!empty($widget['template_builder']) && $name_space !== 'TemplateBuilder') {
     608                continue;
     609            }
     610
    576611            if (isset($widget['status']) && $widget['status'] == 1) {
    577612
  • addons-for-elementor-builder/trunk/app/Widgets/FancyText.php

    r3297649 r3386622  
    222222        $classes[] = in_array($settings['ft_efct'], ['typing', 'rotate-2', 'rotate-3', 'scale']) ?
    223223            'afeb-anim-text-letters' : '';
     224
     225        $classes = array_filter($classes);
     226        $classes = array_map('sanitize_html_class', $classes);
    224227        $this->add_render_attribute(
    225228            [
    226229                'fancy_text' => [
    227                     'class' => implode(' ', array_filter($classes, 'esc_attr')),
     230                    'class' => implode(' ', $classes),
    228231                    'data-settings' => [
    229232                        wp_json_encode([
     
    236239        );
    237240
    238         echo $this->get_render_attribute_string('fancy_text');
    239241    }
    240242
     
    255257            in_array($settings['ft_html_tg'], $html_tags)) ?
    256258            $settings['ft_html_tg'] : 'h3';
    257         $type = !empty($settings['ft_efct']) ? $settings['ft_efct'] : 'typing'; ?>
    258         <<?php echo $html_tag; ?> <?php $this->render_attrs($settings); ?>>
     259        $type = !empty($settings['ft_efct']) ? $settings['ft_efct'] : 'typing';
     260        $this->render_attrs($settings);
     261        $escaped_html_tag = tag_escape($html_tag);
     262        ?>
     263        <<?php echo $escaped_html_tag; ?> <?php $this->print_render_attribute_string('fancy_text'); ?>>
    259264
    260265            <?php if (!empty($settings['ft_prfx_txt'])): ?>
     
    287292            <?php endif; ?>
    288293
    289         </<?php echo $html_tag; ?>>
     294        </<?php echo $escaped_html_tag; ?>>
    290295<?php }
    291296}
  • addons-for-elementor-builder/trunk/app/Widgets/FormBuilder/FormBuilder.php

    r3382971 r3386622  
    15681568                    Icons_Manager::render_icon($value['step_icon'], ['aria-hidden' => 'true']);
    15691569                    $step_icon[] = ob_get_clean();
    1570                     $step_label[] = '<span class="afeb-step-main-label">' . $value['field_label'] . '</span>';
    1571                     $step_sub_label[] = '<span class="afeb-step-sub-label">' . $value['field_sub_label'] . '</span>';
     1570                    $step_label[] = sprintf(
     1571                        '<span class="afeb-step-main-label">%s</span>',
     1572                        esc_html($value['field_label'])
     1573                    );
     1574                    $step_sub_label[] = sprintf(
     1575                        '<span class="afeb-step-sub-label">%s</span>',
     1576                        esc_html($value['field_sub_label'])
     1577                    );
    15721578                }
    15731579            }
     
    16021608                        $step_html = '<span class="afeb-step"><span class="afeb-step-content">' . $step_icon[$i] . '</span><span class="afeb-step-label">' . $step_label[$i] . $step_sub_label[$i] . '</span></span>';
    16031609
    1604                     echo $step_html;
     1610                    echo wp_kses_post($step_html);
    16051611
    16061612                    if ($settings['show_separator'] == 'yes') {
     
    16131619            echo '</div>';
    16141620            ?>
    1615             <div <?php echo $this->get_render_attribute_string('wrapper'); ?>>
     1621            <div <?php $this->print_render_attribute_string('wrapper'); ?>>
    16161622                <?php
    16171623                $step_count = 0;
     
    17661772                $_COOKIE['afeb_form_submit_success_' . $this->get_id()] = !empty($settings['success_message']) ?
    17671773                    $settings['success_message'] : OldCHelper::$LIM;
    1768             if (!empty($_COOKIE['afeb_form_submit_success_' . $this->get_id()])): ?>
     1774            $form_submit_success_cookie_key = 'afeb_form_submit_success_' . $this->get_id();
     1775            $form_submit_success_message = '';
     1776            if (!empty($_COOKIE[$form_submit_success_cookie_key])) {
     1777                $form_submit_success_message = sanitize_text_field(wp_unslash($_COOKIE[$form_submit_success_cookie_key]));
     1778            }
     1779            if (!empty($form_submit_success_message)): ?>
    17691780                <div class="afeb-field-group afeb-form-builder-message-group">
    17701781                    <div class="afeb-form-builder-success-box">
    1771                         <?php echo esc_html($_COOKIE['afeb_form_submit_success_' . $this->get_id()]); ?>
     1782                        <?php echo esc_html($form_submit_success_message); ?>
    17721783                    </div>
    17731784                </div>
     
    17771788                $_COOKIE['afeb_form_submit_error_' . $this->get_id()] = !empty($settings['error_message']) ?
    17781789                    $settings['error_message'] : OldCHelper::$LIM;
    1779             if (!empty($_COOKIE['afeb_form_submit_error_' . $this->get_id()])) :
     1790            $form_submit_error_cookie_key = 'afeb_form_submit_error_' . $this->get_id();
     1791            $form_submit_error_message = '';
     1792            if (!empty($_COOKIE[$form_submit_error_cookie_key])) {
     1793                $form_submit_error_message = sanitize_text_field(wp_unslash($_COOKIE[$form_submit_error_cookie_key]));
     1794            }
     1795            if (!empty($form_submit_error_message)) :
    17801796            ?>
    17811797                <div class="afeb-field-group afeb-form-builder-message-group">
    17821798                    <div class="afeb-form-builder-error-box">
    1783                         <?php echo esc_html($_COOKIE['afeb_form_submit_error_' . $this->get_id()]); ?>
     1799                        <?php echo esc_html($form_submit_error_message); ?>
    17841800                    </div>
    17851801                </div>
  • addons-for-elementor-builder/trunk/app/Widgets/FormBuilder/Helper.php

    r3382971 r3386622  
    55use Elementor\Icons_Manager;
    66use Elementor\Utils;
    7 
    8 if (!defined('ABSPATH')) {
    9     exit;
    10 }
     7use function wp_handle_upload;
    118
    129/**
    1310 * "Vertex Addons for Elementor" FormBuilder Widget Helper Class
    14  * 
     11 *
    1512 * @class Helper
    1613 * @version 1.4.0
     
    2017    public function form_fields_render_attributes($context, $i, $settings, $item)
    2118    {
     19        $field_identifier = $this->get_field_identifier($item);
     20
    2221        $context->add_render_attribute(
    2322            [
     
    2726                        'afeb-field-group',
    2827                        'afeb-column',
    29                         'afeb-field-group-' . esc_attr($item['field_id']),
     28                        'afeb-field-group-' . esc_attr($field_identifier),
    3029                    ],
    3130                ],
    3231                'input' . $i => [
    33                     'type' => ('acceptance' === $item['field_type']) ? 'checkbox' : (($item['field_type'] === 'upload') ? 'file' :  $item['field_type']),
     32                    'type' => ('acceptance' === $item['field_type']) ? 'checkbox' : (($item['field_type'] === 'upload') ? 'file' : $item['field_type']),
    3433                    'name' => $this->get_attribute_name($item),
    3534                    'id' => $this->get_attribute_id($item),
     
    6059            $context->add_render_attribute('label' . $i, 'class', 'afeb-hidden-element');
    6160
    62         if (!empty($item['required'])) {
     61        if (!empty($item['required']))
     62        {
    6363            $class = 'afeb-form-field-required';
    6464            if (!empty($settings['mark_required']))
     
    7070    }
    7171
    72     public function get_attribute_name($item)
    73     {
    74         return "form_fields[{$item['field_id']}]";
    75     }
    76 
    77     public function get_attribute_id($item)
     72    public function get_attribute_name($item): string
     73    {
     74        $field_identifier = $this->get_field_identifier($item);
     75        if ($field_identifier === '') return 'form_fields[]';
     76
     77        return "form_fields[$field_identifier]";
     78    }
     79
     80    private function get_field_identifier($item)
     81    {
     82        if (!empty($item['field_id'])) return $item['field_id'];
     83
     84        return $item['_id'] ?? '';
     85    }
     86
     87    public function get_attribute_id($item): string
    7888    {
    7989        $id_suffix = !empty($item['field_id']) ? $item['field_id'] : $item['_id'];
     
    8797    }
    8898
    89     public function make_textarea_field($context, $item, $item_index)
     99    public function make_textarea_field($context, $item, $item_index): string
    90100    {
    91101        $context->add_render_attribute('textarea' . $item_index, [
     
    94104                'afeb-form-field',
    95105                'elementor-field-textual',
    96                 esc_attr($item['css_classes'])
     106                esc_attr($item['css_classes']),
    97107            ],
    98108            'name' => $this->get_attribute_name($item),
     
    101111        ]);
    102112
    103         if ($context->get_settings_for_display()['show_placeholders'] == 'true' && !Utils::is_empty($item['placeholder'])) {
     113        if ($context->get_settings_for_display()['show_placeholders'] == 'true' && !Utils::is_empty($item['placeholder']))
     114        {
    104115            $context->add_render_attribute('textarea' . $item_index, 'placeholder', $item['placeholder']);
    105116        }
    106117
    107         if ($item['required']) {
     118        if ($item['required'])
     119        {
    108120            $this->add_required_attribute($context, 'textarea' . $item_index);
    109121        }
     
    117129    {
    118130        ob_start();
    119 ?>
     131        ?>
    120132        <div class="afeb-form-field afeb-select-wrap <?php echo esc_attr($item['css_classes']); ?>">
    121133            <select
    122134                id="<?php echo $this->get_attribute_id($item); ?>"
    123135                class="afeb-form-field-textual elementor-field-textual"
     136                title=""
    124137                name="<?php echo $this->get_attribute_name($item); ?>"
    125138                <?php echo $item['required'] ? 'required' : '' ?>>
     
    129142                $options = preg_split("/\\r\\n|\\r|\\n/", $item['field_options']);
    130143
    131                 foreach ($options as $key => $option) {
     144                foreach ($options as $key => $option)
     145                {
    132146                    $option_value = esc_attr($option);
    133147                    $option_label = esc_html($option);
    134148
    135                     if (strpos($option, '|') !== false) {
    136                         list($label, $value) = explode('|', $option);
     149                    if (strpos($option, '|') !== false)
     150                    {
     151                        [$label, $value] = explode('|', $option);
    137152                        $option_value = esc_attr($value);
    138153                        $option_label = esc_html($label);
    139154                    }
    140155
    141                     if (isset($options_temp[$option_value]) || !trim($option_value)) {
     156                    if (isset($options_temp[$option_value]) || !trim($option_value))
     157                    {
    142158                        continue;
    143159                    }
    144                 ?>
     160                    ?>
    145161                    <option value="<?php echo esc_attr($option_value); ?>">
    146162                        <?php
     
    149165                        ?>
    150166                    </option>
    151                 <?php
     167                    <?php
    152168                    $options_temp[$option_value] = $option_label;
    153169                } ?>
    154170            </select>
    155171        </div>
    156     <?php
    157         $select = ob_get_clean();
    158         return $select;
     172        <?php
     173        return ob_get_clean();
    159174    }
    160175
     
    164179            array_filter(
    165180                preg_split("/\\r\\n|\\r|\\n/", $item['field_options']),
    166                 static function ($option) {
     181                static function ($option)
     182                {
    167183                    return trim($option) !== '';
    168184                }
     
    170186        );
    171187
    172         if (empty($options)) {
     188        if (empty($options))
     189        {
    173190            return '';
    174191        }
     
    176193        $options_temp = [];
    177194        ob_start();
    178     ?>
    179         <div class="afeb-field-sub-group <?php echo esc_attr($item['css_classes']) . ' ' . esc_attr($item['inline_list']); ?>">
     195        ?>
     196        <div
     197            class="afeb-field-sub-group <?php echo esc_attr($item['css_classes']) . ' ' . esc_attr($item['inline_list']); ?>">
    180198            <?php
    181199            foreach ($options as $key => $option):
     
    183201                $option_value = $option;
    184202
    185                 if (strpos($option, '|') !== false) {
    186                     list($option_label, $option_value) = explode('|', $option);
    187                 }
    188 
    189                 if (isset($options_temp[$option_value]) || !trim($option_value)) {
    190                     continue;
    191                 }
    192             ?>
    193                 <span class="afeb-form-field-option" data-key="form-field-<?php echo esc_attr($item['field_id']); ?>">
     203                if (strpos($option, '|') !== false)
     204                {
     205                    [$option_label, $option_value] = explode('|', $option);
     206                }
     207
     208                if (isset($options_temp[$option_value]) || !trim($option_value))
     209                {
     210                    continue;
     211                }
     212                ?>
     213                <span class="afeb-form-field-option"
     214                      data-key="form-field-<?php echo esc_attr($this->get_field_identifier($item)); ?>">
    194215                    <input
    195216                        id="<?php echo esc_attr($this->get_attribute_id($item) . '-' . $key) ?>"
     
    201222                        <input
    202223                            type="hidden"
    203                             name="<?php echo esc_attr($this->get_attribute_name($item) . (($type == 'checkbox' && count($options) > 1) ? '[]' : '')); ?>">
     224                            name="<?php echo esc_attr($this->get_attribute_name($item) . (count($options) > 1 ? '[]' : '')); ?>">
    204225                    <?php endif; ?>
    205                     <label for="<?php echo esc_attr($this->get_attribute_id($item) . '-' . $key) ?>"><?php echo esc_html($option_label); ?></label>
     226                    <label
     227                        for="<?php echo esc_attr($this->get_attribute_id($item) . '-' . $key) ?>"><?php echo esc_html($option_label); ?></label>
    206228                </span>
    207             <?php
     229                <?php
    208230                $options_temp[$option_value] = $option_label;
    209231            endforeach;
    210232            ?>
    211233        </div>
    212     <?php
    213         $radio_checkbox = ob_get_clean();
    214         return $radio_checkbox;
     234        <?php
     235        return ob_get_clean();
    215236    }
    216237
    217238    private function render_form_icon($context, $settings)
    218239    {
    219     ?>
    220         <span <?php echo $context->get_render_attribute_string('icon-align'); ?>>
     240        ?>
     241        <span <?php $context->print_render_attribute_string('icon-align'); ?>>
    221242            <?php Icons_Manager::render_icon($settings['selected_button_icon'], ['aria-hidden' => 'true']); ?>
    222243            <?php if (empty($settings['button_text'])): ?>
     
    226247            <?php endif; ?>
    227248        </span>
    228     <?php
     249        <?php
    229250    }
    230251
    231252    public function render_submit_button($context, $settings)
    232253    {
    233     ?>
    234         <button type="submit" <?php echo $context->get_render_attribute_string('button'); ?>>
    235             <span <?php echo $context->get_render_attribute_string('content-wrapper'); ?>>
     254        ?>
     255        <button type="submit" <?php $context->print_render_attribute_string('button'); ?>>
     256            <span <?php $context->print_render_attribute_string('content-wrapper'); ?>>
    236257                <?php if (
    237258                    !empty($settings['selected_button_icon']) &&
     
    241262                <?php endif; ?>
    242263                <?php if (!empty($settings['button_text'])): ?>
    243                     <span><?php echo $context->print_unescaped_setting('button_text'); ?></span>
     264                    <span><?php echo wp_kses_post($settings['button_text']); ?></span>
    244265                <?php endif; ?>
    245266                <?php if (
     
    251272            </span>
    252273        </button>
    253 <?php
    254     }
     274        <?php
     275    }
     276
    255277    /**
    256278     * Get all available field types for the form builder.
     
    261283    {
    262284        return [
    263                 'text'        => esc_html__('Text', 'addons-for-elementor-builder'),
    264                 'textarea'    => esc_html__('Textarea', 'addons-for-elementor-builder'),
    265                 'email'        => esc_html__('Email', 'addons-for-elementor-builder'),
    266                 'url'          => esc_html__('URL', 'addons-for-elementor-builder'),
    267                 'number'      => esc_html__('Number', 'addons-for-elementor-builder'),
    268                 'tel'          => esc_html__('Tel', 'addons-for-elementor-builder'),
    269                 'radio'        => esc_html__('Radio', 'addons-for-elementor-builder'),
    270                 'select'      => esc_html__('Select', 'addons-for-elementor-builder'),
    271                 'checkbox'    => esc_html__('Checkbox', 'addons-for-elementor-builder'),
    272                 'date'        => esc_html__('Date', 'addons-for-elementor-builder'),
    273                 'time'        => esc_html__('Time', 'addons-for-elementor-builder'),
    274                 'upload'      => esc_html__('File Upload', 'addons-for-elementor-builder'),
    275                 'password'    => esc_html__('Password', 'addons-for-elementor-builder'),
    276                 'html'        => esc_html__('HTML', 'addons-for-elementor-builder'),
    277                 'recaptcha_v3' => esc_html__('reCAPTCHA V3', 'addons-for-elementor-builder'),
    278                 'hidden'      => esc_html__('Hidden', 'addons-for-elementor-builder'),
    279                 'step'        => esc_html__('Step', 'addons-for-elementor-builder'),
     285            'text' => esc_html__('Text', 'addons-for-elementor-builder'),
     286            'textarea' => esc_html__('Textarea', 'addons-for-elementor-builder'),
     287            'email' => esc_html__('Email', 'addons-for-elementor-builder'),
     288            'url' => esc_html__('URL', 'addons-for-elementor-builder'),
     289            'number' => esc_html__('Number', 'addons-for-elementor-builder'),
     290            'tel' => esc_html__('Tel', 'addons-for-elementor-builder'),
     291            'radio' => esc_html__('Radio', 'addons-for-elementor-builder'),
     292            'select' => esc_html__('Select', 'addons-for-elementor-builder'),
     293            'checkbox' => esc_html__('Checkbox', 'addons-for-elementor-builder'),
     294            'date' => esc_html__('Date', 'addons-for-elementor-builder'),
     295            'time' => esc_html__('Time', 'addons-for-elementor-builder'),
     296            'upload' => esc_html__('File Upload', 'addons-for-elementor-builder'),
     297            'password' => esc_html__('Password', 'addons-for-elementor-builder'),
     298            'html' => esc_html__('HTML', 'addons-for-elementor-builder'),
     299            'recaptcha_v3' => esc_html__('reCAPTCHA V3', 'addons-for-elementor-builder'),
     300            'hidden' => esc_html__('Hidden', 'addons-for-elementor-builder'),
     301            'step' => esc_html__('Step', 'addons-for-elementor-builder'),
    280302        ];
    281303    }
     
    289311    {
    290312        return [
    291                 [
    292                         '_id'          => 'field_' . wp_generate_password(8, false, false),
    293                         'type'        => 'text',
    294                         'label'        => esc_html__('Untitled', 'addons-for-elementor-builder'),
    295                         'placeholder' => '',
    296                         'required'    => false,
    297                         'value'        => '',
    298                         'column_width' => 100,
    299                 ],
     313            [
     314                '_id' => 'field_' . wp_generate_password(8, false),
     315                'type' => 'text',
     316                'label' => esc_html__('Untitled', 'addons-for-elementor-builder'),
     317                'placeholder' => '',
     318                'required' => false,
     319                'value' => '',
     320                'column_width' => 100,
     321            ],
    300322        ];
    301323    }
     
    309331    {
    310332        $defaults = [
    311                 'extensions' => ['jpg', 'jpeg', 'png', 'gif', 'pdf', 'doc', 'docx', 'zip'],
    312                 'mime_types' => [
    313                         'image/jpeg', 'image/png', 'image/gif',
    314                         'application/pdf',
    315                         'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
    316                         'application/zip'
    317                 ],
    318                 'max_size'  => 5 * 1024 * 1024, // 5MB
     333            'extensions' => ['jpg', 'jpeg', 'png', 'gif', 'pdf', 'doc', 'docx', 'zip'],
     334            'mime_types' => [
     335                'image/jpeg', 'image/png', 'image/gif',
     336                'application/pdf',
     337                'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
     338                'application/zip',
     339            ],
     340            'max_size' => 5 * 1024 * 1024, // 5MB
    319341        ];
    320342
     
    322344    }
    323345
    324     /**
    325      * Validate uploaded files array with enhanced security and error handling.
    326      *
    327      * @param array $files Array of files to validate (either $_FILES array or URLs)
    328      * @param array $rules {
    329      *     @type int    $max_size    Maximum file size in bytes
    330      *     @type array  $exts        Allowed file extensions (e.g., ['jpg', 'png'])
    331      *     @type array  $mime_types  Allowed mime types (wp_get_mime_types() format)
    332      * }
    333      * @param bool  $is_required Whether the field is required
    334      * @return array {
    335      *     @type bool   $valid   Whether all files are valid
    336      *     @type array  $files   Array of validated file URLs
    337      *     @type array  $errors  Array of error messages
    338      * }
    339      */
    340     public static function validate_uploaded_files($files, $rules = [], $is_required = false)
     346    public static function validate_uploaded_files($files, $rules = [], $is_required = false): array
    341347    {
    342348        $normalized_files = [];
     
    345351        // Convert MB to bytes if needed (common case where max_size is in MB)
    346352        $max_size = !empty($rules['max_size']) ?
    347                 (is_numeric($rules['max_size']) ? (int)$rules['max_size'] * 1024 * 1024 : wp_max_upload_size())
    348                 : wp_max_upload_size();
    349 
    350         $allowed_exts = !empty($rules['exts']) ? array_map('strtolower', (array)$rules['exts']) : [];
    351         $allowed_mimes = !empty($rules['mime_types']) ? (array)$rules['mime_types'] : wp_get_mime_types();
    352 
    353         if (!is_array($files)) {
     353            (is_numeric($rules['max_size']) ? (int) $rules['max_size'] * 1024 * 1024 : wp_max_upload_size())
     354            : wp_max_upload_size();
     355
     356        $allowed_exts = !empty($rules['exts']) ? array_map('strtolower', (array) $rules['exts']) : [];
     357        $allowed_mimes = !empty($rules['mime_types']) ? (array) $rules['mime_types'] : wp_get_mime_types();
     358
     359        if (!is_array($files))
     360        {
    354361            $files = $files ? [$files] : [];
    355362        }
     
    389396                {
    390397                    $errors[] = sprintf(
    391                             __('"%s" is not an allowed file type. Allowed: %s', 'addons-for-elementor-builder'),
    392                             esc_html($file['name']),
    393                             esc_html(implode(', ', $allowed_exts))
     398                        __('"%s" is not an allowed file type. Allowed: %s', 'addons-for-elementor-builder'),
     399                        esc_html($file['name']),
     400                        esc_html(implode(', ', $allowed_exts))
    394401                    );
    395402                    continue;
     
    400407                {
    401408                    $errors[] = sprintf(
    402                             __('"%s" exceeds maximum file size of %s.', 'addons-for-elementor-builder'),
    403                             esc_html($file['name']),
    404                             size_format($max_size)
     409                        __('"%s" exceeds maximum file size of %s.', 'addons-for-elementor-builder'),
     410                        esc_html($file['name']),
     411                        size_format($max_size)
    405412                    );
    406413                    continue;
    407414                }
    408415
    409                 if ( ! function_exists( 'wp_handle_upload' ) ) require_once ABSPATH . 'wp-admin/includes/file.php';
     416                if (!function_exists('wp_handle_upload')) require_once ABSPATH . 'wp-admin/includes/file.php';
    410417
    411418                // Handle the upload
    412                 $upload = \wp_handle_upload($file, [
    413                         'test_form' => false,
    414                         'test_type' => true,
    415                         'mimes' => $allowed_mimes
     419                $upload = wp_handle_upload($file, [
     420                    'test_form' => false,
     421                    'test_type' => true,
     422                    'mimes' => $allowed_mimes,
    416423                ]);
    417424
     
    425432            }
    426433            // Handle existing URLs (for multi-step forms)
    427             elseif (is_string($file) && filter_var($file, FILTER_VALIDATE_URL)) $normalized_files[] = esc_url_raw($file);
     434            else if (is_string($file) && filter_var($file, FILTER_VALIDATE_URL)) $normalized_files[] = esc_url_raw($file);
    428435        }
    429436
     
    445452    {
    446453        $messages = [
    447                 UPLOAD_ERR_INI_SIZE  => __('"%s" exceeds server upload limit.', 'addons-for-elementor-builder'),
    448                 UPLOAD_ERR_FORM_SIZE => __('"%s" exceeds form upload limit.', 'addons-for-elementor-builder'),
    449                 UPLOAD_ERR_PARTIAL    => __('"%s" was only partially uploaded.', 'addons-for-elementor-builder'),
    450                 UPLOAD_ERR_NO_FILE    => __('No file was uploaded for "%s".', 'addons-for-elementor-builder'),
    451                 UPLOAD_ERR_NO_TMP_DIR => __('Missing temporary folder for "%s".', 'addons-for-elementor-builder'),
    452                 UPLOAD_ERR_CANT_WRITE => __('Failed to write "%s" to disk.', 'addons-for-elementor-builder'),
    453                 UPLOAD_ERR_EXTENSION => __('Server extension stopped "%s" upload.', 'addons-for-elementor-builder'),
     454            UPLOAD_ERR_INI_SIZE => __('"%s" exceeds server upload limit.', 'addons-for-elementor-builder'),
     455            UPLOAD_ERR_FORM_SIZE => __('"%s" exceeds form upload limit.', 'addons-for-elementor-builder'),
     456            UPLOAD_ERR_PARTIAL => __('"%s" was only partially uploaded.', 'addons-for-elementor-builder'),
     457            UPLOAD_ERR_NO_FILE => __('No file was uploaded for "%s".', 'addons-for-elementor-builder'),
     458            UPLOAD_ERR_NO_TMP_DIR => __('Missing temporary folder for "%s".', 'addons-for-elementor-builder'),
     459            UPLOAD_ERR_CANT_WRITE => __('Failed to write "%s" to disk.', 'addons-for-elementor-builder'),
     460            UPLOAD_ERR_EXTENSION => __('Server extension stopped "%s" upload.', 'addons-for-elementor-builder'),
    454461        ];
    455462
    456463        return sprintf(
    457                 $messages[$error_code] ?? __('Upload error for "%s".', 'addons-for-elementor-builder'),
    458                 esc_html($filename)
     464            $messages[$error_code] ?? __('Upload error for "%s".', 'addons-for-elementor-builder'),
     465            esc_html($filename)
    459466        );
    460467    }
    461 
    462 
    463 
    464     /**
    465      * Normalize submission fields into associative array keyed by _id.
    466      *
    467      * @param array $fields_meta
    468      * @param array $posted_fields
    469      * @return array
    470      */
    471     public static function normalize_submission_fields_by_id(array $fields_meta, array $posted_fields = []): array
    472     {
    473         $out = [];
    474         $index_map = []; // Track original positions
    475 
    476         // First pass: create index map
    477         foreach ($fields_meta as $index => $field) {
    478             $id = $field['_id'] ?? '';
    479             if ($id) {
    480                 $index_map[$id] = $index;
    481             }
    482         }
    483 
    484         // Second pass: build ordered output
    485         foreach ($fields_meta as $field) {
    486             $id = $field['_id'] ?? '';
    487             if (!$id) continue;
    488 
    489             $out[$id] = $field;
    490             if (isset($posted_fields[$id])) {
    491                 $out[$id]['value'] = $posted_fields[$id];
    492             }
    493         }
    494 
    495         // Third pass: sort by original positions
    496         uasort($out, function($a, $b) use ($index_map) {
    497             return $index_map[$a['_id']] <=> $index_map[$b['_id']];
    498         });
    499 
    500         return $out;
    501     }
    502 
    503468}
  • addons-for-elementor-builder/trunk/app/Widgets/LoginRegister/LoginRegister.php

    r3382971 r3386622  
    16071607            if (($this->is_editor == 'yes' && !empty($settings['succ_msg_bx_prev'])))
    16081608                $_COOKIE['afeb_login_success_' . $options['widget_id']] = CHelper::$LIM;
    1609             if (!empty($_COOKIE['afeb_login_success_' . $options['widget_id']])): ?>
     1609            $login_success_cookie_key = 'afeb_login_success_' . $options['widget_id'];
     1610            $login_success_message = '';
     1611            if (!empty($_COOKIE[$login_success_cookie_key])) {
     1612                $login_success_message = sanitize_text_field(wp_unslash($_COOKIE[$login_success_cookie_key]));
     1613            }
     1614            if (!empty($login_success_message)): ?>
    16101615                <div class="afeb-lr-form-succ-box">
    1611                     <?php echo esc_html($_COOKIE['afeb_login_success_' . $options['widget_id']]); ?>
     1616                    <?php echo esc_html($login_success_message); ?>
    16121617                </div>
    16131618            <?php endif; ?>
     
    16151620            if (($this->is_editor == 'yes' && !empty($settings['err_msg_bx_prev'])))
    16161621                $_COOKIE['afeb_login_error_' . $options['widget_id']] = CHelper::$LIM;
    1617             if (!empty($_COOKIE['afeb_login_error_' . $options['widget_id']])) :
     1622            $login_error_cookie_key = 'afeb_login_error_' . $options['widget_id'];
     1623            $login_error_message = '';
     1624            if (!empty($_COOKIE[$login_error_cookie_key])) {
     1625                $login_error_message = sanitize_text_field(wp_unslash($_COOKIE[$login_error_cookie_key]));
     1626            }
     1627            if (!empty($login_error_message)) :
    16181628            ?>
    16191629                <div class="afeb-lr-form-err-box">
    1620                     <?php echo esc_html($_COOKIE['afeb_login_error_' . $options['widget_id']]); ?>
     1630                    <?php echo esc_html($login_error_message); ?>
    16211631                </div>
    16221632            <?php endif; ?>
     
    17221732            if (($this->is_editor == 'yes' && !empty($settings['succ_msg_bx_prev'])))
    17231733                $_COOKIE['afeb_register_success_' . $options['widget_id']] = CHelper::$LIM;
    1724             if (!empty($_COOKIE['afeb_register_success_' . $options['widget_id']])) : ?>
     1734            $register_success_cookie_key = 'afeb_register_success_' . $options['widget_id'];
     1735            $register_success_message = '';
     1736            if (!empty($_COOKIE[$register_success_cookie_key])) {
     1737                $register_success_message = sanitize_text_field(wp_unslash($_COOKIE[$register_success_cookie_key]));
     1738            }
     1739            if (!empty($register_success_message)) : ?>
    17251740                <div class="afeb-lr-form-succ-box">
    1726                     <?php echo esc_html($_COOKIE['afeb_register_success_' . $options['widget_id']]); ?>
     1741                    <?php echo esc_html($register_success_message); ?>
    17271742                </div>
    17281743            <?php endif; ?>
     
    17301745            if (($this->is_editor == 'yes' && !empty($settings['err_msg_bx_prev'])))
    17311746                $_COOKIE['afeb_register_error_' . $options['widget_id']] = CHelper::$LIM;
    1732             if (!empty($_COOKIE['afeb_register_error_' . $options['widget_id']])) : ?>
     1747            $register_error_cookie_key = 'afeb_register_error_' . $options['widget_id'];
     1748            $register_error_message = '';
     1749            if (!empty($_COOKIE[$register_error_cookie_key])) {
     1750                $register_error_message = sanitize_text_field(wp_unslash($_COOKIE[$register_error_cookie_key]));
     1751            }
     1752            if (!empty($register_error_message)) : ?>
    17331753                <div class="afeb-lr-form-err-box">
    1734                     <?php echo esc_html($_COOKIE['afeb_register_error_' . $options['widget_id']]); ?>
     1754                    <?php echo esc_html($register_error_message); ?>
    17351755                </div>
    17361756            <?php endif; ?>
     
    17861806            if (($this->is_editor == 'yes' && !empty($settings['succ_msg_bx_prev'])))
    17871807                $_COOKIE['afeb_lostpassword_success_' . $options['widget_id']] = CHelper::$LIM;
    1788             if (!empty($_COOKIE['afeb_lostpassword_success_' . $options['widget_id']])) : ?>
     1808            $lostpassword_success_cookie_key = 'afeb_lostpassword_success_' . $options['widget_id'];
     1809            $lostpassword_success_message = '';
     1810            if (!empty($_COOKIE[$lostpassword_success_cookie_key])) {
     1811                $lostpassword_success_message = sanitize_text_field(wp_unslash($_COOKIE[$lostpassword_success_cookie_key]));
     1812            }
     1813            if (!empty($lostpassword_success_message)) : ?>
    17891814                <div class="afeb-lr-form-succ-box">
    1790                     <?php echo esc_html($_COOKIE['afeb_lostpassword_success_' . $options['widget_id']]); ?>
     1815                    <?php echo esc_html($lostpassword_success_message); ?>
    17911816                </div>
    17921817            <?php endif; ?>
     
    17941819            if (($this->is_editor == 'yes' && !empty($settings['err_msg_bx_prev'])))
    17951820                $_COOKIE['afeb_lostpassword_error_' . $options['widget_id']] = CHelper::$LIM;
    1796             if (!empty($_COOKIE['afeb_lostpassword_error_' . $options['widget_id']])) : ?>
     1821            $lostpassword_error_cookie_key = 'afeb_lostpassword_error_' . $options['widget_id'];
     1822            $lostpassword_error_message = '';
     1823            if (!empty($_COOKIE[$lostpassword_error_cookie_key])) {
     1824                $lostpassword_error_message = sanitize_text_field(wp_unslash($_COOKIE[$lostpassword_error_cookie_key]));
     1825            }
     1826            if (!empty($lostpassword_error_message)) : ?>
    17971827                <div class="afeb-lr-form-err-box">
    1798                     <?php echo esc_html($_COOKIE['afeb_lostpassword_error_' . $options['widget_id']]); ?>
     1828                    <?php echo esc_html($lostpassword_error_message); ?>
    17991829                </div>
    18001830            <?php endif; ?>
     
    18731903            if (($this->is_editor == 'yes' && !empty($settings['succ_msg_bx_prev'])))
    18741904                $_COOKIE['afeb_resetpassword_success_' . $options['widget_id']] = CHelper::$LIM;
    1875             if (!empty($_COOKIE['afeb_resetpassword_success_' . $options['widget_id']])) : ?>
     1905            $resetpassword_success_cookie_key = 'afeb_resetpassword_success_' . $options['widget_id'];
     1906            $resetpassword_success_message = '';
     1907            if (!empty($_COOKIE[$resetpassword_success_cookie_key])) {
     1908                $resetpassword_success_message = sanitize_text_field(wp_unslash($_COOKIE[$resetpassword_success_cookie_key]));
     1909            }
     1910            if (!empty($resetpassword_success_message)) : ?>
    18761911                <div class="afeb-lr-form-succ-box">
    1877                     <?php echo esc_html($_COOKIE['afeb_resetpassword_success_' . $options['widget_id']]); ?>
     1912                    <?php echo esc_html($resetpassword_success_message); ?>
    18781913                </div>
    18791914            <?php else:
     
    18831918            if (($this->is_editor == 'yes' && !empty($settings['err_msg_bx_prev'])))
    18841919                $_COOKIE['afeb_resetpassword_error_' . $options['widget_id']] = CHelper::$LIM;
    1885             if (!empty($_COOKIE['afeb_resetpassword_error_' . $options['widget_id']])) : ?>
     1920            $resetpassword_error_cookie_key = 'afeb_resetpassword_error_' . $options['widget_id'];
     1921            $resetpassword_error_message = '';
     1922            if (!empty($_COOKIE[$resetpassword_error_cookie_key])) {
     1923                $resetpassword_error_message = sanitize_text_field(wp_unslash($_COOKIE[$resetpassword_error_cookie_key]));
     1924            }
     1925            if (!empty($resetpassword_error_message)) : ?>
    18861926                <div class="afeb-lr-form-err-box">
    1887                     <?php echo esc_html($_COOKIE['afeb_resetpassword_error_' . $options['widget_id']]); ?>
     1927                    <?php echo esc_html($resetpassword_error_message); ?>
    18881928                </div>
    18891929            <?php endif; ?>
  • addons-for-elementor-builder/trunk/app/Widgets/SearchForm/Helper.php

    r3297649 r3386622  
    135135        }
    136136
    137         $css = '';
    138         $css = sprintf('<style id="%s">%s</style>', 'afeb-dynamic-loop-' . $template_id, $css);
     137        $style_id = 'afeb-dynamic-loop-' . sanitize_key($template_id);
     138        $sanitized_css = wp_strip_all_tags($post_css);
    139139
    140         echo $css; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
     140        printf(
     141            '<style id="%s">%s</style>',
     142            esc_attr($style_id),
     143            $sanitized_css
     144        );
    141145
    142146        Plugin::instance()->documents->restore_document();
  • addons-for-elementor-builder/trunk/app/Widgets/Slides.php

    r3297649 r3386622  
    855855        }
    856856
    857         $title_tag = Utils::validate_html_tag($settings['slides_title_tag']);
    858         $description_tag = Utils::validate_html_tag($settings['slides_description_tag']);
    859 
    860         $this->add_render_attribute('button', 'class', ['elementor-button', 'afeb-slides-item-button']);
    861 
    862         $slides = [];
     857        $title_tag = tag_escape(Utils::validate_html_tag($settings['slides_title_tag']));
     858        $description_tag = tag_escape(Utils::validate_html_tag($settings['slides_description_tag']));
     859
    863860        $slide_count = 0;
    864 
    865         foreach ($settings['slides_content_repeater'] as $slide) {
    866             $slide_html = '';
    867             $btn_attributes = '';
    868             $slide_attributes = '';
    869             $slide_element = 'div';
    870             $btn_element = 'a';
    871 
    872             if (!empty($slide['link']['url'])) {
    873                 $this->add_link_attributes('slide_link' . $slide_count, $slide['link']);
    874 
    875                 if ($slide['link_click'] === 'button') {
    876                     $btn_attributes = $this->get_render_attribute_string('slide_link' . $slide_count);
    877                 } else {
    878                     $slide_element = 'a';
    879                     $slide_attributes = $this->get_render_attribute_string('slide_link' . $slide_count);
    880                 }
    881             }
    882 
    883             $slide_html .= '<' . $slide_element . ' class="afeb-slides-item-inner" ' . $slide_attributes . '>';
    884             $slide_html .= '<div class="afeb-slides-contents">';
    885 
    886             if ($slide['heading']) {
    887                 $slide_html .= '<' . $title_tag . ' class="afeb-slides-item-heading">' . $slide['heading'] . '</' . $title_tag . '>';
    888             }
    889 
    890             if ($slide['description']) {
    891                 $slide_html .= '<' . $description_tag . ' class="afeb-slides-item-description">' . $slide['description'] . '</' . $description_tag . '>';
    892             }
    893 
    894             if ($slide['button_text']) {
    895                 $slide_html .= '<' . $btn_element . ' ' . $btn_attributes . ' ' . $this->get_render_attribute_string('button') . '>' . $slide['button_text'] . '</' . $btn_element . '>';
    896             }
    897 
    898             $slide_html .= '</div></' . $slide_element . '>';
    899             $slide_html = '<div class="afeb-slides-item-bg" role="img"></div>' . $slide_html;
    900             $slides[] = '<div class="elementor-repeater-item-' . esc_attr($slide['_id']) . ' afeb-slides-item" role="group" aria-roledescription="slide">' . $slide_html . '</div>';
    901 
    902             $slide_count++;
    903         }
    904861
    905862        $slick = [
     
    928885?>
    929886        <div <?php $this->print_render_attribute_string('slides'); ?>>
     887            <?php foreach ($settings['slides_content_repeater'] as $slide):
     888                $slide_element = 'div';
     889                $slide_wrapper_key = 'slide-wrapper-' . $slide_count;
     890                $button_key = 'slide-button-' . $slide_count;
     891                $slide_item_key = 'slide-item-' . $slide_count;
     892
     893                $this->add_render_attribute($slide_wrapper_key, 'class', 'afeb-slides-item-inner');
     894                $this->add_render_attribute($button_key, 'class', ['elementor-button', 'afeb-slides-item-button']);
     895
     896                if (!empty($slide['link']['url'])) {
     897                    if ($slide['link_click'] === 'button') {
     898                        $this->add_link_attributes($button_key, $slide['link']);
     899                    } else {
     900                        $slide_element = 'a';
     901                        $this->add_link_attributes($slide_wrapper_key, $slide['link']);
     902                    }
     903                }
     904
     905                $this->add_render_attribute($slide_item_key, 'class', [
     906                    'elementor-repeater-item-' . sanitize_html_class($slide['_id']),
     907                    'afeb-slides-item'
     908                ]);
     909                $this->add_render_attribute($slide_item_key, 'role', 'group');
     910                $this->add_render_attribute($slide_item_key, 'aria-roledescription', 'slide');
     911
     912                $slide_tag = tag_escape($slide_element);
     913                $button_element = (!empty($slide['link']['url']) && $slide['link_click'] === 'button') ? 'a' : 'span';
     914                $button_tag = tag_escape($button_element);
     915            ?>
     916                <div <?php $this->print_render_attribute_string($slide_item_key); ?>>
     917                    <div class="afeb-slides-item-bg" role="img"></div>
     918                    <<?php echo $slide_tag; ?> <?php $this->print_render_attribute_string($slide_wrapper_key); ?>>
     919                        <div class="afeb-slides-contents">
     920                            <?php if (!empty($slide['heading'])): ?>
     921                                <<?php echo $title_tag; ?> class="afeb-slides-item-heading">
     922                                    <?php echo wp_kses_post($slide['heading']); ?>
     923                                </<?php echo $title_tag; ?>>
     924                            <?php endif; ?>
     925
     926                            <?php if (!empty($slide['description'])): ?>
     927                                <<?php echo $description_tag; ?> class="afeb-slides-item-description">
     928                                    <?php echo wp_kses_post($slide['description']); ?>
     929                                </<?php echo $description_tag; ?>>
     930                            <?php endif; ?>
     931
     932                            <?php if (!empty($slide['button_text'])): ?>
     933                                <<?php echo $button_tag; ?> <?php $this->print_render_attribute_string($button_key); ?>>
     934                                    <?php echo esc_html($slide['button_text']); ?>
     935                                </<?php echo $button_tag; ?>>
     936                            <?php endif; ?>
     937                        </div>
     938                    </<?php echo $slide_tag; ?>>
     939                </div>
    930940            <?php
    931             // PHPCS - Slides for each is safe.
    932             echo implode('', $slides); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    933             ?>
     941                $slide_count++;
     942            endforeach; ?>
    934943        </div>
    935944<?php
  • addons-for-elementor-builder/trunk/app/Widgets/TeamMemberCarousel.php

    r3297649 r3386622  
    11811181                                }
    11821182                    ?>
    1183                                 <a <?php echo $this->get_render_attribute_string('button_attribute_' . $i); ?>>
     1183                                <a <?php $this->print_render_attribute_string('button_attribute_' . $i); ?>>
    11841184                                    <?php echo esc_html($repeater_item['buttons_label_' . $i]); ?>
    11851185                                </a>
  • addons-for-elementor-builder/trunk/app/Widgets/TemplateBuilder/CommentsForm.php

    r3297649 r3386622  
    11491149            ]
    11501150        );
    1151 
    1152         $this->get_render_attribute_string('comments_form');
    11531151    }
    11541152
     
    11691167        }
    11701168
    1171         echo "<div {$this->render_attrs($settings)}>";
     1169        $this->render_attrs($settings);
     1170
     1171        ?>
     1172        <div <?php $this->print_render_attribute_string('comments_form'); ?>>
     1173        <?php
    11721174
    11731175        $count = get_comments_number(get_the_ID());
  • addons-for-elementor-builder/trunk/app/Widgets/TemplateBuilder/TextRender.php

    r3297649 r3386622  
    252252        if (!empty($settings['text_render_url']['url'])) {
    253253            $this->add_link_attributes('url', $settings['text_render_url']);
    254             $text_render = sprintf('<a %1$s>%2$s</a>', $this->get_render_attribute_string('url'), $text_render);
     254
     255            ob_start();
     256            ?>
     257            <a <?php $this->print_render_attribute_string('url'); ?>>
     258                <?php echo $text_render; // Already escaped above ?>
     259            </a>
     260            <?php
     261            $text_render = trim(ob_get_clean());
    255262        }
    256263
    257         $text_render_html = sprintf(
    258             '<%1$s %2$s>%3$s</%1$s>',
    259             Utils::validate_html_tag($settings['text_render_html_tag']),
    260             $this->get_render_attribute_string('text-render'),
    261             $text_render
    262         );
    263 
    264         // PHPCS - the variable $text_render_html holds safe data
    265         echo $text_render_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
     264        $text_render_tag = tag_escape(Utils::validate_html_tag($settings['text_render_html_tag']));
     265        ?>
     266        <<?php echo $text_render_tag; ?> <?php $this->print_render_attribute_string('text-render'); ?>>
     267            <?php echo $text_render; // Escaped above ?>
     268        </<?php echo $text_render_tag; ?>>
     269        <?php
    266270    }
    267271
  • addons-for-elementor-builder/trunk/app/Widgets/Woo/AddToCart.php

    r3382971 r3386622  
    3030    public function get_icon(): string
    3131    {
    32         return 'afebp-iconsvg-add-to-cart';
     32        return 'afeb-iconsvg-add-to-cart';
    3333    }
    3434
     
    7777                'query_slug' => 'product',
    7878                'render_type' => 'template',
    79                 'description' => esc_html__('Search for a product by name.'),
     79                'description' => esc_html__('Search for a product by name.', 'addons-for-elementor-builder-pro'),
    8080            ]);
    8181
     
    8484                'condition' => ['product_source' => 'specific'],
    8585                'render_type' => 'template',
    86                 'description' => esc_html__('Used if no product is selected above.'),
     86                'description' => esc_html__('Used if no product is selected above.', 'addons-for-elementor-builder-pro'),
    8787            ]);
    8888
     
    9595                'label' => esc_html__('Input Position', 'addons-for-elementor-builder-pro'),
    9696                'options' => [
    97                     'horizontal' => ['title' => esc_html__('Horizontal'), 'icon' => 'eicon-h-align-left'],
    98                     'vertical' => ['title' => esc_html__('Vertical'), 'icon' => 'eicon-v-align-top'],
     97                    'horizontal' => ['title' => esc_html__('Horizontal', 'addons-for-elementor-builder-pro'), 'icon' => 'eicon-h-align-left'],
     98                    'vertical' => ['title' => esc_html__('Vertical', 'addons-for-elementor-builder-pro'), 'icon' => 'eicon-v-align-top'],
    9999                ],
    100100                'default' => 'horizontal',
     
    123123                    'stay' => esc_html__('Stay on Page (AJAX)', 'addons-for-elementor-builder-pro'),
    124124                    'cart' => esc_html__('Go to Cart Page', 'addons-for-elementor-builder-pro'),
    125                     'checkout' => esc_html__('Go to Checkout Page'),
     125                    'checkout' => esc_html__('Go to Checkout Page', 'addons-for-elementor-builder-pro'),
    126126                ],
    127127                'render_type' => 'template',
  • addons-for-elementor-builder/trunk/app/Widgets/Woo/ProductCategory.php

    r3382971 r3386622  
    3333            wp_register_script(
    3434                'swiper',
    35                 'https://unpkg.com/swiper/swiper-bundle.min.js',
     35                $this->helper->assets_url('packages/swiper/swiper-bundle.min.js'),
    3636                [],
    3737                '9.3.2',
     
    4040            wp_register_style(
    4141                'swiper',
    42                 'https://unpkg.com/swiper/swiper-bundle.min.css',
     42                $this->helper->assets_url('packages/swiper/swiper-bundle.min.css'),
    4343                [],
    4444                '9.3.2'
     
    561561            echo '</h3>';
    562562        }
    563         if ($show_desc && term_description($term->term_id, 'product_cat')) {
    564             echo '<div class="afebp-woo-cat-desc">' . wp_kses_post(term_description($term->term_id, 'product_cat')) . '</div>';
     563        $term_description = term_description($term);
     564
     565        if ($show_desc && $term_description) {
     566            echo '<div class="afebp-woo-cat-desc">' . wp_kses_post($term_description) . '</div>';
    565567        }
    566568        echo '</a>';
  • addons-for-elementor-builder/trunk/app/Widgets/Woo/ProductImage.php

    r3382971 r3386622  
    166166
    167167            $helper->slider('arrow_padding', [
    168                 'label' => __('Padding'),
     168                'label' => __('Padding', 'addons-for-elementor-builder'),
    169169                'selectors' => [$selector => 'padding: {{SIZE}}{{UNIT}};'],
    170170            ]);
  • addons-for-elementor-builder/trunk/assets/css/widgets/widgets-icons.css

    r3382971 r3386622  
    163163}
    164164
     165.afeb-iconsvg-myacc:before {
     166    background-image: url(../../img/widgets/myacc.svg)
     167}
     168
     169.afeb-iconsvg-add-to-cart:before {
     170    background-image: url(../../img/widgets/add-to-cart.svg)
     171}
     172
    165173.afeb-iconsvg-site-logo::before {
    166174    background-image: url(../../img/widgets/site-logo.svg)
  • addons-for-elementor-builder/trunk/assets/css/widgets/widgets-icons.min.css

    r3382971 r3386622  
    1 .afeb-iconsvg-accordion::before{background-image:url(../../img/widgets/accordion.svg)}.afeb-iconsvg-products-category::before{background-image:url(../../img/widgets/products-category.svg)}.afeb-iconsvg-product-excerpt::before{background-image:url(../../img/widgets/product-excerpt.svg)}.afeb-iconsvg-product-tags::before{background-image:url(../../img/widgets/product-tags.svg)}.afeb-iconsvg-product-content::before{background-image:url(../../img/widgets/product-content.svg)}.afeb-iconsvg-advanced-menus::before{background-image:url(../../img/widgets/advanced-menus.svg)}.afeb-iconsvg-product-img::before{background-image:url(../../img/widgets/product-img.svg)}.afeb-iconsvg-alert-box::before{background-image:url(../../img/widgets/alert-box.svg)}.afeb-iconsvg-author-box::before{background-image:url(../../img/widgets/author-box.svg)}.afeb-iconsvg-archive-title:before{background-image:url(../../img/widgets/archive-title.svg)}.afeb-iconsvg-breadcrumb::before{background-image:url(../../img/widgets/breadcrumb.svg)}.afeb-iconsvg-comments-form::before{background-image:url(../../img/widgets/comments-form.svg)}.afeb-iconsvg-countdown::before{background-image:url(../../img/widgets/countdown.svg)}.afeb-iconsvg-creative-button::before{background-image:url(../../img/widgets/creative-button.svg)}.afeb-iconsvg-datatable::before{background-image:url(../../img/widgets/data-table.svg)}.afeb-iconsvg-dynamic-archive-posts::before{background-image:url(../../img/widgets/dynamic-archive-posts.svg)}.afeb-iconsvg-dynamic-grid-carousel::before{background-image:url(../../img/widgets/dynamic-grid-carousel.svg)}.afeb-iconsvg-fancy-text::before{background-image:url(../../img/widgets/fancy-text.svg)}.afeb-iconsvg-flip-box::before{background-image:url(../../img/widgets/flip-box.svg)}.afeb-iconsvg-form-builder::before{background-image:url(../../img/widgets/form-builder.svg)}.afeb-iconsvg-going-up:before{background-image:url(../../img/widgets/going-up.svg)}.afeb-iconsvg-hotspot::before{background-image:url(../../img/widgets/hotspot.svg)}.afeb-iconsvg-information-box::before{background-image:url(../../img/widgets/information-box.svg)}.afeb-iconsvg-login-register::before{background-image:url(../../img/widgets/login-register.svg)}.afeb-iconsvg-lottie::before{background-image:url(../../img/widgets/lottie.svg)}.afeb-iconsvg-map::before{background-image:url(../../img/widgets/map.svg)}.afeb-iconsvg-news-ticker::before{background-image:url(../../img/widgets/news-ticker.svg)}.afeb-iconsvg-notice-box::before{background-image:url(../../img/widgets/notice-box.svg)}.afeb-iconsvg-offcanvas:before{background-image:url(../../img/widgets/off-canvas.svg)}.afeb-iconsvg-page-title:before{background-image:url(../../img/widgets/page-title.svg)}.afeb-iconsvg-post-content:before{background-image:url(../../img/widgets/post-content.svg)}.afeb-iconsvg-post-date:before{background-image:url(../../img/widgets/post-date.svg)}.afeb-iconsvg-post-excerpt:before{background-image:url(../../img/widgets/post-excerpt.svg)}.afeb-iconsvg-post-featured-image:before{background-image:url(../../img/widgets/post-featured-image.svg)}.afeb-iconsvg-post-title:before{background-image:url(../../img/widgets/post-title.svg)}.afeb-iconsvg-post-terms:before{background-image:url(../../img/widgets/post-terms.svg)}.afeb-iconsvg-post-time:before{background-image:url(../../img/widgets/post-time.svg)}.afeb-iconsvg-post-comments:before{background-image:url(../../img/widgets/post-comments.svg)}.afeb-iconsvg-post-navigation:before{background-image:url(../../img/widgets/post-navigation.svg)}.afeb-iconsvg-price-box::before{background-image:url(../../img/widgets/price-box.svg)}.afeb-iconsvg-search-form:before{background-image:url(../../img/widgets/search-form.svg)}.afeb-iconsvg-site-logo::before{background-image:url(../../img/widgets/site-logo.svg)}.afeb-iconsvg-site-title:before{background-image:url(../../img/widgets/site-title.svg)}.afeb-iconsvg-slides:before{background-image:url(../../img/widgets/slides.svg)}.afeb-iconsvg-sound-player:before{background-image:url(../../img/widgets/sound-player.svg)}.afeb-iconsvg-tabs:before{background-image:url(../../img/widgets/tabs.svg)}.afeb-iconsvg-team-member-carousel:before{background-image:url(../../img/widgets/teammember-carousel.svg)}.afeb-iconsvg-template:before{background-image:url(../../img/widgets/template.svg)}.afeb-iconsvg-testimonial-carousel:before{background-image:url(../../img/widgets/testimonial-carousel.svg)}.afeb-iconsvg-timeline::before{background-image:url(../../img/widgets/timeline.svg)}.afeb-iconsvg-checkout::before{background-image:url(../../img/widgets/checkout.svg)}
     1.afeb-iconsvg-accordion::before {background-image: url(../../img/widgets/accordion.svg) }.afeb-iconsvg-products-category::before {background-image: url(../../img/widgets/products-category.svg) }.afeb-iconsvg-product-excerpt::before {background-image: url(../../img/widgets/product-excerpt.svg);}.afeb-iconsvg-product-tags::before {background-image: url(../../img/widgets/product-tags.svg);}.afeb-iconsvg-product-content::before {background-image: url(../../img/widgets/product-content.svg);}.afeb-iconsvg-advanced-menus::before {background-image: url(../../img/widgets/advanced-menus.svg) }.afeb-iconsvg-product-img::before {background-image: url(../../img/widgets/product-img.svg) }.afeb-iconsvg-alert-box::before {background-image: url(../../img/widgets/alert-box.svg) }.afeb-iconsvg-author-box::before {background-image: url(../../img/widgets/author-box.svg) }.afeb-iconsvg-archive-title:before {background-image: url(../../img/widgets/archive-title.svg) }.afeb-iconsvg-breadcrumb::before {background-image: url(../../img/widgets/breadcrumb.svg) }.afeb-iconsvg-comments-form::before {background-image: url(../../img/widgets/comments-form.svg) }.afeb-iconsvg-countdown::before {background-image: url(../../img/widgets/countdown.svg) }.afeb-iconsvg-creative-button::before {background-image: url(../../img/widgets/creative-button.svg) }.afeb-iconsvg-datatable::before {background-image: url(../../img/widgets/data-table.svg) }.afeb-iconsvg-dynamic-archive-posts::before {background-image: url(../../img/widgets/dynamic-archive-posts.svg) }.afeb-iconsvg-dynamic-grid-carousel::before {background-image: url(../../img/widgets/dynamic-grid-carousel.svg) }.afeb-iconsvg-fancy-text::before {background-image: url(../../img/widgets/fancy-text.svg) }.afeb-iconsvg-flip-box::before {background-image: url(../../img/widgets/flip-box.svg) }.afeb-iconsvg-form-builder::before {background-image: url(../../img/widgets/form-builder.svg) }.afeb-iconsvg-going-up:before {background-image: url(../../img/widgets/going-up.svg) }.afeb-iconsvg-hotspot::before {background-image: url(../../img/widgets/hotspot.svg) }.afeb-iconsvg-information-box::before {background-image: url(../../img/widgets/information-box.svg) }.afeb-iconsvg-login-register::before {background-image: url(../../img/widgets/login-register.svg) }.afeb-iconsvg-lottie::before {background-image: url(../../img/widgets/lottie.svg) }.afeb-iconsvg-map::before {background-image: url(../../img/widgets/map.svg) }.afeb-iconsvg-news-ticker::before {background-image: url(../../img/widgets/news-ticker.svg) }.afeb-iconsvg-notice-box::before {background-image: url(../../img/widgets/notice-box.svg) }.afeb-iconsvg-offcanvas:before {background-image: url(../../img/widgets/off-canvas.svg) }.afeb-iconsvg-page-title:before {background-image: url(../../img/widgets/page-title.svg) }.afeb-iconsvg-post-content:before {background-image: url(../../img/widgets/post-content.svg) }.afeb-iconsvg-post-date:before {background-image: url(../../img/widgets/post-date.svg) }.afeb-iconsvg-post-excerpt:before {background-image: url(../../img/widgets/post-excerpt.svg) }.afeb-iconsvg-post-featured-image:before {background-image: url(../../img/widgets/post-featured-image.svg) }.afeb-iconsvg-post-title:before {background-image: url(../../img/widgets/post-title.svg) }.afeb-iconsvg-post-terms:before {background-image: url(../../img/widgets/post-terms.svg) }.afeb-iconsvg-post-time:before {background-image: url(../../img/widgets/post-time.svg) }.afeb-iconsvg-post-comments:before {background-image: url(../../img/widgets/post-comments.svg) }.afeb-iconsvg-post-navigation:before {background-image: url(../../img/widgets/post-navigation.svg) }.afeb-iconsvg-price-box::before {background-image: url(../../img/widgets/price-box.svg) }.afeb-iconsvg-search-form:before {background-image: url(../../img/widgets/search-form.svg) }.afeb-iconsvg-myacc:before {background-image: url(../../img/widgets/myacc.svg) }.afeb-iconsvg-add-to-cart:before {background-image: url(../../img/widgets/add-to-cart.svg) }.afeb-iconsvg-site-logo::before {background-image: url(../../img/widgets/site-logo.svg) }.afeb-iconsvg-site-title:before {background-image: url(../../img/widgets/site-title.svg) }.afeb-iconsvg-slides:before {background-image: url(../../img/widgets/slides.svg) }.afeb-iconsvg-sound-player:before {background-image: url(../../img/widgets/sound-player.svg) }.afeb-iconsvg-tabs:before {background-image: url(../../img/widgets/tabs.svg) }.afeb-iconsvg-team-member-carousel:before {background-image: url(../../img/widgets/teammember-carousel.svg) }.afeb-iconsvg-template:before {background-image: url(../../img/widgets/template.svg) }.afeb-iconsvg-testimonial-carousel:before {background-image: url(../../img/widgets/testimonial-carousel.svg) }.afeb-iconsvg-timeline::before {background-image: url(../../img/widgets/timeline.svg) }.afeb-iconsvg-checkout::before {background-image: url(../../img/widgets/checkout.svg) }
  • addons-for-elementor-builder/trunk/html/admin/menus/dashboard/fragments/content/dashboard/tpl.php

    r3382971 r3386622  
    5555
    5656                <div class="afeb-changelog-list-box">
     57                    <div class="afeb-changelog-date">
     58                        <?php esc_html_e('October 28, 2025', 'addons-for-elementor-builder'); ?>
     59                        <span class="afeb-changelog-version"><?php esc_html_e('Version 1.6.1', 'addons-for-elementor-builder'); ?></span>
     60                    </div>
     61                    <ul class="afeb-changelog-list">
     62                        <li><?php esc_html_e('Fixed : Enhanced the security and fixed some minor issues.', 'addons-for-elementor-builder'); ?></li>
     63                    </ul>
    5764                    <div class="afeb-changelog-date">
    5865                        <?php esc_html_e('October 22, 2025', 'addons-for-elementor-builder'); ?>
     
    106113                        <li><?php esc_html_e('Added : Layout animation feature in the Dynamic Grid/Carousel Widget', 'addons-for-elementor-builder'); ?></li>
    107114                        <li><?php esc_html_e('Added : Irregular grid feature for the 2-column layout in the Dynamic Grid/Carousel Widget', 'addons-for-elementor-builder'); ?></li>
    108                         <li><?php esc_html_e('Added : \'Stay in Column\' feature in the Sticky Extension', 'addons-for-elementor-builder'); ?></li>
     115                        <li><?php esc_html_e("Added : 'Stay in Column' feature in the Sticky Extension", 'addons-for-elementor-builder'); ?></li>
    109116                        <li><?php esc_html_e('Added : Feature to display pages related to each demo in the Templates Kit section', 'addons-for-elementor-builder'); ?></li>
    110117                    </ul>
     
    506513                </p>
    507514                <div class="afeb-space afeb-mr-20"></div>
    508                 <a class="afeb-box-btn afeb-primary-btn" href="https://wordpress.org/support/plugin/addons-for-elementor-builder/reviews/?filter=5" target="_blank">
     515                <a class="afeb-box-btn afeb-primary-btn" href="https://wordpress.org/support/plugin/addons-for-elementor-builder/reviews/" target="_blank">
    509516                    <?php esc_html_e("Rate On WordPress", 'addons-for-elementor-builder'); ?>
    510517                </a>
  • addons-for-elementor-builder/trunk/html/admin/metaboxes/submissions/additional-info/tpl.php

    r3297649 r3386622  
    1414                    ?>:
    1515                    <a href="<?php echo get_the_permalink($page_id) ?>" title="<?php echo get_the_title($page_id); ?>">
    16                         <b><?php echo get_the_title($page_id); ?></b>
     16                        <b><?php echo esc_html(get_the_title($page_id)); ?></b>
    1717                    </a>
    1818                </span>
  • addons-for-elementor-builder/trunk/html/admin/metaboxes/submissions/submission/tpl.php

    r3382971 r3386622  
    171171            formData.append('action', 'afeb_update_submission');
    172172            formData.append('post_id', '<?php echo esc_js($post_id); ?>');
    173             formData.append('nonce', '<?php echo wp_create_nonce( 'afeb_admin_submission' ); ?>');
     173            formData.append('nonce', '<?php echo esc_js( wp_create_nonce( 'afeb_admin_submission' ) ); ?>');
    174174
    175175            // Append our fields manually from DOM
  • addons-for-elementor-builder/trunk/readme.txt

    r3382971 r3386622  
    66Requires PHP: 7.2
    77Tested up to: 6.8
    8 Stable tag: 1.6.0
     8Stable tag: 1.6.1
    99License: GPLv2 or later
    1010License URI: http://www.gnu.org/licenses/gpl-2.0.html
     
    120120Want to dive deeper into how each widget works? Check out [Vertex documentation](https://api.webilia.com/go/vertex-docs) to learn about every feature and customization option available in the Vertex Addons.
    121121
     122== Development and Source ==
     123
     124The distributed plugin bundles several minified assets for performance. Human-readable sources are provided or linked below so the code can be audited, modified, or rebuilt as needed.
     125
     126=== Vertex-authored assets ===
     127
     128The following readable sources live in the repository next to their compiled counterparts:
     129
     130* `assets/js/global/dynamic-hook.js` → `assets/js/global/dynamic-hook.min.js`
     131* `assets/packages/ripple/ripple.js` → `assets/packages/ripple/ripple.min.js`
     132* `assets/packages/sticky/sticky.js` → `assets/packages/sticky/sticky.min.js`
     133* `assets/packages/news-ticker-init/news-ticker-init.js` → `assets/packages/news-ticker-init/news-ticker-init.min.js`
     134* `assets/css/common.css` → `assets/css/common.min.css`
     135* `assets/css/widgets/woo-checkout.css` → `assets/css/widgets/woo-checkout.min.css`
     136* `assets/css/widgets/woo-my-account.css` → `assets/css/widgets/woo-my-account.min.css`
     137* `assets/css/widgets/rtl/woo-my-account.css` → `assets/css/widgets/rtl/woo-my-account.min.css`
     138
     139Pro add-on assets follow the same pattern:
     140
     141* `plugins/addons-for-elementor-builder-pro/assets/js/form-builder.js` → `plugins/addons-for-elementor-builder-pro/assets/js/form-builder.min.js`
     142* `plugins/addons-for-elementor-builder-pro/assets/css/widgets/form-builder.css` → `plugins/addons-for-elementor-builder-pro/assets/css/widgets/form-builder.min.css`
     143
     144When you modify any of the above helpers, re-minify them with your preferred tooling before releasing a build. Each file can be minified individually with tools such as `uglify-js`, `terser`, or `cssnano`.
     145
     146=== Third-party libraries ===
     147
     148The plugin also ships minified builds of open-source libraries. Readable, beautified copies of the distributed bundles now live next to every `.min` file, so you can inspect or diff the exact payload we include. Refer to the upstream repositories for the canonical source code and build instructions:
     149
     150* DataTables core and extensions (`assets/packages/data-table/data-table*.{js,css}`) — <https://datatables.net/>
     151* Font Awesome (`assets/packages/font-awesome/fontawesome.{css,min.css}`) — <https://fontawesome.com/>
     152* Font Icon Picker (`assets/packages/font-iconpicker/fonticonpicker*.{js,css}`) — <https://github.com/itsjavi/fonticonpicker>
     153* GLightbox (`assets/packages/glightbox/glightbox*.{js,css}`) — <https://github.com/mcstudios/glightbox>
     154* GMaps.js (`assets/packages/gmaps/gmaps.{js,min.js}`) — <https://github.com/hpneo/gmaps>
     155* Howler.js (`assets/packages/howler/howler.{js,min.js}`) — <https://github.com/goldfire/howler.js>
     156* Leaflet (`assets/packages/leaflet/leaflet*.{js,css}`) — <https://leafletjs.com/>
     157* LightGallery (Pro add-on: `plugins/addons-for-elementor-builder-pro/assets/packages/lightgallery/lightgallery-bundle.{css,min.css}`) — <https://www.lightgalleryjs.com/>
     158* Lottie Web (`assets/packages/lottie/lottie.{js,min.js}`) — <https://github.com/airbnb/lottie-web>
     159* MixItUp (`assets/packages/mixitup/mixitup.{js,min.js}`) — <https://www.kunkalabs.com/mixitup/>
     160* Normalize.css (`assets/css/normalize.{css,min.css}`) — <https://github.com/necolas/normalize.css>
     161* Slick Slider (`assets/packages/slick/slick*.{js,css}`) — <https://github.com/kenwheeler/slick>
     162* SmartMenus (`assets/packages/smart-menus/smartmenus.{js,min.js}`) — <https://github.com/vadikom/smartmenus>
     163* Swiper (`assets/packages/swiper/swiper-bundle*.{js,css}`) — <https://swiperjs.com/>
     164* jQuery UI dialog styles (`assets/packages/jquery-ui/dialog.{css,min.css}`) — <https://jqueryui.com/dialog/>
     165
     166Each vendor project documents its own build pipeline; follow the linked instructions if you need to regenerate the distributed files from source.
     167
     168== External services ==
     169
     170= Google Maps Platform =
     171Vertex Addons can load the Google Maps JavaScript and Static Maps APIs hosted at `maps.googleapis.com` when you enable map-related widgets. The visitor's browser calls Google's servers with the API key you configure, the map coordinates you supply, and standard browser metadata (such as IP address and user agent) so the map tiles and related functionality can be rendered. See the [Google Maps Platform Terms of Service](https://maps.google.com/help/terms_maps/) and the [Google Privacy Policy](https://policies.google.com/privacy) for details on how Google handles this data.
     172
     173= Vertex Addons CDN and API =
     174When you browse or import Templates Kits, the plugin connects to Webilia-operated endpoints at `cdn.webilia.com` and `api.webilia.com` to fetch kit listings, previews, and assets. Those requests transmit the selected kit identifier together with the default WordPress request headers, which include your site's URL and WordPress version, so the templates can be downloaded and installed. Review the [Vertex Addons Terms & Conditions](https://vertexaddons.com/terms-and-conditions/) and [Vertex Addons Privacy Policy](https://vertexaddons.com/privacy-policy/) to understand how that data is processed.
     175
    122176== Commercial ==
    123177This plugin is free but offers additional paid commercial upgrades and support. [Learn more](https://vertexaddons.com)
     
    177231
    178232== Changelog ==
     233
     234= 1.6.1 =
     235* Fixed : Enhanced the security and fixed some minor issues.
     236
     237= 1.6.0 =
     238Added : Woo Checkout Widget
     239Added : Woo Add To Cart Widget
     240Added : Woo Product Category Widget
     241Added : Woo Product Tags Widget
     242Added : Product Image Widget
     243Added : Product Content Widget
     244Added : Product Excerpt Widget
    179245
    180246= 1.5.3 =
Note: See TracChangeset for help on using the changeset viewer.