Db.bulk (WordPress)

Uit De Vliegende Brigade
Ga naar: navigatie, zoeken
Datamodel & productgegevens: Een product is een post. Die staan in tabel wp_posts. Ze hebben een post-ID, genaamd ID. Additionele zaken staan in tabel wp_postmeta. Hier zie je hoe voor post 1840 de waardes van additionele velden worden onthouden
Afbeelding-metadata - Velden: Het gaat om de velden URL (bestandsnaam), Title, Caption, Alt text en misschien Description
Datamodel & afbeelding-metadata: De velden Title, Caption en Description worden opgeslagen in tabel wp_posts
Datamodel & afbeelding-metadata: Het veld Alt text wordt opgeslagen in tabel wp_postmeta

Status (april 2019): Gebruik PHP-API bleek verrassend simpel te zijn - Daarom Db.bulk gestaakt: Het risico en de onzekerheid van deze aanpak, maakt dit te onaantrekkelijk.

Db.bulk heeft betrekking op bulk-handelingen rondom WordPress, direct op database-niveau. De reden om dit buiten API's om, direct op db-niveau te doen: Gebruik van API's is te omslachtig en incompleet. Ook al is dit een drastische stap.

Dit artikel heeft vooralsnog uitsluitend betrekking op WooCommerce-producten en bijbehorende zaken, zoals vertalingen, afbeeldingen & taxonomie.

Product aanmaken - Proof of concept

Dit proof of concept kostte me precies 57 minuten - Daar kan geen API tegenop:

  1. Product aangemaakt
  2. Dit product geassociëerd met een bestaande afbeelding
  3. De taal van dit product ingesteld op Duits.
#
#################################################################################################################################
# Create product
#################################################################################################################################
#
# Initialise a wp_posts-ID
########################################
#
# insert into wp_posts (ID)
# values (0);

# Store this ID in @post_id
########################################
#
set @post_id=(select max(ID) from wp_posts);

# Update this product
########################################
#
# update wp_posts
# set
#     post_author	= 1,
#     post_date		= now(),
#     post_date_gmt	= now(),
#     post_content	= "Dit is het nieuwste product - 1569 - post_content",
#     post_title	= "Dit is de 1569-titel",
#     post_name		= "test_product_1569",
#     post_type		= "product"
# where ID=@post_id;    


#################################################################################################################################
# Add WC-fields
#################################################################################################################################
#
# insert into wp_postmeta (meta_id, post_id, meta_key, meta_value)
# values
#    (null, @post_id, "_sku", "sku-1569"),
#    (null, @post_id, "_regular_price", "15.69");
#    (null, @post_id, "_price", "15.69");           # Appearantly, only specifying "_regular_price", isn't enough


#################################################################################################################################
# Associate with image
#################################################################################################################################
#
# Post with id=1567, happens to be a picture - Let's use it
#
# insert into wp_postmeta (meta_id, post_id, meta_key, meta_value)
# values
# 	(null, @post_id, "_thumbnail_id", "1567");


#################################################################################################################################
# Set language to German
#################################################################################################################################
#
# * German is wp_term_taxonomy id = 26 (of zoiets)
#
# insert into wp_term_relationships (object_id, term_taxonomy_id, term_order)
# values (@post_id, 26, 0)

Producten & taalkoppelingen

Veel ingewikkelder dan meertalige gekoppelde producten, wordt het waarschijnlijk niet. Als dit lukt, dan kan ik alles.

Casus

  • Product: Er is een product (in het NL) met sku = xyz
  • Vertalingen: Dit product heeft vertalingen in EN en DE
  • Dezelfde SKU: De vertalingen hebben dezelfde SKU. Da's niet vanzelfsprekend, want afhankelijk van de wijze van importeren, moet ik soms per taal andere sku's genereren
  • Koppeling: Deze vertalingen zijn met elkaar gekoppeld. Je kunt dus in WooCommerce een product selecteren → wisselen van taal → Je ziet hetzelfde product in een andere taal. Deze koppeling is het echte pièce de resistance.
Voorbeeld: de sku is hetzelfde voor de drie taalvarianten van hetzelfde product. Alleen zijn ze nog niet gekoppeld

Taalinstellingen achterhalen

Hier worden diverse taalinstellingen getraceerd, waaronder hoe het kan dat een product per 'taalvarianten' toch maar één SKU heeft. De koppeling komt hier nog niet aan bod.

#
#################################################################################################################################
# Fetch this product from wp_posts
#################################################################################################################################
#
# It has three entries in "wp_posts": One per language. That is how Polylang works. Some other language plugins actually store
#  all language-variants in the same object, but not Polylang
#
# ID's:
#
# * 1233 - NL (you can tell by the title, not otherwise from only this table)
# * 1245 - EN
# * 1293 - DE
#
SELECT * FROM rt.wp_posts where post_type like "product" and post_title like "%powered%";


#################################################################################################################################
# SKUs from wp_postmeta
#################################################################################################################################
#
# They all three have the same sku. Sometimes, life is simple
#
select * from wp_postmeta where 

(
    post_id = 1233 or
    post_id = 1245 or
    post_id = 1293
)
and
(
    meta_key like "_sku"
);


#################################################################################################################################
# Language-definitions from wp_term_taxonomy
#################################################################################################################################
#
# Tjakka:
#
# NL: term_taxonomy_id = 19 & term_id = 19
# EN: term_taxonomy_id = 22 & term_id = 22
# DE: term_taxonomy_id = 26 & term_id = 26
#
select * from rt.wp_term_taxonomy where taxonomy like "language";

#################################################################################################################################
# Fetch associated data from wp_term_relationships
#################################################################################################################################
#
select * from wp_term_relationships
where
( 
    object_id = 1233 or
    object_id = 1245 or
    object_id = 1293
)
and
(
    term_taxonomy_id = 19 or	# NL
    term_taxonomy_id = 22 or	# EN
    term_taxonomy_id = 26	# DE
);

Koppeling - detecteer mutaties

Detecteer database-mutaties op het moment dat ik de koppeling uit- en aanzet:

#
# Figure out how langauge-variants are connected to each other
#################################################################################################################################
#
select
   table_schema,
   table_name,
   update_time

from information_schema.tables

where 
   table_schema like "rt"
   and
   date_sub(now(), interval 1 minute) < update_time
   and
   table_name not like "wp_wf%";   # Too much noise from WordFence (in this context)
Dit zijn de tabellen die veranderden, op het moment dat ik een bestaand Duits product (id 1293 associëerde met z'n Nederlandse variant ( id 1233)

Koppeling gevonden!

Koppelingen worden in tabel wp_term_taxonomy bijgehouden, en beide producten verwijzen naar zo'n record in tabel wp_term_relatopships.

#
# Figure out how langauge-variants are connected to each other
#################################################################################################################################
#
select

    table_schema,
    table_name,
    update_time

from information_schema.tables

where 

   table_schema like "rt"
   and
   date_sub(now(), interval 1 minute) < update_time
   and
   table_name not like "wp_wf%"   	# Too much noise from WordFence (in this context)
   and
   table_name not like "wp_options";	# This seems to get changed continuously, even when the site is idle


#################################################################################################################################
# Mutations wp_posts?
#################################################################################################################################
#
# I suspect that only the column "post_modified" gets updated
#
# select * from wp_posts;


#################################################################################################################################
# Mutations wp_postmeta
#################################################################################################################################
#
# Seems only the value for "_edit_lock" got updated
#
# select * from wp_postmeta
# where
#      post_id = 1293; #or
#     #post_id = 1233;


#################################################################################################################################
# Mutations wp_terms
#################################################################################################################################
#
# I don't see any changes


#################################################################################################################################
# wp_term_taxonomy - Koppelingen worden hier bijgehouden!
#################################################################################################################################
#
# Deze koppeling:
#
# * term_taxonomy_id = 61
# * term_id = 61
#
select * from wp_term_taxonomy where taxonomy like "post_translations";


#################################################################################################################################
# wp_term_relationships - Posts & koppelingen worden hier gekoppeld
#################################################################################################################################
#
# object_id = 1293 & term_taxonomy_id = 61:
#
select * from wp_term_relationships where object_id = 1293;

# object_id = 1233 & term_taxonomy_id = 61:
#
select * from wp_term_relationships where object_id = 1233;

Koppeling zelf aanpassen

Tjakka:

#################################################################################################################################
# Change the koppeling myself - GELUKT
#################################################################################################################################
#
# Couple DE & NL
#################
#
update wp_term_taxonomy
set description = 'a:2:{s:2:"de";i:1293;s:2:"nl";i:1233;}'
where 
	term_taxonomy_id = 61 and
	term_id = 61;

# Decouple DE & NL
##################
#
# update wp_term_taxonomy
# set description = 'a:1:{s:2:"de";i:1293;}'
# where 
#   term_taxonomy_id = 61 and
#   term_id = 61;

P.s.

Het lijkt allemaal vrij eenvoudig zelf na te bouwen, maar dat is waarschijnlijk niet echt het geval: Er veranderen allerlei 'bijkomstige' tabellen (bv. timestamps in wp_posts, of edit-locks in wp_metadata). Om al die wijzigingen accuraat na te bouwen, is veel werk. Het wordt dus allemaal een vrij brute aangelegenheid - Van dik hout zaagt men planken.

Afbeeldingen importeren

  • Uiteraard inclusief alle mogelijke metadata!
  • Ik zorg zelf (handmatig) dat de afbeelding op

Zie ook