/** * There really isn't any concept of 'parent' method. An ExtensibleObject * instance contains an ordered array of extension classes, which provides * the method implementations for the instance to use. Suppose that an * ExtensibleObject has two extension, and both have the same methods.The * last extension appears to 'override' the first extension. So, instead of calling * a 'parent' method, we're actually just calling an extension that was added sooner than * the one that is providing the current method implementation. */ function call_parent($method) { $retval = NULL; // To simulate a 'parent' call, we remove the current mixin providing the // implementation. $klass = $this->object->get_mixin_providing($method); // Perform the routine described above... $this->object->disable_mixin_for($method, $klass); // Get the method map cache $orig_method_map = $this->object->_method_map_cache; $this->object->_method_map_cache = (array) C_Pope_Cache::get(array($this->object->context, $this->object->_mixin_priorities, $this->object->_disabled_map), $this->object->_method_map_cache); // Call anchor $args = func_get_args(); // Remove $method parameter array_shift($args); // Execute the method $retval = $this->object->call_method($method, $args); // Cache the method map for this configuration of mixins C_Pope_Cache::set(array($this->object->context, $this->object->_mixin_priorities, $this->object->_disabled_map), $this->object->_method_map_cache); // Re-enable mixins; // $this->object->add_mixin($klass); $this->object->enable_mixin_for($method, $klass); // Restore the original method map $this->object->_method_map_cache = $orig_method_map; return $retval; }
/** * There really isn't any concept of 'parent' method. An ExtensibleObject * instance contains an ordered array of extension classes, which provides * the method implementations for the instance to use. Suppose that an * ExtensibleObject has two extension, and both have the same methods.The * last extension appears to 'override' the first extension. So, instead of calling * a 'parent' method, we're actually just calling an extension that was added sooner than * the one that is providing the current method implementation. */ function call_parent($method) { $retval = NULL; // To simulate a 'parent' call, we remove the current extension from the // ExtensibleObject that is providing the method's implementation, re-emit // the call on the instance to trigger the implementation from the previously // added extension, and then restore things by re-adding the current extension. // It's complicated, but it works. // We need to determine the name of the extension. Because PHP 5.2 is // missing get_called_class(), we have to look it up in the backtrace $backtrace = debug_backtrace(); $klass = get_class($backtrace[0]['object']); // Perform the routine described above... $this->object->disable_pre_hooks($method); $this->object->disable_post_hooks($method); $this->object->disable_mixin($method, $klass); // Call anchor $args = func_get_args(); // Remove $method parameter array_shift($args); $retval = $this->object->call_method($method, $args); // Re-enable hooks $this->object->enable_pre_hooks($method); $this->object->enable_post_hooks($method); $this->object->enable_mixin($method, $klass); return $retval; }