doktrin kaydının derin kopyalama

0 Cevap php

I want to make a deep copy/clone of a doctrine record in a symfony project. The existing copy($deep)-method doesn't work properly with $deep=true.

Bir örnek için en sınıf ders bir göz atalım. Bu ders başlangıç ​​ve bitiş tarihi vardır ve aralarında birkaç sonları vardır. Bu sınıf bir Buildung olduğunu.

lesson-break is a one-to-many relationship, so a lot of breaks could be inside a lesson. lesson-building is a many-to-one relationship, so a lesson could only be in ONE Building.

Ben oda bir kopyasını yapmak istiyorsanız sonları da kopyalanması gerekir. Bina (burada hiçbir kopyasını) aynı kalmalıdır.

Ben sfDoctrineRecord uzanan ve kopya yöntemini geçersiz kılan bir PHP sınıfı oluşturmak web üzerinde bazı örnekler buldum.

Ne denedim oldu:

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

Şimdi bu bir başarısızlık neden olur: Doctrine_Connection_Mysql_Exception: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '2-1' for key 'PRIMARY'

Bu yeni bir rekor olmalı çünkü Yani ben yeni bir rekor ($ ret) ve id "null" gerekir. Nerede ve nasıl / ben bunu yapmalıyım ki?

UPDATE: The error is fixed with following code:

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

But it doesn't work well. In the DoctrineCollection lesson->Breaks all new breaks are fine. But they aren't saved in the database. I want to copy a lesson and add 7 days to it's time:

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

Eğer tatili kaydedilir, görmek, ama göründüğü gibi Yani db değildir.

0 Cevap