Attribuut-taxonomieën (WooCommerce): verschil tussen versies
Regel 371: | Regel 371: | ||
|[[file:20190718-11.11.png|thumb|Tabel <code>wp_woocommerce_attribute_taxonomies</code> - Voor ik 'm verwijderde]] | |[[file:20190718-11.11.png|thumb|Tabel <code>wp_woocommerce_attribute_taxonomies</code> - Voor ik 'm verwijderde]] | ||
|} | |} | ||
+ | |||
+ | ''' wp_options - _transient_wc_attribute_taxonomies ''' | ||
+ | |||
+ | Tjakka: wp_options bevat de definities. Waarde van ''option_value'' in bovenstaand voorbeeld: | ||
+ | |||
+ | <pre> | ||
+ | a:11:{i:0;O:8:"stdClass":6:{s:12:"attribute_id";s:2:"10";s:14:"attribute_name";s:8:"apparaat";s:15:"attribute_label";s:8:"Apparaat";s:14:"attribute_type";s:6:"select";s:17:"attribute_orderby";s:10:"menu_order";s:16:"attribute_public";s:1:"1";}i:1;O:8:"stdClass":6:{s:12:"attribute_id";s:1:"5";s:14:"attribute_name";s:17:"automatische_stop";s:15:"attribute_label";s:17:"Automatische stop";s:14:"attribute_type";s:6:"select";s:17:"attribute_orderby";s:10:"menu_order";s:16:"attribute_public";s:1:"1";}i:2;O:8:"stdClass":6:{s:12:"attribute_id";s:1:"1";s:14:"attribute_name";s:7:"breedte";s:15:"attribute_label";s:7:"Breedte";s:14:"attribute_type";s:4:"text";s:17:"attribute_orderby";s:10:"menu_order";s:16:"attribute_public";s:1:"1";}i:3;O:8:"stdClass":6:{s:12:"attribute_id";s:1:"7";s:14:"attribute_name";s:9:"connector";s:15:"attribute_label";s:9:"Connector";s:14:"attribute_type";s:6:"select";s:17:"attribute_orderby";s:10:"menu_order";s:16:"attribute_public";s:1:"1";}i:4;O:8:"stdClass":6:{s:12:"attribute_id";s:1:"4";s:14:"attribute_name";s:7:"diagram";s:15:"attribute_label";s:7:"Diagram";s:14:"attribute_type";s:4:"text";s:17:"attribute_orderby";s:10:"menu_order";s:16:"attribute_public";s:1:"1";}i:5;O:8:"stdClass":6:{s:12:"attribute_id";s:1:"2";s:14:"attribute_name";s:6:"diepte";s:15:"attribute_label";s:6:"Diepte";s:14:"attribute_type";s:4:"text";s:17:"attribute_orderby";s:10:"menu_order";s:16:"attribute_public";s:1:"1";}i:6;O:8:"stdClass":6:{s:12:"attribute_id";s:1:"3";s:14:"attribute_name";s:6:"lengte";s:15:"attribute_label";s:6:"Lengte";s:14:"attribute_type";s:4:"text";s:17:"attribute_orderby";s:10:"menu_order";s:16:"attribute_public";s:1:"1";}i:7;O:8:"stdClass":6:{s:12:"attribute_id";s:1:"9";s:14:"attribute_name";s:4:"merk";s:15:"attribute_label";s:4:"Merk";s:14:"attribute_type";s:6:"select";s:17:"attribute_orderby";s:10:"menu_order";s:16:"attribute_public";s:1:"1";}i:8;O:8:"stdClass":6:{s:12:"attribute_id";s:2:"11";s:14:"attribute_name";s:21:"originele koolborstel";s:15:"attribute_label";s:21:"Originele Koolborstel";s:14:"attribute_type";s:6:"select";s:17:"attribute_orderby";s:10:"menu_order";s:16:"attribute_public";s:1:"1";}i:9;O:8:"stdClass":6:{s:12:"attribute_id";s:1:"6";s:14:"attribute_name";s:11:"stroomdraad";s:15:"attribute_label";s:11:"Stroomdraad";s:14:"attribute_type";s:6:"select";s:17:"attribute_orderby";s:10:"menu_order";s:16:"attribute_public";s:1:"1";}i:10;O:8:"stdClass":6:{s:12:"attribute_id";s:1:"8";s:14:"attribute_name";s:4:"veer";s:15:"attribute_label";s:4:"Veer";s:14:"attribute_type";s:6:"select";s:17:"attribute_orderby";s:10:"menu_order";s:16:"attribute_public";s:1:"1";}} | ||
+ | </pre> | ||
== Zie ook == | == Zie ook == |
Versie van 18 jul 2019 11:23
WooCommerce's Attributes (Kenmerken) zijn een instantie van het WordPress Categorie-taxonomische systeem, bedoeld voor ontsluiting van producten op basis van intrinsieke eigenschappen (bv. maat & kleur als het om kleding gaat).
Attibutes komen in twee smaken:
- Predefined Attributes
- Custom Attributes.
Dit hoofdstuk gaat voornamelijk over deze eerste variant.
Database-tabellen
wp_woocommerce_attribute_taxonomies
Tabel wp_woocommerce_attribute_taxonomies
Lijkt niets te doen. Zie hoodstuk over verwijdering van attribuut-taxonomieën, elders in dit artikel:
SELECT * FROM kbo3.wp_woocommerce_attribute_taxonomies; attribute_id attribute_name attribute_label attribute_type attribute_orderby attribute_public ------------ -------------- ----------------- -------------- ----------------- ---------------- 5 breedte Breedte text name_num 1 6 diepte Diepte text name_num 1 7 lengte Lengte text name_num 1 8 automatische_stop Automatische stop text name 1
wp_terms
Subtaxons verschijnen gewoon in wp_terms
. Dat maakt het gemakkelijk om met subtaxons te werken, want het werkt hetzelfde als voor gewone categorieën.
wp_term_taxonomy
Tabel wp_term_taxonomy
verbindt taxons met taxonomieën. Hier kun je zien dat WooCommerce 'onder water' losse taxonomieën defineert voor alle attributen. Je herkent ze aan de prefix pa_
. Merk op dat parent=0
: Er wordt niet gebruik gemaakt van hierarchie! Ook niet zo vreemd, omdat je bij attributen max. twee lagen hebt. Voorbeeld:
SELECT * FROM kbo3.wp_term_taxonomy where taxonomy like "pa_%"; term_taxonomy_id term_id taxonomy description parent count ---------------- ------- ---------- ------------- ------ ----- 110 110 pa_breedte Breedte-taxon 0 0
wp_term_relationships
Tabel wp_term_relationships
verbindt taxons met WordPress-objecten.
wp_termmeta
Tabel wp_termmeta
lijkt metadata te bevatten: Als je nog iets extra's kwijt wilt over een taxon, kun je dat hier doen. WooCommerce maakt hier bv. voor product_cat-taxonomieën aan, om de count per hoofdtaxon in op te slaan.
Het lijkt vooralsnog niet gebruikt te worden voor attribuut-taxonomieën.
Database-velden
In het algemeen zijn veldnamen binnen een WordPress-instantie niet consistent. Dat kun je zien aan het ER-diagram elders in dit artikel:
- In tabel wp_users heet de pk ID
- In tabel wp_usermeta heet dit veld user_id
- In tabel wp_posts heet dit veld post_author.
Desalniettemin: Rondom taxonomieën lijken veldnamen consistent te zijn. Anders had dit hoofdstuk weinig zin.
term_id
term_id
is de pk voor een taxon of term.
term_taxonomy_id
term_taxonomy_id
is de pk van de tussentabelwp_term_taxonomy
, die ervoor zorgt dat je een many-to-many-relatie hebt tussenterms
enterm_relationships
- Zo'n veel-veel-relatie ben ik tot op heden nog niet tegengekomen. Vandaar dat deze twee velden steeds dezelfde waardes lijken te hebben: Er zijn dan evenveel records in beide tabellen
- Overigens: Ik heb geen idee waarom je zo'n veel-veel-relatie wilt hebben, maar daar gaat het nu niet om.
UI-Velden
Dit zijn de velden die ik zoal in de user interface tegenkom. Namen zijn inconsistent en niet-intuïtief
Name - attribute_name
Shown on the front-end
Slug - attribute_label
Max. 28 karakters.
attribute_type
Het soort control dat gebruikt wordt als interface??? Bv.:
select
- Beperkt aantal keuzes, zoals een lookup-tabel of voor Boolese waardentext
- Tekstveld, lijkt me.
Enable Archives
Dus dat je een 'taxon-pagina' hebt. Altijd doen. Voor Attributes-taxonomieën kun je helaas geen afbeelding of tekst toevoegen (itt. gewone Categorieën) [1]
Custom ordering - attribute_orderby
Niet zo spannend:
menu_order
name
- etc.
attribute_public
Taxonomieën worden binnen een WordPress-site veelvuldig gebruikt voor interne aangelegenheden. Bv. om vertalingen bij te houden. Vandaar dat je er voor kunt kiezen om attribuut-taxonomieën verborgen te houden voor gebruikers.
Taxonomie toevoegen
Met taxonomie bedoel ik hier hetzelfde als hoofdtaxon .
Toevoegen van een hoofdtaxon/taxonomie, wil niet lukken met bv. wp_insert_term
. Aangezien Attributes een speciaal geval is van een categorie, zou je verwachten dat dit werkt. Maar dat doet het niet. Gelukkig kun je dit op een meer low-level fixen mbv. $wpdb
. Daar gebruik ik deze functies voor. Deze staat in één van m'n libraries (niet in functions.php
). Geïnspireerd op [2]:
function dvb_add_attribute_taxonomy($attribute) { # Add a WooCommerce Attribute-taxonomy ####################################################################################################### # # * Somehow, the usual function register_taxonomy doesn't work for WooCommerce Attributes, hence the # lower-level approach in this function # * Based on the example https://wordpress.stackexchange.com/questions/244335/creating-custom-woocommerce-attribute-taxonomies-from-a-plugin # * Jeroen Strompf, De Vliegende Brigade - April 2019 # * To be included in functions.php where appropriate ####################################################################################################### # Get acces to $wpdb class ####################################################################################################### # global $wpdb; ####################################################################################################### # Verify input ####################################################################################################### # 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', __( 'Attribute name and/and slug is missing.', 'woocommerce' ) ); } elseif ( ( $valid_attribute_name = dvb_check_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" already in use', 'woocommerce' ), sanitize_title( $attribute['attribute_name'] ) ) ); } ####################################################################################################### # Insert into WordPress ####################################################################################################### # $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 dvb_check_attribute_name( $attribute_name ) { # Check if a given attribute name is valid ####################################################################################################### # # * Based on the example https://wordpress.stackexchange.com/questions/244335/creating-custom-woocommerce-attribute-taxonomies-from-a-plugin # * Jeroen Strompf, De Vliegende Brigade - April 2019 # * To be included in functions.php where appropriate if ( strlen( $attribute_name ) >= 28 ) { return new WP_Error( 'error', sprintf( __( 'Slug "%s" is longer than 28 characters)', '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.', 'woocommerce' ), sanitize_title( $attribute_name ) ) ); } return true; };
Voorbeeld van een aanroep:
<?php ############################################################### # Call require_once ############################################################### # # Functions "dvb_add_attribute_taxonomy" and # "dvb_check_attribute_name" have been included in functions.php. # They become available through this "require_once" command # require_once("/home/strompf/www/example.com/wp-load.php"); ############################################################### # Define new attribute-taxonomy ############################################################### # $attribute_definition = array ( 'attribute_name' => 'attribute-naam (2)', 'attribute_label' => 'attribute-plakker (2)', 'attribute_type' => 'text', 'attribute_orderby' => 'menu_order', 'attribute_public' => false ); ############################################################### # Create this new attribute-taxonomy ############################################################### # dvb_add_attribute_taxonomy($attribute_definition);
Subtaxons toevoegen
- Attribuut-taxonomieën zijn niet-hiërarchisch, en zitten iets anders in elkaar dan product_cat-taxonomieën:
- Subtaxons toevoegen, gaat op dezelfde manier als voor product_cat-taxonomieën, met één verschil: De naam van de taxonomie, is de naam, voorafgegaan door
pa_
- De gebruikelijke API-functie hiervoor:
wp_insert_term
Voorbeeld uit een SQL-script, waarbij pa_breedte
de betreffende taxonomie is:
# Create table ############## # create table dim1_taxons_tmp select distinct dim1, concat ( "wp_insert_term('", replace(dim1, ".", ","),"'", ", 'pa_breedte',", " array('description' => 'Alle koolborstels met een breedte van ",replace(dim1, ".", ",")," mm',", " 'parent' => 0, 'slug' => 'breedte-",replace(dim1, "," ,""),"' ));" ) as dim1_php from root_tmp;
Je weet de 'pa-naam' pas met zekerheid, nadat er subtaxons zijn aangemaakt. Dan vind je 'm terug met zoiets als dit (in SQL):
SELECT distinct taxonomy FROM example_com.wp_term_taxonomy;
Mochten er nog geen taxons zijn toegevoegd:
- Voeg er eentje handmatig toe, om het te testen
- Gebruik je gezond verstand om uit te vogelen wat de naam zou zijn.
Nog één voorbeeld:
<?php require_once("/var/www/kbo3.dvb/wp-load.php"); wp_insert_term ( 'Met automatische stop' , 'pa_automatische_stop', array ( 'description' => 'Alle koolborstels met automatische stop', 'parent' => 0, 'slug' => 'met-automatische-stop' ) ); wp_insert_term ( 'Zonder automatische stop' , 'pa_automatische_stop', array ( 'description' => 'Alle koolborstels zonder automatische stop', 'parent' => 0, 'slug' => 'zonder-automatische-stop' ) );
Verwijderen
Hoe kun je alle attribuut-taxonomieën compleet verwijderen? Dus inclusief hoofdtaxons, subtaxons, en koppelen met objecten? Voor een beetje serieuse site, is het geen optie om dit handmatig te doen, vandaar. Ik kwam geen kant-en-klare code tegen, dus lekker zelf doen!
De uitdaging is, om de onderdelen in de juiste volgorde te verwijderen, zodat je weet wat-wat is. Als ik bv. terms als laatste verwijder, is er een kans dat ik niet meer weet bij welke taxonomie ze horen. Een impressie:
select * from wp_term_relationships; # Taxons <-> Objecten - Vroeg verwijderen select * from wp_termmeta; # Metadata <-> Taxons - Vroeg verwijderen select * from wp_term_taxonomy; # Taxons <-> Taxonomy - Laat verwijderen select * from wp_terms; # Taxons - Laat verwijderen select * from wp_woocommerce_attribute_taxonomies; # Hoofdtaxons - Als laatste verwijderen
Taxons verwijderen
Dit script verwijdert alle WooCommerce-gerelateerde taxons, inclusief product_cat-taxons:
function dvb_delete_all_woocommerce_taxonomical_data() { global $wpdb; ################################################################################### # Delete all category & attribute taxons ################################################################################### # # * This SQL script deletes taxons, not the taxonomies themselves # * It works at the db-level. It doesn't use any API calls (except for db-access) # * Is uses a temporary table "taxon_tmp" to hold intermediate results. # As this is a temporary table, it doesn't need to be explicitly deleted # $sql_01 = "drop table if exists taxon_tmp;"; $sql_02 = "create temporary table taxon_tmp select term_id from ".$wpdb->prefix."term_taxonomy where taxonomy like 'product_cat' or taxonomy like 'pa%';"; $sql_03 = "delete ".$wpdb->prefix."termmeta from ".$wpdb->prefix."termmeta where meta_key like 'product_count_product_cat';"; $sql_04 = "delete ".$wpdb->prefix."termmeta from ".$wpdb->prefix."termmeta join taxon_tmp on wp_termmeta.term_id = taxon_tmp.term_id;"; $sql_05 = "delete ".$wpdb->prefix."term_relationships from ".$wpdb->prefix."term_relationships join taxon_tmp on ".$wpdb->prefix."term_relationships.term_taxonomy_id = taxon_tmp.term_id;"; $sql_06 = "delete ".$wpdb->prefix."term_taxonomy from ".$wpdb->prefix."term_taxonomy where taxonomy like 'product_cat';"; $sql_07 = "delete ".$wpdb->prefix."term_taxonomy from ".$wpdb->prefix."term_taxonomy where taxonomy like 'pa_%';"; $sql_08 = "delete ".$wpdb->prefix."terms from ".$wpdb->prefix."terms join taxon_tmp on ".$wpdb->prefix."terms.term_id = taxon_tmp.term_id;"; # Ready to go? ###################################### # // echo "\nsql_01: ".$sql_01; // echo "\nsql_02: ".$sql_02; // echo "\nsql_03: ".$sql_03; // echo "\nsql_04: ".$sql_04."\n"; try { $wpdb->query($sql_01); $wpdb->query($sql_02); $wpdb->query($sql_03); $wpdb->query($sql_04); $wpdb->query($sql_05); $wpdb->query($sql_06); $wpdb->query($sql_07); $wpdb->query($sql_08); } catch(Exception $e){} }
Attribuut-taxonomieën verwijderen
Niet wp_woocommerce_attribute_taxonomies
De tabel wp_woocommerce_attribute_taxonomies
lijkt niet te maken te hebben met deze attributen: Als ik de inhoud verwijder, verandert er niets:
wp_options - _transient_wc_attribute_taxonomies
Tjakka: wp_options bevat de definities. Waarde van option_value in bovenstaand voorbeeld:
a:11:{i:0;O:8:"stdClass":6:{s:12:"attribute_id";s:2:"10";s:14:"attribute_name";s:8:"apparaat";s:15:"attribute_label";s:8:"Apparaat";s:14:"attribute_type";s:6:"select";s:17:"attribute_orderby";s:10:"menu_order";s:16:"attribute_public";s:1:"1";}i:1;O:8:"stdClass":6:{s:12:"attribute_id";s:1:"5";s:14:"attribute_name";s:17:"automatische_stop";s:15:"attribute_label";s:17:"Automatische stop";s:14:"attribute_type";s:6:"select";s:17:"attribute_orderby";s:10:"menu_order";s:16:"attribute_public";s:1:"1";}i:2;O:8:"stdClass":6:{s:12:"attribute_id";s:1:"1";s:14:"attribute_name";s:7:"breedte";s:15:"attribute_label";s:7:"Breedte";s:14:"attribute_type";s:4:"text";s:17:"attribute_orderby";s:10:"menu_order";s:16:"attribute_public";s:1:"1";}i:3;O:8:"stdClass":6:{s:12:"attribute_id";s:1:"7";s:14:"attribute_name";s:9:"connector";s:15:"attribute_label";s:9:"Connector";s:14:"attribute_type";s:6:"select";s:17:"attribute_orderby";s:10:"menu_order";s:16:"attribute_public";s:1:"1";}i:4;O:8:"stdClass":6:{s:12:"attribute_id";s:1:"4";s:14:"attribute_name";s:7:"diagram";s:15:"attribute_label";s:7:"Diagram";s:14:"attribute_type";s:4:"text";s:17:"attribute_orderby";s:10:"menu_order";s:16:"attribute_public";s:1:"1";}i:5;O:8:"stdClass":6:{s:12:"attribute_id";s:1:"2";s:14:"attribute_name";s:6:"diepte";s:15:"attribute_label";s:6:"Diepte";s:14:"attribute_type";s:4:"text";s:17:"attribute_orderby";s:10:"menu_order";s:16:"attribute_public";s:1:"1";}i:6;O:8:"stdClass":6:{s:12:"attribute_id";s:1:"3";s:14:"attribute_name";s:6:"lengte";s:15:"attribute_label";s:6:"Lengte";s:14:"attribute_type";s:4:"text";s:17:"attribute_orderby";s:10:"menu_order";s:16:"attribute_public";s:1:"1";}i:7;O:8:"stdClass":6:{s:12:"attribute_id";s:1:"9";s:14:"attribute_name";s:4:"merk";s:15:"attribute_label";s:4:"Merk";s:14:"attribute_type";s:6:"select";s:17:"attribute_orderby";s:10:"menu_order";s:16:"attribute_public";s:1:"1";}i:8;O:8:"stdClass":6:{s:12:"attribute_id";s:2:"11";s:14:"attribute_name";s:21:"originele koolborstel";s:15:"attribute_label";s:21:"Originele Koolborstel";s:14:"attribute_type";s:6:"select";s:17:"attribute_orderby";s:10:"menu_order";s:16:"attribute_public";s:1:"1";}i:9;O:8:"stdClass":6:{s:12:"attribute_id";s:1:"6";s:14:"attribute_name";s:11:"stroomdraad";s:15:"attribute_label";s:11:"Stroomdraad";s:14:"attribute_type";s:6:"select";s:17:"attribute_orderby";s:10:"menu_order";s:16:"attribute_public";s:1:"1";}i:10;O:8:"stdClass":6:{s:12:"attribute_id";s:1:"8";s:14:"attribute_name";s:4:"veer";s:15:"attribute_label";s:4:"Veer";s:14:"attribute_type";s:6:"select";s:17:"attribute_orderby";s:10:"menu_order";s:16:"attribute_public";s:1:"1";}}