var_dump() for Javascript

PHP, for example, has var_dump() and print_r() to facilitate quick variable dumps to log files, etc.

For Javascript, one can use console.log() in combination with JSON.stringify() to achieve something similar.

  console.log( JSON.stringify(object) );

It’s also possible to “pretty-print” the output like so:

  console.log( JSON.stringify(object, null, 2) );

For more information about JSON.stringify(), check out this page

Cloudbridge Mattermost

Cloudbridge Mattermost is a WordPress plugin that provides integration between WordPress and Mattermost. In the initial release, we focus on login notifications (successful, failed, unknown) from the various WordPress user roles.

We will, of course, be adding more functionality in the future.

You can download it from the official WordPress repository:
wordpress.org/plugins/cloudbridge-mattermost

You can also get it from GitHub, should you prefer that source:
github.com/joho1968/cloudbridge-mattermost

This is the initial release of this plugin.

Displaying WordPress roles in the current language

While writing a WordPress plugin that displays the available user roles, I came across a snag: the user roles that I had fetched from WordPress weren’t translated into the site’s current language.

I’m not quite sure I understand the reasoning behind this since WordPress offers functions to return an array with the actual role as the key, and the display string as the array value, like:

array( 'administrator' => 'Administrator' );

So why can’t WordPress return the “correct” (i18n) language string for the array value … anyway, there’s a solution.

Looking at how WordPress does it under “Settings > General” in the WordPress Admin, I eventually found a call to translate_user_role(), which requires one parameter, the role array name value, e.g. “Administrator”. The function will then return the correct (language context aware) display string.

So to put it into a functional context, it may look something like this:

function i18n_get_wp_roles() {
    $wp_roles = wp_roles();
    if ( is_object( $wp_roles ) ) {
        $roles = array_keys( $wp_roles->roles );
        $role_names = $wp_roles->get_names();
    } else {
        $roles = false;
        $role_names = array();
    }
    $return_roles = array();
    if ( is_array( $roles ) ) {
        foreach( $roles as $role_k => $role_v ) {
            if ( ! empty( $role_names[$role_v] ) ) {
                $return_roles[$role_v] = translate_user_role( $role_names[$role_v] );
            } else {
                $return_roles[$role_v] = 'Unknown role (' . $role_v . ')';
            }
        }
    } else {
        error_log( basename(__FILE__) . ' (' . __FUNCTION__ . '): wp_roles() returned empty' );
    }
    return( $return_roles );
}

 

Where did my Emacs color-theme go in Ubuntu 20.04.LTS?!

Having recently upgraded a small VPS from Ubuntu 18.04.LTS to Ubuntu 20.04.LTS, I ran into a little snag with Emacs and its color-theme (from the emacs-goodies-el package).

After some digging, it seems this is now done somewhat differently in Ubuntu 20.04.LTS.

This is what my .emacs file used to contain:

(require 'color-theme) 
(color-theme-initialize) 
(color-theme-charcoal-black)

This is what I changed it to:

(add-to-list 'custom-theme-load-path 
(file-name-as-directory "/usr/share/emacs/site-lisp/elpa/color-theme-modern-0.0.2"))
(load-theme 'charcoal-black t t) 
(enable-theme 'charcoal-black)

In addition, I also had to install the elpa-color-theme-modern package (from the Ubuntu 20.04.LTS distribution).

 

pdftk and php-pdftk on Ubuntu 18.04 without using snap

During a product launch I recently came across an “interesting” issue involving pdftk (and php-pdftk). Some of the developers had made assumptions (ever heard that one before?) about the operating environment and how things were/are configured.

These assumptions were based on a development environment that in no way reflected the final production environment (ever heard that one before?). In this particular case, they were expecting the great PDF toolkit (pdftk) to be available and working just like it did in their development environment.

To summarize the issue: pdftk has been removed from Ubuntu 18.04 due to dependency issues. The “recommended” solution is to install pdftk using snap. This, in itself, is not a bad recommendation. But in a web server environment, it may put you in a place you don’t want to be in.

So after a few hours of toying with ideas and testing various things, I figured there must be some Debian-like package that would actually work when installed on Ubuntu 18.04 and that is not a snap package.

There is.

Later versions (or packages) of pdftk now exist as pdftk-java, and they do work with php-pdftk as well.

In my case, I located pdftk-java_3.1.1-1_all.deb and installed it. Or tried to rather. It has a number of dependencies that you will see for yourself. You’ll need to decide if their “weight” makes it worthwhile for you to go down this path. But it was one, reasonably good, way for us to solve the problem.

The developers you ask? They have been sent to /dev/codersgulag/cobol and will spend a number of solar iterations there.

(The file I ended up using was http://ftp.debian.org/debian/pool/main/p/pdftk-java/pdftk-java_3.1.1-1_all.deb, and it does work on Ubuntu 18.04.LTS)

 

 

Nextcloud and WebDAV “SEARCH” requests

Using WebDAV to access Nextcloud resources is a pretty nice way to write integrations for Nextcloud. While adding support for Nextcloud file browsing in a service we’re constantly improving, I ran into a minor snag: How to format the WebDAV “SEARCH” request when interfacing with Nextcloud.

1. The example in the official documentation is correct. You just have to read it carefully. In particular, pay attention to this:

Search requests can be made by sending a SEARCH http request to https://cloud.example.com/remote.php/dav/ with a content type of text/xml and the query as xml in the request body.

2. Make sure you structure your XML data properly, in particular, you need to make sure you include a d:prop of which “field” you want your search data to be applied to.

<d:searchrequest xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns">
  <d:basicsearch>
    <d:select>
      <d:prop>
        <oc:fileid/>
        <d:displayname/>
        <d:getcontenttype/>
      </d:prop>
    </d:select>
    <d:from>
      <d:scope>
        <d:href>/files/testuser/</d:href>
        <d:depth>infinity</d:depth>
      </d:scope>
    </d:from>
    <d:where>
      <d:like>
        <d:prop>
          <d:displayname/>
        </d:prop>
        <d:literal>Nextcloud%</d:literal>
      </d:like>
    </d:where>
    <d:orderby/>
  </d:basicsearch>
</d:searchrequest>

This would search for files beginning with Nextcloud and return fileid, displayname, and the content type; the search will be made in the folders that testuser has access to.

And that’s that.

 

Please use proper message headers (FFS)

Writing software that deals with automated message processing on the Internet is, in a word, painful. The number of people who cannot seem to read simple specifications and/or proposals is staggering.

And one would think that if you can’t read specifications, you’d at least bother to “View message source” on a few thousand e-mail message to get a feel for how some other (well known) companies are doing it, INSTEAD OF INVENTING YOUR OWN STANDARD.

So, if you’re sending out automated e-mail messages, for example, please add one of these headers:

auto-submitted
x-auto-response-supress
precedence
feedback-id
x-autoreply

I’ll leave it as an exercise for the reader to look them up … and if you’re doing some kind of mailing list stuff, please add:

list-id
list-unsubscribe

Thank you!

You may now resume sleep mode.

SwiftMailer 5, PHP5, and ISO-8859-15

I’ve been using SwiftMailer for as long as I can remember because it’s, IMHO, a great library and far more logical than PHPMailer and “others”. While maintaining a PHP5 codebase for a rather large project, I ran into an issue while using ISO-8859-15 encoded data. Most people won’t care about ISO-8859-15 over ISO-8859-1 (“Latin1”), but since I live in Europe, I prefer to have support for the €uro character 🙂

To make a long story short, if you need SwiftMailer 5 to properly handle ISO-8859-15, look for a line in “MimePart.php” that looks like this:

if (!in_array($charset, array('utf-8', 'iso-8859-1', ''))) {

and change it to this:

if (!in_array($charset, array('utf-8', 'iso-8859-15', 'iso-8859-1', ''))) {

(Yes, the project will move to a PHP7 codebase at some not so distant point in the future.)

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 🙂