Change the displayed username in Drupal 8 ala Realname

Recovering from surgery finally gave me time to update my last D6 site—a 7 year old private photo and media sharing site with nearly 10,000 nodes and 20+ GB of content—to Drupal 8. Drupal 8 has become a lot more mature lately, to the point where I'm comfortable building a site and not having the foundation rot out from beneath as large ecosystem shifts have mostly settled down.

One thing that I thought would have the simplest implementation actually took a little while to figure out. I needed to have users' full name display instead of their usernames throughout the site. For D6 (and for similar D7 use cases), the easiest way to do this was to enable the Realname module, configure it a tiny bit, and be done with it.

In Drupal 8, however, Realname doesn't yet have a full release (see this issue for progress), and the way usernames are generated has changed slightly (see change record hook_username_alter() changed to hook_user_format_name_alter()).

Fixing sonar-runner error - Can not add twice the same measure

Sometimes, when running sonar-runner to compile the results of a Jenkins build into measurable data for a SonarQube dashboard for a project, I get the following errors, and execution stops before the data is sent to the central sonar server:

ERROR: Error during Sonar runner execution
ERROR: Unable to execute Sonar
ERROR: Caused by: Can not add twice the same measure on org.sonar.api.resources.File...

I was looking into what causes this issue, and couldn't find much via Google. However, just running sonar-runner again, without changing anything or modifying anything, seems to let sonar succeed.

I'll update this post if I ever figure out what might be causing the 'twice the same measure' error, but for now, just run sonar-runner again if you ever bump into this error message :)

I'll be posting more about how to use Sonar + Jenkins + Phing to do some pretty awesome Drupal and PHP code analysis and deployments in future blog posts—stay tuned!

Finding an Image's width/height dimensions using JavaScript

For a complex Drupal node form I've been working on for flocknote, I have a relatively complicated image switching functionality that lets people change an imagefield on the node (either when creating a new one or editing an existing node), and once the imagefield is changed, some custom jQuery code will grab that image and display it in the form, for a very WYSWIYG-like experience (the node looks almost exactly the same when editing/adding as it does once the user saves the node).

One problem is that images can be arbitrarily high (though they're resized to 600px wide), and I can't easily get the height of the image through any traditional means. If I were grabbing an already-saved imagefield image, I could throw the image height into the JS settings for the page. However, getting a dynamically-added image's height/width values is surprisingly tricky using JavaScript, at least if you take a look around the web and try using many people's suggestions (which work great if the image was already loaded with the page's content, but not if the image is dynamically added, or if the image hasn't yet loaded on the page.

Getting Ping statistics with PHP

[Note: Since writing this post, I've created the Ping class for PHP, which incorporates three different ping/latency/uptime methods for PHP, and is a lot more robust than the script I have posted below.]

I recently needed to display some ping/server statistics on a website using PHP. The simplest way to do something like this is to use the built-in linux utility ping, and then parse the results. Instead of doing complex regex with the entirety of ping's output, though, I also used a couple other built-in linux utilities to get just what I needed.

Here's how I got just the response time of a given IP address:

= '123.456.789.0'; // IP address you'd like to ping.
exec("ping -c 1 " . $ip_address . " | head -n 2 | tail -n 1 | awk '{print $7}'", $ping_time);
$ping_time[0]; // First item in array, since exec returns an array.

The above script will ping the given IP address, and simply pull out the response time in milliseconds. You can further parse the response time to just be the numeric value by running it through substr($ping_time[0], 5).

Prefill the Subject of a Privatemsg Message

I've had a nice go at making private messaging capabilities for flockNote work a lot nicer than the out-of-the-box Privatemsg module experience, by simplifying everything to the point that it's closer to the Facebook Direct Message system than the normal Privatemsg UX. (Privatemsg is the premiere way of handling private messaging in Drupal. It's already awesome out of the box... just needed a bit more help for our particular site ;-).

One thing I had wanted to do for a while is prefill the subject field of certain messages. I already have the new private message page appear inside an overlay popup after a user clicks on a link to send a private message to another user on the site.

Privatemsg prefill subject

Programmatically adding and removing roles to users in Drupal

[UPDATE: Here is a much simpler method for editing a user's roles.]

I thought there might be some sort of API function that allows me to add a user role to a user object by the role id (rid), but after looking at user_save() and some other information around the Drupal universe (like this thread), it looks like it's not as easy as I'd hoped. Definitely not like node_save(), where you just modify the node object, save it, and you're done!

I wrote this helper function that you could stick in your own custom module (tested with Drupal 7), which lets you add roles as simply as:

Programmatically Adding or Removing a User or Node Reference from a Node (D7 / References)

The References module in Drupal 7 allows for easy creation and removal of user and node references through Drupal's interface. However, programmatically adding and removing these references is a little more difficult.

You basically have to load the node which has the reference in it, edit the reference field (in my example, the reference field can have an unlimited number of references), add or remove the user ID (or node ID if you're chaging a node reference), and save the node.

Let's look at the example of simply adding a user reference to a node:

// Load the node you'd like to edit.
$node = node_load($nid);
// Add the user ID you'd like to add to this node reference.
$node->field_node_user_references[$node->language][] = array('uid' => $uid);
// Save the node.

It takes a little more effort to remove a user reference (or node reference) from a node. For this, since I have to do it for a few different fields on a node, I've written a helper function that removes a given $uid from the array of user references on a given node.

On Writing Documentation

I've been slowly reading through "Coders at Work," an excellent book in which Peter Siebel interviews many different programmers on their work and craft, and I hit a great little snippet of advice from Peter Norvig:

"The overall design of what's going to do what, that's really important to lay out first. It's got to be something that everybody understands and it's also got to be the right choice."

Basically, before you start doing some huge project, have a bit of a meta discussion about what you're trying to do. Document the process / steps, make sure it makes sense, and code to that process. You don't need to necessarily comment on every little tidbit of code you write—code should be somewhat self-explanatory if written well—but you should at least document what your functions do, and what kind of idea you're trying to implement.

Plus, if you document beforehand, you'll be able to conform code to documentation, and at the end you'll have a framework of your docs already complete!

Subscribe to RSS - code