Chcę wykonać głęboką kopię/klon zapisu doktryny w projekcie symfony. Istniejąca kopia ($ deep) -method nie działa poprawnie z $ deep = true.głęboka kopia zapisu doktrynowego
Na przykład rzućmy okiem na lekcję w klasie. Ta lekcja ma datę początkową i końcową, a pomiędzy nimi jest kilka przerw. Ta klasa jest w buildung.
Przerwa lekcyjna to relacja jeden-do-wielu, więc podczas lekcji może być dużo przerw. Budowanie lekcji jest relacją wiele do jednego, więc lekcja może być tylko w JEDNYM budynku.
Jeśli chcę zrobić kopię pokoju, należy również skopiować kopie. Budynek powinien pozostać taki sam (brak kopii tutaj).
Znalazłem kilka przykładów w Internecie, które tworzą klasę PHP, która rozciąga się od sfDoctrineRecord i nadpisuje metodę copy.
Co próbowałem było:
class BaseDoctrineRecord extends sfDoctrineRecord {
public function copy($deep = false) {
$ret = parent::copy(false);
if (!$deep)
return $ret;
// ensure to have loaded all references (unlike Doctrine_Record)
foreach ($this->getTable()->getRelations() as $name => $relation) {
// ignore ONE sides of relationships
if ($relation->getType() == Doctrine_Relation::MANY) {
if (empty($this->$name))
$this->loadReference($name);
// do the deep copy
foreach ($this->$name as $record)
$ret->{$name}[] = $record->copy($deep);
}
}
return $ret;
}
}
Teraz to powoduje wystąpienie błędu: Doctrine_Connection_Mysql_Exception: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '2-1' for key 'PRIMARY'
Więc muszę „null” Identyfikator nowego rekordu ($ ret), ponieważ to powinno być nowy rekord. Gdzie i jak mogę/powinienem to zrobić?
UPDATE: Błąd jest mocowana za pomocą następującego kodu:
class BaseDoctrineRecord extends sfDoctrineRecord {
public function copy($deep = false) {
$ret = parent::copy(false);
if($this->Table->getIdentifierType() === Doctrine_Core::IDENTIFIER_AUTOINC) {
$id = $this->Table->getIdentifier();
$this->_data[$id] = null;
}
if(!$deep) {
return $ret;
}
// ensure to have loaded all references (unlike Doctrine_Record)
foreach($this->getTable()->getRelations() as $name => $relation) {
// ignore ONE sides of relationships
if($relation->getType() == Doctrine_Relation::MANY) {
if(empty($this->$name)) {
$this->loadReference($name);
}
// do the deep copy
foreach($this->$name as $record) {
$ret->{$name}[] = $record->copy($deep);
}
}
}
return $ret;
}
}
Ale to nie działa dobrze. W lekcji DoctrineCollection-> Breaks wszystkie nowe przerwy są w porządku. Ale nie są one zapisane w bazie danych. Chcę skopiować nauczkę i dodać 7 dni na to czas:
foreach($new_shift->Breaks as $break) {
$break->start_at = $this->addOneWeek($break->start_at);
$break->end_at = $this->addOneWeek($break->end_at);
$break->save();
}
Więc jak widać, przerwy są zapisywane, ale wydaje się, że nie są w db.
Napisałem konkretną metodę do moich potrzeb. Ogólne rozwiązanie powoduje więcej problemów, niż rozwiązuje ... Cóż, obecnie nie rozwiązuje żadnego problemu :) – hering