wordpress 如何自动为每个变体及其分类法分配属性?Woocommerce

4zcjmb1e  于 11个月前  发布在  WordPress
关注(0)|答案(1)|浏览(242)

我已经创建了代码,允许您保存CSV文件,从该文件在WooCommerce产品编辑器页面上创建产品变体,然后发布产品也属性和分类,但我不知道如何分配每个产品变体适当的分类和属性?

//nowy
// Funkcja do usuwania przestarzałych plików CSV
function remove_old_csv_files() {
    $args = array(
        'post_type' => 'product',
        'posts_per_page' => -1,
        'post_status' => 'any',
        'meta_query' => array(
            array(
                'key' => 'product_csv_file_url',
                'value' => '',
                'compare' => '!='
            )
        )
    );
    $products = new WP_Query($args);

    if ($products->have_posts()) {
        while ($products->have_posts()) {
            $products->the_post();
            $product_id = get_the_ID();
            $csv_file_url = get_post_meta($product_id, 'product_csv_file_url', true);
            $upload_date = get_post_meta($product_id, 'product_csv_file_upload_date', true);

            if (!empty($csv_file_url) && !empty($upload_date)) {
                $current_time = current_time('timestamp');
                $upload_time = strtotime($upload_date);

                if (($current_time - $upload_time) > DAY_IN_SECONDS) {
                    $file_path = str_replace(wp_get_upload_dir()['baseurl'], wp_get_upload_dir()['basedir'], $csv_file_url);
                    if (file_exists($file_path)) {
                        unlink($file_path);
                    }

                    delete_post_meta($product_id, 'product_csv_file_url');
                    delete_post_meta($product_id, 'product_csv_file_name');
                    delete_post_meta($product_id, 'product_csv_file_upload_date');
                }
            }
        }
        wp_reset_postdata();
    }
}

// Harmonogram codziennego usuwania plików CSV
if (!wp_next_scheduled('daily_csv_cleanup')) {
    wp_schedule_event(time(), 'daily', 'daily_csv_cleanup');
}
add_action('daily_csv_cleanup', 'remove_old_csv_files');

// Dodanie meta boxa do produktów WooCommerce dla uploadu pliku CSV.
function add_product_csv_upload_meta_box() {
    add_meta_box(
        'product_csv_upload_meta_box',
        'Upload Product CSV',
        'product_csv_upload_meta_box_html',
        'product'
    );
}
add_action('add_meta_boxes', 'add_product_csv_upload_meta_box');

// HTML dla meta boxa uploadu pliku CSV.
function product_csv_upload_meta_box_html($post) {
    wp_nonce_field('product_csv_upload_meta_box', 'product_csv_upload_meta_box_nonce');

    $csv_file_url = get_post_meta($post->ID, 'product_csv_file_url', true);
    $csv_file_name = get_post_meta($post->ID, 'product_csv_file_name', true);

    if (!empty($csv_file_url)) {
        echo '<p>Current Product CSV File: <a href="' . esc_url($csv_file_url) . '">' . esc_html($csv_file_name) . '</a></p>';
        echo '<label for="delete_product_csv">Delete File:</label> ';
        echo '<input type="checkbox" name="delete_product_csv" id="delete_product_csv"><br><br>';
    }

    echo '<input type="file" name="product_csv_file" id="product_csv_file" accept=".csv">';
    echo '<input type="submit" name="save_product_csv" value="Zapisz CSV">';
}

// Zapisywanie danych meta boxa do produktu i przetwarzanie pliku CSV.
function save_product_csv_meta_box_data($post_id) {
    if (!isset($_POST['product_csv_upload_meta_box_nonce']) ||
        !wp_verify_nonce($_POST['product_csv_upload_meta_box_nonce'], 'product_csv_upload_meta_box') ||
        defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ||
        !current_user_can('edit_post', $post_id)) {
        return;
    }

    if (!empty($_POST['delete_product_csv'])) {
        delete_post_meta($post_id, 'product_csv_file_url');
        delete_post_meta($post_id, 'product_csv_file_name');
        return;
    }

    if (isset($_FILES['product_csv_file']) && !empty($_FILES['product_csv_file']['name'])) {
        $uploaded_file = wp_handle_upload($_FILES['product_csv_file'], array('test_form' => false));

        if (isset($uploaded_file['file'])) {
            update_post_meta($post_id, 'product_csv_file_url', $uploaded_file['url']);
            update_post_meta($post_id, 'product_csv_file_name', $_FILES['product_csv_file']['name']);

            process_product_csv_file($post_id, $uploaded_file['file']);
        }
    }
}

add_action('save_post', 'save_product_csv_meta_box_data');



// Aktualizacja formularza edycji produktu, aby umożliwić upload plików.
function update_product_edit_form() {
    echo ' enctype="multipart/form-data"';
}
add_action('post_edit_form_tag', 'update_product_edit_form');

// Zmiana w funkcji process_product_csv_file
function process_product_csv_file($post_id, $csv_file_path) {
   $csv_data = array_map('str_getcsv', file($csv_file_path));
   array_shift($csv_data); // Usuń nagłówek CSV, jeśli istnieje

    foreach ($csv_data as $row) {
        if (count($row) >= 3) {
            $width = $row[0];
            $height = $row[1];
            $price = $row[2];

            create_or_update_product_variant($post_id, $width, $height, $price);
        }
    }
}

// Funkcja do tworzenia wariantu produktu.
function create_product_variant($product_id, $width, $height, $price) {
    $variant = new WC_Product_Variation();
    $variant->set_parent_id($product_id);
    $variant->set_regular_price($price);

    $variant->save(); // Zapisanie wariantu
}

// Funkcja do tworzenia lub aktualizacji wariantu produktu.
function create_or_update_product_variant($product_id, $width, $height, $price) {
    $existing_variants = wc_get_products(array(
        'status' => 'publish',
        'type' => 'variation',
        'parent' => $product_id,
        'limit' => -1,
    ));

    $variant_id = null;

    // Sprawdzenie, czy wariant już istnieje
    foreach ($existing_variants as $variant) {
        $variant_dimensions = $variant->get_dimensions(false);
        if ($variant_dimensions['width'] == $width && $variant_dimensions['height'] == $height) {
            $variant_id = $variant->get_id();
            break;
        }
    }

    if ($variant_id) {
        $variant = new WC_Product_Variation($variant_id);
    } else {
        $variant = new WC_Product_Variation();
        $variant->set_parent_id($product_id);
    }

    $variant->set_regular_price($price);
    $variant->set_props(array(
        'length' => '0', // Ustawienie długości na 0, jeśli nie jest dostarczana
        'width' => $width,
        'height' => $height
    ));

    $variant->save(); // Zapisanie wariantu

    // Zapisanie ID wariantu w metadanych produktu
    $variant_ids = get_post_meta($product_id, 'variant_ids', true) ?: array();
    if (!in_array($variant->get_id(), $variant_ids)) {
        $variant_ids[] = $variant->get_id();
        update_post_meta($product_id, 'variant_ids', $variant_ids);
    }
}
function create_attribute_on_product_publish($post_id) {
    // Make sure this is a genuine product save action and not a revision
    if (get_post_type($post_id) === 'product' && !wp_is_post_revision($post_id)) {
        create_custom_attribute($post_id);
    }
}

function create_custom_attribute($post_id) {
    // Get the current product name using the post ID
    $product_name = get_the_title($post_id);
    $attribute_name = sanitize_title($product_name); // Use the product name as the attribute name
    $attribute_taxonomy_name = wc_attribute_taxonomy_name($attribute_name);

    // Check if attribute already exists
    if (!attribute_exists($attribute_name)) {
        // Add new attribute
        $args = array(
            'name' => $attribute_name,
            'type' => 'select',
            'order_by' => 'menu_order',
            'has_archives' => false,
        );
        wc_create_attribute($args);
    }

    // Check if taxonomy for the attribute already exists
    if (!taxonomy_exists($attribute_taxonomy_name)) {
        // Register taxonomy for the attribute
        register_taxonomy(
            $attribute_taxonomy_name,
            'product',
            array(
                'label' => $attribute_name,
                'hierarchical' => false,
                'show_in_nav_menus' => false,
                'show_ui' => false,
            )
        );
    }

    // Get the product object using the post ID
    $product = wc_get_product($post_id);
    if (!$product) return;

    // Check if the product is a variable product
    if ($product->is_type('variable')) {
        // Get metadata from product variants and create attribute values
        $variants = $product->get_available_variations();
        foreach ($variants as $variant) {
            $variant_obj = new WC_Product_Variation($variant['variation_id']);
            $width = $variant_obj->get_width();
            $height = $variant_obj->get_height();

            // Check if both width and height are available
            if ($width && $height) {
                $dimension_value = $width . 'x' . $height; // Combine width and height

                if (!term_exists($dimension_value, $attribute_taxonomy_name)) {
                    wp_insert_term($dimension_value, $attribute_taxonomy_name);
                }
            }
        }
    }
}
add_action('save_post', 'create_attribute_on_product_publish');

function attribute_exists($attribute_name) {
    global $wpdb;
    $attribute_name = wc_sanitize_taxonomy_name($attribute_name);
    $sql = "SELECT attribute_id FROM " . $wpdb->prefix . "woocommerce_attribute_taxonomies WHERE attribute_name = %s";
    return $wpdb->get_var($wpdb->prepare($sql, $attribute_name)) ? true : false;
}

字符串
我试着做这样的事情,但不幸的是,这不是一条正确的路。

function assign_dimension_attribute_to_variant($post_id) {
    // Pobieranie produktu
    $product = wc_get_product($post_id);
    if (!$product || !$product->is_type('variable')) return;

    $attribute_name = 'pa_dimensions'; // Nazwa atrybutu

    // Sprawdź, czy atrybut istnieje, jeśli nie - zakończ funkcję
    if (!taxonomy_exists($attribute_name)) {
        error_log('Atrybut wymiarów nie istnieje: ' . $attribute_name);
        return;
    }

    $variants = $product->get_children(); // Pobierz ID wariantów produktu

    foreach ($variants as $variant_id) {
        $variant = wc_get_product($variant_id);
        if (!$variant) continue;

        // Pobierz wymiary wariantu
        $width = $variant->get_width();
        $height = $variant->get_height();

        // Jeśli wymiary są dostępne, zaktualizuj atrybut w wariancie
        if ($width && $height) {
            $dimension_value = $width . 'x' . $height;

            // Zaktualizuj atrybut w wariancie
            wp_set_object_terms($variant_id, $dimension_value, $attribute_name);
        }
    }

    // Aktualizacja atrybutów w produkcie głównym
    $product_attributes = $product->get_attributes();
    $product_attributes[$attribute_name] = array(
        'name' => $attribute_name,
        'value' => '',
        'is_visible' => '1',
        'is_variation' => '1',
        'is_taxonomy' => '1'
    );
    $product->set_attributes($product_attributes);

    // Zapisz produkt
    $product->save();
}

add_action('save_post_product', 'assign_dimension_attribute_to_variant', 10, 1);

3gtaxfhh

3gtaxfhh1#

您编写的代码是正确的,但还有一些问题需要解决。
首先,你为每个变量创建一个新的属性,这是不必要的。你应该有一个属性(例如,“Dimensions”),每个变量应该有这个属性的不同术语(例如,“10x20”,“20x30”等)。
其次,您试图将属性直接分配给变体。然而,在WooCommerce中,属性被分配给父产品,而不是变体。变体具有属性值,而不是属性本身。
下面是assign_dimension_attribute_to_variant函数的修改版本,应该可以工作:

function assign_dimension_attribute_to_variant($post_id) {
    $product = wc_get_product($post_id);
    if (!$product || !$product->is_type('variable')) return;

    $attribute_name = 'pa_dimensions'; // The attribute taxonomy name
    $attribute_values = array(); // An array to store attribute values

    $variants = $product->get_children(); // Get the IDs of the product variants
    foreach ($variants as $variant_id) {
        $variant = wc_get_product($variant_id);
        $width = $variant->get_width();
        $height = $variant->get_height();

        if ($width && $height) {
            $dimension_value = $width . 'x' . $height;
            $attribute_values[] = $dimension_value;

            // Update the variant with the attribute value
            update_post_meta($variant_id, 'attribute_' . $attribute_name, $dimension_value);
        }
    }

    // Ensure that the attribute exists and is a product attribute
    if (!taxonomy_exists($attribute_name)) {
        register_taxonomy(
            $attribute_name,
            'product',
            array('hierarchical' => true, 'label' => 'Dimensions')
        );
    }

    // Update the product with the attribute and its values
    wp_set_object_terms($post_id, $attribute_values, $attribute_name);
    $product_attributes = $product->get_attributes();
    $product_attributes[$attribute_name] = array(
        'name' => $attribute_name,
        'value' => '',
        'is_visible' => '1',
        'is_variation' => '1',
        'is_taxonomy' => '1'
    );
    update_post_meta($post_id, '_product_attributes', $product_attributes);

    // Save the product
    $product->save();
}
add_action('save_post_product', 'assign_dimension_attribute_to_variant', 10, 1);

字符串
这个函数将创建一个“Dimensions”属性(如果它还不存在),将其分配给产品,并将适当的尺寸值分配给每个变量。

相关问题