Cache Warmer automatisch starten na Plugin updates

Cache warmer is een dienst om jouw site cache 'warm te houden. Hoe warm je hem opnieuw op, na een update van je plugins?

Wil je direct een mail ontvangen wanneer nieuwe snippets zijn toegevoegd?

Vul dan onderstaand formulier in en je krijgt direct na het toevoegen van nieuwe snippets een email. Zo blijf je altijd bij!

Cache Warmer automatisch starten

Cache warmer is een (betaalde) online dienst, die samen met jouw WordPress caching plugin ervoor zorgt, dat de bezoeker aan jouw site snel door de pagina’s kan wandelen.

Wanneer je echter je plugins update, dan zullen veel caching plugins de cache leeg gooien. In één keer is je hele site dus ‘niet meer gecachet’ en zal de bezoeker een flink wat tragere site ervaren. Dat wil je natuurlijk voorkomen.

Gelukkig wordt dit ook ondersteunt door de Cache warmer website. Je krijgt namelijk een hoogst persoonlijke ‘eigen URL’ waarmee je direct de ‘opwarm job’ voor jouw website op kan starten.

Toch zit hier een kleine valkuil in. Ten eerste, je moet natuurlijk wel die URL opstarten, wanneer je je plugins hebt geupdate. Maar nog veel belangrijker, het is mogelijk, dat jij ‘automatische updates’ aan hebt staan. En dan vinden al die updates plaats zonder dat jij ervan op de hoogte bent.

Gelukkig is dat allemaal oplosbaar met een klein codefragment.

Laten we eerst eens kijken, hoe zo’n ‘URL voor Cache Warmer’ eruit ziet.

https://app.cache-warmer.com/webhook/cachewarmer/1234/AbC_dEfgHoJklMno_loRGXc_8ThFvjVVWIkSAt28

Deze URL moeten we dus aanroepen. Hoe doe je dat in PHP? Dat is eigenlijk ook weer kinderlijk eenvoudig. Voor het openen van externe URL’s die niet op de site zelf aanwezig zijn heeft WordPress een tweetal functies. wp_remote_get() en wp_remote_post().

Dit zijn typisch functies die je gebruikt om een zogenaamde ‘webhook’ aan te roepen. Een URL die informatie doorgeeft of ophaalt. Met de ‘wp_remote_get’ gebruik je parameters die deel uitmaken van de query string van de URL, dus bijvoorbeeld ‘https://mijnurl.com/?name=Wilko’. Bij een wp_remote_post, is de informatie die je door wilt geven deel van de body van je post.

In ons geval geven we helemaal geen informatie door via de URL. De URL zelf bevat alle informatie. Het is dus lood om oud ijzer of we wp_remote_post of wp_remote_get gebruiken. Maar omdat de wp_remote_get net een heel klein beetje minder overhead heeft, kiezen we voor de wp_remote_get.

Waar roepen we de code aan?

Je weet nu de functie, en je weet welke URL je moet gebruiken. Dus wanneer je helemaal nieuw bent in het programmeren met WordPress zou je wellicht denken, dat de volgende code zou kunnen werken.

<?php
define('MY_WARMER_URL','https://app.cache-warmer.com/de-opgegeven-url');
$response = wp_remote_get(MY_WARMER_URL);   

Maar… wanneer wordt deze code aangeroepen?

Zoals je in eerdere snippets hebt gelezen, WordPress zit vol met ‘hooks’, momenten in het programma waarop je in kan haken, om WordPress op het juiste moment de juiste dingen te laten doen.

En het ‘juiste moment’ is in ons geval, wanneer WordPress klaar is met het updaten van alle plugins binnen het huidige update proces. Het maakt hierbij niet uit, of deze updates met de hand of automatisch zijn gestart.

De ‘upgrader_process_complete’ action

Alle magie gebeurt tijdens de ‘upgrader_process_complete’ action. Deze actie wordt aangeroepen voor iedere plugin die geupgrade wordt. Hier schuilen echter een aantal addertjes onder het gras.

Omdat deze functie bij iedere update aangeroepen zal worden, krijg je per update een aanroep van de action. Wanneer je bij iedere aanroep van de action ook de webhoop riching cache warmer op zou starten, zou je toch wel een groot aantal jobs opstarten, meer dan je wilt.

Dit kan je op een aantal manieren voorkomen. En dat doe je door gebruik te maken van ‘Transients’. Een ’transient in WordPress is een tijdelijke variabele die wordt opgeslagen in de database. Zo’n transient lijkt eigenlijk best wel een beetje op een cache: Wanneer de geldigheidsduur voorbij is, houdt de variabele op te bestaan.

Voor onze oplossing gaan we zo’n transient bekijken, maar voor we dit doen, bestuderen we eerst even twee scenarios.

Scenario 1 – Aan het einde van alle updates wordt de webhook aangeroepen

In dit eerste scenario worden eerst alle plugins geupdate. Aan het einde van iedere update wordt gekeken, of dit de laatste plugin was in de lijst die een update nodig had, en als dit zo is wordt de webhook aangeroepen.

Dit is in principe de mooiste oplossing, maar faalt in een aantal situaties.

  1. Allereerst wanneer je om welke reden dan ook slechts één plugin update, dan zal er een ‘lijst met niet geupdate plugins’ open blijven staan en zal de webhook niet worden aangeroepen, terwijl de cache wel is geïnvalideerd.
  2. Omgekeerd, wanneer je om welke reden dan ook één of enkele plugins uit wilt sluiten van een update, heb je eenzelfde situatie bij de hand. Het aantal geupdate plugins is ongelijk aan het aantal wat geupdate zou moeten worden.
  3. En als derde situatie, wanneer om wat voor reden een plugin niet geupdate kan worden, bijvoorbeeld een commerciële plugin waarvan de server tijdelijk niet bereikbaar is, of een plugin waarvan de licentie verlengd moet worden, dan hebben we weer hetzelfde verhaal. Cache is geïnvalideerd, maar de warmer zal niet worden aangeroepen.

Dit zijn situaties die ik in de huidige code van WordPress niet zou weten hoe op te lossen, en daarom gaan we het op een iets minder mooie, maar nog steeds wel efficiënte wijze oplossen.

Scenario 2 – We starten direct met het ‘opwarmen’

Na iedere update kijken we of er een transient met de naam ‘wxp_called_cache_warmer’ bestaat. Bestaat deze, dan roepen we de cache warmer URL niet aan, bestaat hij niet, dan geven we de transient een waarde van ’true’ en een verlooptijd die gelijk is aan 200% van je gemiddelde ‘update tijd’ wanneer je een groot aantal plugins moet updated. Dit is natuurlijk sterk afhankelijk van de plugins (grootte, aantal en gemiddelde update frequentie) die je hebt.

Omdat cache warmer meestal toch enkele minuten nodig heeft om op te starten, zullen er misschien een paar pagina’s, maar in ieder geval niet veel worden gemist. Om je een idee te geven, gemiddeld duurt bij mij een serie plugin updates 10 minuten. Na het activeren van cache warmer duurt het zo’n 8-12 minuten voor de eerste pagina’s worden ‘opgewarmd’.

In mijn geval heb ik dus de verlooptijd van mijn transients op 20 minuten ingesteld. Mocht er dus na 20 minuten opnieuw een plugin geupdate worden, dan zal de aanroep naar cache warmer wel plaats vinden, anders niet.

Maar nu genoeg gekletst, laten we eens met wat code beginnen.

<?php

// Pas de constante aan aan jouw URL:
define('MY_WARMER_URL','https://app.cache-warmer.com/de-opgegeven-url');

add_action('upgrader_process_complete', 'wxp_all_plugins_updated_action', 10, 2);

function wxp_all_plugins_updated_action($upgrader_object, $options) {
   if ($options['action'] == 'update'  && $options['type'] == 'plugin') { 

      if (get_transient('wxp_called_cache_warmer') !== true)) {
          //Dit is dus de eerste plugin in de lijst die we updaten, we roepen cache warmer aan
          $response = wp_remote_get(MY_WARMER_URL); //let op, geen quotes!
          if (is_wp_error($response)) {
              error_log('Webhook failed ' . $response->get_error_message());
          } else {
              set_transient('wxp_called_cache_warmer',true, 20*60);
          }
      }
  }   
}

Wat doen we hier precies? Laten we eens naar een aantal belangrijke regels kijken

Regel 4:
Hier definieren we de URL, zodat deze makkelijk in de code te gebruiken is. Wanneer je meerdere snippets hebt die deze URL gebruiken, is een betere plaats om deze niet hier maar in je wp-config.php te gebruiken, waar hij beschikbaar is voor alle functies.

regel 9:
In het array ‘$options’ komt informatie mee over wat er op dit moment geupdate is. Dat kan ‘core’, ‘plugin’, ‘language’ of ’theme’ zijn. We willen deze code alleen in het geval van een plugin update uitvoeren. Wanneer we dit weg zouden laten. En alleen bij een ‘update’ niet bij een ‘install’.

regel 11:
Als er geen transient met de waarde ’true’ is, dan starten starten we de webhook regel 13).

regel 15:
Als zich een fout heeft voorgedaan, kortom, de webhook is niet uitgevoerd, dan loggen we de foutmelding in de errorlog. We laten de transient met rust.

regel 17:
Als het goed is gegaan, dan stellen we de transient in op 20*60 seconden, ofwel 20 minuten.

Merk hierbij op, dat omdat we rond regel 15 geen transient zetten, bij de volgende plugin upgrade opnieuw gepoogd wordt om de webhook uit te voeren. Mocht het dus niet gelukt zijn door bijvoorbeeld een drukke server, dan wordt er net zo vaak opnieuw geprobeerd als er plugins in de update lijst staan.

Ik hoop dat je veel plezier van deze integratie zal hebben. En natuurlijk, je kan het idee achter deze code natuurlijk ook gebruiken voor andere acties die zouden moeten gebeuren na het updaten van je plugins.

Codesnippet verbeteren

Het doel van deze code snippet is een probleem op te lossen in een specifieke situatie. Daarom zie je regelmatig voorbeelden waar je specifiek tekst moet aanpassen om te krijgen wat je wilt. 

Wil jij leren hoe je complete plugins zelf kunt programmeren inclusief ‘admin’ schermen voor het instellen en de output in de gewenste taal, dan is misschien de cursus ‘Introductiecursus Plugins Programmeren‘ iets voor jou. 

Wil je als ‘full stack’ WordPress programmeur aan de gang gaan, dan biedt WordXPression ook een compleet traject ‘WordPress Developer‘ aan. Dit is een traject wat deels online, deels klassikaal wordt gegeven.

WordPress Developer worden?

Wil je leren hoe je zelf plugins, thema's, shortcodes, widgets, Gutenberg blocks en meer kan maken?
Schrijf je dan in voor de cursus WordPress Developer.

Meer snippets

Laat zien wanneer een product al in de winkelwagen is
Laat je klant zien, dat een product al in de winkelwagen is geplaatst.
Een 'Niet op voorraad' knop in WooCommerce
Hoe voorkom je teleurstelling bij je klant wanneer hij zijn favoriete product bij jou vindt, zonder dat...
Shortcodes voor het tonen en verbergen van content
Hoe maak ik een shortcode waarmee ik content van mijn posts kan verbergen?
De WordPress 'admin bar' ook daadwerkelijk alleen voor admins
Zelf vind ik de WordPress ‘admin bar’ heel handig om snel toegang te krijgen tot verschillende...
Beperk zoekresultaten tot bepaalde post-typen
Hoe beperk je de post typen die terug komen vanuit een zoekopdracht?
Het aantal (custom) post types per pagina instellen
Wanneer je het aantal blogposts wilt beperken wat er op een pagina getoond wordt, dan is dat heel makkelijk...

Veiligheid voor alles!

Met betrekking tot de code die je hier aantreft een aantal waarschuwingen, voordat je deze code snippets toepast op je eigen website.

  1. Voer de code nooit direct uit op je eigen website, maar probeer deze eerst op een staging omgeving of een locale kopie van je website. 
  2. Voor je de geteste code installeert op je website, maak eerst een back up van je website.
  3. Zorg altijd voor alle zekerheid, dat je voor je een aanpassing live zet, je ook de FTP gegevens van je website bij de hand hebt.  
 
Voel je je onvoldoende vertrouwd met het toepassen van een dergelijke code snippet, bedenk dat je dit ook door een professional kan laten doen. De WordXPression support strippenkaart is een voordelige manier om dit soort aanpassingen te laten doen.
Heeft dit artikel je geholpen je probleem op te lossen?
Deel het met je vrienden via je favoriete social media.

Heb je vragen bij, of opmerkingen over deze code snippet, stel deze bij de commentaren hieronder.

Geef een reactie

Je e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *

Word je website de baas. Neem vandaag nog contact op!

Contact Information

WordXPression 

Bezoekadres
Eperweg 135 (op afspraak)
8072 PL Nunspeet

Postadres
Aardoliestraat 14-I
7553GT Hengelo

06-10449807 (van 9:00 tot 17:00 van ma-vr)

KVK : 75580152 

Social media
Stuur een bericht

Introductiecursus Plugins Programmeren

wordpress coding Can use php code as background in html

Ontdek de wereld van WordPress Plugin ontwikkeling met WordXPression's introductiecursus