Verwijderen van WordPress berichten in bulk traag door Sucuri

Onlangs liepen we bij Pronamic tegen “504 Gateway Timeout” fouten aan bij het verwijderen van (veel) WordPress berichten de WordPress admin omgeving. In eerste instantie dachten we aan een hosting issue, maar al snel bleek dat een plugin de boosdoener was. Het kan echter soms lastig zijn om te achterhalen welke plugin de veroorzaker is. Plugins kunnen op allerlei filter/actie hooks inhaken en zaken vertragen. In dit geval trad het probleem op bij het verwijderen van berichten. Door de WordPress code te bekijken kwamen we er snel achter dat WordPres bij het verwijderen van berichten o.a. de wp_trash_post en deleted_post actie uitvoert:

Met 20+ actieve plugins en duizenden bestanden blijft het echter zoeken naar een speld in een hooiberg. Gelukkig hebben we vaak SSH-toegang tot onze hosting omgevingen en kunnen we met een eenvoudig commando snel zoeken:

  • grep --recursive --include="*.php" "deleted_post" .
  • grep --recursive --include="*.php" "trash_post" .

Hieruit bleek al snel dat de “Sucuri Security” plugin de boosdoener was. Deze plugin communiceert elke bericht verwijdering door naar de Sucuri API. Doordat voor elk bericht een HTTP-request werd uitgevoerd ontstond er een enorme vertraging bij het verwijderen van berichten.

Deze API-communicatie kan gelukkig eenvoudig uitgeschakeld worden via de Sucuri plugin instellingen pagina:

SSH-toegang en tools zoals grep kunnen goed helpen bij het opspeuren van dergelijke problemen.

WordPress network/multisite cron vervangen met Linux cron SiteGround

Veel WordPress ontwikkelaars zijn geen fan van de standaard WordPress cron functionaliteit. Vaak wordt daarom geadviseerd om de WordPress cron te vervangen met een Linux cron. De meeste artikelen adviseren om in wp-config.php de WordPress uit te schakelen via define( 'DISABLE_WP_CRON', 'true' ); en via cPanel of DirectAdmin een Linux cron in te stellen:

/usr/local/bin/php /home/user/public_html/wp-cron.php

Voor een eenvoudige WordPress installatie werkt dit vaak goed, maar binnen een WordPress network/multisite installatie wordt het vaak al lastiger. Als je je website host bij SiteGround is dit echter ook een fluitje van een cent. De volgende WP-CLI commando komt hier namelijk goed bij van pas:

wp site list --path=/home/user/public_html --deleted=0 --field=url | xargs -I {} wp cron event run --due-now --path=/home/user/public_html --quiet --url={}

Bovenstaand commando bestaat eigenlijk uit 2 commando’s, één voor het opvragen alle sites en één voor het uitvoeren van de verlopen cron events:

  1. wp site list --path=/home/user/public_html --deleted=0
  2. wp cron event run --due-now --path=/home/user/public_html --quiet --url={}

Met behulp van het xargs command geven we de output van het eerste commando door aan het tweede commando. Op die manier worden de verlopen cron events van alle (niet verwijderde) websites uitgevoerd.

Resources

Homebrew, PHP 7.1 en cURL error 56: SSLRead() return error -9806

Na het installeren van PHP 7.1 via Brew kreeg ik via de WordPress HTTP API soms de volgende foutmelding te zien:

cURL error 56: SSLRead() return error -9806

Ik was deze fout wel vaker tegen gekomen, maar het is altijd weer even zoeken naar de oplossing. Het belangrijkste is dat er gewerkt wordt Homebrew curl en openssl:

brew uninstall git
brew uninstall curl

brew install openssl
brew install libressl

brew install curl --with-openssl

brew install php71 --with-homebrew-curl --with-homebrew-libressl --build-from-source
brew install php71-xdebug
brew install php71-mcrypt

Verder zijn ook de volgende Homebrew packages handig om te installeren:

brew install svn

brew install git --with-brewed-curl --with-brewed-openssl --with-brewed-svn --without-completions
brew install git-ftp
brew install git-flow

brew install composer
brew install php-code-sniffer
brew install phpmd
brew install phpunit
brew install phpmyadmin

Bronnen

WordPress plugin testen met PHPUnit – mysqli_query(): Couldn’t fetch mysqli

Verschillende WordPress plugins die we ontwikkelen bij Pronamic testen we automatisch. Hiervoor maken we gebruik van de WordPress test repository https://develop.svn.wordpress.org/ en PHPUnit. Voor onder andere de Pronamic iDEAL plugin maken we hier al een aantal jaren gebruik maken. Echter na het bijwerken naar de laatste versie van de WordPress test repository https://develop.svn.wordpress.org/ liep ik tegen de volgende foutmelding aan:

mysqli_query(): Couldn't fetch mysqli

In eerste instantie kon ik niet achterhalen waar wat fout ging, maar na lang zoeken en overleg met mijn collega Reüel heb ik hier wat meer informatie over kunnen vinden. In een WordPress.org support topic van 1½ maand geleden werd dezelfde foutmelding genoemd: https://wordpress.org/support/topic/wp_unittestcaseteardown-causes-mysqli_query-couldnt-fetch-mysqli/. Ryan McCue verwijst daar weer naar WordPress Trac ticket 39327. Hij beschrijft hier ook direct een oplossing:

Tracked this down a bit with @pento; it turns out to be a problem with PHPUnit’s global backups, and can be fixed by setting protected $backupGlobals = true in the test class. The key is that PHPUnit serialises the data and unserialises it to restore it.

Vervolgens geeft @pento later in een reactie ook aan hoe dit probleem het beste opgelost kan worden:

For an immediate plugin fix, the best option is to add backupGlobals=”false” to your phpunit.xms.dist.

Plugins zoals bijvoorbeeld Easy Digital Downloads hebben dit ook opgenomen in hun phpunit.xml  bestand: https://github.com/easydigitaldownloads/easy-digital-downloads/blob/master/phpunit.xml. Na het toevoegen van backupGlobals="false" is het probleem ook daadwerkelijk opgelost.

Schermafbeelding venster schaduw Mac OS uitschakelen

Als WordPress webontwikkelaar bij Pronamic maak ik veel gebruik van de Mac OS schermafbeelding functionaliteit (cmd ⌘ + shift ⇧ + 4 » spatie). Voornamelijk voor blog berichten, support en documentatie doeleinden komt deze functionaliteit goed van pas. Wat ik minder mooi vind is de schaduw rondom schermafbeeldingen van Mac OS applicatie vensters. Na een zoektocht via Google blijkt dit eenvoudig uitgeschakeld te kunnen worden. Door het uitvoeren van de volgende commando in de terminal is dit uit te schakelen:

defaults write com.apple.screencapture disable-shadow -bool true

Hierna zal SystemUIServer herstart moeten worden om de wijziging actief te maken:

killall SystemUIServer

Schermafbeelding met venster schaduw 

Schermafbeelding zonder venster schaduw

Uiteraard kan de schaduw ook weer ingeschakeld worden:

defaults write com.apple.screencapture disable-shadow -bool false

Bron: http://osxdaily.com/2011/05/23/disable-shadow-screen-shots-mac/

SiteGround timeout verhogen

Veel WordPress gebruikers zullen wel eens tegen timeouts aanlopen. Vooral bij bulk acties in WordPress wil dit nog wel eens voorkomen. Gelukkig kan de timeout limiet vaak verhoogd worden via bijvoorbeeld een .htaccess bestand. Bij SiteGround kan de limiet verhoogd worden via onderstaande code:

# BEGIN Custom timeout
<IfModule mod_dtimeout.c>
	<Files ~ ".php">
		SetEnvIf Request_URI "edit.php" DynamicTimeout=3600
	</Files>
</IfModule>
# END Custom timeout

Bron: https://wordpress.org/support/topic/temporary-failure/

PHP 7 Cron Jobs bij SiteGround

Gebruikers van SiteGround weten waarschijnlijk wel dat SiteGround altijd bovenop nieuwe ontwikkelingen zit. Zo hadden ze PHP 7 al vrij snel beschikbaar gesteld aan hun gebruikers. Door een regel op te nemen in een .htaccess  bestand kan PHP 7 eenvoudig geactiveerd worden:

AddHandler application/x-httpd-php70 .php .php5 .php4 .php3

Meer informatie hierover is te vinden op de volgende SiteGround pagina’s:

Voor zover mij bekend werkt dit echter niet voor Cron Jobs die direct de PHP executable aanroepen via bijvoorbeeld:

/usr/local/bin/php /home/username/public_html/wp-cron.php

Nou is het vrij eenvoudig om de PHP 7 executable te gebruiken door bovestaande commando aan te passen:

/usr/local/bin/php70 /home/username/public_html/wp-cron.php

Dit resulteerde bij mij echter in de volgende fout:

Cannot load Zend OPcache - it was already loaded

Reden om even te informeren bij de SiteGround support afdeling:

PHP 7 Cron Jobs bij SiteGround

Helaas werd de chatsessie zomaar beëindigd en heeft SiteGround niet opnieuw contact met me opgenomen. Na een korte zoektocht kwam ik echter zelf een oplossing tegen:

Usage: php [options] [-f] <file> [--] [args...]
   php [options] -r <code> [--] [args...]
   php [options] [-B <begin_code>] -R <code> [-E <end_code>] [--] [args...]
   php [options] [-B <begin_code>] -F <file> [-E <end_code>] [--] [args...]
   php [options] -S <addr>:<port> [-t docroot]
   php [options] -- [args...]
   php [options] -a

  -a               Run as interactive shell
  -c <path>|<file> Look for php.ini file in this directory
  -n               No configuration (ini) files will be used
  -d foo[=bar]     Define INI entry foo with value 'bar'
  -e               Generate extended information for debugger/profiler
  -f <file>        Parse and execute <file>.
  -h               This help
  -i               PHP information
  -l               Syntax check only (lint)
  -m               Show compiled in modules
  -r <code>        Run PHP <code> without using script tags <?..?>
  -B <begin_code>  Run PHP <begin_code> before processing input lines
  -R <code>        Run PHP <code> for every input line
  -F <file>        Parse and execute <file> for every input line
  -E <end_code>    Run PHP <end_code> after processing all input lines
  -H               Hide any passed arguments from external tools.
  -S <addr>:<port> Run with built-in web server.
  -t <docroot>     Specify document root <docroot> for built-in web server.
  -s               Output HTML syntax highlighted source.
  -v               Version number
  -w               Output source with stripped comments and whitespace.
  -z <file>        Load Zend extension <file>.

  args...          Arguments passed to script. Use -- args when first argument
                   starts with - or script is read from stdin

  --ini            Show configuration file names

  --rf <name>      Show information about function <name>.
  --rc <name>      Show information about class <name>.
  --re <name>      Show information about extension <name>.
  --rz <name>      Show information about Zend extension <name>.
  --ri <name>      Show configuration for extension <name>.

Door de -n optie toe te voegen aan het commando was de foutmelding verdwenen.

/usr/local/bin/php70 -n /home/username/public_html/wp-cron.php

Mollie Recurring testen betaling blijft pending

Bij Pronamic werken we momenteel hard aan de ondersteuning van Mollie Recurring in de Pronamic iDEAL plugin. Hierbij liepen we tegen het probleem aan dat test incasso betalingen de status pending  bleven houden. We hebben daarom zojuist even geïnformeerd bij Mollie wat we over het hoofd zien:

Hallo Mollie,

We zijn momenteel bezig met de Mollie Recurring API en lopen tegen een probleem aan. De test directdebit betaling blijft de status pending houden terwijl er een valid mandate is:

curl -X GET https://api.mollie.nl/v1/payments/tr_********** -H "Authorization: Bearer test_******************************"
curl -X GET https://api.mollie.nl/v1/customers/cst_**********/mandates/mdt_********** -H "Authorization: Bearer test_******************************"

Zien wij iets over het hoofd?

Het handige van Mollie is dat de API ook eenvoudig via curl  is aan te roepen. In combinatie met tools zoals underscore-cli of jq kun je zo de Mollie API eenvoudig testen.

jq

brew install jq
curl -X GET https://api.mollie.nl/v1/payments/tr_********** -H "Authorization: Bearer test_******************************" | jq

Mollie API test curl jq

underscore-cli

npm install -g underscore-cli
curl -X GET https://api.mollie.nl/v1/payments/tr_********** -H "Authorization: Bearer test_******************************" | underscore print --color

Mollie API test curl underscore

Update maandag 10 oktober

Inmiddels hebben we een reactie gekregen van Mollie:

In de testmodus klopt dit inderdaad. Om recurring te testen kun je dit het beste doen met de Creditcard betaalmethode. Dit zal hetzelfde werken als met SEPA-incasso.

Als er nog vragen zijn, horen wij deze graag. Veel informatie is overigens ook terug te vinden op onze Support-pagina: https://www.mollie.com/nl/support

Het is wel jammer dat dit in testmodus niet correct werkt en Mollie ook geen stappen lijkt te nemen om dit of de documentatie hiervan te verbeteren.

Van KPN Internet Thuis Instap naar Alles-in-1 Standaard

Helaas is op het adres waar ik woon geen TV kabel beschikbaar dus zijn we aangewezen op internet via de telefoonlijn. Hiervoor heb ik jaren gebruik gemaakt van het KPN Internet Thuis Instap pakket. Dit pakket heeft een download snelheid van 20 Mbit/s en een upload snelheid tot 2 Mbit/s.

Als webdeveloper merk ik zo nu en dan toch dat de 20 Mbit/s niet heel snel is. Vandaag ben ik daarom overgestapt naar het Alles-in-1 Standaard pakket van KPN. Dit pakket heeft een download snelheid van 60 Mbit/s en een een upload snelheid tot 6 Mbit/s. Bij het bestellen stond echter wel de volgende opmerking:

Op dit adres is de maximaal haalbare internetsnelheid 36 Mbit/s down en 6 Mbit/s up.

Ik ben erg benieuwd of na de upgrade, die pas over een paar weken actief zal zijn, mijn internetsnelheid is verbeterd. Ik heb daarom de snelheid even gemeten met een aantal tools:

Speedtest.net

Speedtest.net geeft momenteel een download snelheid van 8,66 Mb/s en een upload snelheid van 1,41 Mb/s.

http://www.speedtest.net/my-result/5537965661 Speedtest.net resultaten

Speedtest.nl

Speedtest.nl resultaten

KPN Speedtest

KPN Speedtest geeft momenteel een download snelheid van 12,56 Mbps en een upload snelheid van 1,54 Mbps.

kpn-speedtest-results

Ik ben erg benieuwd of na de upgrade de download snelheid in de buurt komt van de 36 Mbit/s. Zodra de upgrade door KPN is uitgevoerd zal ik dit bericht voorzien van een update.