Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
Observers and class inheritance
  • What's the correct way to add Observers to a derived class where its parent class already has some observers?

    In the example below, I would like the Model_Derived class to add a new Observer for 'before_create' but still maintain the Observers defined in the Model_Base class.

    Any suggestions other than copying and pasting the Observers from the base class into the derived class? 

    Ex:

    class Model_Base extends \Orm\Model {

        protected static $_observers = array(
            'Orm\Observer_CreatedAt' => array(
                'events' => array('before_insert'),
                'mysql_timestamp' => false,
            )
    }

    class Model_Derived extends Model_Base {

        protected static $_observers = array(
            'Observer_SendEmail' => array(
                'events' => array('before_create'),
                'mysql_timestamp' => false,
            )
    }


  • HarroHarro
    Accepted Answer
    Define an _init() method, and add them to the array:

    public static function _init()
    {
        static::$_observers['Model\\Observer_Date'] => array(
                'events' => array('after_load', 'before_save', 'after_save'),
                'property' => array(
                    'birthdate' => 'eu',
                )
            );
    }
  • Thanks - I wasn't aware of its existence.
  • It's functionality provided by the Fuel Autoloader.

    You can see it as the static equivalence of the constructor, it is called as soon as the autoloader loads the class. It is available for every class defined within the framework.
  • Something weird happens when I add an Observer via _init().

    It works but the Observer is also called by related objects.

    I have a class called User which has a many-to-many relationship with Projects. I attach the Observer SendMail to the 'on_save' event for the User class using _init().

    If I add a Project to a User object, the SendMail Observer is called not only when the User is saved (as expected) but also for every Project object associated with that User. This doesn't happen if I add the Observer to the User class via the traditional static _observers member.

    Any idea what's going on here? I tried tracing it and SendMail is in the array returned by Project::observers()

    Cheers,

    Jesse
  • I can't see without knowing what you exactly do. But assuming all you do is add it to the array in _init, I don't see what the difference would be.
  • Here's the relevant code from the class:

    class Model_User extends Model_Base_App {
    protected static $_many_many = array (
    'contains' => array (
    'key_from' => 'id',
    'key_through_from' => 'user_id', 
    'table_through' => 'users_to_projects',
    'key_through_to' => 'project_id', 
    'model_to' => 'Model_Project',
    'key_to' => 'id'))

        public static function _init()
        {
            
            static::$_observers['SendEmail'] = array(
                'events' => array('on_save'),
                'mysql_timestamp' => false);
        }
    }
  • I have models that do:

    static::$_observers['Orm\\Observer_CreatedAt'] = array('events' => array('before_insert'),'property' => 'created_at', 'mysql_timestamp' => false);
    static::$_observers['Orm\\Observer_UpdatedAt'] = array('events' => array('before_update'), 'property' => 'updated_at', 'mysql_timestamp' => false);
    static::$_observers['Orm\\Observer_Self']['events'][] = array('before_insert', 'before_update');

    and that works fine.
  • So I'm doing everything correctly. Is this a bug?
  • If it were a bug, it wouldn't work for me too. But it does.

    If you have this _init() in a base class, you need to define the property in the base class too, otherwise it won't work:

    protected static $_observers = array();

    This is more of a PHP thing than a Fuel thing...
  • I'm already defining Oberserver in my base class:

    class Model_Base_App extends \Orm\Model {
       
        protected static $_observers = array(
            'Orm\Observer_CreatedAt' => array(
                'events' => array('before_insert'),
                'mysql_timestamp' => false,
            ),
            'Orm\Observer_UpdatedAt' => array(
                'events' => array('before_save'),
                'mysql_timestamp' => false,
            )
    )

    I ask about a bug because we're still on v1.0. Doing a full update isn't an option at this point but I could selectively grab some code that fixes this. I did a search and I couldn't find any evidence of a known bug related to Observers and relations.

    Cheers.
  • Ah....

    Then it probably is. Unfortunately, we don't have the time to support almost 3 year old code.

    You'll have to dive into the ORM's model.php, and debug the observers() method (which loads and parses the observer definition) and the observe() method that calls them.

    I'm pretty sure the structure of the observers array was different in 1.0 then it is today, so current docs are not relevant at that point.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion