Afbeeldingen & databasemodel (WordPress)

Uit De Vliegende Brigade
Naar navigatie springen Naar zoeken springen

Hoe het werkt

Als je een afbeelding upload, worden er direct records aangemaakt in tabellen wp_posts en wp_postmeta, ook als je de afbeelding verder nergens toepast (als bv. een WooCommerce-productafbeelding of WooCommerce-gallery-afbeelding):

  • Primair: Er wordt een post toegevoegd aan tabel wp_posts van het type attachment en in dit geval subtype image/jpeg
  • Secundair: Voor allerlei aanvullende gegevens worden zo'n 5 records aangemaakt in tabel wp_postmeta.

wp_posts

select
   *
from
   wp_posts
where
   post_type = "attachment";

wp_postmeta

select
   # wp_posts.*,
   wp_postmeta.*
from
   wp_posts
join
   wp_postmeta
   on
   wp_posts.ID = wp_postmeta.post_id
where
   wp_posts.post_type = "attachment";

Voorbeeld: Uploaden van een afbeelding

Databasemodel rondom een afbeelding (die verder nergens mee is geassociëerd) in volle glorie

Als voorbeeld heb ik een afbeelding riverbug.jpeg geüpload.

Om in één keer alle data te zien (dit geeft een Cartesiaans product, want 1 record in wp_posts en 5 records in wp_postmeta):

select
   *
from
   wp_posts
join
   wp_postmeta
   on
   wp_posts.ID = wp_postmeta.post_id
where
   wp_posts.post_title 
   like 
   "River Bug%";

wp_posts

select * from wp_posts where post_type = "attachment" and post_title like "River Bug%";

De belangrijkste velden (denk ik, voor mij, op dit moment):

Veld Opmerkingen
ID Gebruikelijke post-id. Dit is de meest algemene PK in een WordPress-database
post_content Description - Beschrijving
post_title Post-title - Ingewikkelder is het niet
post_excerpt Caption - Zie schermafdruk
post_name Slug. De afbeelding is op minimaal drie manieren te bereiken:
guid Global Unique IDentifier for feed-readers. Gewoon negeren. Echt waar
post_type attachment
post_mime_type Can be handy when searching for an object. In this case: image/jpeg
Media library » View: Velden post_content, post_name en post_title
Media library » Edit: Velden post_excerpt, post_content en wp_postmeta » _wp_attachment_image_alt

wp_postmeta

Nogmaals: Direct bij uploaden van een afbeelding, worden er al records aangemaakt in tabel wp_postmeta. Ik vermoed dat dit met backwards compatibility heeft te maken: Tegenwoordig zijn er meer velden relevant dan in de tijd dat dit onderdeel van WordPress was ontworpen. Die nieuwe velden zijn daarom ondergebracht in deze tabel.

Om de relevante zaken boven water te toveren:

select
   wp_postmeta.*
from
   wp_posts
join
   wp_postmeta
   on
   wp_posts.ID = wp_postmeta.post_id
where
   wp_posts.post_title like "River Bug%";

of als je het post_id weet:

select * from wp_postmeta where post_id = 59303;

Belangrijkste velden:

meta_key Opmerkingen
_wp_attached_file
  • Filepath van het bestand. Je moet hier alleen baseurl/wp-content/uploads aan vooraf laten gaan
  • Alternatief voor de slug
  • Waarschijnlijk de primaire bron om de bestandsnaam te achterhalen: Je kunt 'm op andere manieren achterhalen, maar dit is hoogstwaarschijnlijk de enige juiste manier
_wp_attachment_image_alt Alt-tekst
wp_postmeta: Alle records voor het geüploade bestand
wp_postmeta: Serialised content van _wp_attachment_metadata. God behoedde dat ik dit ooit moet gaan parsen

Voorbeeld: Bestandsnaam aanpassen

  • Bestandsnamen worden écht bijgehouden in tabel wp_postmeta met meta_key = _wp_attached_file
  • Wil je een andere afbeelding bij een product? Verander dan dit veld - dwz. laat het naar een andere bestand wijzen
Oude situatie: Bestand wordt niet gevonden
SQL-code
Nieuwe situatie: Bestand werd gelijk gevonden

Voorbeeld: Thumbnail (2019)

Dit voorbeeld komt uit een ander artikel. Het stamt vermoedelijk uit 2019:

Vantevoren

Testproduct (zonder afbeelding) met id = 1347
Afbeelding met met id = 1348
En voor de zekerheid ook nog een 'gewone' post, met id = 1349 - Posts kennen geen standaard-afbeelding
En voor de zekerheid ook nog een 'gewone' pagina, met id = 1351. Pagina's kennen wel een standaard-afbeelding, featured image (niet geconfigureerd)
Tabel wp_posts: Al deze objecten, plus twee revisies
Tabel wp_postmeta: Entries tav. product id = 1347: Weinig spannends
Tabel wp_postmeta: Entries tav. afbeelding id = 1348: Ook weinig spannends. Merk op dat veld _thumbnail niet voorkomt

Thumbnail toevoegen

De afbeelding wordt toegevoegd aan het product
De afbeelding staat er écht
in wp_postmeta is dit de enige verandering: Veld _thumbnail_id is toegevoegd. De waarde is de ID van de afbeelding - Zo simpel

Afbeeldingen & producten

WooCommerce-producten kennen twee soorten afbeeldingen: De primaire afbeelding, en gallerij-afbeeldingen.

Voorbeeld-code

Gebaseerd op Databasemodel (WordPress)#WooCommerce-producten - Uitgebreide variant en onder de aanname dat de gallery maar één additionele afbeelding bevat:

################################################################################
# Select product data
################################################################################
#
select 
    wp_posts.id			as post_id,
    wp_posts.post_title		as post_title,
    wp_posts.post_content	as content,
    wp_postmeta.meta_value	as sku,
    wp_postmeta_03.meta_value	as thumbnail_path,
    wp_postmeta_05.meta_value	as second_image_path
from 
    wp_posts


# First join to wp_postmeta to retrieve sku
############################################################
#
left join
    wp_postmeta
    on
    wp_posts.id = wp_postmeta.post_id


# Second join to wp_postmeta to retrieve "_thumbnail_id"
############################################################
#
# "_thumbnail_id" on its turn, is a wp_postmeta.product_id
#
left join
    wp_postmeta as wp_postmeta_02
    on
    wp_postmeta_02.post_id = wp_posts.id
    and
    wp_postmeta_02.meta_key = "_thumbnail_id"


# Join 03 to wp_postmeta to retrieve thumbnail-path
############################################################
#
# This join is different from the two below, as it is a
# double join: It retrieves the meta_id for the thumbnail-
# attachment
#
left join
    wp_postmeta as wp_postmeta_03
    on
    wp_postmeta_03.post_id = wp_postmeta_02.meta_value
    and
    wp_postmeta_03.meta_key = "_wp_attached_file"


# Join 04 to wp_postmeta: "_product_image_gallery"
############################################################
#
# Retrieve the meta_value for "_product_image_gallery":
# It is the post_id of everything related to the second
# image
#
left join
    wp_postmeta as wp_postmeta_04
    on
    wp_postmeta_04.post_id = wp_posts.id
    and
    wp_postmeta_04.meta_key = "_product_image_gallery"


# Join 05 to wp_postmeta: "_product_image_gallery"
############################################################
#
# Retrieve the meta_value for "_product_image_gallery":
# It is the post_id of everything related to the second
# image
#
left join
    wp_postmeta as wp_postmeta_05
    on
    wp_postmeta_05.post_id = wp_postmeta_04.meta_value
    and
    wp_postmeta_05.meta_key = "_wp_attached_file"


# Where clause
############################################################
#    
where 
    post_type="product"
    and
    post_status="publish"
    and
    wp_postmeta.meta_key="_sku"


# Limit
############################################################
#
limit 
    0, 10;

Zie ook