Changeset 5019

Show
Ignore:
Timestamp:
10/02/08 00:06:24 (3 months ago)
Author:
jwage
Message:

[1.1] fixes #1409 fixes #1436 Fixed unlink() and link() to not delete relationships by default until record is saved

Location:
branches/1.1
Files:
5 modified

Legend:

Unmodified
Added
Removed
  • branches/1.1/lib/Doctrine/Connection/UnitOfWork.php

    r4988 r5019  
    9292                    $pendingDelete->delete(); 
    9393                } 
     94                 
     95                foreach ($record->getPendingUnlinks() as $alias => $ids) { 
     96                    if ( ! $ids) { 
     97                        $record->unlinkInDb($alias, array()); 
     98                    } else { 
     99                        $record->unlinkInDb($alias, array_keys($ids)); 
     100                    } 
     101                } 
     102                $record->resetPendingUnlinks(); 
    94103 
    95104                $record->getTable()->getRecordListener()->postSave($event); 
  • branches/1.1/lib/Doctrine/Record.php

    r4995 r5019  
    137137     */ 
    138138    protected $_pendingDeletes = array(); 
     139     
     140    /** 
     141     * Array of pending un links in format alias => keys to be executed after save 
     142     * 
     143     * @var array $_pendingUnlinks 
     144     */ 
     145    protected $_pendingUnlinks = array(); 
    139146 
    140147    /** 
     
    12151222    { 
    12161223        return $this->_pendingDeletes; 
     1224    } 
     1225 
     1226    /** 
     1227     * Get pending un links array 
     1228     * 
     1229     * @return array $pendingUnlinks 
     1230     */ 
     1231    public function getPendingUnlinks() 
     1232    { 
     1233        return $this->_pendingUnlinks; 
     1234    } 
     1235 
     1236    /** 
     1237     * Reset pending un links array 
     1238     * 
     1239     * @return void 
     1240     */ 
     1241    public function resetPendingUnlinks() 
     1242    { 
     1243        $this->_pendingUnlinks = array(); 
    12171244    } 
    12181245 
     
    14811508            if ($key == '_identifier') { 
    14821509                $refresh = true; 
    1483                 $this->assignIdentifier((array) $value); 
     1510                $this->assignIdentifier($value); 
    14841511                continue; 
    14851512            } 
     
    15131540            if ($key == '_identifier') { 
    15141541                $refresh = true; 
    1515                 $this->assignIdentifier((array) $value); 
     1542                $this->assignIdentifier($value); 
    15161543                continue; 
    15171544            } 
    15181545 
    15191546            if ($deep && $this->getTable()->hasRelation($key)) { 
    1520                 $this->get($key)->synchronizeWithArray($value); 
     1547                if (isset($value['_identifiers']) && is_array($value['_identifiers'])) { 
     1548                    $this->unlink($key, array(), false); 
     1549                    foreach ($value['_identifiers'] as $id => $exists) { 
     1550                        if ($exists) { 
     1551                            $this->link($key, $id, false); 
     1552                        } 
     1553                    } 
     1554                } else { 
     1555                    $this->$key->synchronizeWithArray($value); 
     1556                } 
    15211557            } else if ($this->getTable()->hasField($key)) { 
    15221558                $this->set($key, $value); 
     
    15251561 
    15261562        // eliminate relationships missing in the $array 
    1527         foreach ($this->_references as $name => $obj) { 
     1563        foreach ($this->_references as $name => $relation) { 
     1564             
    15281565            if ( ! isset($array[$name])) { 
    15291566                unset($this->$name); 
     
    18721909     * @param string $alias     related component alias 
    18731910     * @param array $ids        the identifiers of the related records 
     1911     * @param boolean $now      wether or not to execute now or set pending 
    18741912     * @return Doctrine_Record  this object 
    18751913     */ 
    1876     public function unlink($alias, $ids = array()) 
     1914    public function unlink($alias, $ids = array(), $now = false) 
    18771915    { 
    18781916        $ids = (array) $ids; 
    18791917 
     1918        if (isset($this->_references[$alias])) { 
     1919            foreach ($this->_references[$alias] as $k => $record) { 
     1920                if (in_array(current($record->identifier()), $ids) || empty($ids)) { 
     1921                    $this->_references[$alias]->remove($k); 
     1922                } 
     1923            } 
     1924            $this->_references[$alias]->takeSnapshot(); 
     1925        } 
     1926        if (!$this->exists() || $now === false) { 
     1927            if (count($ids)) { 
     1928                foreach ($ids as $id) { 
     1929                    $this->_pendingUnlinks[$alias][$id] = true; 
     1930                } 
     1931            } else { 
     1932                $this->_pendingUnlinks[$alias] = false; 
     1933            } 
     1934            return $this; 
     1935        } else { 
     1936            return $this->unlinkInDb($alias, $ids); 
     1937        } 
     1938    } 
     1939 
     1940    public function unlinkInDb($alias, $ids = array()) 
     1941    { 
    18801942        $q = new Doctrine_Query(); 
    1881  
    18821943        $rel = $this->getTable()->getRelation($alias); 
    18831944 
     
    19041965            $q->execute(); 
    19051966        } 
    1906         if (isset($this->_references[$alias])) { 
    1907             foreach ($this->_references[$alias] as $k => $record) { 
    1908                 if (in_array(current($record->identifier()), $ids)) { 
    1909                     $this->_references[$alias]->remove($k); 
    1910                 } 
    1911             } 
    1912             $this->_references[$alias]->takeSnapshot(); 
    1913         } 
    19141967        return $this; 
    19151968    } 
     
    19211974     * @param string $alias     related component alias 
    19221975     * @param array $ids        the identifiers of the related records 
     1976     * @param boolean $now      wether or not to execute now or set pending 
    19231977     * @return Doctrine_Record  this object 
    19241978     */ 
    1925     public function link($alias, $ids) 
     1979    public function link($alias, $ids, $now = false) 
    19261980    { 
    19271981        $ids = (array) $ids; 
     
    19301984            return $this; 
    19311985        } 
    1932  
     1986        if (!$this->exists() || $now === false) { 
     1987            $relTable = $this->getTable()->getRelation($alias)->getTable(); 
     1988            $records = $relTable->createQuery() 
     1989                ->whereIn($relTable->getIdentifier(), $ids) 
     1990                ->execute(); 
     1991            foreach ($records as $record) { 
     1992                $this->$alias->add($record); 
     1993            } 
     1994            foreach ($ids as $id) { 
     1995                if (isset($this->_pendingUnlinks[$alias][$id])) { 
     1996                    unset($this->_pendingUnlinks[$alias][$id]); 
     1997                } 
     1998            } 
     1999            return $this; 
     2000        } else { 
     2001            return $this->linkInDb($alias, $ids); 
     2002        } 
     2003    } 
     2004 
     2005    public function linkInDb($alias, $ids) 
     2006    { 
    19332007        $identifier = array_values($this->identifier()); 
    19342008        $identifier = array_shift($identifier); 
     
    19832057 
    19842058            $q->execute(); 
    1985  
    19862059        } 
    19872060 
    19882061        return $this; 
    19892062    } 
    1990  
    19912063 
    19922064    /** 
  • branches/1.1/tests/RecordTestCase.php

    r4830 r5019  
    798798        $this->assertEqual($user->Group[2]->id, 2); 
    799799 
    800         $user->unlink('Group', array($group1->id, $group2->id)); 
     800        $user->unlink('Group', array($group1->id, $group2->id), true); 
    801801        $this->assertEqual($user->Group->count(), 1); 
    802802 
     
    814814 
    815815        // REPLACING OLD ASSOCIATED REFERENCE 
    816         $user->unlink('Group', 3);  // you MUST first unlink old relationship 
     816        $user->unlink('Group', 3, true);  // you MUST first unlink old relationship 
    817817        $user->Group[1] = $group1; 
    818818        $user->Group[0] = $group2; 
     
    824824        $this->assertEqual($user->Group[1]->identifier(), $group1->identifier()); 
    825825 
    826         $user->unlink('Group'); 
     826        $user->unlink('Group', array(), true); 
    827827        $user->save(); 
    828828        $user->free(); 
  • branches/1.1/tests/RelationTestCase.php

    r3884 r5019  
    6868        $this->assertEqual($user->Group->count(), 3); 
    6969         
    70         $user->unlink('Group', array(2, 3, 4)); 
     70        $user->unlink('Group', array(2, 3, 4), true); 
    7171         
    7272        $this->assertEqual($user->Group->count(), 0); 
     
    9393        $this->assertEqual($user->Phonenumber->count(), 3); 
    9494         
    95         $user->unlink('Phonenumber', array(1, 2, 3)); 
     95        $user->unlink('Phonenumber', array(1, 2, 3), true); 
    9696         
    9797        $this->assertEqual($user->Phonenumber->count(), 0); 
  • branches/1.1/tests/Ticket/1436TestCase.php

    r4948 r5019  
    6363    public function testSynchronizeAddMNLinks() 
    6464    { 
    65         $user = Doctrine_Query::create()->from('User u, u.Group g')->fetchOne(); 
     65        $user = Doctrine_Query::create()->from('User u')->fetchOne(); 
    6666        $userArray = array( 
    6767            'Group' => array( 
    6868                '_identifiers' => array( 
    69                     $this->group_one, 
    70                     $this->group_two, 
    71                     $this->group_three 
     69                    $this->group_one => true, 
     70                    $this->group_two => true, 
     71                    $this->group_three => false 
    7272                    ) 
    7373            )); 
    7474 
    7575        $user->synchronizeWithArray($userArray); 
    76         $this->assertEqual($user->Group->count(), 3); 
    77         $user->save(); 
    78         $user->free(); 
    7976 
     77        try { 
     78          $user->save(); 
     79        } catch (Exception $e ) { 
     80          $this->fail("Failed saving with " . $e->getMessage()); 
     81        } 
     82    } 
     83    public function testSynchronizeAddMNLinksAfterSave() 
     84    { 
    8085        $user = Doctrine_Query::create()->from('User u, u.Group g')->fetchOne(); 
    81         $this->assertEqual($user->Group->count(), 3); 
    8286        $this->assertEqual($user->Group[0]->name, 'Group One'); 
    8387        $this->assertEqual($user->Group[1]->name, 'Group Two'); 
    84         $this->assertEqual($user->Group[2]->name, 'Group Three'); 
     88        $this->assertTrue(!isset($user->Group[2])); 
    8589    } 
    86  
    87     public function testSynchronizeRemoveMNLinks() 
     90    public function testSynchronizeChangeMNLinks() 
    8891    { 
    8992        $user = Doctrine_Query::create()->from('User u, u.Group g')->fetchOne(); 
     
    9194            'Group' => array( 
    9295                '_identifiers' => array( 
    93                     $this->group_three 
     96                    $this->group_one => false, 
     97                    $this->group_two => true, 
     98                    $this->group_three => true 
    9499                    ) 
    95100            )); 
    96  
     101         
    97102        $user->synchronizeWithArray($userArray); 
    98         $this->assertEqual($user->Group->count(), 1); 
    99         $user->save(); 
    100         $user->free(); 
    101  
    102         $user = Doctrine_Query::create()->from('User u, u.Group g')->fetchOne(); 
    103         $this->assertEqual($user->Group->count(), 1); 
    104         $this->assertEqual($user->Group[0]->name, 'Group Three'); 
    105     } 
    106  
    107     public function testSynchronizeRemoveAllLinks() 
    108     { 
    109         $user = Doctrine_Query::create()->from('User u, u.Group g')->fetchOne(); 
    110         $userArray = array( 
    111             'Group' => array( 
    112                 '_identifiers' => array() 
    113             )); 
    114  
    115         $user->synchronizeWithArray($userArray); 
    116         $this->assertEqual($user->Group->count(), 0); 
    117         $user->save(); 
    118         $user->free(); 
    119  
    120         $user = Doctrine_Query::create()->from('User u, u.Group g')->fetchOne(); 
    121         $this->assertEqual($user->Group->count(), 0); 
    122     } 
    123  
    124     public function testSynchronizeDoesNotPersistUntilSave() 
    125     { 
    126         $user = Doctrine_Query::create()->from('User u, u.Group g')->fetchOne(); 
    127         $userArray = array( 
    128             'Group' => array( 
    129                 '_identifiers' => array( 
    130                     $this->group_three 
    131                     ) 
    132             )); 
    133  
     103         
     104        $this->assertTrue(!isset($user->Groups)); 
     105         
    134106        try { 
    135             $user->synchronizeWithArray($userArray); 
    136             $this->pass(); 
    137         } catch (Exception $e) { 
    138             $this->fail($e->getMessage()); 
     107          $user->save(); 
     108        } catch (Exception $e ) { 
     109          $this->fail("Failed saving with " . $e->getMessage()); 
    139110        } 
    140111         
    141         $this->assertEqual($user->Group->count(), 1); 
    142         $user->free(); 
    143  
    144         $user = Doctrine_Query::create()->from('User u, u.Group g')->fetchOne(); 
    145         $this->assertEqual($user->Group->count(), 0); 
     112        $user->refresh(); 
     113        $user->loadReference('Group'); 
     114         
     115        $this->assertEqual($user->Group[0]->name, 'Group Two'); 
     116        $this->assertEqual($user->Group[1]->name, 'Group Three'); 
     117        $this->assertTrue(!isset($user->Group[2])); 
     118    } 
     119    public function testSynchronizeMNRecordsDontDeleteAfterUnlink() 
     120    { 
     121        $group = Doctrine::getTable('Group')->find($this->group_one); 
     122         
     123        $this->assertTrue(!empty($group)); 
     124        $this->assertEqual($group->name, 'Group One'); 
    146125    } 
    147126}