Variabelen en scoping en dink

Grmbl, grmbl. 

Ik maak een custom taxonomy aan in WordPress, ik geef die de propere naam “author”, en alles lijkt in orde te zijn: ik kan aan posts meer dan één author geven (in plaats van standaard één, die dan nog eens een WordPress-user moet zijn), daar zijn archieven van, en tag clouds en watnog, en dat linkt allemaal proper naar elkaar zonder al te veel moeite.

De auteurs, om ze alfabetische te kunnen sorteren, sla ik op als “achternaam – voornaam”, en als ze dan getoond moeten worden, zet ik voornaam voor achternaam. En neen, ik kan er geen rol bij zetten (schrijver, illustrator, vertaler, …), maar bon, ‘t is geen boekendatabase die ik aan het maken ben. 

En alles werkt goed tot er een auteur met één naam toegevoegd wordt, bijvoorbeeld “Moebius” als ik er niet “Giraud – Jean” van zou maken: daar geeft WordPress een lege archiefpagina voor. 

Aargh! 

Debug, debug, debug. Blijkt dat de query om de lijst van posts van een auteur met voor- en achternaam er zo uitziet:

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) WHERE 1=1 AND ( wp_term_relationships.term_taxonomy_id IN (246) ) AND (wp_posts.post_author != 0) AND wp_posts.post_type IN ('post', 'page', 'attachment') AND (wp_posts.post_status = 'publish' OR wp_posts.post_author = 1 AND wp_posts.post_status = 'private') GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 20

en een query voor een auteur met één naam zo:

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) WHERE 1=1 AND ( wp_term_relationships.term_taxonomy_id IN (138) ) AND (wp_posts.post_author = 0) AND wp_posts.post_type IN ('post', 'page', 'attachment') AND (wp_posts.post_status = 'publish' OR wp_posts.post_author = 1 AND wp_posts.post_status = 'private') GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 20

Het verschil al gezien? Ha, inderdaad de ene doet 

(wp_posts.post_author != 0)

de andere doet 

(wp_posts.post_author = 0)

Toink? Als de taxonomieterm twee of meer woorden bevat, zoek dan posts waarvan de WordPress-auteur niet nul is, en anders: zoek posts waarvan de WordPress-auteur wél nul is (en die user bestaat niet). 

Wat in de WordPress-code gewroet, maar niet enorm vreselijk veel zin om daar in te gaan prutsen — en dan maar mijn taxonomie hernoemd van “author” naar “myauthor”: 

update wp_term_taxonomy taxonomy='myauthor' where taxonomy='author';

en dan in functions.php 

register_taxonomy('author', 'post', array( 'hierarchical' => false, …

vervangen door 

register_taxonomy('myauthor', 'post', array( 'hierarchical' => false, …

en taxonomy-author.php hernomen naar taxonomy-myauthor.php: hey presto, alles werkt zoals het zou moeten gewerkt hebben. 

Ik heb niet enorm veel goesting om te gaan kijken wat het precies was, maar ik kan niet anders dan vermoeden dat er érgens een variabele de naam van de taxonomie krijgt ($author in dit geval) en dat die een andere variabele $author overschrijft die ergens gebruikt moet worden om godweetwat in op te slaan, en dat dat op de één of andere manier verkeerd loopt onder zeer specifieke voorwaarden. 

Een interessante bug, denk ik, want treedt herhaalbaar op, zou niet mogen optreden, en is wellicht gemakkelijk te verbeteren. 

Als ik dan nog eens tijd en goesting heb, maak ik een tiketje aan.