Plugin Directory

Changeset 3341185


Ignore:
Timestamp:
08/07/2025 04:46:39 PM (8 months ago)
Author:
malakontask
Message:

Update to version 2.7.0

Location:
transfer-brands-for-woocommerce
Files:
20 added
7 edited

Legend:

Unmodified
Added
Removed
  • transfer-brands-for-woocommerce/trunk/CHANGELOG.md

    r3294781 r3341185  
    55The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
    66and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
     7
     8## [2.7.0] - 2025-08-07
     9
     10### Added
     11- Full compatibility with WordPress 6.8.2
     12- Full compatibility with WooCommerce 10.0.4
     13- Support for both 'thumbnail_id' and 'brand_image_id' meta keys for brand images
     14- Enhanced security with capability checks in all AJAX handlers
     15- Stores brand images in both meta keys for maximum compatibility
     16
     17### Changed
     18- Updated minimum PHP requirement to 7.4
     19- Updated minimum WordPress requirement to 6.0
     20- Updated minimum WooCommerce requirement to 8.0.0
     21- Improved SQL queries with proper placeholder handling
     22- Enhanced error handling and debugging capabilities
     23
     24### Fixed
     25- Fixed critical brand images transfer issue preventing images from migrating properly
     26- Fixed duplicate code in product batch processing
     27- Fixed SQL query security issues with proper prepared statements
     28- Added missing permission checks in AJAX handlers
    729
    830## [2.6.3] - 2025-05-16
  • transfer-brands-for-woocommerce/trunk/includes/class-ajax.php

    r3294781 r3341185  
    4747    public function ajax_transfer() {
    4848        check_ajax_referer('tbfw_transfer_brands_nonce', 'nonce');
     49       
     50        if (!current_user_can('manage_woocommerce')) {
     51            wp_die(__('You do not have permission to perform this action.', 'transfer-brands-for-woocommerce'));
     52        }
     53       
    4954        $step = isset($_POST['step']) ? sanitize_text_field($_POST['step']) : 'backup';
    5055        $offset = isset($_POST['offset']) ? intval($_POST['offset']) : 0;
     
    115120    public function ajax_check_brands() {
    116121        check_ajax_referer('tbfw_transfer_brands_nonce', 'nonce');
     122       
     123        if (!current_user_can('manage_woocommerce')) {
     124            wp_die(__('You do not have permission to perform this action.', 'transfer-brands-for-woocommerce'));
     125        }
    117126       
    118127        $source_terms = get_terms([
     
    181190           
    182191            // Check if term has image
     192            // Check both possible image meta keys
    183193            $image_id = get_term_meta($term->term_id, 'thumbnail_id', true);
     194            if (!$image_id) {
     195                $image_id = get_term_meta($term->term_id, 'brand_image_id', true);
     196            }
    184197            if ($image_id) {
    185198                $terms_with_images++;
     
    316329        check_ajax_referer('tbfw_transfer_brands_nonce', 'nonce');
    317330       
     331        if (!current_user_can('manage_woocommerce')) {
     332            wp_die(__('You do not have permission to perform this action.', 'transfer-brands-for-woocommerce'));
     333        }
     334       
    318335        $result = $this->core->get_backup()->rollback_transfer();
    319336       
     
    332349        check_ajax_referer('tbfw_transfer_brands_nonce', 'nonce');
    333350       
     351        if (!current_user_can('manage_woocommerce')) {
     352            wp_die(__('You do not have permission to perform this action.', 'transfer-brands-for-woocommerce'));
     353        }
     354       
    334355        $result = $this->core->get_backup()->rollback_deleted_brands();
    335356       
     
    349370    public function ajax_init_delete() {
    350371        check_ajax_referer('tbfw_transfer_brands_nonce', 'nonce');
     372       
     373        if (!current_user_can('manage_woocommerce')) {
     374            wp_die(__('You do not have permission to perform this action.', 'transfer-brands-for-woocommerce'));
     375        }
    351376       
    352377        // Make sure we completely remove previous data
     
    373398    public function ajax_delete_old_brands() {
    374399        check_ajax_referer('tbfw_transfer_brands_nonce', 'nonce');
     400       
     401        if (!current_user_can('manage_woocommerce')) {
     402            wp_die(__('You do not have permission to perform this action.', 'transfer-brands-for-woocommerce'));
     403        }
    375404       
    376405        $offset = isset($_POST['offset']) ? intval($_POST['offset']) : 0;
     
    530559        check_ajax_referer('tbfw_transfer_brands_nonce', 'nonce');
    531560       
     561        if (!current_user_can('manage_woocommerce')) {
     562            wp_die(__('You do not have permission to perform this action.', 'transfer-brands-for-woocommerce'));
     563        }
     564       
    532565        $result = $this->core->get_backup()->cleanup_backups();
    533566       
     
    545578    public function ajax_refresh_counts() {
    546579        check_ajax_referer('tbfw_transfer_brands_nonce', 'nonce');
     580       
     581        if (!current_user_can('manage_woocommerce')) {
     582            wp_die(__('You do not have permission to perform this action.', 'transfer-brands-for-woocommerce'));
     583        }
    547584       
    548585        // Clear object cache
     
    590627        check_ajax_referer('tbfw_transfer_brands_nonce', 'nonce');
    591628       
     629        if (!current_user_can('manage_woocommerce')) {
     630            wp_die(__('You do not have permission to perform this action.', 'transfer-brands-for-woocommerce'));
     631        }
     632       
    592633        if (isset($_POST['clear']) && $_POST['clear']) {
    593634            delete_option('tbfw_brands_debug_log');
     
    605646    public function ajax_refresh_destination_taxonomy() {
    606647        check_ajax_referer('tbfw_transfer_brands_nonce', 'nonce');
     648       
     649        if (!current_user_can('manage_woocommerce')) {
     650            wp_die(__('You do not have permission to perform this action.', 'transfer-brands-for-woocommerce'));
     651        }
    607652       
    608653        // Refresh the destination taxonomy
  • transfer-brands-for-woocommerce/trunk/includes/class-backup.php

    r3294781 r3341185  
    4747        if (!is_wp_error($dest_terms)) {
    4848            foreach ($dest_terms as $term) {
     49                // Check both possible image meta keys
    4950                $image_id = get_term_meta($term->term_id, 'thumbnail_id', true);
     51                if (!$image_id) {
     52                    $image_id = get_term_meta($term->term_id, 'brand_image_id', true);
     53                }
    5054                $backup['terms'][$term->term_id] = [
    5155                    'name' => $term->name,
  • transfer-brands-for-woocommerce/trunk/includes/class-transfer.php

    r3294781 r3341185  
    7575            $new_id = is_array($new) ? $new['term_id'] : $new;
    7676           
    77             // Transfer image if exists
     77            // Transfer image if exists - support both old and new meta keys
    7878            $image_id = get_term_meta($term->term_id, 'thumbnail_id', true);
     79            if (!$image_id) {
     80                $image_id = get_term_meta($term->term_id, 'brand_image_id', true);
     81            }
    7982            if ($image_id) {
     83                // Store in both keys for maximum compatibility
    8084                update_term_meta($new_id, 'thumbnail_id', $image_id);
     85                update_term_meta($new_id, 'brand_image_id', $image_id);
    8186                $log_message .= ' (with image)';
    8287            }
     
    129134       
    130135        // Create exclusion placeholders for already processed products
    131 $exclude_condition = '';
    132 $query_args = [
    133     '%' . $wpdb->esc_like($this->core->get_option('source_taxonomy')) . '%',
    134     $this->core->get_batch_size()
    135 ];
    136 if (!empty($processed_products)) {
    137     $placeholders = implode(',', array_fill(0, count($processed_products), '%d'));
    138     $exclude_condition = " AND post_id NOT IN ($placeholders)";
    139     $query_args = array_merge([$query_args[0]], $processed_products, [$query_args[1]]);
    140 }
    141 
    142 // Find products with brand attribute that haven't been processed yet
    143 $query = "SELECT DISTINCT post_id
    144         FROM {$wpdb->postmeta}
    145         WHERE meta_key = '_product_attributes'
    146         AND meta_value LIKE %s
    147         AND post_id IN (SELECT ID FROM {$wpdb->posts} WHERE post_type = 'product' AND post_status = 'publish')
    148         {$exclude_condition}
    149         LIMIT %d";
    150 
    151 $product_ids = $wpdb->get_col(
    152     $wpdb->prepare($query, $query_args)
    153 );
    154         $product_ids = $wpdb->get_col(
    155             $wpdb->prepare(
    156                 "SELECT DISTINCT post_id
     136        $exclude_condition = '';
     137        $query_args = [
     138            '%' . $wpdb->esc_like($this->core->get_option('source_taxonomy')) . '%'
     139        ];
     140       
     141        if (!empty($processed_products)) {
     142            $placeholders = implode(',', array_fill(0, count($processed_products), '%d'));
     143            $exclude_condition = " AND post_id NOT IN ($placeholders)";
     144            $query_args = array_merge($query_args, $processed_products);
     145        }
     146       
     147        $query_args[] = $this->core->get_batch_size();
     148       
     149        // Find products with brand attribute that haven't been processed yet
     150        $query = "SELECT DISTINCT post_id
    157151                FROM {$wpdb->postmeta}
    158152                WHERE meta_key = '_product_attributes'
     
    160154                AND post_id IN (SELECT ID FROM {$wpdb->posts} WHERE post_type = 'product' AND post_status = 'publish')
    161155                {$exclude_condition}
    162                 LIMIT %d",
    163                 '%' . $wpdb->esc_like($this->core->get_option('source_taxonomy')) . '%',
    164                 $this->core->get_batch_size()
    165             )
     156                LIMIT %d";
     157       
     158        $product_ids = $wpdb->get_col(
     159            $wpdb->prepare($query, $query_args)
    166160        );
    167161       
  • transfer-brands-for-woocommerce/trunk/includes/class-utils.php

    r3294781 r3341185  
    190190        $result = [];
    191191        foreach ($terms as $term) {
     192            // Check both possible image meta keys
    192193            $image_id = get_term_meta($term->term_id, 'thumbnail_id', true);
     194            if (!$image_id) {
     195                $image_id = get_term_meta($term->term_id, 'brand_image_id', true);
     196            }
    193197            if ($image_id) {
    194198                $result[] = [
  • transfer-brands-for-woocommerce/trunk/readme.txt

    r3294819 r3341185  
    11=== Transfer Brands for WooCommerce ===
    22Contributors: malakontask
    3 Tags: woocommerce, brands, taxonomy, attribute, transfer
    4 Requires at least: 5.6
    5 Tested up to: 6.8
    6 Stable tag: 2.6.3
    7 Requires PHP: 7.2
     3Tags: woocommerce, brand, taxonomy, attribute, transfer, woocommerce 9.6, woocommerce brands, product brands, brand migration, brand transfer
     4Requires at least: 6.0
     5Tested up to: 6.8.2
     6Stable tag: 2.7.0
     7Requires PHP: 7.4
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
    10 WC requires at least: 5.0.0
    11 WC tested up to: 8.0.0
    12 
    13 Migrate product brand attributes to WooCommerce's brand taxonomy with image support, backup protection, and real-time progress tracking.
     10WC requires at least: 8.0.0
     11WC tested up to: 10.0.4
     12
     13Easily migrate your existing brand attributes to WooCommerce 9.6's new brand taxonomy with complete backup, image transfer, and real-time progress tracking.
    1414
    1515== Description ==
     
    116116
    117117== Changelog ==
     118= 2.7.0 =
     119* Full compatibility with WordPress 6.8.2 and WooCommerce 10.0.4
     120* Fixed brand images transfer issue - now supports both 'thumbnail_id' and 'brand_image_id' meta keys
     121* Enhanced security with proper capability checks in all AJAX handlers
     122* Updated minimum PHP requirement to 7.4 for better performance and security
     123* Updated minimum WordPress requirement to 6.0
     124* Improved SQL queries with proper placeholder handling
     125* Fixed duplicate code in product batch processing
     126* Added support for WooCommerce's new brand taxonomy structure
     127* Stores brand images in both meta keys for maximum compatibility
     128* Enhanced error handling and debugging capabilities
     129
    118130= 2.6.3 =
    119131* Updated textdomain loading to follow WordPress best practices
     
    180192== Upgrade Notice ==
    181193
     194= 2.7.0 =
     195Critical update for WooCommerce 10.0.4 compatibility. Fixes brand image transfer issues and adds full support for WordPress 6.8.2. This update is required for proper brand migration with the latest WooCommerce version.
     196
    182197= 2.6.3 =
    183 This update optimizes the plugin for WooCommerce brand compatibility and improves overall security and performance. Recommended for all users.
     198This update optimizes the plugin for WooCommerce 9.6 compatibility and improves overall security and performance.
    184199
    185200= 2.6.1 =
  • transfer-brands-for-woocommerce/trunk/transfer-brands-for-woocommerce.php

    r3294802 r3341185  
    44 * Plugin URI: https://pluginatlas.com/transfer-brands-for-woocommerce
    55 * Description: Official migration tool for WooCommerce 9.6 Brands. Safely transfer your product brand attributes to the new brand taxonomy with image support, batch processing, and full backup capabilities.
    6  * Version: 2.6.3
    7  * Requires at least: 5.6
    8  * Requires PHP: 7.2
     6 * Version: 2.7.0
     7 * Requires at least: 6.0
     8 * Requires PHP: 7.4
    99 * Requires Plugins: woocommerce
    1010 * Author: Kostas Malakontas
     
    1414 * Text Domain: transfer-brands-for-woocommerce
    1515 * Domain Path: /languages
    16  * WC requires at least: 5.0.0
    17  * WC tested up to: 8.0.0
     16 * WC requires at least: 8.0.0
     17 * WC tested up to: 10.0.4
    1818 *
    1919 * This program is free software: you can redistribute it and/or modify
     
    3636
    3737// Define plugin constants
    38 define('TBFW_VERSION', '2.6.3');
     38define('TBFW_VERSION', '2.7.0');
    3939define('TBFW_PLUGIN_DIR', plugin_dir_path(__FILE__));
    4040define('TBFW_PLUGIN_URL', plugin_dir_url(__FILE__));
     
    144144        }
    145145    }
    146     // Create necessary folders if they don't exist
    147     if (!file_exists(TBFW_PLUGIN_DIR . 'includes/')) {
    148         wp_mkdir_p(TBFW_PLUGIN_DIR . 'includes/');
    149     }
    150    
    151     if (!file_exists(TBFW_PLUGIN_DIR . 'assets/css/')) {
    152         wp_mkdir_p(TBFW_PLUGIN_DIR . 'assets/css/');
    153     }
    154    
    155     if (!file_exists(TBFW_PLUGIN_DIR . 'assets/js/')) {
    156         wp_mkdir_p(TBFW_PLUGIN_DIR . 'assets/js/');
    157     }
    158146   
    159147    // Add default options
Note: See TracChangeset for help on using the changeset viewer.