📄 abstract.php
字号:
* Saves the properties to the database. * * This performs an intelligent insert/update, and reloads the * properties with fresh data from the table on success. * * @return mixed The primary key value(s), as an associative array if the * key is compound, or a scalar if the key is single-column. */ public function save() { /** * If the _cleanData array is empty, * this is an INSERT of a new row. * Otherwise it is an UPDATE. */ if (empty($this->_cleanData)) { return $this->_doInsert(); } else { return $this->_doUpdate(); } } /** * @return mixed The primary key value(s), as an associative array if the * key is compound, or a scalar if the key is single-column. */ protected function _doInsert() { /** * A read-only row cannot be saved. */ if ($this->_readOnly === true) { require_once 'Zend/Db/Table/Row/Exception.php'; throw new Zend_Db_Table_Row_Exception('This row has been marked read-only'); } /** * Run pre-INSERT logic */ $this->_insert(); /** * Execute the INSERT (this may throw an exception) */ $data = array_intersect_key($this->_data, $this->_modifiedFields); $primaryKey = $this->_getTable()->insert($data); /** * Normalize the result to an array indexed by primary key column(s). * The table insert() method may return a scalar. */ if (is_array($primaryKey)) { $newPrimaryKey = $primaryKey; } else { $newPrimaryKey = array(current((array) $this->_primary) => $primaryKey); } /** * Save the new primary key value in _data. The primary key may have * been generated by a sequence or auto-increment mechanism, and this * merge should be done before the _postInsert() method is run, so the * new values are available for logging, etc. */ $this->_data = array_merge($this->_data, $newPrimaryKey); /** * Run post-INSERT logic */ $this->_postInsert(); /** * Update the _cleanData to reflect that the data has been inserted. */ $this->_refresh(); return $primaryKey; } /** * @return mixed The primary key value(s), as an associative array if the * key is compound, or a scalar if the key is single-column. */ protected function _doUpdate() { /** * A read-only row cannot be saved. */ if ($this->_readOnly === true) { require_once 'Zend/Db/Table/Row/Exception.php'; throw new Zend_Db_Table_Row_Exception('This row has been marked read-only'); } /** * Get expressions for a WHERE clause * based on the primary key value(s). */ $where = $this->_getWhereQuery(false); /** * Run pre-UPDATE logic */ $this->_update(); /** * Compare the data to the modified fields array to discover * which columns have been changed. */ $diffData = array_intersect_key($this->_data, $this->_modifiedFields); /** * Were any of the changed columns part of the primary key? */ $pkDiffData = array_intersect_key($diffData, array_flip((array)$this->_primary)); /** * Execute cascading updates against dependent tables. * Do this only if primary key value(s) were changed. */ if (count($pkDiffData) > 0) { $depTables = $this->_getTable()->getDependentTables(); if (!empty($depTables)) { $db = $this->_getTable()->getAdapter(); $pkNew = $this->_getPrimaryKey(true); $pkOld = $this->_getPrimaryKey(false); foreach ($depTables as $tableClass) { try { @Zend_Loader::loadClass($tableClass); } catch (Zend_Exception $e) { require_once 'Zend/Db/Table/Row/Exception.php'; throw new Zend_Db_Table_Row_Exception($e->getMessage()); } $t = new $tableClass(array('db' => $db)); $t->_cascadeUpdate($this->getTableClass(), $pkOld, $pkNew); } } } /** * Execute the UPDATE (this may throw an exception) * Do this only if data values were changed. * Use the $diffData variable, so the UPDATE statement * includes SET terms only for data values that changed. */ if (count($diffData) > 0) { $this->_getTable()->update($diffData, $where); } /** * Run post-UPDATE logic. Do this before the _refresh() * so the _postUpdate() function can tell the difference * between changed data and clean (pre-changed) data. */ $this->_postUpdate(); /** * Refresh the data just in case triggers in the RDBMS changed * any columns. Also this resets the _cleanData. */ $this->_refresh(); /** * Return the primary key value(s) as an array * if the key is compound or a scalar if the key * is a scalar. */ $primaryKey = $this->_getPrimaryKey(true); if (count($primaryKey) == 1) { return current($primaryKey); } return $primaryKey; } /** * Deletes existing rows. * * @return int The number of rows deleted. */ public function delete() { $where = $this->_getWhereQuery(); /** * Execute pre-DELETE logic */ $this->_delete(); /** * Execute cascading deletes against dependent tables */ $depTables = $this->_getTable()->getDependentTables(); if (!empty($depTables)) { $db = $this->_getTable()->getAdapter(); $pk = $this->_getPrimaryKey(); foreach ($depTables as $tableClass) { try { @Zend_Loader::loadClass($tableClass); } catch (Zend_Exception $e) { require_once 'Zend/Db/Table/Row/Exception.php'; throw new Zend_Db_Table_Row_Exception($e->getMessage()); } $t = new $tableClass(array('db' => $db)); $t->_cascadeDelete($this->getTableClass(), $pk); } } /** * Execute the DELETE (this may throw an exception) */ $result = $this->_getTable()->delete($where); /** * Execute post-DELETE logic */ $this->_postDelete(); /** * Reset all fields to null to indicate that the row is not there */ $this->_data = array_combine( array_keys($this->_data), array_fill(0, count($this->_data), null) ); return $result; } /** * Returns the column/value data as an array. * * @return array */ public function toArray() { return $this->_data; } /** * Sets all data in the row from an array. * * @param array $data * @return Zend_Db_Table_Row_Abstract Provides a fluent interface */ public function setFromArray(array $data) { foreach ($data as $columnName => $value) { $this->$columnName = $value; } return $this; } /** * Refreshes properties from the database. * * @return void */ public function refresh() { return $this->_refresh(); } /** * Retrieves an instance of the parent table. * * @return Zend_Db_Table_Abstract */ protected function _getTable() { if (!$this->_connected) { require_once 'Zend/Db/Table/Row/Exception.php'; throw new Zend_Db_Table_Row_Exception('Cannot save a Row unless it is connected'); } return $this->_table; } /** * Retrieves an associative array of primary keys. * * @param bool $useDirty * @return array */ protected function _getPrimaryKey($useDirty = true) { if (!is_array($this->_primary)) { require_once 'Zend/Db/Table/Row/Exception.php'; throw new Zend_Db_Table_Row_Exception("The primary key must be set as an array"); } $primary = array_flip($this->_primary); if ($useDirty) { $array = array_intersect_key($this->_data, $primary); } else { $array = array_intersect_key($this->_cleanData, $primary); } if (count($primary) != count($array)) { require_once 'Zend/Db/Table/Row/Exception.php'; throw new Zend_Db_Table_Row_Exception("The specified Table '$this->_tableClass' does not have the same primary key as the Row"); } return $array; } /** * Constructs where statement for retrieving row(s). * * @param bool $useDirty * @return array */ protected function _getWhereQuery($useDirty = true) { $where = array(); $db = $this->_getTable()->getAdapter(); $primaryKey = $this->_getPrimaryKey($useDirty); $info = $this->_getTable()->info(); $metadata = $info[Zend_Db_Table_Abstract::METADATA]; // retrieve recently updated row using primary keys $where = array(); foreach ($primaryKey as $columnName => $value) { $column = $db->quoteIdentifier($columnName, true); $type = $metadata[$columnName]['DATA_TYPE']; $where[] = $db->quoteInto("$column = ?", $value, $type); } return $where; } /** * Refreshes properties from the database. * * @return void */ protected function _refresh() { $where = $this->_getWhereQuery(); $row = $this->_getTable()->fetchRow($where); if (null === $row) { require_once 'Zend/Db/Table/Row/Exception.php'; throw new Zend_Db_Table_Row_Exception('Cannot refresh row as parent is missing'); } $this->_data = $row->toArray(); $this->_cleanData = $this->_data; $this->_modifiedFields = array(); } /** * Allows pre-insert logic to be applied to row. * Subclasses may override this method. * * @return void */ protected function _insert() { }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -