web-dev-qa-db-de.com

Erstellen benutzerdefinierter Woocommerce-Attributtaxonomien aus einem Plugin

Ich habe ein Plugin zum Importieren von Produkten in Wordpress mit Woocommerce erstellt. Es funktioniert einwandfrei mit Ausnahme der Produktattribute - ich kann keine Möglichkeit finden, sie ordnungsgemäß zu importieren.

Das Problem ist, dass ich bei Produkten benutzerdefinierte Taxonomien hinzufüge, die nicht im Dashboard definiert sind. Überraschenderweise kann ich keine Methode dafür finden. Ich habe wp_insert_term() mit register_taxonomy() ausprobiert, aber diese fügen der wp_woocommerce_attribute_taxonomies-Tabelle in der Datenbank nichts hinzu, und ich finde sie weder in den Produktattributen noch auf der Seite mit den Produktattributen im Dashboard. Ich habe sie nur in der wp_terms-Tabelle in der Datenbank gefunden und von dem, was ich erfahren habe, ist es nicht so, dass Produktattribute in Woocommerce gehören.

update_post_meta() scheint ebenfalls nicht zu funktionieren (es können Attribute als Meta hinzugefügt werden, aber ich benötige sie als Woocommerce-Produktattribute).

Ich muss Attribute erstellen, wenn sie nicht vorhanden sind, bevor ich die Produkte importiere. Gibt es eine Funktion, die ich übersehen habe?

Ich bin mir nicht sicher, ob ich etwas veröffentlichen soll, aber hier ist der Code, der mit dem Problem zusammenhängt:

// This is an example of what I get from my AJAX input
$product_attributes = array(
    "attr_id_01" => array(
        "name" => "Material",
        "value" => "Metal",
        "is_visible" => 1,
        "is_taxonomy" => 1
    ),
    "attr_id_02" => array(
        "name" => "Type",
        "value" => "Has a handle",
        "is_visible" => 1,
        "is_taxonomy" => 1
    )
);
foreach ($product_attributes_copy as $key => $value) {
    // sanitize_title filter is provided by CyrToLat plugin,
    // it basically makes the string url-friendly, 
    // it's used because names and values could contain Cyrillic, uppercase and spaces
    $filtered_name = apply_filters('sanitize_title', $value['name']);
    $filtered_value = apply_filters('sanitize_title', $value['value']);

    $taxonomy = 'pa_' . $filtered_name;
    $parent_term = term_exists( $filtered_value, $taxonomy );
    $parent_term_id = $parent_term['term_id'];

    if ( ! taxonomy_exists($taxonomy) ) {
        register_taxonomy($taxonomy, 'product', array('label' => $value['name']) );
    }

    // No errors from the following
    $insert_result = wp_insert_term(
        $filtered_value,
        $taxonomy,
        array(
            'description'=> '',
            'slug' => $filtered_value,
            'parent'=> $parent_term_id
        )
    );
}
3
Dmitriy Demir

Aus irgendeinem Grund möchte Woocommerce nicht, dass Sie dies tun. Ich bin mir nicht sicher, warum, da die manuelle Ausführung in einigen Fällen ein Problem für die Skalierbarkeit darstellt (ganz zu schweigen davon, dass bei Attributen mit vielen möglichen Werten die Schnittstelle, die sie bereitstellen, geladen wird wirklich langsam). Nachdem Sie ein bisschen gegraben haben, sind hier die privaten Funktionen, die die Admin-Seiten verwenden, geändert für systemische Aufrufe.

function process_add_attribute($attribute)
{
    global $wpdb;
//      check_admin_referer( 'woocommerce-add-new_attribute' );

    if (empty($attribute['attribute_type'])) { $attribute['attribute_type'] = 'text';}
    if (empty($attribute['attribute_orderby'])) { $attribute['attribute_orderby'] = 'menu_order';}
    if (empty($attribute['attribute_public'])) { $attribute['attribute_public'] = 0;}

    if ( empty( $attribute['attribute_name'] ) || empty( $attribute['attribute_label'] ) ) {
            return new WP_Error( 'error', __( 'Please, provide an attribute name and slug.', 'woocommerce' ) );
    } elseif ( ( $valid_attribute_name = valid_attribute_name( $attribute['attribute_name'] ) ) && is_wp_error( $valid_attribute_name ) ) {
            return $valid_attribute_name;
    } elseif ( taxonomy_exists( wc_attribute_taxonomy_name( $attribute['attribute_name'] ) ) ) {
            return new WP_Error( 'error', sprintf( __( 'Slug "%s" is already in use. Change it, please.', 'woocommerce' ), sanitize_title( $attribute['attribute_name'] ) ) );
    }

    $wpdb->insert( $wpdb->prefix . 'woocommerce_attribute_taxonomies', $attribute );

    do_action( 'woocommerce_attribute_added', $wpdb->insert_id, $attribute );

    flush_rewrite_rules();
    delete_transient( 'wc_attribute_taxonomies' );

    return true;
}

function valid_attribute_name( $attribute_name ) {
    if ( strlen( $attribute_name ) >= 28 ) {
            return new WP_Error( 'error', sprintf( __( 'Slug "%s" is too long (28 characters max). Shorten it, please.', 'woocommerce' ), sanitize_title( $attribute_name ) ) );
    } elseif ( wc_check_if_attribute_name_is_reserved( $attribute_name ) ) {
            return new WP_Error( 'error', sprintf( __( 'Slug "%s" is not allowed because it is a reserved term. Change it, please.', 'woocommerce' ), sanitize_title( $attribute_name ) ) );
    }

    return true;
}

Wie folgt aufgerufen:

$insert = proccess_add_attribute(array('attribute_name' => 'my-new-slug', 'attribute_label' => 'my-new-attribute', 'attribute_type' => 'text', 'attribute_orderby' => 'menu_order', 'attribute_public' => false));
if (is_wp_error($insert)) { do_something_for_error($insert); }

Die mit dem Attribut verknüpften Felder sind der Name (Standard-WP-Slug), die Bezeichnung (vom Menschen lesbare Version des Attributnamens), der Typ (Sie haben die Wahl zwischen "Auswählen" und "Text". Wenn Sie jedoch systematisch erstellen, sind Sie es Ich möchte wahrscheinlich, dass Text, den ich in der Funktion als Standard geändert habe, öffentlich (in der Benutzeroberfläche als "Archive aktivieren" gekennzeichnet ist, ich habe die Funktion als Standardeinstellung für die Benutzeroberfläche festgelegt) und sortiert nach (die Auswahlmöglichkeiten lauten "menu_order" (als "Benutzerdefiniert" bezeichnet) Sortierung "in der Schnittstelle)," Name "(selbsterklärend)," name_num "(numerischer Name) und" id "(Term-ID)

7
Ardidaj