De privacy en optimalisatie van een WordPress Dashboard Widget

Wat je gaat creëren

In de eerste twee delen van deze serie hebben we een volledig functionele plug-in voltooid die ons de serverstatus toont als dashboardwidget. Als zodanig is het beschikbaar voor elke ingelogde gebruiker. Sommige informatie kan gevoelig zijn en we willen niet dat ze deze zien, dus het is beter om te controleren op de gebruikersrol om te bepalen of we de widget beschikbaar moeten maken voor hen. 

Rollen of mogelijkheden gebruiken om zichtbaarheid te beperken

WordPress gebruikt een concept van rollen, ontworpen om de eigenaar van de site de mogelijkheid te geven om te bepalen wat gebruikers wel en niet kunnen doen binnen de site. Elke rol is toegestaan ​​om een ​​aantal taken uit te voeren met de naam Capabilities. We kunnen de rol en de mogelijkheden ervan aanpassen met add_roles en add_cap-functies.

Onze plug-in zal een nieuwe capability-oproep creëren servermetric. Alleen de gebruiker met die mogelijkheid kan onze dashboardwidgets laden. We zullen deze mogelijkheid voor de beheerdersrol toevoegen, zodat alle beheerders dit standaard zullen zien. 

Voor de andere gebruikers kunt u plug-in Gebruikersrol-editor gebruiken om de mogelijkheden van een bepaalde gebruiker te beheren en de servermetic mogelijkheid voor de gebruiker.

We gebruiken add_cap om een ​​nieuwe mogelijkheid toe te voegen, maar deze functie schrijft naar de database, dus we zouden het alleen moeten doen bij het activeren van de plug-in. Na het deactiveren moeten we de database opschonen door de rol met remove_cap te verwijderen.

class Dashboard // ... andere code const CAP_METRIC = 'server_metric'; / ** * Start met instellen hook * / public function run () add_action ('wp_dashboard_setup', array ($ this, 'add_dashboard_widgets')); add_action ('admin_enqueue_scripts', array ($ this, 'add_asset')); add_action ('admin_footer', array ($ this, 'footer')); register_activation_hook (__ FILE__, array ($ this, 'add_servermetric_caps')); register_deactivation_hook (__ FILE__, array ($ this, 'remove_servermetric_caps'));  / ** * Severmetric-mogelijkheid standaard voor admin toevoegen * / function add_servermetric_caps () // krijgt de auteur-role $ role = get_role ('administrator'); // Dit werkt alleen omdat het de klasse-instantie benadert. // zou de auteur toestaan ​​om berichten van anderen te bewerken voor alleen het huidige thema $ role-> add_cap (self :: CAP_METRIC);  function remove_servermetric_caps () // get_role retourneert een exemplaar van WP_Role. $ role = get_role ('beheerder'); $ role-> remove_cap (self :: CAP_METRIC);  // ...

We creëren een nieuwe constante oproep CAP_METRIC en stel de waarde in op server_metric dus we kunnen gemakkelijk de naam van de mogelijkheid later gemakkelijk veranderen. We wijzigen onze rennen methode om twee haken toe te voegen.

De register_activation_hook wordt uitgevoerd wanneer plugin wordt geactiveerd. Het accepteert twee parameters:

  1. (string) bestandsnaam: pad naar het belangrijkste plugin-bestand
  2. (Bel terug) (verplicht) De functie die moet worden uitgevoerd wanneer de plug-in is geactiveerd

register_deactivation_hook wordt uitgevoerd bij het deactiveren van de plug-in. Het accepteert dezelfde parameter als register_activation_hook.

Binnen elke gekoppelde functie laden we de rol beheerder en bel add_cap of remove_cap op het object rollen.

Vervolgens zullen we onze wijzigen add_dashboard_widgets methode om alleen de widgets te registreren als de huidige gebruiker de servermetric pet.
 / ** * Dashboard-widget-proider registreren voor weergave op dashboard * / function add_dashboard_widgets () if (! Current_user_can (self :: CAP_METRIC)) return false;  $ widget = Widget :: instance (); foreach ($ widget-> get_provider () als $ naam => $ provider) $ widget-> registreer ($ naam); 
Vervolgens gebruiken we current_user_can om te controleren of de huidige gebruiker de verzoekmogelijkheid heeft.
Nu zal alleen de beheerder de widget zien tijdens het laden van het dashboard. Als u de serverstatuswidget voor andere gebruikers wilt inschakelen, kunt u plug-in Gebruikersrol-editor installeren om rollen en mogelijkheden voor alle gebruikers te beheren. 
Eenmaal geïnstalleerd en geactiveerd, ga naar het menu Gebruikers, selecteer de Gebruiker> Mogelijkheden:

Vervolgens kunnen we op het capaciteitenscherm de server_metric pet.

Bewerk gebruikersmogelijkheden met de plug-in Gebruikersrol-editor

Door rollen en mogelijkheden te gebruiken, hebben we onze pluginbeveiliging verbeterd om onze widget beschikbaar te maken voor alleen de gebruikers die we vertrouwen.

Cache van de servergegevens

WordPress gebruikt de Transients-API als een cache-API. De gegevens worden geserialiseerd en opgeslagen in de wp_option tabel van WordPress met een vervaltijd van de cache. 

In plaats van metagegevens over elke HTTP-aanvraag te krijgen, kunnen we de gegevens één keer ophalen en opslaan in de cache. We kunnen echter niet eenvoudig alles in de cache plaatsen of dezelfde vervaltijd gebruiken. Schijfruimte kan bijvoorbeeld 15 minuten in de cache worden bewaard en serverinformatie kan 60 minuten in de cache worden bewaard, omdat deze zelden worden gewijzigd. Op dezelfde manier kan geïnstalleerde software een dag in de cache worden opgeslagen, omdat deze zelden wordt gewijzigd nadat de server is ingesteld en voor productie is ingericht.

We gebruiken meestal get_transient en set_transient bij het werken met de API. Volgens de WordPress-documentatie:

  1. get_transient ($ voorbijgaande aard): de transiënte naam als tekenreeks ophalen en de bijbehorende gegevens retourneren. Als de gegevens zijn verlopen, wordt false geretourneerd. We zouden moeten gebruiken === operator om te controleren omdat we een lege waarde voor de transiënt kunnen opslaan.
  2. set_transient ($ transient, $ value, $ expiration): haalt drie parameters op: de tijdelijke naam, de waarde ervan en de vervaltijd op de tweede plaats. Merk op dat de transiënte naam niet langer mag zijn dan 45 tekens.

Onze twee opties zijn het overwegen van caching van de metrische gegevens of het cachen van de gegenereerde HTML-gegevens. Het cachen van de HTML-gegevens kan onze site erg snel maken, maar het belast de database. Daarom kunnen we benchmarken om te beslissen welke het beste is. 

Laten we voor onze zelfstudie de gegevens in de cache opslaan. Daarnaast moeten we een manier hebben om de cache ongeldig te maken - zoals een anker - waarmee we de dashboardgegevens opnieuw kunnen laden en de gegevens kunnen laden in plaats van uit de cache..

Gegevens cachen voor de widget

We kunnen de functie direct gebruiken get_transient of set_transient werken met Transient API. Als we echter besluiten de manier te wijzigen waarop we de Transient API hebben gebruikt, moeten we elke plaats die we gebruiken en elke widget aanpassen voor elke widget. 

Laten we nog een laag toevoegen om het cachemechanisme te abstraheren. We ontwerpen een eenvoudige cacheklasse voor onze widget met drie methoden:

  1. reeks: cachegegevens voor een widget instellen
  2. krijgen: cachegegevens ophalen voor een widget
  3. laden: probeer te laden vanuit de cache, als deze niet bestaat, bereken gegevens, stel de cache in en retourneer

Laten we het bestand samenstellen widget / cache.php op de volgende manier. Merk op dat, als onze automatische laadconventie, de klassenaam zal zijn Cache en de naamruimte is AX \ StatBoard \ Widget

get_metric (); static :: set ($ provider, $ data, $ cache_time); return $ data;  
Merk allereerst op dat we onze cachemethoden hebben gemarkeerd als statisch. Onze reeks en krijgen methoden zijn gewoon wrappers voor  get_transient en set_transient. De laden methode zit bovenop reeks en krijgen. Al deze methoden verwachten dat het widgetproviderobject wordt opgehaald; daarom, binnen van laden methode die we kunnen gebruiken get_metric methode om de echte gegevens te krijgen. 
Hier is het belangrijkste ding de voorbijgaande naam. Omdat de klassennaam uniek is in onze toepassing, beschouwen we deze als uniek genoeg voor de tijdelijke naam. get_class-functie retourneert de klassenaam van een object.
Tijd voor het gebruik van onze Cache klasse. We zullen proberen te implementeren Cache voor widget / software.php. Verander ons origineel Inhoud krijgen methode om:
$ info) $ content. = "

$ cmd $ info

"; echo $ content; // ...
Je kunt zien dat we ons ontdoen van $ cmds = $ this-> get_metric () en gewoon vervangen door Cache :: load welke gegevens uit de cache zal laden, of zal het van het systeem laden als er geen cache bestaat. 
Zorg ervoor dat u de tweede parameter doorgeeft voor hoe lang u wilt dat de gegevens in de cache worden opgeslagen; anders worden de gegevens slechts vijf minuten gecached. Omdat software-informatie op de server zelden op korte termijn verandert, stellen we de cacheduur in op 24 uur.
Nu dat je het idee hebt, kun je herhalen met elke andere widget die je wilt cachen. Vervang gewoon get_metric binnen Inhoud krijgen met:
Cache :: laden ($ this, $ time_in_second);
om ervoor te zorgen dat het in de cache blijft.
De gegevens van schijfgebruik kunnen uren in de cache worden opgeslagen en de ethernetinterface kan een dag of wat cache zijn. Het is aan u om te beslissen hoe lang u het in de cache wilt opslaan. We kunnen ook een optiepagina voor de plug-in maken om deze lifetime-cachewaarde te beheren. Dat kan een oefening voor u zijn om aan te werken nadat we dit artikel hebben voltooid.
We hebben een laatste voorbeeld met widget / ethernet.php. We kunnen cachevaardigheden toevoegen als volgt:
publieke functie get_content () 
$ interfaces = Cache :: laden ($ dit, 3600 * 24 * 7);
$ html = '


';
foreach ($ interfaces als $ interface => $ ip)
$ html. = "


";

$ html. = '
InterfaceIK P
$-Interface$ Ip
';
echo $ html;

  // ...
Nogmaals, we hoeven alleen maar te vervangen get_metric met Cache :: load. De ethernet-informatie en het IP-adres veranderen waarschijnlijk nooit, dus ik heb een zeer lange cache-levensduur ingesteld op één week: 3600 seconden * 24 uur * 7 dagen.

Force laden van echte gegevens

Zodra we een cachevermogen hebben toegevoegd, moeten we een mechanisme ondersteunen zodat de beheerder de widget kan ophalen zonder dat deze in de cache wordt geplaatst. De eenvoudigste manier om dit te doen is om een ​​speciale queryparameter te gebruiken om aan te geven dat we echte gegevens willen. 

Hoe zit het met kleine parameter zoals nocache voor deze? Dus in plaats van de standaard WordPress dashboard-URL met domain.com/wp-admin/ we kunnen gebruiken domain.com/wp-admin/?nocache

Klinkt eenvoudig? Laten we het doen.

Bewerk onze methode krijgen in widget / cache.php

 static function get (Provider $ provider) if (isset ($ _ GET ['nocache'])) return false;  $ cache_id = get_class ($ provider); if (false! == $ data = get_transient ($ cache_id)) return $ data;  return false; 
Zolang de nocache queryparameter bestaat, we geven false onmiddellijk terug en dwingen daarom de echte gegevens te halen in plaats van gegevens in de cache.
Laten we nu eens nadenken over het toevoegen van deze functie zonder de cacheklasse. We moeten mogelijk naar elke regel gaan get_transient en controleer daar de queryparameter. Overweeg daarom dingen op te splitsen in vele lagen bij het ontwerpen van uw plug-in. Plaats niet alles in hetzelfde bestand of kopieer de plakcode steeds opnieuw.
Laten we nu proberen te bezoeken domain.com/wp-admin en domain.com/wp-admin?nocache en let op de verschillende snelheden.987ms laden met cache inschakelen

Hier is het resultaat met ?nocache = 1 toegevoegd aan de URL.

3.01 seconde laden zonder cache

Cronjob gebruiken om cache te genereren

Hoewel we een cache hebben geïmplementeerd en gebruikt, is de pagina nog steeds traag als de cache ontbreekt. Het heeft nog steeds tijd nodig om gegevens van de server te halen. We hebben nog steeds ruimte om te verbeteren met cronjob. We kunnen plannen dat onze plug-in op een specifiek interval wordt uitgevoerd. WordPress stelt ons in staat om dit via te doen wp_schedule_event. Idealiter kunnen we gebruiken wp_schedule_event om een ​​haak in te plannen die met een specifiek interval wordt uitgevoerd.

Als we naar dit voorbeeld kijken, kan onze plug-in plannen dat elke drie minuten een haak wordt aangeroepen, de haak, om beurt weer een andere functie op te roepen om de metrische gegevens op te halen. De gegevens zijn altijd beschikbaar in de cache en voldoende vers.

Open ons belangrijkste plugin-bestand, serverdashboard.php, en werk de run-methode bij met zowel nieuwe hook als nieuwe hook-handler.

 3 * 60, 'display' => __ ('Een keer per 3 minuten')); return $ schema's;  / ** * Setup-schema voor gebeurtenis. Als het schema niet bestaat, * registreren we het in * / function setup_schedule () if (! Wp_next_scheduled ('metric_generate_every_3min')) wp_schedule_event (time (), '3min', 'metric_generate_every_3min');  / ** * De hoofdfunctie die op cron draait en * data genereert * / function generate_metric () $ widget = Widget :: instance (); foreach ($ widget-> get_provider () als $ naam => $ provider) // Door get_content aan te roepen, activeren we het cache :: laadproces. $ Provider-> get_content (); 
Ten eerste ondersteunt de methode wp_schedule_event alleen drie typen herhaling: dagelijks, elk uur en twee keer per dag. We moeten een nieuw soort herhaling toevoegen met het filter wp_get_schedules. 
We voegen een meer terugkerend type toe dat elke drie minuten wordt uitgevoerd. De definitie:
 $ schedules ['3min'] = array ('interval' => 3 * 60, 'display' => __ ('Once every 3 minutes')); return $ schema's;
We kunnen de intervalwaarde aanpassen tot het aantal seconden dat we de opdracht willen herhalen. Vervolgens hebben we een metric_generate_every_3min haak.
 add_action ('metric_generate_every_3min', array ($ this, 'generate_metric'));
Dit is onze eigen haak, het bestaat niet in WordPress. We registreren een handvat met methode generate_metric voor die haak. telkens als metric_generate_every_3min haak wordt aangeroepen, generate_metric zal worden uitgevoerd.
In de volgende verklaring komen we in actie in het met setup_schedule methode om te controleren op het bestaan ​​van de volgende geplande gebeurtenis van de haak metric_generate_every_3min. Als het nog niet is gedefinieerd, plannen we een evenement met wp_schedule_event, gebruik onze aangepaste herhaling voor elke drie minuten voor die haak.
Binnen in de generate_metric methode, doorlopen we alle beschikbare widgetaanbiedingen en bellen we hun Inhoud krijgen methode. Door dat te doen triggeren we Cache :: load proces voor die statistiek.
WordPress voert deze geplande afspraken automatisch uit wanneer iemand uw WordPress-site bezoekt. Het zal proberen de geplande gebeurtenis te vinden die moet worden uitgevoerd en deze moet worden aangeroepen.
U kunt ze echter ook handmatig uitvoeren. WordPress voert cronjob uit via een bezoek aan het bestand wp-content.php met de URL yourdomain.com/wp-cron.php?doing_wp_cron.
Mogelijk wilt u uw cronjob bijwerken om een ​​nieuwe taak toe te voegen die de bovenstaande URL elke minuut pingt
Laten we uw crontab op server openen met crontab -e en voeg deze regel aan het einde toe:
0 * * * * wget domain.com/wp-cron.php?doing_wp_cron> / dev / null 2> & 1
We gebruikten wget om een ​​HTTP-verzoek naar het bestand wp-cron.php te maken. Omdat we ons niet druk maken om de uitvoer en om het even welke fout, sturen we alle uitvoer om naar / Dev / null.
Je kunt meer lezen over het instellen van deze cronjob in de volgende artikelen:
  1. http://tommcfarlin.com/wordpress-cron-jobs/
  2. http://code.tutsplus.com/articles/insights-into-wp-cron-an-introduction-to-scheduling-tasks-in-wordp...

Conclusie

Dit concludeert onze lange tutorial over het bouwen van een server dashboard widget die inzicht geeft in verschillende aspecten van ons systeem.
In deze reeks hebben we bibliotheken van derden gebruikt, een idee gemaakt, met de opdrachtregel geëxperimenteerd, informatie over Rollen en Capabilities verzameld en de Transient-functies van WordPress en de bijbehorende event scheduling-mechanismen besproken.
Uiteindelijk hebben we alles samengebonden in een WordPress-plug-in.
Overweeg om een ​​opmerking achter te laten en laat ons weten welke aanvullende ideeën en wijzigingen u bedenkt, evenals eventuele vragen en / of opmerkingen over deze specifieke serie..