Quiero hacer una copia/copia profunda de un registro de doctrina en un proyecto de Symfony. El método de copia existente ($ profundo) no funciona correctamente con $ profundo = verdadero.copia en profundidad del registro de la doctrina
Por ejemplo, echemos un vistazo a una clase de clase. Esta lección tiene una fecha de inicio y finalización y entre ellos hay varios descansos. Este aula está en un buildung.
salto de clase es una relación de uno a varios, por lo que una gran cantidad de descansos pueden ser dentro de una lección. la construcción de lecciones es una relación de varios a uno, por lo que una lección solo podría ser en UN EDIFICIO.
Si quiero hacer una copia de la sala, también se deben copiar los descansos. El edificio debe permanecer igual (no copia aquí).
Encontré algunos ejemplos en la web que crean una clase de PHP que se extiende desde sfDoctrineRecord y anula el método de copia.
Lo que intenté fue:
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;
}
}
Ahora bien, esto hace que en un fracaso: Doctrine_Connection_Mysql_Exception: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '2-1' for key 'PRIMARY'
por lo que necesito "nulo" el ID del nuevo registro ($ ret), ya que esto debe ser una nuevo record. ¿Dónde y cómo podría/debería hacerlo?
ACTUALIZACIÓN: El error se fija con el código siguiente:
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;
}
}
Pero no funciona bien. En la lección de DoctrineCollection-> Rompe todos los descansos nuevos están bien. Pero no se guardan en la base de datos. quiero copiar una lección y añadir 7 días a la misma hora:
foreach($new_shift->Breaks as $break) {
$break->start_at = $this->addOneWeek($break->start_at);
$break->end_at = $this->addOneWeek($break->end_at);
$break->save();
}
Así que como ves, los descansos son salvados, pero parece que no están en el PP.
He escrito un método específico para mis necesidades. La solución genérica produce más problemas de los que resuelve ... Bueno, actualmente no resuelve ningún problema :) – hering