Changeset 4503

Show
Ignore:
Timestamp:
06/09/08 00:17:53 (13 months ago)
Author:
jwage
Message:

fixes #1075

Location:
branches/0.11
Files:
6 modified

Legend:

Unmodified
Added
Removed
  • branches/0.11/lib/Doctrine/AuditLog.php

    r4252 r4503  
    4141                            'className'     => '%CLASS%Version', 
    4242                            'versionColumn' => 'version', 
     43                            'tableName'     => false, 
    4344                            'generateFiles' => false, 
    4445                            'table'         => false, 
     
    5051    /** 
    5152     * Accepts array of options to configure the AuditLog 
    52      *  
     53     * 
    5354     * @param   array $options An array of options 
    5455     * @return  void 
     
    6061 
    6162    /** 
    62      * Get array of information for the passed record and the specified version 
    63      *  
    64      * @param   Doctrine_Record $record  
    65      * @param   mixed           $version  
    66      * @return  array           An array with version information 
    67      */ 
    68     public function getVersion(Doctrine_Record $record, $version) 
    69     { 
    70         if ( ! $this->_options['auditLog']) { 
    71             throw new Doctrine_Exception('Audit log is turned off, no version history is recorded.'); 
    72         } 
    73  
    74         $className = $this->_options['className']; 
    75  
    76         $q = new Doctrine_Query(); 
    77  
    78         $values = array(); 
    79         foreach ((array) $this->_options['table']->getIdentifier() as $id) { 
    80             $conditions[] = $className . '.' . $id . ' = ?'; 
    81             $values[] = $record->get($id); 
    82         } 
    83  
    84         $where = implode(' AND ', $conditions) . ' AND ' . $className . '.' . $this->_options['versionColumn'] . ' = ?'; 
    85          
    86         $values[] = $version; 
    87  
    88         $q->from($className) 
    89           ->where($where); 
    90  
    91         return $q->execute($values, Doctrine::HYDRATE_ARRAY); 
    92     } 
    93  
    94     /** 
    9563     * Build definition for audit log table 
    96      *  
    97      * @param   Doctrine_Table  $table  
     64     * 
     65     * @param   Doctrine_Table  $table 
    9866     * @return  boolean         true on success otherwise false. 
    9967     */ 
     
    10169    { 
    10270        $name = $this->_options['table']->getComponentName(); 
    103  
    10471        $columns = $this->_options['table']->getColumns(); 
    10572 
     
    11683        $this->hasColumn($this->_options['versionColumn'], 'integer', 8, array('primary' => true)); 
    11784    } 
     85 
     86    /** 
     87     * Get array of information for the passed record and the specified version 
     88     * 
     89     * @param   Doctrine_Record $record 
     90     * @param   mixed           $version 
     91     * @return  array           An array with version information 
     92     */ 
     93    public function getVersion(Doctrine_Record $record, $version) 
     94    { 
     95        $className = $this->_options['className']; 
     96 
     97        $q = new Doctrine_Query(); 
     98 
     99        $values = array(); 
     100        foreach ((array) $this->_options['table']->getIdentifier() as $id) { 
     101            $conditions[] = $className . '.' . $id . ' = ?'; 
     102            $values[] = $record->get($id); 
     103        } 
     104 
     105        $where = implode(' AND ', $conditions) . ' AND ' . $className . '.' . $this->_options['versionColumn'] . ' = ?'; 
     106 
     107        $values[] = $version; 
     108 
     109        $q->from($className) 
     110          ->where($where); 
     111 
     112        return $q->execute($values, Doctrine::HYDRATE_ARRAY); 
     113    } 
     114 
     115    /** 
     116     * Get the highest version number for a given Doctrine_Record 
     117     * 
     118     * @param Doctrine_Record $record 
     119     * @return Integer $versionnumber 
     120     */ 
     121    public function getMaxVersion(Doctrine_Record $record) 
     122    { 
     123        $className = $this->_options['className']; 
     124        $select = 'MAX(' . $className . '.' . $this->_options['versionColumn'] . ') max_version'; 
     125 
     126        foreach ((array) $this->_options['table']->getIdentifier() as $id) { 
     127            $conditions[] = $className . '.' . $id . ' = ?'; 
     128            $values[] = $record->get($id); 
     129        } 
     130 
     131        $q = Doctrine_Query::create() 
     132                ->select($select) 
     133                ->from($className) 
     134                ->where(implode(' AND ',$conditions)); 
     135 
     136        $result = $q->execute($values, Doctrine::HYDRATE_ARRAY); 
     137 
     138        return isset($result[0]['max_version']) ? $result[0]['max_version']:0; 
     139    } 
    118140} 
  • branches/0.11/lib/Doctrine/AuditLog/Listener.php

    r4252 r4503  
    9191    { 
    9292        if ($this->_auditLog->getOption('auditLog')) { 
    93             $class = $this->_auditLog->getOption('className'); 
     93                $className = $this->_auditLog->getOption('className'); 
     94                $versionColumn = $this->_auditLog->getOption('versionColumn'); 
     95                $event->getInvoker()->set($versionColumn, null); 
    9496 
    95             $record  = $event->getInvoker(); 
     97                $q = Doctrine_Query::create(); 
     98                foreach ((array) $this->_auditLog->getOption('table')->getIdentifier() as $id) { 
     99                    $conditions[] = 'obj.' . $id . ' = ?'; 
     100                    $values[] = $event->getInvoker()->get($id); 
     101                } 
     102 
     103                $rows = $q->delete($className) 
     104                                          ->from($className.' obj') 
     105                                          ->where(implode(' AND ',$conditions)) 
     106                                          ->execute($values); 
     107 
     108                if ( ! count($rows)){ 
     109                   throw new Doctrine_Record_Exception('Can not delete Versions!',Doctrine::ERR_CANNOT_DELETE); 
     110                } 
     111        } 
     112    } 
     113   
     114    /** 
     115     * Pre update event hook for inserting new version record 
     116     * 
     117     * @param  Doctrine_Event $event 
     118     * @return void 
     119     */ 
     120    public function preUpdate(Doctrine_Event $event) 
     121    { 
     122        if ($this->_auditLog->getOption('auditLog')) { 
     123            $class  = $this->_auditLog->getOption('className'); 
     124            $record = $event->getInvoker(); 
    96125 
    97126            $versionColumn = $this->_auditLog->getOption('versionColumn'); 
    98             $version = $record->get($versionColumn); 
    99127 
    100             $record->set($versionColumn, ++$version); 
     128            $record->set($versionColumn, $this->_getNextVersion($record)); 
    101129 
    102130            $version = new $class(); 
     
    107135 
    108136    /** 
    109      * Pre update event hook for inserting new version record 
     137     * Get the next version for the audit log 
    110138     * 
    111      * @param  Doctrine_Event $event  
    112      * @return void 
     139     * @param Doctrine_Record $record  
     140     * @return integer $nextVersion 
    113141     */ 
    114     public function preUpdate(Doctrine_Event $event) 
     142    protected function _getNextVersion(Doctrine_Record $record) 
    115143    { 
    116         if ($this->_auditLog->getOption('auditLog')) { 
    117             $class  = $this->_auditLog->getOption('className'); 
    118             $record = $event->getInvoker();  
    119  
    120             $versionColumn = $this->_auditLog->getOption('versionColumn'); 
    121  
    122             $version = $record->get($versionColumn); 
    123  
    124             $record->set($versionColumn, ++$version); 
    125          
    126             $version = new $class(); 
    127             $version->merge($record->toArray()); 
    128             $version->save(); 
    129         } 
     144      if ($this->_auditLog->getOption('auditLog')) { 
     145          return ($this->_auditLog->getMaxVersion($record) + 1); 
     146      } 
    130147    } 
    131148} 
  • branches/0.11/lib/Doctrine/Record.php

    r4487 r4503  
    16801680        return $this->_node; 
    16811681    } 
    1682     /** 
    1683      * revert 
    1684      * reverts this record to given version, this method only works if versioning plugin 
    1685      * is enabled 
    1686      * 
    1687      * @throws Doctrine_Record_Exception    if given version does not exist 
    1688      * @param integer $version      an integer > 1 
    1689      * @return Doctrine_Record      this object 
    1690      */ 
    1691     public function revert($version) 
    1692     { 
    1693         $auditLog = $this->_table->getTemplate('Doctrine_Template_Versionable')->getAuditLog(); 
    1694  
    1695         if ( ! $auditLog->getOption('auditLog')) { 
    1696             throw new Doctrine_Record_Exception('Audit log is turned off, no version history is recorded.'); 
    1697         } 
    1698  
    1699         $data = $auditLog->getVersion($this, $version); 
    1700  
    1701         if ( ! isset($data[0])) { 
    1702             throw new Doctrine_Record_Exception('Version ' . $version . ' does not exist!'); 
    1703         } 
    1704  
    1705         $this->_data = $data[0]; 
    1706  
    1707         return $this; 
    1708     } 
    17091682 
    17101683    public function unshiftFilter(Doctrine_Record_Filter $filter) 
  • branches/0.11/lib/Doctrine/Template/Versionable.php

    r4442 r4503  
    3838     * __construct 
    3939     * 
    40      * @param array $options  
     40     * @param array $options 
    4141     * @return void 
    4242     */ 
     
    7171        return $this->_plugin; 
    7272    } 
     73 
     74     /** 
     75     * revert 
     76     * reverts this record to given version, this method only works if versioning plugin 
     77     * is enabled 
     78     * 
     79     * @throws Doctrine_Record_Exception    if given version does not exist 
     80     * @param integer $version      an integer > 1 
     81     * @return Doctrine_Record      this object 
     82     */ 
     83    public function revert($version) 
     84    { 
     85        $auditLog = $this->_plugin; 
     86 
     87        if ( ! $auditLog->getOption('auditLog')) { 
     88            throw new Doctrine_Record_Exception('Audit log is turned off, no version history is recorded.'); 
     89        } 
     90 
     91        $data = $auditLog->getVersion($this->getInvoker(), $version); 
     92 
     93        if ( ! isset($data[0])) { 
     94            throw new Doctrine_Record_Exception('Version ' . $version . ' does not exist!'); 
     95        } 
     96 
     97        $this->getInvoker()->merge($data[0]); 
     98 
     99 
     100        return $this->getInvoker(); 
     101    } 
    73102} 
  • branches/0.11/tests/AuditLogTestCase.php

    r4232 r4503  
    3131 * @version     $Revision$ 
    3232 */ 
    33 class Doctrine_AuditLog_TestCase extends Doctrine_UnitTestCase  
     33class Doctrine_AuditLog_TestCase extends Doctrine_UnitTestCase 
    3434{ 
    3535 
     
    3838 
    3939    public function prepareTables() 
    40     {  
     40    { 
    4141        $this->profiler = new Doctrine_Connection_Profiler(); 
    4242        $this->conn->addListener($this->profiler); 
    4343        $this->tables = array('VersioningTest', 'VersioningTestVersion', 'VersioningTest2'); 
    44          
     44 
    4545        parent::prepareTables(); 
    4646    } 
     
    5757        $entity->save(); 
    5858        $this->assertEqual($entity->name, 'zYne 2'); 
    59          
     59        $this->assertEqual($entity->version, 2); 
    6060        $this->conn->clear(); 
    6161 
    6262        $entity = $this->conn->getTable('VersioningTest')->find(1); 
    63  
    64         $this->assertEqual($entity->name, 'zYne 2'); 
    65         $this->assertEqual($entity->version, 2); 
    66  
    67         $entity->delete(); 
    68         $this->assertEqual($entity->version, 3); 
    69  
    70         $entity->revert(2); 
    7163 
    7264        $this->assertEqual($entity->name, 'zYne 2'); 
     
    7769        $this->assertEqual($entity->name, 'zYne'); 
    7870        $this->assertEqual($entity->version, 1); 
     71        $entity->save(); // new Version 3 should be created 
     72    } 
    7973 
    80     } 
    81      
    8274    public function testRevertThrowsExceptionForTransientRecords() 
    8375    { 
    8476        $entity = new VersioningTest(); 
    85          
     77 
    8678        try { 
    8779            $entity->revert(1); 
     
    10294        $this->assertTrue($entity->version, 2); 
    10395    } 
     96    public function testTableName() 
     97    { 
     98        $entity = new VersioningTest3(); 
     99        $this->assertEqual($entity->getAuditLog()->getTable()->getTableName(), 'tbl_prefix_comments_version'); 
     100        $this->assertEqual($entity->getAuditLog()->getTable()->getComponentName(), 'VersioningTestClass'); 
     101    } 
     102 
    104103 
    105104    public function testNoAuditLogThrowsExceptions() 
  • branches/0.11/tests/models/VersioningTest.php

    r4232 r4503  
    2525    } 
    2626} 
     27 
     28class VersioningTest3 extends Doctrine_Record  
     29{ 
     30    public function setTableDefinition() 
     31    { 
     32        $this->hasColumn('name', 'string'); 
     33        $this->hasColumn('version', 'integer'); 
     34    } 
     35    public function setUp() 
     36    { 
     37           
     38        $this->actAs('Versionable', array('tableName' =>  'tbl_prefix_comments_version', 
     39                                          'className' =>  'VersioningTestClass')); 
     40 
     41    } 
     42}