Ik heb in de afgelopen tijd heel wat code snippets voor WooCommerce laten zien, waarbij ik je liet zien hoe je aan productgegevens komt.
Maar dan rijst natuurlijk ook de vraag, hoe je eigenlijk aan deze productgegevens kan komen? Het makkelijkst voor mij is natuurlijk je direct te verwijzen naar de WooCommerce API documentatie,
Maar die documentatie is niet voor iedereen even toegankelijk. Het is een soort ‘samenvatting’ van wat automatisch uit de broncode van WooCommerce kon worden gegenereerd.
Daarom heb ik een aantal zaken op een rijtje gezet over hoe je nu gegevens over producten benaderen in WooCommerce.
In dit artikel wordt dus geen functioneel voorbeeld gegeven van iets wat je zelf kan implementeren, maar als ik jou was zou ik deze pagina bookmarken, want wanneer jij snel wilt weten hoe je bepaalde productinformatie kan benaderen, dan is dit toch wel de bron.
Welke productvelden zijn er en hoe kom ik hier bij?
In principe moet je zoveel mogelijk voorkomen om direct bij productinformatie te komen. En met ‘direct’ probeer ik vooral te zeggen: Haal de informatie niet zelf op uit de database. Dat is om vier redenen goed om niet te doen.
Direct ophalen uit de database is een complexe serie acties
Wanneer je direct via SQL statements gegevens uit de database wilt halen, dan is dat een behoorlijk complexe actie. Je zal meerdere database queries ‘af moeten vuren’ om alle productinformatie compleet te krijgen.
Direct ophalen uit de database kan slecht zijn voor de performance
Wanneer je een cache programma gebruikt, dan kan direct ophalen uit de database slecht voor de performance zijn. Veel caching plugins voor WordPress maken gebruik van ‘object caching’. Of met andere woorden, wanneer jij binnen een bepaalde tijd een post type voor een tweede keer opvraagt, zal dit post type niet uit de database, maar uit de cache gehaald worden. Dat zorgt dat de pagina’s sneller laden.
Haal jij informatie direct uit de database, dan ‘omzeil’ je eigenlijk de cache.
Theoretisch kan de onderliggende databasestructuur veranderen
Het zal niet snel, en zeker ook niet vaak gebeuren, maar het is mogelijk, dat WordPress of WooCommerce ooit besluit dat bepaalde informatie op een andere manier opgeslagen dient te worden. Wanneer je informatie ophaalt via database queries zal dan jouw code snippet niet meer werken. De objecten in WordPress zorgen voor een abstractielaag over de daadwerkelijke database heen.
Plugins en code snippets kunnen de data uit de database ‘bewerken’
En de belangrijkste reden, waarom je zeker nooit direct informatie uit de database moet halen, is omdat de opgeslagen informatie niet de juiste hoeft te zijn!
Stel je voor. Ik bak pizzas. Ploeg’s Prachtige Pizzas!
En op woensdag zijn alle pizzas slechts 6 euro, mits je deze zelf afhaalt.
Nu kan ik natuurlijk iedere dinsdagavond alle prijzen aanpassen, en dat woensdag na sluitingstijd weer terug zetten, maar het is veel makkelijker een code snippet te gebruiken, die op woensdag alle prijzen voor pizzas toont als 7 euro.
Wanneer één of andere halfgare plugin bakker een plugin zou maken die alle informatie direct uit de database haalt, dan zou op woensdag met de verkeerde prijzen worden gewerkt.
Objecten
WooCommerce barst van de objecten. Ieder informatie-item in WooCommerce is een object en vaak ook gerelateerd aan vele andere objecten. Een winkelwagentje is een object. En de producten in mijn winkelwagen zijn ook weer objecten.
Een klant is een object, en de bestellingen die die klant ooit geplaatst heeft zijn ook weer objecten. En het zal je weinig verbazen, dat de producten in die bestelling opnieuw objecten zijn.
Nu hebben we een afspraak in WooCommerce, dat we nooit direct de waarde van een WooCommerce zullen benaderen, maar dat we dit door zogenaamde ‘get’ en ‘set’ functies doen.
Het voordeel is, dat die ‘get’ en ‘set’ functies acties kunnen triggeren die nodig zijn om ons de juiste waarde van het veld te geven.
Willen we bijvoorbeeld weten, wat de ID van een product is, gebruiken we de methode ‘get_id()’.
<?php
$product_id = $product->get_id();
Hieronder vind je een vrijwel (er kan altijd wat bij komen) compleet overzicht van de waarden die je in het $product object kan benaderen.
<?php
// Identificerende informatie
$product->get_id(); //De unieke ID van het product
// Algemene informatie
$product->get_type();
//Het type product
$product->get_name(); //Naam / titel van het product
$product->get_slug(); //De 'slug', onderdeel van de permalink
$product->get_date_created(); //Datum aanmaken van het product
$product->get_date_modified(); //Laatste wijziging van het product
$product->get_status(); //De status van het product
$product->get_featured(); //Is het product wel of geen featured pr
$product->get_catalog_visibility(); //Zichtbaarheid in winkel/zoekresultaat
$product->get_description(); //Lange omschrijving
$product->get_short_description(); //korte omschrijving
$product->get_sku(); //SKU
$product->get_menu_order(); //Sorteernummer om producten in een bepaalde volgorde te krijgen
$product->get_virtual(); //Is het een virtueel product
get_permalink( $product->get_id() ); //De complete URL om het product te bekijken.
// Prijsgegevens
$product->get_price(); //De huidige prijs van het product
$product->get_regular_price(); //De reguliere prijs van het product
$product->get_sale_price(); //De kortingsprijs van het product
$product->get_date_on_sale_from(); //Begindatum kortingsactie
$product->get_date_on_sale_to(); //Einddatum kortingsactie
$product->get_total_sales(); //aantal malen verkocht
// Belasting, voorraad en verzending
$product->get_tax_status(); //Belasting status
$product->get_tax_class(); //Belasting
$product->get_manage_stock(); //Houden we de voorraad bij?
$product->get_stock_quantity(); //Hoeveelheid op voorraad
$product->get_stock_status(); //status van de voorraad
$product->get_backorders(); //Is het mogelijk te bestellen als er geen voorraad is?
$product->get_sold_individually(); //Mag je per bestelling slechts 1 van het product bestellen?
$product->get_purchase_note(); //Notitie voor bij de bestelling
$product->get_shipping_class_id(); //Shipping class voor het product
// Maten en gewicht
$product->get_weight();
//Gewicht van het product
$product->get_length(); //Lengte
$product->get_width(); //Breedte
$product->get_height(); //Hoogte
$product->get_dimensions(); //Alle maten in één array
// Gelinkte informatie
$product->get_upsell_ids(); //Geeft een lijst met ID's van de upsell producten
$product->get_cross_sell_ids(); //Geeft een lijst met de ID's van de cross-sell producten
$product->get_parent_id(); //Geeft het parent ID van het 'parent' product bij een gegroepeerd product of de 'parent' van een gevarieerd product.
// Variaties en Eigenschappen (attributes)
$product->get_children(); //Afhankelijk van het product type: Geeft de variaties voor een gevarieerd product, de onderliggende producten bij een gegroepeerd product
$product->get_attributes(); //Een lijst met de product attributen
$product->get_default_attributes(); //Een lijst met de productattributen en hun default waarde (voor varianten)
$product->get_attribute( 'attributeid' ); //Een specifieke attribuutwaarde
// Get Product Taxonomies
$product->get_categories(); //Een lijst met alle categorieën geassocieerd met het product als objecten
$product->get_category_ids(); //Een lijst met alle categorieën geassocieerd met het product als IDs
$product->get_tag_ids(); //Een lijst van alle product tags als IDs
// Get Product Downloads
$product->get_downloads(); //Een lijst met downloads als ID's
$product->get_download_expiry(); //Lijst met de verloopdatum vd download
$product->get_downloadable(); //Haal het te downloaden bestand op
$product->get_download_limit(); //Lijst hoevaak gedownload mag worden.
// Product Images
$product->get_image_id(); //ID van de product image
$product->get_image(); //Array met de kenmerken van een product image
$product->get_gallery_image_ids(); //Lijst met ID's van de gallery afbeeldingen.
// Get Product Reviews
$product->get_reviews_allowed(); //True indien het geven van reviews
$product->get_rating_counts(); //Aantal ratings (malen ster gegeven)
$product->get_average_rating(); //gemiddeld aantal sterren gegeven
$product->get_review_count(); //Aantal (tekst) reviews
Nu is er ook nog een groot aantal hulp functies die specifiek voor in templates bedoeld zijn. Er zijn zo bijvoorbeeld diverse functies om een prijs te tonen met daarbij de omliggende HTML om dit op consistente wijze te doen.
Dit soort functies valt buiten de scope van dit artikel.
Hoe krijg ik het product, wanneer ik alleen een product ID heb?
Veel filter en action hooks in WooCommerce geven een product ID mee met de hook, niet een compleet product object. Hoe kom je nu aan het bijbehorend object?
Een tijd geleden heb ik je een deze code laten zien:
<?php
add_filter( 'the_title', 'wxp_shorten_woo_product_title',80,2);
function wxp_shorten_woo_product_title( $title, $id ) {
if ( is_shop() && get_post_type( $id ) === 'product' ) {
return substr( $title, 0, 15 );
} else {
return $title;
}
}
We gaan de code zelf niet bespreken, maar het filter ’the_title’ geeft twee velden mee, een title, en een id. De enige manier om te ontdekken welke parameters er mee komen is de API documentatie in te duiken. Maar het gaat hier dus om ‘id’. Dat is een product ID.
Nu hadden we in dat geval het product helemaal niet nodig (we controleerden alleen of het inderdaad wel een product was, omdat we niet alle titels in wilden korten) omdat de titel al meekwam in de hook. Maar stel dat we wel wat hadden willen doen, dan hadden we het complete product als volgt op kunnen halen:
<?php
add_filter( 'the_title', 'wxp_shorten_woo_product_title',80,2);
function wxp_shorten_woo_product_title( $title, $id ) {
// Gewoon om te demonstreren hoe we een product op kunnen halen
$product = wc_get_product($id);
if ( is_shop() && get_post_type( $id ) === 'product' ) {
return substr( $title, 0, 15 );
} else {
return $title;
}
}
In regel 6 vind je dus, hoe je aan de hand van een id een product op kan halen.
Hoe krijg ik een product binnen een order?
Wanneer je een order (id) hebt, hoe kan je dan de producten benaderen?
Er zijn gewoonlijk twee manieren waarop je binnen WooCommerce een order ‘naar boven’ kan halen. De eerste mogelijkheid is, dat de order ID via een hook wordt doorgegeven, de tweede manier is dat je de orders zoekt bij een ingelogde klant.
Een voorbeeld van hoe je orders voor een ingelogde klant ophaalt, vind je hier.
En wanneer je een order ID binnen krijgt via een hook, dan ziet de code er uit als hieronder
<?php
$order = wc_get_order($id);
Heb je eenmaal de order, dan kan je op de volgende manier de producten in de order benaderen:
<?php
$order = wc_get_order( $order_id );
$items = $order->get_items();
foreach ( $items as $item ) {
$product = $item->get_product();
// En hier kan je met het product doen wat je verder wilt
}
Hoe krijg ik een product binnen een winkelwagen?
Wanneer je iets wilt doen met de producten binnen een winkelwagen, moeten we op een andere manier te werk gaan. Bij het laden van WooCommerce wordt er een ‘global object’ met de naam $woocommerce aangemaakt.
Dat $woocommerce object is de toegangspoort tot een aantal zaken binnen WooCommerce die globaal beschikbaar moeten blijven. Een daarvan is de winkelwagen. En die winkelwagen kan je ophalen met de methode ‘get_cart()’.
Dat ziet er in PHP ongeveer als volgt uit :
Meestal zal je iets met een winkelwagen willen doen vanuit een functie. Een voorbeeld van hoe je de tekst van de ‘In Winkelwagen’ knop aanpast op basis van de inhoud van je winkelwagen vind je hier.
<?php
function wxp_do_something_with_products_in_cart() {
global $woocommerce;
$cart = $woocommerce->cart->get_cart();
//$cart is een array met een key en een $cart_item.
//Dat $cart_item heeft weer een aantal array elementen, waarvan 'data' het
//product object is dus:
foreach ($cart as $cart_item_key => $cart_item){
$product = $cart_item['data'];
// En vanaf hier kunnen we dus leuke dingen met 'product' doen...
}
}
Het product benaderen vanuit een single page
Wanneer je een product probeert te benaderen vanuit een single page, dan is vrij makkelijk te doen. Want op een single page is er altijd een object $post beschikbaar, wat juist op die single page het product is wat zichtbaar is op die pagina.
Los van wat er met eventuele hooks aan extra informatie wordt opgegeven, kan ik vrijwel overal met de volgende code het product ophalen:
<?php
global $post;
$product = wc_get_product($post);
Regel 2 is alleen nodig, wanneer je binnen een functie werkt (meestal dus).
Samenvattend
Wanneer je ‘iets’ wilt doen met producten in WooCommerce dan zijn dit de meest voorkomende situaties. In dit artikel heb je kunnen lezen hoe je bij de producten kunt komen in deze situaties.
Wanneer je regelmatig snippets voor WooCommerce moet maken, is dit een heel handige pagina om te bookmarken.
Heb je nog vragen, stel ze rustig in de commentaren hieronder.