Using a PHP Framework or Library in WordPress Plugins and Themes

Anyone who has spent a fair amount of time creating WordPress Plugins or Themes has likely also come across the need to package a PHP framework or library inside a plugin or theme. On the surface this is a fairly routine thing to do – simply copy the file into your plugin or theme, or use composer. There are lots of plugins out there using various PHP libraries and frameworks.

The Problems Begin

I’ve personally started including a PHP framework that I’ve created to help make development easier and add some features that I repeatedly use from project to project. At first this is great, and development is humming along, but eventually you’ll likely run into some problems, like I did. When WordPress loads it loads each activated plugin alphabetically (based on the plugin directory), so let’s say we have two plugins – one called “Analytics” and one called “Cache” and both include the same “Utilities” framework. When Analytics is loaded it will load the Utilities framework, and when Cache is loaded (depending on how the Utilities framework is built) it will either skip loading Utilities because it’s already been loaded or everything will come crashing down due to “Fatal error: Cannot redeclare class/function”. Assuming everything loaded properly, without any fatal errors, the Utilities framework is now loaded and available for use by Analytics and Cache, and you move on with development.

In a closed system where you control the entire stack, all dependencies, plugins, and themes this isn’t a problem. However, with WordPress the idea is that any number of plugins or themes may be installed by the end user, and in this case the developer of a plugin or theme doesn’t have control over what other dependencies, plugins, or themes get installed. So, back to the example from above, what if Analytics needs version 1.0.0 of the Utilities framework and Cache needs version 2.1.0 of the Utilities framework? Knowing the order in which plugins are loaded we know that the Analytics plugin will successfully load the 1.0.0 version of Utilities that is packaged with it, but Cache will be stuck with version 1.0.0 as well.

Assuming that the framework is just a simple class, one way around this problem is to rename the class based on it’s version, or namespace the framework based on it’s version. The problem with this solution is the implementation within your plugin or theme – each time the framework updates you have to update the calls to the framework, which makes maintenance a complete mess (not only for your plugin or theme but also for the developer of the framework). Making things worse, what if the framework is a package in itself, containing dozens of interface and class files?

As a quick side note, one could argue that the chances of this exact situation happening is quite unlikely. However, I think there’s a strong case to be made for plugin developers who make multiple plugins that are relevant to the same audience actually running into this problem. Especially if the plugin end-users happen to update one plugin (that includes a framework) but not another plugin (thus leaving one of the plugins with an outdated framework).

WordPress Hooks Are Our Friend

The solution that I came up with is similar to what the CMB2 toolkit uses, but is instantiated in a different way and uses namespacing as part of the solution. In my specific situation (using my own framework) I had the following requirements:

  • Ability load two separate version of the framework simultaneously.
  • Allow for the newest version to load in a way that guaranteed backwards compatibility.
  • No need for changing the framework namespace or class names with each version.

What I ended up with is a framework that adheres to the following versioning scheme:

  • Major version (1.0.0 to 2.0.0) releases are namespaced by including /v1/ or /v2/ in the namespace to allow for major version releases to run side-by-side with no conflicts. This allows one plugin to use version 1 while another uses version 2.
  • Minor version (1.0.0 to 1.1.0) releases only add new features (never remove) and do not change the interface of existing classes and methods to guarantee backwards compatibility. This allows plugins that expect an old version of the framework to still run properly with a newer version of the framework.
  • Dot version (1.0.0. to 1.0.1) releases only fix bugs and security issues and never change functionality.

The Code

This addresses version dependency issues, but in order to force the highest version of the framework to load I needed to add an init file. So, in the section of my plugin where all other dependencies are loaded I simply add a line such as this:

Which loads the init.php:

Lastly, in order to actually use the framework all I need to do is hook into the ‘after_setup_theme’ action, such as this:

The way all of this works is by each plugin or theme loading the framework init.php file which creates an instance of itself, using the singleton pattern. In the constructor it checks for the existence of a full version global number to compare against. If the current version of the framework is greater than the global version then it hooks into the ‘after_setup_theme’ action and sets the global version to be the same as its version. Lastly the callback for the ‘after_setup_theme’ performs a few checks to make sure that it’s attempting to load the highest version number and that the framework hasn’t been loaded yet, and then finally loads the main framework class.

Ultimately, it’s a fairly simple setup for using a PHP framework or library in a WordPress plugin that’s easy to implement and maintain. This is the solution that worked for me, but I’m sure there are other solutions out there so please share your thoughts, and what you’ve done, in the comments.

Search WordPress Users by Name

If you run a WordPress site with a large list of users and have ever needed to search for a specific user (from the Users > All Users admin page) there’s a good chance no users were found. The problem is that the default query only searches by nicename (username) and email address. However, if you need to search by first name, last name, or a custom user meta field, the default search query is all but useless. Thankfully, the Improved user search in backend plugin fixes this shortcoming, but unfortunately this plugin is outdated and won’t work if you’re running PHP 5.5 and WordPress 3.9 or higher.

So, I’ve gone ahead and created my own user query filter to fix the problem, and included some additional functionality to improve the usefulness of the user search.

 

This can simply be dropped into your theme’s functions.php file, or can be used to create a plugin. It will work as is, but if you have custom user meta fields, possibly added using Advanced Custom Fields, you can simply add the field key to the $usermeta_keys array to include it in the user query.

WordPress Menu Anchor

I recently had the need to add a series of anchor links to a WordPress menu that linked to specific sections of a page. I found this to be tedious, since the page URL needed to be hard coded into the custom link menu item and if the page URL was ever updated each anchor needed to be updated as well. To complicate things further, when looking at the custom link within the menu editor it’s not immediately obvious that the link is an anchor if the URL is longer than the input box.

What I wanted to be able to do is simply create a custom link menu item and set the link value to #my-custom-anchor. Generally if you create a custom link menu item and set the link to be something like #my-custom-anchor it will work, if you’re already on the page for the given anchor, however it will also navigate to “my-custom-anchor” even if you’re on another page where “my-custom-anchor” doesn’t exist.

What I needed was for the anchor to navigate to the desired page and then to the specific section of the page. To do this, the URL would need to have the page URL prepended to the anchor hash. This would allow anchor links to be clicked from anywhere on the website and still navigate to the correct page, and correct section, but if the page was already being viewed the page would not reload (so scrolling animations would still work as well).

Since all of the anchor links were nested under a page menu item, as illustrated in the example below, I was able to filter the menu and prepend the URL with the URL of its’ parent menu item.

Menu Structure Example

  • Page Menu Item 1
    • Page Section 1 Anchor Menu Item
    • Page Section 2 Anchor Menu Item
      • Page Section 2 Sub Section 1 Anchor Menu Item
      • Page Section 2 Sub Section 2 Anchor Menu Item
    • Page Section 3 Anchor Menu Item
  • Page Menu Item 2
  • Page Menu Item 3

In the above example each “Page Section… Menu Item” would link to “Page Menu Item 1” and scroll to the specified section of that page. This is very useful for long pages with many sections and sub-sections.

The Solution is in the Code

To accomplish this I created a menu filter function, that gets added to the themes functions.php file, that searches for menu items with URLs that begin with a # and then prepends the URL with the URL of its’ parent menu item.

This allowed me to create custom link menu items with easily readable anchor links, that could be nested, and would also dynamically update if the page URL ever changed. Another benefit to this method vs “hard coding” an anchor link menu item is that the URL continues to work in a Domain Mapped environment, and across dev, staging, and production environments as well.

WordPress Check if a Menu is Empty

While working with WordPress there are times that it can be very useful to check if a menu is empty before outputting markup. One example is for displaying dynamic, custom, menus in a sidebar where you may not want to output any markup if the menu is empty. This is actually the default functionality of the wp_nav_menu method, but generally menus are wrapped in modules and if the menu is empty one may want to omit the entire module. Since wp_nav_menu will return false if echo is set to false and the menu is empty we can use this with a simple conditional statement to determine if the menu module markup should be output or not.

Its a rather simple solution that just requires a solid understanding of the underlying functionality built into the nav-menu-template.php WordPress core file.

WordPress Custom Sectional Menu

WordPress Menus

With the release of WordPress 3.0 menus were introduced as a visually editable element within the dashboard, dramatically improving WordPress’ CMS capabilities. However, many large websites require menu systems that are a bit more flexible and dynamic that what the built-in menu system provides. For instance, have you ever needed to create a primary navigation menu that resolved to top-level sections of the website and a series of secondary navigation menus that resolved to sub-pages related to each top-level section? Sure, you can create one menu for the top-level primary navigation and another menu for each sub-section of the website and then create a page template corresponding to each of the sub-section menus. The problem with this approach is that you have to create and maintain so many different menus and page templates, not to mention if you’re planning to turn the site over to a client upon completion it requires them to learn and follow certain steps with each page that they create. What if, instead, we could create one master menu and use the regular page template? This is where a custom sectional menu comes in by use of the wp_nav_menu_objects filter hook.

Custom Sectional Menus

To do this we need to create a large nested menu, resembling something similar to the list below, and then set it to be the active menu for the primary and secondary theme locations.

  • top-level-menu-item1
    • sub-section-menu-item1
    • sub-section-menu-item2
    • sub-section-menu-item3
      • nested-sub-section-menu-item1
  • top-level-menu-item2
  • top-level-menu-item3
    • sub-section-menu-item1
    • sub-section-menu-item2
      • nested-sub-section-menu-item1
      • nested-sub-section-menu-item2
      • nested-sub-section-menu-item3

Using the nested menu example from above the primary navigation menu would always show the top-level-menu-items. However, when viewing a sub-section page, such as the page associated with “nested-sub-section-menu-item3” the secondary menu would only show the menu items that are nested under “top-level-menu-item3”. The only remaining question is, how exactly do we do this?

The Solution

I’ve put together a fairly simple function snippet that can be copied and pasted into your themes functions.php file.

Update September 17, 2014 – I’ve updated the lb_sectional_menu filter function to be much more efficient and less prone to error. The wp_nav_menu_objects filter is applied after all menu_items have been sorted/ordered so instead we can just look for menu_items with a menu_item_parent that is equal to zero (meaning that it’s a root parent menu_item) and allow menu_items until the next menu_item_parent equal to zero is encountered. This means the menu will work even if it’s a page, post, tag, custom link, etc. It will also work no matter how many menu items are nested.

This function allows you to build a single, nested, menu and then reuse it across the entire website, where it will dynamically display the necessary menu items for the section being viewed.

JavaScript Scroll Into View

There are times when you may want to add interactivity to your website based on the scroll position relative to an elements position but don’t want to use yet another jQuery plugin. This can be useful to check to see if an element has scrolled into view. So, below I’ve added a very simple function that accepts a jQuery selector string as its only parameter and then returns an object that contains position information about the desired element. All position attributes are boolean values so they can easily be used with conditional logic. The first is “visible” which will be set to true if the desired element is currently visible on the screen (partially or wholly). The second is “above” which will be set to true if the desired element is currently above what is visible on the screen. The last is “below” which will be set to true if the desired element is currently below what is visible on the screen.

This function can easily be used in combination with a the jQuery scroll method.

As you can see it’s easy to check if an element has scrolled into view by checking if it’s visible, above, or below the view. This could be used to add or remove classes to an element, and perhaps used to set an elements position to be fixed. There are jQuery plugins, such as ScrollMagic, which provide many more features and allow for much more complex interactivity, but for simple scroll based interactions the above function is quite useful.

As always please use the comments area to share your thoughts or suggestions for improvement.

Running a Development Copy of WordPress Multisite – Update

WordPress Multisite Updates

Back in January I wrote a guide which provided details on how to setup a WordPress Multisite environment for Production and Development that both shared the same database. Since then there have been several updates with the WordPress core and I’ve also come up with several fixes for the sunrise.php file, so I thought I would write a follow up guide. At the time of writing the original guide the only method to make the Development environment fully operational was to modify two core files, which goes against common practice and was especially problematic when it came to updating WordPress. So I would like to focus on the WordPress core updates, incorporated into WordPress 3.9, that allow for the use of a newly introduced filter instead of modifying the core files.

A Better Way of Doing Things

Prior to the WordPress 3.9 release, two core files, ms-settings.php and ms-blogs.php, both needed to be manually edited in order for the Development environment to function properly. Specifically, this fixed the issue where WordPress would check to see if the current request URI matched the site URL saved in the database and since the Development environment differed from the Production environment this test always failed and redirected to the Production environment. Thanks to the introduction of several new methods and most notably the new “pre_get_site_by_path” filter we can now prevent this redirect from happening by making WordPress think it’s being viewed from the correct URI.

To do this we need to add some additional code to our customized sunrise.php drop-in plugin to account for the “pre_get_site_by_path” filter.

The comments within the code explain what exactly is being done, and for further understanding look at the ms-loads.php WordPress core file. The only item not covered in the comments is the WP_PRODUCTION_DOMAIN defined variable, which should be defined in your wp-config.php file. Please read the original guide for full details.

Thankfully, that’s all there is to it! At this point we can undo the changes to the WordPress core files and don’t need to worry about making changes to core files with each new WordPress update.

Also, note that I’ve added some other filters to the sunrise.php file to allow all content (database and wp-content/uploads) to reside in a single location and thus be shared by the Production and Development environments without needing to clone any data. I’ve updated the original guide to reflect those additional filters.

As always I hope this has been helpful, and please leave comments if you have questions or comments.

 

WordPress Editor Custom Buttons and Dialog Windows

When building a custom website on WordPress one goal is to ensure that it’s as easy as possible for the client to be able to create, update, and maintain their own content. Depending on the complexity of the site, or custom features that are added, there are times that the built-in editor doesn’t provide enough functionality. So, being able to add your own buttons or menus is critical. Thankfully, with the release of WordPress 3.9 which incorporated TinyMCE 4.0, customizing the WordPress editor is easier than ever. In this guide I’ll explain how to create custom buttons and dialog windows, packaged as a simple TinyMCE 4.x plugin, in order to customize the WordPress editor.

Getting Started

The first thing we need to do is add the necessary actions and filters to our WordPress plugin or theme to let it know that we’re wanting to customize the editor. The action we’ll be hooking into is “admin_head” and the filters are “mce_external_plugins”, and “mce_buttons”. Let’s go ahead and gets some code added.

The “admin_head” action hook is checking to see if the current admin screen being viewed represents a post type, whether it be “post”, “page”, or any other custom post type. Next it’s adding the necessary filter hooks needed in order to actually add the TinyMCE plugin and TinyMCE button. Next we’ll need to created the callback functions for each of the filters.

This callback function is pushing our TinyMCE plugin into the $plugin_array variable so that WordPress is aware of its existence. In this case I’ve named the plugin “my_mce_plugin”, but you’ll want to change this to match the naming of your own plugin. I’m also assuming your plugin is being added to your WordPress theme within a “js” folder, so if this is not the case you’ll need to make necessary edits.

This callback function is pushing the “my_mce_plugin” into the $buttons array so that WordPress knows to add our plugin to the list of buttons in the editor. Note that this specific filter hook will add the button to the top, primary toolbar, row. If you’d like to add your button to the second, advanced toolbar, row you will need to use the “mce_buttons_2” filter instead. There are filters for the third and fourth toolbar rows, however WordPress disables these toolbars by default so in many cases they will not be used.

Creating the TinyMCE Plugin

Now that all of the necessary WordPress action and filter hooks are in place the only thing left to do is actually create the TinyMCE plugin. First, we’ll add the framework for the plugin. Note that this will go into a new JavaScript file.

There are a couple of things to point out in the above code. First, what we’re doing is creating a plugin using the tinymce API and then registering it with the tinymce plugin manager. Next, within the plugin creation code, you can see that we’re adding a button to the editor. This button happens to be a menu (menubutton) with three menu items. Each menu item has an onclick event listener that then executes a tinymce command. The commands are registered just below the menu code. Right now the commands are simply inserting text into the WordPress editor as shortcodes. However, wouldn’t it be nice to allow your client to be able to visually select options for the shortcode and then have the corresponding shortcode text insert into the WordPress editor? This is where the TinyMCE Dialog box (windowManager) comes into play.

To illustrate this we’ll customize the “shortcode3” command to open a dialog box, allow for user input, and then output the shortcode text. To do this we will completely rewrite the shortcode3 command. For now, we’ll create two inputs within the dialog box. One will allow the client to enter a title shortcode attribute and the other will allow them to enter a limit shortcode attribute. Note that these attributes will not do anything, since the shortcode does not exist, but are used to illustrate how you could accomplish this and adapt it to your own project.

Going through the above code, line by line, the first thing we did was create a data object to store the default values that we’d like to use for title and limit. Next we tell the window manager to open a new window with the settings we’ve specified. Within the new window we specify a title, data, body, and onSubmit object properties. The body takes in an array of tinymce input objects. I’ve given an example of two different types, textbox and listbox, but more information about these can be found in the TinyMCE 4.x API documentation and by looking through the TinyMCE source. The onSubmit property takes a function and is called when the OK button is clicked on the dialog box. Lastly, we’re using the same command to actually insert the shortcode text, mceInsertContent.

There are other things that you can do with TinyMCE such as getting the current selected text and modifying it (similar to how you add a link in the WordPress editor) or use AJAX to pull information from WordPress to allow for dynamic user input, but those are things to be covered in a follow-up guide. At this point, you should have a fully functioning custom button in the WordPress editor that can easily be adapted to what ever project you may be working on.

As always, I hope this has been an insightful guide, but let me know if you have any questions or comments.

Update – March 30, 2016

The TinyMCE api documentation has been updated and doesn’t include as detailed of information as it previously did, so it may be useful to look through the TinyMCE source. Specifically, the UI Classes will be helpful if you’re wanting to use different TinyMCE widgets than what was used in this article.

Events Manager Custom Event Attributes and Conditionals

The Events Manager plugin for WordPress can be used to build a fantastic event and calendaring system, with countless features and expandability, but there are times that the built in event attributes just aren’t enough. Thankfully the plugin is very developer friendly and allows users to create custom event attributes directly in the dashboard. However, what if you need to display a custom event attribute if it’s used, and not display it if it’s not used? That’s where event attribute conditional placeholders come in, however if you’re wanting to use a conditional placeholder with custom event attributes you’ll have to create it yourself. That’s what we’ll cover in this article.

Creating Custom Event Attributes

First in order to use a custom conditional placeholder you’ll need to have custom event attributes, so let’s create those first. To do this simply login to your WordPress dashboard and go to Events > Settings > General (tab) > General Options and scroll down until you find the radio input for “Enable event attributes?” and be sure that is set to “Yes”. Next you will need to scroll down to the “Event Attributes” text area and add your own custom event attributes. Note that in order for the custom conditional placeholder to function properly the custom event attribute should have no spaces, such as “#_ATT{this_is_my_custom_event_attribute}”. Also note that the custom event attribute is strictly case sensitive so be sure the exact same name is used throughout. For the sake of this article I will be creating a custom event attribute called test, so it will be added using the code below.

Once you’ve finished adding your custom event attributes be sure to save changes.

Creating Custom Conditional Placeholders

Next, we’ll add the necessary code to process our custom conditional placeholders. To do this we’ll implement the use of a filter hook that is called by the Events Manager plugin. Note that the code for the conditional placeholders will be added to your theme’s functions.php file. Thankfully the code for creating custom conditional placeholder is fairly simple, so I’ll show the code that I’ve used for the “test” custom event attribute and then explain how it works, and what you need to change.

It’s as simple as that! Once the above code has been added to the functions.php file the “#_ATT{test}” custom event attribute and “{has_test}” custom conditional placeholder are ready to be used.

Explaining the above code, we’re making use of the “em_event_output_condition” filter that is called by the Events Manager plugin each time it encounters a conditional placeholder that doesn’t match one of the built-in conditional placeholders.

Here is a description of the passed attributes:

  • $replacement (string) will almost always be empty
  • $condition (string) will be the custom conditional placeholder name (such as, “has_test”)
  • $match (string) will contain the text from the beginning of the custom conditional placeholder to the end (such as, “{has_test} #_ATT{test} {/has_test}”)
  • $EM_Event (event object) will be the event object of the current event being viewed

Essentially what the above code does is check for the existence of our custom conditional placeholder, then checks to see if the custom event attribute exists and if it has a non-empty value. If those conditions are met, then the content within the custom conditional placeholder, inside $match, is returned. If those conditions are not met then an empty string is returned.

Due to the simplicity of this filter, in order to modify the above code to work with your custom conditional placeholders simply change the word “test” on lines 2 and 3 to be the name of your custom event attribute, such as “my_custom_event_attribute”.

There you have it! You’ve now created a custom event attribute and a corresponding custom conditional placeholder. You may be wondering, “what if I need to create multiple custom conditional placeholders?”, or “where do I use the custom conditional placeholder?”, and I’ll cover both of those questions in the final section.

Wrapping Everything Up

In the case that you’re needing to create multiple custom conditional placeholders you simply duplicate a portion of the filter code above.

This is the code that actually does the processing, and duplicating it (and placing it above or below the existing code) and then replacing the custom event attribute with your additional custom event attribute is all you need to do. The reason that this works is because the Events Manager will call this filter *each* time it encounters a conditional placeholder that doesn’t match the built-in conditional placeholders. Note that your duplicated code MUST come before the line noted below.

Lastly, in order for the custom event attribute and custom conditional placeholder to have any effect we need to add it to the front-end. The most common, and simple, way to do this is to login to your WordPress dashboard and then go to Events > Settings > Formatting (tab) > Events and scroll down to the  “Default single event format” text area. This is where you can add your custom event attribute and custom conditional placeholder code where ever you’d like it to display on the single event page.

What About no_attribute Conditionals

Update – September 26, 2014: As a follow up to  Koen’s question in the comments I’ve also added a snippet below that will allow you to use a conditional placeholder in the case that a custom attribute is not used.

This can simply be used in addition to your other conditions (has_attribute or no_attribute) within the “em_event_output_condition_filter” filter function.

Nesting Conditionals

Update – October 23, 2014: If you plan to nest conditionals within other conditionals (whether they’re custom or built-in) you will first need to enable this functionality. By default the Events Manager plugin will only look for the first level of conditionals, and unfortunately there is no option for enabling conditional recurrence within the Events Manager Settings within the dashboard. Instead you will need to add some additional code to your functions.php theme file. Once the below code has been added you will need to go to the Events Manager Settings and click save (no changes necessary) to fire the “em_options_save” action. I used this action since this is technically updating an Events Manager option and it prevents the update_option method from being called each page load.

 

The Events Manager plugin checks for the dbem_conditional_recursions option upon instantiation. If this option is set it will use its value, and if not then it will use the default value of one. So, the above code sets the option value to two thus overriding the default.  This will allow for one conditional to be nested within another, however you will need to adjust the above code if you plan nest conditionals at an even deeper level. Keep in mind high levels of recursion can negatively impact performance.

In Conclusion

Overall, the process of adding a custom event attribute and custom conditional placeholder is relatively simple and provides nearly infinite customizability to the Events Manager plugin. I hope this has been an easy to follow and informative guide on how to create custom event attributes. Be sure to post comments and let me know if you’ve ran into any problems or have any questions.