I’ll be honest: most of the posts that I write are either because I’ve solved a problem for a client, or because I solved a problem that Past-David created. This is one of those PD problems, where I wrote some code that stopped functioning. When I looked into it, it turns out that I was using the wrong function to test for a variable in PHP.

There are a variety of functions made to test the state and value of variables, including ones that can tell you if there is anything available to use at all. Three of these functions that are easy to mix up are isset(), empty(), and is_null().

Built-in Variable Testing Tools

All three of these functions are built into PHP, so they should always be available for your use when writing code. empty() and isset() are language constructs, while is_null() is a standard function. We’ll go over why that’s important later in the article.

Before I discuss the difference and show a few examples, here are the descriptions for empty(), isset(), and is_null() from the php.net manual.

empty()

empty ( mixed$var ) : bool

Determine whether a variable is considered to be empty. A variable is considered empty if it does not exist or if its value equals FALSEempty() does not generate a warning if the variable does not exist.

isset()

isset ( mixed$var [, mixed$... ] ) : bool

Determine if a variable is set and is not NULL.

If a variable has been unset with unset(), it will no longer be set. isset() will return FALSE if testing a variable that has been set to NULL. Also note that a null character (“\0”) is not equivalent to the PHP NULL constant.

If multiple parameters are supplied then isset() will return TRUE only if all of the parameters are set. Evaluation goes from left to right and stops as soon as an unset variable is encountered.

is_null()

is_null ( mixed$var ) : bool

Finds whether the given variable is NULL.

What’s the difference between these variable testing functions?

You can see from the above definitions that these three functions do similar, but not the same things. You’ve gotta determine if you’re trying to test for whether a variable is null, true or false, and whether the variable has been declared.

When to use empty()

If you are using empty() you can test if a variable is false, but also if the variable does not exist. This function is best used when you want to ensure both that the variable exists, and has a value that does not equal false. Note that PHP will treat empty strings, integers of 0, floats of 0.0, empty arrays, and the boolean value of false as false. So basically, only use empty() when you want to ensure that there is some actual value to the variable.

Since you don’t have to declare variables before using them in PHP, you can get in a position where you are trying to perform actions or run other tests on a variable that hasn’t yet been declared. While it’s best practice to declare your variables before use for this and other reasons, this gotcha is one of the reasons that empty() is used differently from isset().

When to use isset()

If you are using isset(), you can test specifically if the variable has been declared already, and that the value is not null. So as long as you have a declared variable that has a value set and is not of the value NULL, you’ll return true when you test it with isset(). This would be a good condition to check before doing other checks to perform actions on a variable:

// Declaring our variable
$variable = 'Some String';

// Testing that our variable exists, then testing the value
if ( isset( $variable ) && $variable !== 'Some Other String' ) {
    echo 'This code evaluates since both of the above are true';
}

In the above example, we’ve declared our variable as a string, then tested if the variable is set (it is), and if it is not equal to a different string (it is not). Since both of those tests are true, we would then echo out the sentence in that conditional statement.

Should you use is_null()?

Finally, is_null() works in a similar manner to isset() as its opposite, with one key difference: the variable must be declared to return true, provided that it is declared without any value, or is declared specifically as NULL.

I said above that isset() tests whether a variable has been set or not, which is true, but it can handle no variable being set and providing an output of false. That is helpful if somewhere else in the code the unset() construct has been used to remove a variable from scope entirely.

In contrast, is_null() would not only not properly evaluate, it would also return a notice due to its inability to evaluate. Usually that’ll look something like this:

Notice:  Undefined variable: variable in /directory/to/code.php on line X

Since isset() is both a language construction, and can handle variables that aren’t declared, I’d generally recommend it over using is_null() in any situation. If you need to use is_null(), I might suggest finding a way to rewrite your code instead.

Language Construct vs. Built-In Function

I mentioned before that isset() and empty() are both language constructs in PHP, where is_null() is a built in function. Language constructs are reserved keywords that can evaluate whatever follows them in a specific manner. That means that it already knows what to do without having to find the definition of the construct like it would a function.

The main things to keep in mind between the two when evaluating your code is that language constructs in PHP are slightly faster (but honestly not enough to worry about for speed optimization), they can’t be used in variable functions, and they don’t throw any errors when evaluating variables that don’t exist.

Many times I see warnings and notices because a variable hasn’t been declared, and no one has confirmed that the variable already exists before trying to do some other conditional check with it. Using isset() and empty() can go a long way to avoiding those errors.

Examples of output of these three functions

The following table has been taken directly from a demo created by Virendra Chandak on his personal site. You can view the demo here.

Value of variable ($var)isset($var)empty($var)is_null($var)
“” (an empty string)bool(true)bool(true)bool(false)
” ” (space)bool(true)bool(false)bool(false)
FALSEbool(true)bool(true)bool(false)
TRUEbool(true)bool(false)bool(false)
array() (an empty array)bool(true)bool(true)bool(false)
NULLbool(false)bool(true)bool(true)
“0” (0 as a string)bool(true)bool(true)bool(false)
0 (0 as an integer)bool(true)bool(true)bool(false)
0.0 (0 as a float)bool(true)bool(true)bool(false)
var $var; (a variable declared, but without a value)bool(false)bool(true)bool(true)
NULL byte (“\ 0”)bool(true)bool(false)bool(false)

Recently, I helped a client import a large set of addresses into a location plugin for WordPress. The import mainly went smoothly, but we noticed some issues when searching in areas with zip codes leading with one or two zeroes. The addresses weren’t coming up as they should.

After examining some of the imported addresses, we realized that all of the leading zeroes were being stripped, and we could no longer search by those zip codes. I’m going to give a brief overview of why this happened, and how I solved it. Hopefully it helps if you need to make this kind of update to a WordPress database too!

Why is this happening?

Some programs “helpfully” strip leading zeroes from numbered cells, including Excel, Numbers, and Google Sheets. This means that 04102 in Portland, Maine becomes 4102, which isn’t a zip code in the US.

The same could happen upon import into the database, depending on how the import is done. In either case, I’m working with an import that’s already complete, as opposed to having caught this issue before the addresses were added to the site. I don’t want to remove all other relevant content just to import again and fix these zip codes, so I’m going to go directly to the database to solve the problem.

How to fix the missing zeroes

There are several ways to add the zeroes back, but most places that you search will suggest changing the datatype of the zip code column, which doesn’t help when it’s in WordPress where we can’t modify that when there is other info stored in the same place. Plus some zip codes have the full nine digit route number depending on where the data was taken from, and some are postal codes from Canada and other countries that don’t follow the same pattern.

In this particular case, we know what we’re looking for (postmeta with a key of wpsl_zip, and we know where it’s at (the wp_postmeta table). If you connect to the MySQL database through PHPMyAdmin or an external application you can run the following query to see how many zip codes stored have fewer than five digits:

Important: Always make a backup of your database before doing any of the changes below!

SELECT
    *
FROM
    `wp_postmeta`
WHERE
    `meta_key` = 'wpsl_zip' AND LENGTH(`meta_value`) < 5

What we’ve told the database to do, is to “select all rows from the wp_postmeta table that have a meta_key of ‘wpsl_zip’, and that have a meta_value of less than five characters in length”.

It’s important to ignore rows that already have a value of five or more characters, as LPAD will trim them to fit five characters otherwise. We don’t want that, just the ones that are too short.

The above will return all of the rows that match the query, so that we can review them and confirm that they are indeed the addresses that we want to update.

Now that we’ve identified how many there are (89 in this case), the following MySQL command will update those zipcodes using LPAD to add a left padding of 0’s until the meta_value is five characters. Values that are already five characters or larger are ignored.

UPDATE
    `wp_postmeta`
SET
    `meta_value` = LPAD(`meta_value`, 5, 0)
WHERE
    `meta_key` = 'wpsl_zip' AND LENGTH(`meta_value`) < 5

You’ll see that the WHERE clause is the same, since we already confirmed that we had the right records to change before. What we’ve done differently with this query is to say that we want to make updates to the wp_postmeta table by setting the meta_value of the rows that we selected to have exactly five characters, and that if they have fewer than five characters, to left pad them with 0’s.

Summary

To review, the MySQL function LPAD works like this:

LPAD(
    "cell that we want to change",
    "final cell string length",
    "what to use to left pad the cell if needed"
)

I hope that helps save you spending the same time that it took me to find the problem that I had and to come up with a solution!

While there’s been a lot written about the new editing experience that came out with WordPress v5.0 last month, I want to give a reminder of some of the neat features for end users. One of the best things about the new editor is that a theme or plugin can add or remove features from the editor with simple hooks, allowing you to craft an experience that fits your needs.

As an example, I have taken a few client sites that have embraced the new editor, and used their style guides to add their branding colors, fonts, and variants into the page editor. Now, when they want to add a block of content with a colored background or change the color of a button on a page, they have their palette of brand-approved colors already set to use. No need to remember hex codes or anything confusing!

Sounds great! How do I set up a custom color palette?

Default WordPress Editor Color Palette
Notice that the editor will warn you if your background and text colors aren’t high contrast. This makes it a bit easier to keep your content accessible!

By default the editor will have a palette of 11 colors, plus a color picker to get a different color. You can swap to a palette of your own by adding some code to your theme. Place the following in your functions.php file or where appropriate based on your structure. Next, we’ll modify it to fit our needs.

This code came directly from the Gutenberg Theme Support Handbook, a good resource for all WordPress developers.

function mytheme_setup_theme_supported_features() {
    add_theme_support( 'editor-color-palette', array(
        array(
            'name' => __( 'strong magenta', 'themeLangDomain' ),
            'slug' => 'strong-magenta',
            'color' => '#a156b4',
        ),
        array(
            'name' => __( 'light grayish magenta', 'themeLangDomain' ),
            'slug' => 'light-grayish-magenta',
            'color' => '#d0a5db',
        ),
        array(
            'name' => __( 'very light gray', 'themeLangDomain' ),
            'slug' => 'very-light-gray',
            'color' => '#eee',
        ),
        array(
            'name' => __( 'very dark gray', 'themeLangDomain' ),
            'slug' => 'very-dark-gray',
            'color' => '#444',
        ),
    ) );
}

add_action( 'after_setup_theme', 'mytheme_setup_theme_supported_features' );

There’s a lot of code there, but not a lot to break down. First, remember that after_setup_theme is a hook, on which you add the function mytheme_setup_theme_supported_features that you’re creating. In that function we’re using add_theme_support, a built in WordPress function, where we’re using editor-color-palette to set our palette up.

We’re adding an array of colors, and each element of that array is itself an array. Within those nested arrays we have the name of the color, which we’re making translatable with the __() function, and setting the textdomain of our theme. Change themeLangDomain to whatever matches your theme. This name is a descriptor for when you hover over it in the palette.

The slug is a string of how you’ll refer to the color elsewhere in your code. The color is the hexadecimal value of the color that you want in your palette. With the above code, you’ve got a new editor palette with four colors that you’ve set, along with the color picker.

Our custom WordPress editor color palette
Our four custom colors now appear, along with the color picker

Adding to Our Palette

There are a few more features of the editor color palette that I’d like to show off, including targeting blocks in CSS, Customizer set colors, and removing the color picker.

Using our Color Palette Selections in CSS

If you’re editing text with the color palette you shouldn’t have to make any other changes. But what if you want to use the color selection in something a bit more customized, or in your own block type?

The slug that we added to our colors in the example above lets us target for both background and text colors. We don’t even need to use the color set in the editor, but something custom to our needs. For example, you may want a specific background or text color when you use the strong magenta color. In that case, here’s the CSS that can target the classes added when we use that color:

.has-strong-magenta-background-color {
    background-color: #313131;
}

.has-strong-magenta-color {
    color: #f78da7;
}

Setting a Color Palette with the Customizer

The twentynineteen theme that comes with WordPress has a custom palette that includes colors that can be set in the Customizer. This means that you can set your own primary and secondary color from the WordPress dashboard, without changing code!

array(
	'name'  => __( 'Primary', 'twentynineteen' ),
	'slug'  => 'primary',
	'color' => twentynineteen_hsl_hex( 'default' === get_theme_mod( 'primary_color' ) ? 199 : get_theme_mod( 'primary_color_hue', 199 ), 100, 33 ),
),
array(
	'name'  => __( 'Secondary', 'twentynineteen' ),
	'slug'  => 'secondary',
	'color' => twentynineteen_hsl_hex( 'default' === get_theme_mod( 'primary_color' ) ? 199 : get_theme_mod( 'primary_color_hue', 199 ), 100, 23 ),
),

The new color is now set as the output of a function that will get a theme mod, if you’ve modified the color. If not, it’ll return the default, ensuring that there’s always a color set.

The WordPress customizer with a primary color selection

Removing the Color Picker

You can also do things like disable the color picker, to ensure that users can only use the colors that you have preset for them. Doing so requires just one line of code in your functions file:

add_theme_support( 'disable-custom-colors' );

With that single line we’ve made it so the beautiful design that we’ve worked so hard to craft and the branding style guide that we have had to constantly review will always be set the way that we want.

Wrapping Up

As you can see, there’s a lot that you can do to change how users edit content in the Gutenberg editor, without having to add a tremendous amount of code.

This is only the beginning, and even more developer and user friendly features like this already exist or are coming to the editor and the rest of WordPress. I’m excited for the new opportunities this gives to all stakeholders of a site, from designers and developers, to admins and editors, all the way to customers and visitors. Let’s keep making WordPress better for everyone!

I’ve mentioned before on the blog that I use Alfred App for OSX and love it. The app helps me do a lot more things quicker, without having to leave the keyboard.

I also use the Alfred Powerpack, which is currently £39.00 for lifetime updates. In US Dollars, that’s $50, which I was quickly able to determine with a currency exchange workflow 😉

Converting currency from GBP to USD
Lots of quick things can be done via Alfred!

The Powerpack includes quite a few extra features, but I make regular use of clipboard history, snippets, auto-expansion, and running shell commands, as well as styling it with a theme and backing up all of my settings

Using Alfred with Homebrew

I also use Homebrew, which is a package manager for OSX. Basically, it’s a way to install and update applications for your mac via the command line. Since I’ve already written some posts about it in the past (as well as how to create the workflow that I’m discussing today), I’m going to refer you back to those posts instead of reiterating them.

Why write this post again?

I have always gone to the terminal, used brew search (and the now deprecated brew cask search to look for applications that I wanted to install. But this meant opening terminal if it wasn’t already, typing the name that I hoped was there, and seeing what came up while guessing if it was the right app when installing.

I recently discovered an Alfred workflow meant specifically for Homebrew tasks, which allows you to do all of the normal Homebrew commands, including searching packages. You can find Homebrew and Cask for Alfred on Github, and it’s already wrapped up as a workflow to install.

I can still use my existing homebrew workflow to update all existing packages that I’ve installed, as well as cleanup when done. Thanks to some updates since the last post about this, there are even fewer tasks to run.

But now I also have access to the normal homebrew tasks, including install, uninstall, search, update, and all of the flags and various commands for them. Even better, when you search for a formula it includes a link to the Github page for it, meaning I can see what that package actually does and not have to guess. Again, this is without ever having to leave the keyboard.

Alfred Homebrew search
Searching the word lint will give all formulas with lint in the name

Having tools like this allows me to work faster and waste less time on managing applications, as well as keeping them all up to date easier. I already procrastinate enough, and I don’t need searching for apps or waiting for them to update when I open them to help me waste even more time!

I’ve started using Beaver Builder with a few clients after having played with it a bit and hearing lots of great reviews. I’ve looked into multiple WordPress Page Builders, and have had experience with quite a few of them through my work offering WordPress maintenance service.

I’ve found that Beaver Builder is able to handle a lot of the customizations that my clients may want to make, but there are still a few things that I have to setup externally to get a feature that they want. As an example, a client wanted to use the callout module to make an entire box clickable, not just a button after text and images.

Doing the above was fairly straightforward for this use-case: I set the entire callout link to be relatively positioned in CSS, so that I could absolutely position the anchor tag within the link to be the full height and width of that box. Finally, I added a hover and focus state to the button so that when hovering with the mouse or focusing with the keyboard there would be a visual indication that it was clickable, besides the cursor icon that was already set.

.callout-link {
	position: relative;
}

.callout-link a {
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
}

.fl-callout-button a:hover,
.fl-callout-button a:focus {
	box-shadow: 1px 1px 3px 0 #315E7D;
}

So what’s the issue?

That looked like a simple solution to the problem that we had, but like many bits of code, I inadvertently created a new issue.

Beaver Builder is a front-end content editor, which means that it uses the same HTML and CSS structure to display the content while editing. While this is normally a good thing, it means that you need to pay attention to custom code that you’ve added to modify Beaver Builder.

Since I changed the layout of links in the callout module, I changed the layout of links for the editor of that module. Additionally, I’d styled unordered list bullets with pseudo-elements, which also caused a display issue. This is what the editor looked like when I tried to modify those links:

Broken Beaver Builder editor CSS
This is what happens when you let me touch code!

After I determined that I was the cause of the issue, I set about to fix it. Thankfully, Beaver Builder adds several body classes while the page editor is open, including the class fl-builder-edit which I used to fix this particular issue. I hid the li::before pseudo-elements, and restored the link anchor to relative positioning.

/* Beaver Builder Editor Fixes */
.fl-builder-edit .entry-content ul li::before,
.fl-builder-edit .fl-builder-content ul li::before {
	display: none;
}

.fl-builder-edit .callout-link a {
    position: relative;
}

With that code in place, the editor layout looked as it should before I mangled it.

Fixed Beaver Builder editor settings
That’s a lot better and actually usable!

Check for unintended consequences of your code.

This broken CSS wasn’t a major problem, and was thankfully easy to fix. But it did bring up a good reminder: when you make one change to your code, you may change something else that you didn’t mean to. It’s always good to review every time that you make a change. Having some version control in place that you use regularly doesn’t hurt either!