Integrating WordPress Into CodeIgniter

One of the sites I maintain was built using CodeIgniter.  If you don’t know CodeIgniter and you are a PHP developer, definitely check it out.  It is a lightweight, extensible framework (don’t they all claim that?).  It does not have an ORM (Object Relational Mapper) but you can easily integrate your favorite (Doctrine, for example.)

I have been building website in CodeIgniter for a while, however this one site is growing beyond scope (again…don’t they all?) and now is requiring more dynamic content.  It’s not quite to the phase where I would rebuild it using WordPress and in any event I don’t really have the motivation to build a custom theme to keep the same look and feel.

So, I’ll be using the tried and true methodology of integrating the “guts” of WordPress so that we can update pages and posts without having to do a major rewrite of the site.

To get started, I downloaded the latest version of WordPress (3.9.2 at the time of this writing) and installed it in a web-accessible sub-directory called “blog.”  I had read a few places online where people had some problems with the conflicting routing systems of WordPress and Codeigniter and went so far as to change the core code in CI and/or WordPress, but I found a much simpler method:  simply update the rewrite rule in your Apache config file:

RewriteEngine on
RewriteCond $1 !^(index\.php|blog|images|robots\.txt|css|js)
RewriteRule ^(.*)$ /index.php/$1 [L]

The second line lists “pass-through” exclusions that are not routed via the index.php file and routing table for Codeigniter.  Now I can access WordPress directly and run the setup and enter and manage content.  The next step is to create/modify model files in Codeigniter to access WordPress instead of the original database.

I had a model call ‘Events’ that was used to obviously store upcoming events and seminars for this client.  I’m going to switch it to use WordPress to pull posts instead.

function getEvents($numPosts = 3) {
  $args = array( 
    'numberposts' => $numPosts, 
    'order_by' => 'date', 
    'category_name' => 'events' 
  );
  $myposts = get_posts( $args );
  return self::fillEvents($myposts);
}

The method “getEvents” formerly used the Codeigniter ActiveRecord system to query the db and was updated to use WordPress methods. As you can see, it uses the “get_posts” method to pull the last N posts from the Events category (with the slug “events.”)  The “fillEvents” method iterates through the records and returns an associative array.

private function fillEvent($post) {
    $event = false;
    $date = strtotime(Date("Y-m-d H:i:s"));
    $custom = get_post_custom($post->ID);
    if (isset($custom['start_date'])) {
      if (strtotime($custom['start_date'][0]) > $date) {
        $event = array(
          'id' => $post->ID,
          'title' => get_the_title(),
          'date' => get_the_date(),
          'start_date' => $custom['start_date'][0],
          'end_date' => $custom['end_date'][0],
          'location' => $custom['location'][0],
          'excerpt' => get_the_excerpt(),
          'content' => get_the_content(),
          'link' => get_the_permalink());
      }
    }
    return $event;
 }

 private function fillEvents($posts) {
    global $post;
    $events = array();
    foreach( $posts as $post ) {
      setup_postdata($post);
      $event = self::fillEvent($post);
      if ($event) {
        $events[] = $event;
      }
    }
    return $events;
 }

At this point I should note a couple of things:

  1. I do not use the templating system built-in to Codeigniter.  I replace it with Smarty as I believe it is a more extensible and versatile system.  Plus, I can upgrade the Smarty implementation without having to update Codeigniter.
  2. I usually return my data objects as associative arrays that are passed to my display templates.

The end result is that I do not have to change my controllers or my template (.tpl) files from their original design.  I just made sure that my model returned the same data in the same format 🙂

So far I have not run into any problems regarding routing or cookies, and my next step is to leverage the WordPress User system to create user accounts.  I’ll be sure to update this post (or create a new one) if I find anything.

Between The Lines

We released a new mobile app today, Between the Lines!

In this game you navigate a maze and try to complete it before the timer runs out.  There are levels of all different sizes and we’ll be adding new ones, which the paid version will automatically download.

There are four modes:  “Normal” mode where you unlock levels as you progress.  “Survival” mode is unlocked once you complete a map in Normal mode and you see how many maps you can complete before the clock beats you.  Free-play lets you play levels in any order you wish as many times as you want. “Challenge” mode lets you try to beat your best time on any map.

You can also create your own custom levels and customize the color theme.  Currently only available for Android with the iOS version on the way.

You’ve been warned…it’s a little addicting!

 

3D Printed Mandolorian Helmet

So…we have  a 3D printer at the office.  That poor thing has been going pretty much non-stop since it was put together.  I, of course, decided I wanted to print something big and test how far the printer can go.

I started perusing grabcad.com and found a full-size Boba Fett file.  In no time I had it fired up in Blender and was gawking at the awesomeness.

However, it was too tall (and almost too wide) for the printer, so the dome was sliced off and printed separately.  The dome took 15 hours to print, the bottom face mask 31 hours (there were also a lot of false starts while we adjusted the position of the mask and printer settings…maybe another 4 or 5 hours involved.)

The result is below.  It’s a perfect skeleton for a helmet.  The next steps are to reinforce it with fiberglass (after reattaching the dome) and then a coat of Bondo on the outside (and maybe inside) to smooth it out…then of course painting and decorating

Still have to print the ear caps and other helmet gear, but this is a great start.