WP_Post objecten in het licht van applicatie ontwikkeling

In de kern mag WordPress dan niet object georiënteerd zijn. Het platform maakt gelukkig wel veel gebruik van classes. Ook de representatie van een post in de database gebeurd met behulp het WP_Post objecten. Dat werkt in principe goed behalve in het geval dat een post tijdens de uitvoering van een applicatie die op WordPress is gebaseerd wordt aangepast.

Het probleem is dat elk WP_Post object dat wordt verkregen via de “get_post” functie op zichzelf staat. WordPress houdt weliswaar een cache bij met alle post data bijhoudt. Wanneer “get_post” wordt aangeroepen wordt er een nieuw WP_Post object aangemaakt.

De enige uitzondering hierop lijkt de global $post variabele te zijn die in “The Loop” wordt gebruikt die wordt teruggeven wanneer “get_post” zonder parameters wordt aangeroepen. Of te wel in dat geval krijg je in plaats van een nieuw WP_Post object een reference naar de global $post variable.

Als gevolg hiervan kunnen er in theorie meerdere WP_Post objecten tegelijkertijd bestaan tijdens runtime met allemaal een andere representatie van de post in de database. Dat wordt niet alleen veroorzaakt doordat er meerdere zelfstandige WP_Post objecten zijn. Er is ook geen signaal naar de objecten toe vanuit WordPress dat er een wijziging in de database is doorgevoerd.

Dit is enkel een “blote constatering”. Als platform waarop blogs worden gepubliceerd is het ook niet bepaald logisch om WP_Post objecten bewust te maken van veranderingen die in de database worden doorgevoerd. Bij een blog schrijf je een artikel in de admin kant van WordPress, dat wordt opgeslagen in de database. Op de website zelf wordt een artikel uit de database geladen zodat het aan de gebruiker kan worden getoond.

In andere woorden de oorspronkelijke opzet van WordPress is eenrichtingsverkeer tijdens een enkele request. Data gaat de database in om op te slaan en wordt er weer uitgehaald om weer te geven. Wanneer het WordPress platform echter als applicatie wordt gebruikt, dan kan er sprake zijn van meerdere keren wordt opgehaald, bewerkt en opnieuw opgeslagen.

Wanneer WordPress als platform voor een applicatie wordt gebruikt is het daarom minder handig als er verschillende representaties van dezelfde post zijn. Natuurlijk kan er altijd een discrepantie zijn tussen wat er in de database is opgeslagen en de representatie tijdens runtime. Dat is zelfs onvermijdelijk omdat aanpassingen eerste op een object worden aangebracht én daarna pas in de database worden doorgevoerd. Zo werkt ORM.

Het is alleen niet de bedoeling dat er tijdens runtime verschillende objecten zijn die allemaal naar dezelfde post in de database verwijzen én verschillende waarden hebben. Dat kan er toe leiden dat er met verkeerde data wordt gewerkt of er zelfs verkeerde data naar de database wordt weggeschreven.

Dit is ook weer één van de zaken die ik met Wpx probeer op te lossen. Als framework zorgt Wpx er voor dat er altijd één versie van een object die verwijst naar een post in de database is. Elke volgende versie van het object dat wordt opgevraagd verwijst naar het al bestaande object. Op die manier is er altijd één versie van een object dat naar een post in de database verwijst.

Er is ook een belangrijk verschil tussen een WP_Post object en de objecten die Wpx gebruikt. Een WP_Post object is vooral een container die data bevat. Daarnaast geeft het ook toegang tot de metadata van een post die worden opgehaald via get_post_meta. De Wpx objecten zijn vooral bedoeld als intermediair tussen WordPress en de PHP code die door de applicatie die daarop gebaseerd is wordt uitgevoerd.

Deze filosofie is ook terug te zien hoe wijzigingen van de data in een Wpx object ten opzichte van de representatie in WordPress en de achterliggende database als “dirty” wordt aangemerkt. Het object is vies omdat de database altijd als leidend moet worden gezien. Pas wanneer de wijzigingen in de database zijn doorgevoerd is het object weer schoon omdat de representatie door het object en de database weer overeenkomen.

Wanneer je een applicatie ontwikkelt op basis van het WordPress platform dan is het belangrijk om rekening te houden met de wijze waarop WP_Post objecten binnen WordPress worden gebruikt. Zeker wanneer gegevens in de database tijdens de uitvoering worden aangepast is het belangrijk om rekening te houden met het feit dat de representatie van een bepaalde post in de database af kan wijken van het WP_Post object waarmee wordt gewerkt.

Gelukkig biedt WordPress ook een eenvoudige oplossing om te voorkomen dat een WP_Post object niet meer overeenkomt met wijzigingen die (via het WordPress platform) tijdens runtime in de database zijn aangebracht. Wanneer via “wp_insert_post” (en functies die daar op leunen zoals “wp_update_post”) wijzingen in de database worden doorgevoerd dan wordt de post cache ook direct gereset. Daardoor zit je door het opvragen van een nieuw WP_Post object met “get_post” in principe altijd veilig.