Welcome Guest, Not a member yet? Register   Sign In
Extending libraries
#1

[eluser]Basketcasesoftware[/eluser]
Ok. The User Guide is very good about telling you how to extend, or even replace, the native libraries. Unfortunately it's completely mute on the subject of extending you own libraries. Is this possible using the CodeIgniter framework?

I have a need to create a user extended base class. The base class is doing some housekeeping that the user don't need to mess with.

I can think of a mechanism to do this much like how CodeIgniter itself works but that's possibly getting a little extreme. No, I don't want to use hooks because of the risk of a user accidentally overriding a core CodeIgniter function.
#2

[eluser]Basketcasesoftware[/eluser]
Starting to analyze the CodeIgniter Loader class. Undocumented feature:
Code:
$libraries=array('email', 'ftp', 'html');
$someargs=array('arg1','arg2','arg3');

$this->load->library($libraries, $someargs);

This works because the Loader class library function tests for, and will iterate through, an array of library names, applying the second and third arguments to each library loaded. And so far the answer to my above question is 'no'. I see a possible bug due to the discovered feature in the case it's used with a third argument. What if the first argument is an array and the third is not? I know how to patch it if it is a bug. I'll investigate it more.
#3

[eluser]Basketcasesoftware[/eluser]
It is a... feature?

The following code will work. Sort of.
Code:
$this->load->library(array('calendar', 'cart', 'email'), , 'mail');

$this-mail->send(); // 'mail' will actually be the third object that was loaded.
                    // The other library classes will be initialized then discarded.

A possible use for this is to take advantage of the initializers of the discarded classes because that's what the loader will do in the above example. It will create an instance and initialize each of the classes in order, discarding that previous class for the newer one. Could be used for the side effects.

Here is my suggested rewrite of the Loader library function:
Code:
* This function lets users load and instantiate classes.
     * It is designed to be called from a user's app controllers.
     *
     * @access    public
     * @param    string    the name of the class
     * @param    mixed    the optional parameters
     * @param    string    an optional object name
     * @return    void
     */    

        // Notice the change to the $params argument. Allows us to discard a test.
    // 'array' used here is a form of "Type Hinting" that is of feature of PHP 5.0+
    // This forces the use here of an array as an argument. The CodeIgniter User Guide
    // states that this argument is 'usually' an array but according to the code, an
        // array is REQUIRED!
    function library($library = '', array $params = NULL, $object_name = NULL)
    {
        if ($library == '')
        {
            return FALSE;
        }

        /* By require $params to be an array in the first place this test is
                 * no longer needed. This is a feature of PHP 5.0+ Type Hinting.
        /* This (hopefully) will produce faster and more optimized code.
        if ( ! is_null($params) AND ! is_array($params))
        {
            $params = NULL;
        }
        */

        if (is_array($objectname))
                {
            if (is_array($library))
            {
                $fillsize=count($library);
                $libraries=$library;
            }
            else
            {
                $fillsize=count($objectname);
                $libraries=array_fill(0,$fillsize,$library);
            }

            $parms=array_fill(0,$fillsize,$parems);
            array_map($this->_ci_load_class,$libraries,$parms,$objectname);
                }
                elseif (is_array($library))
                {
            foreach ($library as $class)
            {
                $this->_ci_load_class($class,$params,$object_name);
            }
                }
                else
                {
            $this->_ci_load_class($library, $params, $object_name);
                }
        
        $this->_ci_assign_to_models();
    }

Ouch! This took hours to re-write. And I think I already know how to answer the question I proposed at the beginning of this thread. Hooks.
#4

[eluser]Basketcasesoftware[/eluser]
Oops. Wrong loader. I think mine is better though. Smile
But I was right about the array input on the first argument not being documented. Plus there is unreachable code. I'm going to use this thread to mark a hook I'm about to write to change the loader function into a more useful form than currently defined. It looks like the current version is a last minute bug fix!




Theme © iAndrew 2016 - Forum software by © MyBB