Lightbox for Bootstrap 4 and jQuery

Lightbox (or “image preview”) functionality for Bootstrap 4 without additional libraries (apart from jQuery).

Written by Joaquim Homrighausen <joho@webbplatsen.se>
30-May-2019
TEAMYUJO

Do as you wish with this 🙂

This is the Javascript/jQuery code for the Bootstrap 4 modal. You don’t have to use jQuery to accomplish this obviously.

$(document).ready(function($) {

  $(".xslightbox").click(function () {
    if ($(this).attr("data-message") != "undefined") {
      document.getElementById("lightbox_target").src = "";
      document.getElementById("lightbox_target").src = $(this).attr("data-message");
    }
    if ($(this).attr("data-title") != "undefined") {
      document.getElementById("lightbox_title").innerText = $(this).attr("data-title");
      }
    $("#xslightmodal").modal("show");
  });
  /* This will focus the close button, but you don't really need to do this or
     have a close button for that matter since Bootstrap will close the modal
     if you click outside the modal or - in this case - press the Esc key */
  $("#xslightmodal").on("shown.bs.modal", function () {
    $("#lightbox_close").trigger("focus");
  });

});

This is the HTML for the Bootstrap 4 modal. You can style it any which way you want. The key to getting the image to behave as you want it (i.e. to make the image responsive) is adding the “img-fluid” class to the img tag.

You can add the “fade” class to the modal if you want it to be “animated”.

<div class="modal" id="xslightmodal" tabindex="-1" role="dialog" aria-hidden="true" data-keyboard="true">
  <div class="modal-dialog modal-dialog-centered" role="document">
    <div class="modal-content bg-light">
      <div class="modal-header">
        <div class="modal-title text-lowercase text-monospace small" id="lightbox_title">
          placeholder
        </div>
      </div>
      <div class="modal-body text-center">
        <img id="lightbox_target" class="img-fluid border border-secondary rounded" />
      </div>
      <div class="modal-footer">
        <button type="button" tabindex="-1" id="lightbox_close" class="btn btn-primary btn-sm" data-dismiss="modal">'.
          Close
        </button>
      </div>
    </div>
  </div>
</div>

And then, to use the lightbox, you need:

<a class="xslightbox" title="Preview me"
   data-message="https://url/to/image/or/loader/script"
   data-title="Name of image">Preview</a>

This is also available as a gist on GitHub. Knock yourself out 🙂

Simple password construct validator for PHP

/* 
 * Simple password construct validator for PHP 
 * Joaquim Homrighausen <joho@webbplatsen.se>
 * May 30, 2019 
 * TEAMYUJO 
 * 
 * Do whatever you want with this snippet :) 
 * 
 * This may not necessarily agree with the section
 * "Strength of Memorized Secrets" in the document
 * from NIST:
 *
 * NIST Special Publication 800-63B 
 * Digital Identity Guidelines 
 * Authentication and Lifecycle Management 
 * https://pages.nist.gov/800-63-3/sp800-63b.html 
 */

function password_check_construct ($pstr, $min_length = 8)
{
  //Setup pattern and stuff minimum requested length into it
  if ($min_length < 4) {
    //We need at least four characters to satisfy our regexp
    $min_length = 4;
  }

  $match_rules = '/^(?=.{'.(int)$min_length.',})(?=.*[a-z])(?=.*[0-9])(?=.*[A-Z])(?=.*[[:punct:]]).*$/';

  //Require at least one a-z, one A-z, one 0-9, and one punctuation/special character
  if (preg_match ($match_rules, $pstr) === 1) {
    return (true);
  }
  return (false);
}

This is also available as a gist on GitHub. Knock yourself out 🙂

Setting PHP.INI path (or file) for PHP CLI shell scripts

Running a PHP script from the command-line, or CLI, is quite useful at times and is often used to perform some automated task, like a CRON cleanup script, to send out reminders, etc.

It’s common that these CLI scripts need some, but possibly not all, settings that are similar to the main application’s. I may, for example want to include the database configuration settings shared with the main application. So I often create a separate php.ini file for this purpose.

Running /usr/bin/php -c /my/very/special/path cronScript.php is simple enough, but what if I want to be able to create an “executable” PHP shell script? The obvious answer would be something like:

#!/usr/bin/php -c /my/very/special/path

at the top of the .php file, followed by my PHP code, right? Except that may not do what you want. I could not get the PHP interpreter to load anything in /my/very/special/path by using the above construct, even if it works from the actual command-line. After banging my head against the wall for a while, this turns out to work for these “shell scripts”:

#!/usr/bin/php -c=/my/very/special/path

Note the use of the = (equal) sign between the -c and the path (or file).

Carry on.

Coding for Microsoft browsers like Internet Explorer and Edge

Having been doing battles with things like Internet Explorer 4 (yes, I’m that old), it seems to me like Microsoft have really gotten themselves into a bind when it comes to Edge.

With a user-agent string like this:

Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299

It’s no wonder Microsoft seems to be suffering from a split personality when it comes to its browser(s).

Once and for all Microsoft, please just join either of the Chrome/Chromimum/Opera/Firefox projects. Please?

PHP is_numeric () fails WordPress version string check

This is, perhaps, obvious to most PHP developers. But it came somewhat as a surprise to me.

Using is_numeric () for validating a WordPress version string, such as ‘4.7’, does not seem to work very well when WordPress introduces minor releases such as ‘4.7.1’.

Since I cannot be bothered to figure out why it behaves in this (erratic, IMHO) way, I have since replaced the call to is_numeric () with a small function using a simple regular expression (regexp):

    function wpVersionStringCheck ($vs)                                                                                                 
    {                                                                                                                                   
        return (preg_match ('/^(\d+\.)+\d+$/', $vs));                                                                                   
    }

I’m sure there is a hole in there somewhere, but on the following strings at least, it gives me the desired result:

1.0 is valid
1.0. is invalid
1.0.1 is valid
1.banana.0 is invalid

Making SimpleXML truly simple using JSON in PHP

JSON_vs_XML
So using SimpleXML in PHP is possibly one of the worst hells of typecasting and data extraction procedures one can encounter, or close to it 🙂 But more the point, you don’t need to walk down that road alone, enter JSON.

In the simplest of ways, this will typically get you something useful:

    $pvar = json_decode ($xml);

 

(Where $xml is a SimpleXML-type object) This returns a “slightly easier to manage” PHP array.

If you want an associative array, do this:

    $pvar = json_decode ($xml, true);

 

To get it back to JSON, you simply use:

    $json = json_encode ($pvar).

 

You may need to handle XML data, but you don’t necessarily need to work with it in XML form inside your application. The above examples may not work fully for you if you have to deal with “foreign” files or clean the input data prior to conversion, but you get the idea.

This is, obviously, obvious to many. It’s a lifesaver for others 🙂

LinkedIn:
www.linkedin.com/pulse/making-simplexml-truly-simple-using-json-php-joaquim-homrighausen

Hur svårt kan det vara att testa något innan man släpper det?

Dag 1:

[Jag] Hej, det här ni släppte i fredags fungerar inte. Jag får inget svar från servern när jag testar.

[MS] Är du säker på att det inte fungerar?

[Jag] Ja, jag är helt säker. Jag har testat 10 ggr nu och det blir samma resultat varje gång.

[MS] Vi har inte ändrat något annat än att lägga till fixen. Vi får helt enkelt börja felsöka.

Dag 2:

[Jag] Hej, hur går det med felsökningen, kommer ni någon vart?

[MS] Nej, det ser bra ut på vår sida. Är du helt säker på att du gör rätt? Vi har inte ändrat något här.

[Jag] Du sade det. Nej, det ser inte bra ut på er sida. Jag kommer inte ens fram till er sida.

[MS] Vi fortsätter att felsöka då.

Dag 3:

[MS] Vi har hittat problemet. Den här delen av servern som tar emot anrop från er applikation fungerade visst inte så bra. Vi har startat om den och nu fungerar det bättre tror jag.

[Jag] Åh vad bra. Då testar jag vidare.

Dag 4:

[Jag] Det fungerar inte så bra, er server verkar inte gilla vårat sätt att göra det på.

[MS] Nej, ni gör fel. Ni skall göra så här.

[Jag] Men vi gör exakt precis så.

[MS] Jag kan inte se att ni gör så som ni skall. I våra loggar hittar vi bara andra metoder.

[Jag] Men vi gör precis exakt så som ni har sagt åt oss att göra. Har ni testat det själva?

[MS] Nu testade jag det. Det fungerar inte. Jag får återkomma när det här fungerar.

 

Timkostnad: En bit över 1000kr/tim ex moms.

Antal dagar bortslösade: 4.

Tror du de tänker bjuda på nedlagd tid eftersom det var hos dem felet låg? Skulle inte tro det.

[MS] är ett “IT-företag” i Stockholm som utvecklat ett “standardsystem” som är allt annat än standard. Man skräddarsyr varje såld kundlösning och tar betalt tills kunden går sönder för allt man gör. Man tar inget ansvar för fel som uppstår vare sig det rör sig om uppgraderingar av egen kod eller saker man levererat. Allt som behöver korrigeras/ändras/fixas debiteras kund.

 

Locating older version of MySQL 4, MySQL 5, source code, binaries, rpm, etc.

Quite some time ago, we needed to move a customer’s MySQL 4 server from one location to another. In the process, we figured we’d update the server to use some moderately modern version like MySQL 5.0 at least. Also, if we were to have any chance of virtualizing and upgrading the actual server environment to something more modern like Ubuntu 10.04.LTS or 12.04.LTS, or Debian 6.0, we’d have to re-compile the sources regardless. Not taking other incompatibilities into account, that line of thinking ran into Chuck Norris because the Windows DLLs supplied with the application using the database were not compatible with anything but MySQL 4.

The particular version of MySQL 4 running on the customer’s server was self-compiled (by us), so I figured I’d at least locate the “most recent” version of MySQL 4. To my surprise, this turned out to be harder than I could possibly imagine. In a world where “nobody” forgets anything, I could not find a single trace of a source distribution for MySQL 4. Google, Facebook, Microsoft, and Apple probably know the size of shoes I wear, but they don’t know where MySQL 4 sources are located. This struck me as very odd as MySQL 4 was a) very popular, b) open source, and c) should at least reside on half a dozen servers on the Internet, or so I thought.

Like a core dump out of the blue skies, someone Skyped me a link today. The person had ran into a mirror archive and remembered that I was looking for this “eons ago”. I have now mirrored most of that archive into/onto my own cloud store. I’ll go through that in a few days and remove the things I don’t need, but this may very well turn out to he a lifesaver.

I wonder if Sun and/or Oracle decided that keeping old MySQL versions around was a bad idea …

If you, like me, need to find some odd version of MySQL, for whatever reason, here are two links that may be of good use to you:

http://www.mirrorservice.org/sites/ftp.mysql.com/Downloads/
http://mirror.provenscaling.com/mysql/

jQueryMobile or “Mobile site” selection sets

Using jQueryMobile for a fairly lightweight “mobile site”, I wonder what all you experts say about selection sets. A (long) list of countries for example. To prevent excessive delays, I now split country selection in two screens. The first one shows A-Ö (A-Z for you English-speaking people), if I tap on B, the next screen shows a list of countries starting with B. Hitting the back button brings me back to A-Ö (A-Z), selecting a country takes me to.

It feels right, and it doesn’t transfer massive amounts of data that a) isn’t used half of the time, and b) doesn’t take time to render on slower mobile devices.

I’m not too concerned with database performance on the server for this particular selection set since the SQL query is static and resides in the cache 99.5% of the time.