WordPress Plugin: Custom Functions.php

One of the limitations of adding code to your theme’s function.php file is that these modifications are lost if you change themes, and another is that it is executed after your plugin files are loaded. This means that if you want to modify any behavior in your other plugins that call filtered functions but aren’t hooked to WordPress Actions, you’re out of luck.

I have worked around this on all my sites by creating a custom plugin to handle all of my non-theme specific additions. The only thing this plugin does is ensure that it is loaded first when you activate it, and then pulls in the contents of a functions.php file in the parent plugins directory. The result is that you have custom code running before any of your other plugins. The functions.php file is specifically not included, but it would just but a standard PHP file like the one in your theme.

This file is always up to date based on the trunk of my SVN repository.

custom-functions.php

<?php
/*
Plugin Name: Custom functions.php
Plugin URI: http://doublesharp.com/
Description: Moves most functions away from functions.php and ensures it loads before all your plugins
Author: Justin Silver
Version: 1.1
Author URI: http://doublesharp.com
License: GPL2
*/

if ( !class_exists( 'CustomFunctionsPHP' ) ):
class CustomFunctionsPHP {

	private static $instance;

	private function __construct() { }

	public static function init() {
		if ( !self::$instance ) {
			self::$instance = new CustomFunctionsPHP();

			// Add actions to make sure this plugin is loaded first
			self::$instance->add_actions();

			// The directory to check in, defaults to WP_PLUGIN_DIR, usually wp-content/plugins
			$custom_dir = defined('CUSTOM_FUNCTIONS_DIR')? 
				CUSTOM_FUNCTIONS_DIR : 
				WP_PLUGIN_DIR;

			// Check for custom settings file name or default to functions.php
			$custom_file = defined('CUSTOM_FUNCTIONS_FILE')? 
				CUSTOM_FUNCTIONS_FILE : 
				'functions.php';
			
			// The full name of the custom functions file
			$custom_functions = "{$custom_dir}/{$custom_file}";

			if ( file_exists( $custom_functions ) )
				include_once $custom_functions;
		}
	}

	public function add_actions() {
		add_action( "activated_plugin", array( $this, "load_this_plugin_first" ) );
	}

	/**
	 * When this plugin is activated, make sure it goes to the top of the load order.
	 * Based on http://wordpress.org/support/topic/how-to-change-plugins-load-order
	 * Props to jsdalton - http://wordpress.org/support/profile/jsdalton
	 */
	public function load_this_plugin_first() {
		// ensure path to this file is via main wp plugin path
		$wp_path_to_this_file = preg_replace( '/(.*)plugins\/(.*)$/', WP_PLUGIN_DIR."/$2", __FILE__ );
		$this_plugin = plugin_basename( trim( $wp_path_to_this_file ) );

		// is this a network wide plugin?
		$is_multisite = is_multisite() && array_key_exists( $this_plugin, get_site_option( 'active_sitewide_plugins', array() ) );

		// get the list of active plugins either from options or site_options
		$active_plugins = ( $is_multisite )?
			get_site_option( 'active_sitewide_plugins' ):
			get_option( 'active_plugins' );

		if ( $is_multisite ) {
			// multisite plugins are array(plugin=>time) so check the key position
			if ( array_search( $this_plugin, array_keys( $active_plugins ) ) ) {
				// unset this key...
				unset( $active_plugins[$this_plugin] );

				// ...and add it back at the beginning
				$active_plugins = array( $this_plugin => time() ) + $active_plugins;

				// update the site option value
				update_site_option( 'active_sitewide_plugins', $active_plugins );
			}
		} else {
			// if it's 0 it's the first plugin already, no need to continue
			$this_plugin_key = array_search( $this_plugin, $active_plugins );
			if ( $this_plugin_key ) {
				// take out $this_plugin...
				array_splice( $active_plugins, $this_plugin_key, 1 );

				// ...and put it back in at the top
				array_unshift( $active_plugins, $this_plugin );

				// update the option value
				update_option( 'active_plugins', $active_plugins );
			}
		}
	}
}

// init class, hook functions to make this run first (and includes functions.php first)
CustomFunctionsPHP::init();

endif; // class exists

m4s0n501

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>