Welcome Guest, Not a member yet? Register   Sign In
Undefined Property Error in custom library
#1

[eluser]azavala[/eluser]
I've put together a couple of classes to use as a library in my application. There is a base parent class, a few child classes that extend the base class, and a wrapper/library class that brings everything together. Code and file structure below.

The Problem: All of the child classes work fine EXCEPT for the Alerts child class. In the construct method for the Alerts class, I call a method in the same class that handles loading a config item from the db via a model call. For some reason, that function in the Alerts class throws an undefined property error:

Quote:A PHP Error was encountered
Severity: Notice
Message: Undefined property: CI::$site_preferences_model
Filename: jets/Alerts.php
Line Number: 32

I do the same type of model call (to different models - none to the site_preferences_model outside of this problematic function) in all of the child classes and even tested it with a quick function in my wrapper class that pulls a bunch of data from the database. No errors at all.

In my base class, I have a __call magic method that handles finding models. Again, it seems to work for all of the child classes except the Alerts class. Changing the scope of _ci to public didn't change anything. Moving the model file to the root of the models folder didn't change anything (I have other models in that same depth of sub directories that work).

My directory structure is as follows (non-relative files removed from list):
> /application
>> /libraries
>>> jets_library.php
>>> /jets
>>>>> jets_base.php
>>>>> alerts.php
>> /models
>>> /site
>>>> /prefs
>>>>> site_preferences_model.php

Code (removed non-relative code to save space):

Code:
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

/**
*    Base Class
**/
class Jets_Base
{
    /**
    *    Stores our CI instance
    *    @var object
    *    @access protected
    **/
    protected $_ci;
    
    /**
    *    The models we need to use in this library
    *    @var Array
    *    @access protected
    **/
    protected $_library_models;
    
    /**
    *    The default support email address
    *    @var string
    *    @access public
    **/
    public $support_address;
    
    /**
    *    Any errors go here
    *    @var boolean/array
    *    @access public
    **/
    public $errors = FALSE;
    
    public function __construct()
    {
        // Check for instance of CI Super Object and assign if necessary
        if (!isset($this->_ci))
        {
            $this->_ci =& get_instance();
        }
        
        // Load resources
        $this->_ci->lang->load('jet_lang');
                
        // Set models
        $this->library_models = $this->_ci->config->item('jet_library_models');
    }
    
    /**
    *    Simple custom __call method to dynamically call models when they are requested
    **/
    public function __call($method, $arguments)
    {
        $errors = 0;
        $total_methods = count($this->library_models);
        
        foreach ($this->library_models as $model)
        {
            if ($errors == $total_methods)
            {
                // We have went through all of the methods and none of them worked!
                $this->errors []= $this->_ci->lang->line('error_missing_model');
            }
            else
            {
                if (!method_exists($this->_ci->$model, $method))
                {
                    $errors++;
                    continue;
                }
                else
                {
                    return call_user_func_array(array($this->_ci->$model, $method), $arguments);
                }
            }
        }
    }
}


Code:
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

/**
*    Alerts Class
*    @see Jets_Base class
**/
class Alerts extends Jets_Base
{
    public function __construct()
    {
        parent::__construct();
        
        // load resources
        $this->_ci->load->library('email');
        $this->_ci->load->library('email_sms');
        
        $this->set_support_email(); // Call the below method to set the support email
    }
    
    /**
    * Set the support/alerts email address
    **/
    public function set_support_email()
    {
        // query the db for the email address
        $support_addy = $this->_ci->site_preferences_model->get_preference_item('email_contact'); // ERROR ON THIS LINE (32)
        
        // Check for successful query
        if ($support_addy !== FALSE)
        {
            $this->support_address = $support_addy;
            return TRUE;
        }
        else
        {
            $this->errors []= 'Setup Error: Unable to assign contact email address in Base Class';
            return FALSE;
        }
    }
}

Code:
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

// Load class files
include APPPATH . 'libraries/jets/Jets_Base.php';
include APPPATH . 'libraries/jets/Alerts.php';

/**
*    Jets Library (wrapper/library class)
*    @package CodeIgniter
*    @subpackage Libraries
**/
class Jets_library
{
    public $alerts;
    
    public function __construct()
    {
        // New class instances
        $this->alerts = New Alerts;
                /**
                 * Note: I have a few other child classes that are loaded here and are used without issue.
                **/
    }
}

I tried not calling the set_support_email method in the wrapper class instead of in the construct of the Alerts class. Same result. All of the other child classes work fine, calling other models without any issues. The config item that is an array that holds all the accessible models for the library. The sub folders are included with the model name in each array value (e.g. dir/subdir/model_name).

Any help would be greatly appreciated. I'm still learning OOP and am interested in improving my craft by getting past errors like this one.

Thank you!
#2

[eluser]azavala[/eluser]
Also, when I try calling different models in the Alerts class, I get the same error. Why is it only the Alerts child class has this problem?

Edit: The problem also occurs if I do the site_preferences_model call in the base and other child classes.

??




Theme © iAndrew 2016 - Forum software by © MyBB