Website Development Tip for Techies: Integrating Codeigniter and WordPress

WordPress is usually an excellent choice for a Content Management System (CMS) when we build our sites. The interface is comfortable and intuitive for our clients and the platform is remarkably flexible. However, there are circumstances when we need to build a customized application and WordPress is not the right tool for the job.

Yet, we still desire the ease of updating and management it provides our clients. For example, we recently developed a site for the Columbus Arts Festival using WordPress and needed to build a web application to manage applications submitted by prospective festival performers, artists, food vendors, and poets. Rather than try to shoehorn such functionality into WordPress, it made more sense to build our app using Codeigniter, a lightweight PHP framework.

We developed the WordPress and Codeigniter elements of the site separately. However, we realized it would be advantageous to use bits from WordPress in our Codeigniter app such as our primary navigation and footer. (Obviously, there is little sense in updating this twice) Since WordPress would act as our primary facing application, our goal was to use WordPress's functions within Codeigniter, but keep the Codeigniter app in a contained subdirectory. The following outlines the steps we took to couple WordPress and Codeigniter. We have created a Github repo to facilitate the following implementation. Our repository contains all of the files mentioned below.

Step 1: Adding the WordPress Bootstrap File

We took a cue from Phil Palmieri and referenced WordPress's wp-load.php file immediately preceding the call to Codeigniter bootstrap file in CI's index.php file:

* --------------------------------------------------------------------
* LOAD THE BOOTSTRAP FILE
* --------------------------------------------------------------------
*
* And away we go...
*
*/
//Load WordPress file.
require_once('/Server/path/to/wp-load.php');
require_once BASEPATH.'core/CodeIgniter.php';

Simple enough.

Before adding any WordPress functionality, we tested everything out. The first page of our app looked fine, but that was about it. Every URL within our app, including form handlers were redirecting to the root directory (i.e. WordPress' directory), resulting in 404 errors. We discovered that both WordPress and Codeigniter have a "site_url" function in global scope. By loading the WordPress bootstrap file before Codeigniter's, we were getting WordPress' site_url. Codeigniter's function "failed" silently because it was checking to see if a site_url function existed, which of course it did.

Without installing the Runkit extension for PHP, you cannot (to my knowledge) overwrite a global function, and even if we could, we needed both site_url functions if Codeigniter and WordPress were to exist in separate directories.

Step 2: "Extending" Codeigniter's URL Helper

Our solution was to "extend" Codeigniter's URL helper (we aren't really extending it because the functions are not within a class), by creating a new namespaced function called ci_site_url, thereby resolving the site_url conflict. This helper (MY_url_helper.php) should be placed in your Codeigniter's application/helpers directory.

Step 3: Change site_url to ci_site_url in the CodeIgniter App.

Do a quick search/replace in your application/controllers application/models and application/views directories and change any references from site_url to ci_site_url. Because the redirect function was updated in the helper file, there is no need to change these references.

Once we completed these steps, our CI app worked the way it was supposed to... almost..

Step 4: Stop WordPress from mangling our cookies!

One aspect of our site that still was not working was the admin panel that we built in Codeigniter. Our credentials were being accepted, but we were redirected back to the login page. In addition, three cookies were created in the CodeIgniter session database table every time we logged in! Temporarily commenting out the WordPress bootstrap file rectified this problem. Clearly, WordPress was doing something to CI's cookie.

The key to the problem was in the wp-inclues/load.php file. Unfortunately, I abandoned the "don't ever modify core files!" principle to get this to work; if a WordPress guru has a more elegant solution, I'd love to hear it. It turns out that WordPress was looping through our $_COOKIE global and applying its add_magic_quotes function for security reasons. This rendered our CI cookie useless. Rather than scrap the functionality all together, I created an array_walk function that will apply WordPress' add_magic_quotes function to every element in the $_COOKIE global except for the CodeIgniter cookie. The code is as follows:

Scroll down to about Line 520 and add this function:
(Assumes you are using CI's default ci_session key; change if you are using something else)
/**
* Applies Magic Quotes to the $_COOKIE global but ignores Codeigniter's Cookie
* @param string $value Value passed by array_walk function
* @param string $key Key passed by array_walk function
*/
function ci_ignore_magic_quotes($value,$key)
{
    if($key != "ci_session")
    {
        stripslashes_deep($value);
    }
}

Comment out the following lines inside the wp_magic_quotes function and add a reference to the above ci_ignore_magic_quotes function.

array_walk($_COOKIE, 'ci_ignore_magic_quotes');
//$_COOKIE = add_magic_quotes( $_COOKIE );

Lastly, at the very top of the file, we need to tell WordPress to not unset our $_COOKIE['ci_session']:

$no_unset = array( 'GLOBALS', '_GET', '_POST', '_COOKIE', '_REQUEST', 
 '_SERVER', '_ENV', '_FILES', 'table_prefix','ci_session' );

Step 5: Implement WordPress Functionality

Once we had completed these steps, everything worked as it should; we included WordPress' navigation in our Codeigniter application without a problem.

To download the files referenced in this post, check out our WordPress/Codeigniter Github repo !