From e7e0415b60b08089b902e5c135e79e08fa451642 Mon Sep 17 00:00:00 2001 From: Andrey Kutejko Date: Sat, 8 Jun 2013 20:19:25 +0300 Subject: [PATCH] magic-call-based record listeners --- ipf/orm.php | 1 - ipf/orm/configurable.php | 36 ----- ipf/orm/connection/unitofwork.php | 22 +-- ipf/orm/hydrator.php | 15 +- ipf/orm/import/builder.php | 3 +- ipf/orm/manager.php | 1 - ipf/orm/query/abstract.php | 2 +- ipf/orm/record/abstract.php | 17 --- ipf/orm/record/listener.php | 22 --- ipf/orm/record/listener/chain.php | 151 -------------------- ipf/orm/record/listener/interface.php | 19 --- ipf/orm/table.php | 10 ++ ipf/orm/template/listener/orderable.php | 2 +- ipf/orm/template/listener/sluggable.php | 4 +- ipf/orm/template/listener/timestampable.php | 4 +- ipf/orm/template/orderable.php | 7 +- ipf/orm/template/sluggable.php | 2 +- ipf/orm/template/timestampable.php | 4 +- 18 files changed, 38 insertions(+), 284 deletions(-) delete mode 100644 ipf/orm/record/listener.php delete mode 100644 ipf/orm/record/listener/chain.php delete mode 100644 ipf/orm/record/listener/interface.php diff --git a/ipf/orm.php b/ipf/orm.php index 348c236..42a4e96 100644 --- a/ipf/orm.php +++ b/ipf/orm.php @@ -131,7 +131,6 @@ final class IPF_ORM { const ATTR_CACHE_LIFESPAN = 151; const ATTR_RESULT_CACHE_LIFESPAN = 151; const ATTR_LOAD_REFERENCES = 153; - const ATTR_RECORD_LISTENER = 154; const ATTR_THROW_EXCEPTIONS = 155; const ATTR_DEFAULT_PARAM_NAMESPACE = 156; const ATTR_QUERY_CACHE = 157; diff --git a/ipf/orm/configurable.php b/ipf/orm/configurable.php index c7ca7fb..98bf3a1 100644 --- a/ipf/orm/configurable.php +++ b/ipf/orm/configurable.php @@ -72,7 +72,6 @@ abstract class IPF_ORM_Configurable extends IPF_ORM_Locator_Injectable case IPF_ORM::ATTR_EXPORT: case IPF_ORM::ATTR_DECIMAL_PLACES: case IPF_ORM::ATTR_LOAD_REFERENCES: - case IPF_ORM::ATTR_RECORD_LISTENER: case IPF_ORM::ATTR_THROW_EXCEPTIONS: case IPF_ORM::ATTR_DEFAULT_PARAM_NAMESPACE: case IPF_ORM::ATTR_AUTOLOAD_TABLE_CLASSES: @@ -183,41 +182,6 @@ abstract class IPF_ORM_Configurable extends IPF_ORM_Locator_Injectable return true; } - public function addRecordListener($listener, $name = null) - { - if ( ! isset($this->attributes[IPF_ORM::ATTR_RECORD_LISTENER]) || - ! ($this->attributes[IPF_ORM::ATTR_RECORD_LISTENER] instanceof IPF_ORM_Record_Listener_Chain)) { - - $this->attributes[IPF_ORM::ATTR_RECORD_LISTENER] = new IPF_ORM_Record_Listener_Chain(); - } - $this->attributes[IPF_ORM::ATTR_RECORD_LISTENER]->add($listener, $name); - - return $this; - } - - public function getRecordListener() - { - if ( ! isset($this->attributes[IPF_ORM::ATTR_RECORD_LISTENER])) { - if (isset($this->parent)) { - return $this->parent->getRecordListener(); - } - return null; - } - return $this->attributes[IPF_ORM::ATTR_RECORD_LISTENER]; - } - - public function setRecordListener($listener) - { - if ( ! ($listener instanceof IPF_ORM_Record_Listener_Interface) - && ! ($listener instanceof IPF_ORM_Overloadable) - ) { - throw new IPF_ORM_Exception("Couldn't set eventlistener. Record listeners should implement either IPF_ORM_Record_Listener_Interface or IPF_ORM_Overloadable"); - } - $this->attributes[IPF_ORM::ATTR_RECORD_LISTENER] = $listener; - - return $this; - } - public function getAttribute($attribute) { if (is_string($attribute)) { diff --git a/ipf/orm/connection/unitofwork.php b/ipf/orm/connection/unitofwork.php index 887fa5d..d4e85b9 100644 --- a/ipf/orm/connection/unitofwork.php +++ b/ipf/orm/connection/unitofwork.php @@ -21,7 +21,7 @@ class IPF_ORM_Connection_UnitOfWork extends IPF_ORM_Connection_Module if ($record->isValid()) { $event = new IPF_ORM_Event($record, IPF_ORM_Event::RECORD_SAVE); $record->preSave($event); - $record->getTable()->getRecordListener()->preSave($event); + $record->getTable()->notifyRecordListeners('preSave', $event); $state = $record->state(); if ( ! $event->skipOperation) { @@ -44,7 +44,7 @@ class IPF_ORM_Connection_UnitOfWork extends IPF_ORM_Connection_Module $pendingDelete->delete(); } - $record->getTable()->getRecordListener()->postSave($event); + $record->getTable()->notifyRecordListeners('postSave', $event); $record->postSave($event); } else { $conn->transaction->addInvalid($record); @@ -81,7 +81,7 @@ class IPF_ORM_Connection_UnitOfWork extends IPF_ORM_Connection_Module $record->preSave($event); - $record->getTable()->getRecordListener()->preSave($event); + $record->getTable()->notifyRecordListeners('preSave', $event); if ( ! $event->skipOperation) { switch ($record->state()) { @@ -99,7 +99,7 @@ class IPF_ORM_Connection_UnitOfWork extends IPF_ORM_Connection_Module } } - $record->getTable()->getRecordListener()->postSave($event); + $record->getTable()->notifyRecordListeners('postSave', $event); $record->postSave($event); } @@ -320,7 +320,7 @@ class IPF_ORM_Connection_UnitOfWork extends IPF_ORM_Connection_Module { $event = new IPF_ORM_Event($record, IPF_ORM_Event::RECORD_DELETE); $record->preDelete($event); - $record->getTable()->getRecordListener()->preDelete($event); + $record->getTable()->notifyRecordListeners('preDelete', $event); return $event->skipOperation; } @@ -329,7 +329,7 @@ class IPF_ORM_Connection_UnitOfWork extends IPF_ORM_Connection_Module { $event = new IPF_ORM_Event($record, IPF_ORM_Event::RECORD_DELETE); $record->postDelete($event); - $record->getTable()->getRecordListener()->postDelete($event); + $record->getTable()->notifyRecordListeners('postDelete', $event); } public function saveAll() @@ -351,7 +351,7 @@ class IPF_ORM_Connection_UnitOfWork extends IPF_ORM_Connection_Module $event = new IPF_ORM_Event($record, IPF_ORM_Event::RECORD_UPDATE); $record->preUpdate($event); $table = $record->getTable(); - $table->getRecordListener()->preUpdate($event); + $table->notifyRecordListeners('preUpdate', $event); if ( ! $event->skipOperation) { $identifier = $record->identifier(); @@ -366,7 +366,7 @@ class IPF_ORM_Connection_UnitOfWork extends IPF_ORM_Connection_Module $record->assignIdentifier(true); } - $table->getRecordListener()->postUpdate($event); + $table->notifyRecordListeners('postUpdate', $event); $record->postUpdate($event); @@ -379,7 +379,7 @@ class IPF_ORM_Connection_UnitOfWork extends IPF_ORM_Connection_Module $event = new IPF_ORM_Event($record, IPF_ORM_Event::RECORD_INSERT); $record->preInsert($event); $table = $record->getTable(); - $table->getRecordListener()->preInsert($event); + $table->notifyRecordListeners('preInsert', $event); if ( ! $event->skipOperation) { if ($table->getOption('joinedParents')) { @@ -392,7 +392,7 @@ class IPF_ORM_Connection_UnitOfWork extends IPF_ORM_Connection_Module } $table->addRecord($record); - $table->getRecordListener()->postInsert($event); + $table->notifyRecordListeners('postInsert', $event); $record->postInsert($event); return true; @@ -665,4 +665,4 @@ class IPF_ORM_Connection_UnitOfWork extends IPF_ORM_Connection_Module return $dataSet; } -} \ No newline at end of file +} diff --git a/ipf/orm/hydrator.php b/ipf/orm/hydrator.php index 51c4fb0..70a17ce 100644 --- a/ipf/orm/hydrator.php +++ b/ipf/orm/hydrator.php @@ -26,8 +26,6 @@ class IPF_ORM_Hydrator extends IPF_ORM_Hydrator_Abstract $isSimpleQuery = count($this->_queryComponents) <= 1; // Holds the resulting hydrated data structure $result = array(); - // Holds hydration listeners that get called during hydration - $listeners = array(); // Lookup map to quickly discover/lookup existing records in the result $identifierMap = array(); // Holds for each component the last previously seen element in the result set @@ -48,7 +46,6 @@ class IPF_ORM_Hydrator extends IPF_ORM_Hydrator_Abstract // Initialize foreach ($this->_queryComponents as $dqlAlias => $data) { $componentName = $data['table']->getComponentName(); - $listeners[$componentName] = $data['table']->getRecordListener(); $identifierMap[$dqlAlias] = array(); $prev[$dqlAlias] = null; $idTemplate[$dqlAlias] = ''; @@ -71,7 +68,7 @@ class IPF_ORM_Hydrator extends IPF_ORM_Hydrator_Abstract // Ticket #1115 (getInvoker() should return the component that has addEventListener) $event->setInvoker($table); $event->set('data', $rowData[$rootAlias]); - $listeners[$componentName]->preHydrate($event); + $table->notifyRecordListeners('preHydrate', $event); $index = false; @@ -79,7 +76,7 @@ class IPF_ORM_Hydrator extends IPF_ORM_Hydrator_Abstract if ($isSimpleQuery || ! isset($identifierMap[$rootAlias][$id[$rootAlias]])) { $element = $driver->getElement($rowData[$rootAlias], $componentName); $event->set('data', $element); - $listeners[$componentName]->postHydrate($event); + $table->notifyRecordListeners('postHydrate', $event); // do we need to index by a custom field? if ($field = $this->_getCustomIndexField($rootAlias)) { @@ -113,7 +110,7 @@ class IPF_ORM_Hydrator extends IPF_ORM_Hydrator_Abstract $table = $map['table']; $componentName = $table->getComponentName(); $event->set('data', $data); - $listeners[$componentName]->preHydrate($event); + $table->notifyRecordListeners('preHydrate', $event); $parent = $map['parent']; $relation = $map['relation']; @@ -137,7 +134,7 @@ class IPF_ORM_Hydrator extends IPF_ORM_Hydrator_Abstract if ( ! $indexExists || ! $indexIsValid) { $element = $driver->getElement($data, $componentName); $event->set('data', $element); - $listeners[$componentName]->postHydrate($event); + $table->notifyRecordListeners('postHydrate', $event); if ($field = $this->_getCustomIndexField($dqlAlias)) { if (isset($prev[$parent][$relationAlias][$element[$field]])) { @@ -165,7 +162,7 @@ class IPF_ORM_Hydrator extends IPF_ORM_Hydrator_Abstract // [FIX] Tickets #1205 and #1237 $event->set('data', $element); - $listeners[$componentName]->postHydrate($event); + $table->notifyRecordListeners('postHydrate', $event); $prev[$parent][$relationAlias] = $element; } @@ -271,4 +268,4 @@ class IPF_ORM_Hydrator extends IPF_ORM_Hydrator_Abstract { return isset($this->_queryComponents[$alias]['map']) ? $this->_queryComponents[$alias]['map'] : null; } -} \ No newline at end of file +} diff --git a/ipf/orm/import/builder.php b/ipf/orm/import/builder.php index 0b9ee0c..ff9a5cb 100644 --- a/ipf/orm/import/builder.php +++ b/ipf/orm/import/builder.php @@ -503,10 +503,9 @@ class IPF_ORM_Import_Builder public function buildListener($listener) { - return PHP_EOL." ".'$this->addListener(new '.$listener.'());'; + return PHP_EOL.' $this->getTable()->listeners[\''.$listener.'\'] = new '.$listener.'();'; } - public function buildAttributes(array $attributes) { $build = PHP_EOL; diff --git a/ipf/orm/manager.php b/ipf/orm/manager.php index a0641aa..4e64efd 100644 --- a/ipf/orm/manager.php +++ b/ipf/orm/manager.php @@ -24,7 +24,6 @@ class IPF_ORM_Manager extends IPF_ORM_Configurable implements Countable, Iterato IPF_ORM::ATTR_RESULT_CACHE => null, IPF_ORM::ATTR_QUERY_CACHE => null, IPF_ORM::ATTR_LOAD_REFERENCES => true, - IPF_ORM::ATTR_RECORD_LISTENER => new IPF_ORM_Record_Listener(), IPF_ORM::ATTR_THROW_EXCEPTIONS => true, IPF_ORM::ATTR_QUERY_LIMIT => IPF_ORM::LIMIT_RECORDS, IPF_ORM::ATTR_IDXNAME_FORMAT => "%s_idx", diff --git a/ipf/orm/query/abstract.php b/ipf/orm/query/abstract.php index 4cc164a..93b52af 100644 --- a/ipf/orm/query/abstract.php +++ b/ipf/orm/query/abstract.php @@ -572,7 +572,7 @@ abstract class IPF_ORM_Query_Abstract $event = new IPF_ORM_Event($record, $callback['const'], $this, $params); $record->$callback['callback']($event); - $table->getRecordListener()->$callback['callback']($event); + $table->notifyRecordListeners($callback['callback'], $event); } } diff --git a/ipf/orm/record/abstract.php b/ipf/orm/record/abstract.php index 5dde97c..2bef507 100644 --- a/ipf/orm/record/abstract.php +++ b/ipf/orm/record/abstract.php @@ -17,23 +17,6 @@ abstract class IPF_ORM_Record_Abstract extends IPF_ORM_Access return $this->_table; } - public function addListener($listener, $name = null) - { - $this->_table->addRecordListener($listener, $name = null); - return $this; - } - - public function getListener() - { - return $this->_table->getRecordListener(); - } - - public function setListener($listener) - { - $this->_table->setRecordListener($listener); - return $this; - } - public function index($name, array $definition = array()) { if ( ! $definition) { diff --git a/ipf/orm/record/listener.php b/ipf/orm/record/listener.php deleted file mode 100644 index 03a31e7..0000000 --- a/ipf/orm/record/listener.php +++ /dev/null @@ -1,22 +0,0 @@ -_listeners[] = $listener; - } else { - $this->_listeners[$name] = $listener; - } - } - - public function get($key) - { - if ( ! isset($this->_listeners[$key])) { - return null; - } - return $this->_listeners[$key]; - } - - public function set($key, $listener) - { - $this->_listeners[$key] = $listener; - } - - public function preSerialize(IPF_ORM_Event $event) - { - foreach ($this->_listeners as $listener) { - $listener->preSerialize($event); - } - } - - public function postSerialize(IPF_ORM_Event $event) - { - foreach ($this->_listeners as $listener) { - $listener->preSerialize($event); - } - } - - public function preUnserialize(IPF_ORM_Event $event) - { - foreach ($this->_listeners as $listener) { - $listener->preUnserialize($event); - } - } - - public function postUnserialize(IPF_ORM_Event $event) - { - foreach ($this->_listeners as $listener) { - $listener->postUnserialize($event); - } - } - - public function preDqlSelect(IPF_ORM_Event $event) - { - foreach ($this->_listeners as $listener) { - $listener->preDqlSelect($event); - } - } - - public function preSave(IPF_ORM_Event $event) - { - foreach ($this->_listeners as $listener) { - $listener->preSave($event); - } - } - - public function postSave(IPF_ORM_Event $event) - { - foreach ($this->_listeners as $listener) { - $listener->postSave($event); - } - } - - public function preDqlDelete(IPF_ORM_Event $event) - { - foreach ($this->_listeners as $listener) { - $listener->preDqlDelete($event); - } - } - - public function preDelete(IPF_ORM_Event $event) - { - foreach ($this->_listeners as $listener) { - $listener->preDelete($event); - } - } - - public function postDelete(IPF_ORM_Event $event) - { - foreach ($this->_listeners as $listener) { - $listener->postDelete($event); - } - } - - public function preDqlUpdate(IPF_ORM_Event $event) - { - foreach ($this->_listeners as $listener) { - $listener->preDqlUpdate($event); - } - } - - public function preUpdate(IPF_ORM_Event $event) - { - foreach ($this->_listeners as $listener) { - $listener->preUpdate($event); - } - } - - public function postUpdate(IPF_ORM_Event $event) - { - foreach ($this->_listeners as $listener) { - $listener->postUpdate($event); - } - } - - public function preInsert(IPF_ORM_Event $event) - { - foreach ($this->_listeners as $listener) { - $listener->preInsert($event); - } - } - - public function postInsert(IPF_ORM_Event $event) - { - foreach ($this->_listeners as $listener) { - $listener->postInsert($event); - } - } - - public function preHydrate(IPF_ORM_Event $event) - { - foreach ($this->_listeners as $listener) { - $listener->preHydrate($event); - } - } - - public function postHydrate(IPF_ORM_Event $event) - { - foreach ($this->_listeners as $listener) { - $listener->postHydrate($event); - } - } -} diff --git a/ipf/orm/record/listener/interface.php b/ipf/orm/record/listener/interface.php deleted file mode 100644 index d3e98aa..0000000 --- a/ipf/orm/record/listener/interface.php +++ /dev/null @@ -1,19 +0,0 @@ -_conn = $conn; @@ -1416,4 +1418,12 @@ class IPF_ORM_Table extends IPF_ORM_Configurable implements Countable throw new IPF_ORM_Exception(sprintf('Unknown method %s::%s', get_class($this), $method)); } + + public function notifyRecordListeners($method, $event) + { + foreach ($this->listeners as $listener) + if (is_callable(array($listener, $method))) + $listener->$method($event); + } } + diff --git a/ipf/orm/template/listener/orderable.php b/ipf/orm/template/listener/orderable.php index 8b210e1..2ff3372 100644 --- a/ipf/orm/template/listener/orderable.php +++ b/ipf/orm/template/listener/orderable.php @@ -1,6 +1,6 @@ columnName = $options['name']; } - public function getColumnName() - { - return $this->columnName; - } - public function setTableDefinition() { $this->hasColumn($this->columnName, 'integer', null, ''); - $this->addListener(new IPF_ORM_Template_Listener_Orderable($this->columnName)); + $this->getTable()->listeners['Orderable_'.$this->columnName] = new IPF_ORM_Template_Listener_Orderable($this->columnName); } } diff --git a/ipf/orm/template/sluggable.php b/ipf/orm/template/sluggable.php index 6812c69..35e5700 100644 --- a/ipf/orm/template/sluggable.php +++ b/ipf/orm/template/sluggable.php @@ -30,7 +30,7 @@ class IPF_ORM_Template_Sluggable extends IPF_ORM_Template $this->index($this->_options['indexName'], array('fields' => $indexFields, 'type' => 'unique')); } - $this->addListener(new IPF_ORM_Template_Listener_Sluggable($this->_options)); + $this->getTable()->listeners['Sluggable_'.print_r($this->_options, true)] = new IPF_ORM_Template_Listener_Sluggable($this->_options); } } diff --git a/ipf/orm/template/timestampable.php b/ipf/orm/template/timestampable.php index aae6814..9a5b9e7 100644 --- a/ipf/orm/template/timestampable.php +++ b/ipf/orm/template/timestampable.php @@ -28,6 +28,6 @@ class IPF_ORM_Template_Timestampable extends IPF_ORM_Template{ if( ! $this->_options['updated']['disabled']) { $this->hasColumn($this->_options['updated']['name'], $this->_options['updated']['type'], null, $this->_options['updated']['options']); } - $this->addListener(new IPF_ORM_Template_Listener_Timestampable($this->_options)); + $this->getTable()->listeners['Timestampable_'.print_r($this->_options, true)] = new IPF_ORM_Template_Listener_Timestampable($this->_options); } -} \ No newline at end of file +} -- 2.49.0