глубокая копия записи доктрины

Я хочу сделать глубокую копию / клон записи доктрины в проекте Symfony. Существующий метод копирования ($ deep) не работает должным образом с $ deep = true.

Для примера рассмотрим урок в классе. У этого урока есть дата начала и окончания, и между ними есть несколько перерывов. Этот класс находится в сложном состоянии.

Перерыв на уроке - это отношения один-ко-многим, поэтому в уроке может быть много перерывов. построение урока - это отношение многих к одному, поэтому урок может быть только в ОДНОМ здании.

Если я хочу сделать копию комнаты, разрывы также должны быть скопированы. Здание должно оставаться прежним (здесь нет копии).

Я нашел несколько примеров в сети, которые создают класс PHP, который выходит из sfDoctrineRecord и переопределяет метод копирования.

Я попытался:

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;
    }
}

Теперь это приводит к сбою: Doctrine_Connection_Mysql_Exception: SQLSTATE [23000]: Нарушение ограничения целостности: 1062 Повторяющаяся запись '2-1' для ключа 'PRIMARY'

Так что мне нужно «обнулить» идентификатор новой записи ($ ret), потому что это должна быть новая запись. Где и как я могу / должен это сделать?

ОБНОВЛЕНИЕ: Ошибка исправлена ​​с помощью следующего кода:

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;
    }
}

Но это не работает хорошо. В уроке DoctrineCollection-> Перерывы все новые перерывы в порядке. Но они не сохраняются в базе данных. Я хочу скопировать урок и добавить к нему 7 дней:

foreach($new_shift->Breaks as $break) {
    $break->start_at = $this->addOneWeek($break->start_at);
    $break->end_at = $this->addOneWeek($break->end_at);
    $break->save();
}

Итак, как вы видите, разрывы сохраняются, но, похоже, их нет в БД.

6
задан Epoc 9 January 2013 в 13:46
поделиться