Inloggen via Passkeys toegevoegd!

Passkeys zijn een veilige manier van inloggen die ons hopelijk eindelijk gaat verlossen van die vreselijk onhandige wachtwoorden. Naar aanleiding van een stuk in cT-magazine heb ik Passkeys als tweede optie toegevoegd voor het inloggen op deze site. Het voordeel van het gebruik van WordPress is dat daar al een plugin voor is: WebAuthn. Nooit gedacht dat WordPress nog eens een voordeel zou zijn op veiligheidsgebied 😃

Today I learned…

Last weekend, I decided to update this website: the WordPress version, the plugins and the PHP version on the server itself. That last update had an interesting consequence: the OpenID plugin broke (which I didn’t notice until I got a nightly warning email).

The (kindly) supplied error message and stacktrace pointed quite straightforward to the cause of the problem: ” Uncaught ValueError: Unknown format specifier ” ” … #0 /home/xxx/domains/erikroos.org/public_html/wordpress/wp-content/plugins/wp-openid-selector/wp-openid-selector.php(63): printf()”.

I decided to take the hard route and try to fix the problem by hand. On the indicated line I found a printf statement with a %1 placeholder in it. As always, Stackoverflow gave the solution almost immediately: in PHP 8, a placeholder must always be terminated with a $, and optionally a format specifier like “s” (for string). So I replaced all the %1’s with %1$1 and, simple as that, OpenID worked again, allowing me to log in again (which can be quite handy).

When looking at the plugin code, I noticed the use of a function “named” __. Some googling showed that this is a built-in WordPress function for translating the given string using the current locale. It is somewhat similar to PHP’s own gettext() function, which can be aliased using a single _. And I thought Python was strange for using dunders (double underscores) in function names!

Today I learned: hoe verhelp ik het nare, gierende geluid van een Philips-scheerapparaat

Al sinds mijn achttiende scheer ik mezelf elke dag trouw. Na een korte periode van nat scheren met mijn opa’s oude Gilette uit de jaren 1950 (en na afloop met zo’n blokje aluin over mijn gemartelde velletje heen), ben ik al gauw overgestapt op elektrisch scheren. Het werd een Philishave en dat is het altijd gebleven, want het beviel nou eenmaal goed. Tot mijn jongste scheerapparaat, eentje uit de 5000-serie, een hoog, gierend geluid begon te maken tijdens het scheren. Ik dacht dat er iets aanliep in een van de scheerkoppen en begon maar eens met het hele apparaat schoon te maken. Azijn tegen de kalk, wasbezine tegen de vettigheid: het apparaat werd schoner dan ooit maar het piepende geluid bleef. Bijzonder irritant! Tot ik ineens een ingeving kreeg en een druppeltje olie (lijnzaad geloof ik) bij de aandrijving van de onderste scheerkop in goot. Opgelost! Hemelse stilte tijdens het scheren! Dus: herken je dit probleem, een druppeltje olie is je redding en je Philishave kan nog jaren mee.

Drupje olie bij de onderste scheerkop, et voilĂ 

Today I learned…

PHP has a nice library to work with zip archives: ZipArchive. However, you cannot open zip files that are hosted on some website. First you have to download the zip file, and then you can open it using ZipArchive. An example:

$file = 'http://www.somesite.com/file.zip';
file_put_contents('file.zip', fopen($file, 'r'));
$zip = new ZipArchive();
if ($zip->open('file.zip') === true) {
    for ($i = 0; $i < $zip->numFiles; $i++) { 
         $stat = $zip->statIndex($i);
         if (strpos($stat['name'], 'partoffilename') !== false) {
             $fileContents = $zip->getFromIndex($i);
             // Do something here...
         }
    }
}

Also note something interesting here: if you don’t know the exact name of the file inside the zip archive that you want to open, you cannot use getFromName(), so you have to take another approach. In the above example, I iterate through the files in the archive using an index, checking every file for the part of the filename that I do know. When there’s a match, I can use the current index and getFromIndex() to open the file.

Today I learned…

In PHP, if you sort -or better: do not sort- an array, using a custom function that happens to return 0 every time, the resulting order is undefined as opposed to the original order as you might expect.

So, if you do something like this and X is never set:

usort($arr_content['content']['results'], function($a, $b) {
    if (isset($a['X']) && isset($b['X'])) {
       if ($a['X'] == $b['X']) {
            return 0;
        }
        if ($a['X'] < $b['X']) {
            return -1;
        }
        return 1;
    }
    if (isset($a['X'])) {
        return -1;
    }
    if (isset($b['X'])) {
        return 1;
    }
    return 0; // this is returned for every element since $a['X'] and $b['X'] are never set
 });

you end up with an array that’s sorted in an unexpected way, in my case even perfectly reversed!

I had to work around this “feature” of PHP by checking the number of undefined X’es in the array and skipping the usort() of their number is equal to the number of elements in the array.