Extending CodeIgniter’s Database Forge Class

UPDATED 2/13: Added License (MIT) Info to code
UPDATED 1/13: Changed ‘required’ ‘required_once’ to avoid errors of redeclaring CI_DBforge

I am working on a project in CodeIgniter that requires use of the database forge class to create/modify/delete database tables. Because the project makes use of database transactions, creating tables with the MYISAM engine was not going to work. So I was faced with two choices: Make all the database creation, etc run by manual queries such as
CREATE TABLE `blah`...
or extend the dbforge class. After some tinkering about I finally managed to successfully do this. Here’s how:
(Note: I am using CI 2. This also assumes you are somewhat familiar with extending CI classes)

  1. Create a MY_Loader.php file in application/core (or open it if you already have one).
  2. If you had to create the MY_Loader file, paste the following:
    <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
    class MY_Loader extends CI_Loader {
    }
  3. Paste the following in your MY_Loader file:

    /**
    * Extend the Database Forge Class
    *
    * @access public
    * @author (Original) EllisLabs / (Extension) J Elmore
    * @license MIT
    * @version 1.0
    * @return string
    */
    function dbforge()
    {
    if ( ! class_exists('CI_DB'))
    {
    $this->database();
    }

    $CI =& get_instance();
    $class = 'CI_DB_'.$CI->db->dbdriver.'_forge';

    require_once BASEPATH.'database/DB_forge'.EXT;
    require_once BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_forge'.EXT;

    if( file_exists(APPPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_forge'.EXT) ) {
    require_once APPPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_forge'.EXT;
    $class = 'DB_'.$CI->db->dbdriver.'_forge';
    }

    $CI->dbforge = new $class();
    }

    This basically adds the code to find/include the extended class, and instantiate it

  4. Next you need to create some folders in your application directory. First, create the folder database. Then, within the database folder, you’ll need to create a drivers folder. Within the drivers folder you’ll need to create a folder for the database type (mysql, mssql, etc) you are using. Since I am using MySQL, I created a mysql folder. My folder structure, then, looked like this:

    application/
    -->database/
    ----->drivers/
    -------->mysql/
  5. In the driver folder you created (in my case, the mysql folder), create a file in the format _forge.php. In my case I created mysql_forge.php.
  6. Create your extended class:

    <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
    class DB_mysql_forge extends CI_DB_mysql_forge {
    }
  7. Have fun extending the functions! To get my tables to specifically create with the InnoDB engine I used the following code:

    /**
    * Modify _create_table to use InnoDB
    *
    * @access public
    * @author (Original) EllisLabs / (Extension) J Elmore
    * @license MIT
    * @version 1.0
    * @return string
    */
    function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
    {
    $sql = parent::_create_table($table, $fields, $primary_keys, $keys, $if_not_exists);

    $sql = rtrim($sql, ';');
    /* Should note here that I have a custom config file with the key/value pair to hold the
    default database engine to use */
    return $sql.' ENGINE='.config_item('database_engine').';';
    }

I tried simply extending the dbforge class but since all the magic happens in the driver classes it was necessary to extend the driver and modify the functions there. Also, I know there are ways to set the mysql server to default to InnoDB creation but since this project may be sold/released at some point it is easier to modify the CodeIgniter files than to try and provide instructions for something most people wouldn’t be able to or know how to do.

CSS-Only Accordion

This was actually really easy to do, so much so that I felt kind of embarassed when I figured it out. Most of the credit should be given to cssnewbie; the modifications I made simply expanded on their article to only show the titles of the accordion sections.

The CSS:
#accordion {}
#accordion div {width:100%; height: 20px; padding: 3px; margin-bottom: 10px; color: #fff; overflow: hidden;}
#accordion div.content {display: block; border:1px solid #efefef; color: #363636;}
#accordion span.acc_head{display: block; font-weight: bold; background: #F1E3EB; padding: 3px;}
#accordion:hover div { height: 20px; }
#accordion:hover div:hover { height: auto; color: #363636;}
#accordion ul { list-style-type:none;display:inline table;margin:0;padding:0; width: 100%;  table-layout: fixed; }
#accordion li { display: table-cell; position: relative; min-width: 175px; max-width: 175px;}

The ul and li items are optional; I tend to use this with stuff I want to display in a table-type format.

The HTML:
<div id="accordion">
<div class="content">
<span class="acc_head">Title One</span>
Content and such
</div>
<div class="content">
<span class="acc_head">Title Two</span>
Content and such again
</div>
</div>

That’s it! The divs (should) only display the the titles of the content divs, the div being hovered on should expand to reveal all content, and the non-hovered divs should remain showing titles only.

Cool, easy way to toggle elements using show and hide

I was looking around, trying to find a way to have 2 form elements hidden when a page loaded, then show and hide them as needed by clicking on a (link,radio button, etc). Using jQuery, this was insanely easy.

1. Wrap the element(s) you want to show and hide with span or div tags and set style to display none. Make sure to give each span/div a unique id, eg:

<span id=’one’>Text 1</span>
<span id=’two’>Text 2</span>

2. Somewhere above these elements, you’ll need to put the following:

$(document).ready(function() {
$(“#itemtoclick1”).click(function() {
$(“#one”).show();
$(“#two”).hide();
});
$(“#itemtoclick2”).click(function() {
$(“#one”).show();
$(“#two”).hide();
});
});

For my needs, I had 2 radio buttons, and both id’s one and two were hidden when the page loaded. When a user clicked on one of the radio buttons (given id “itemtoclick1” and “itemtoclick2”, respectively), the appropriate section would appear.

For cooler effects you can add ‘fast’ or ‘slow’ between the show/hide parentheses.

Hope this was helpful! 🙂