Tüm ilişkileri ile bir Doktrini nesne kopyalayın

5 Cevap php

Onun bütün ilişkileri ile bir rekor kopyalamak istediğiniz.

Ben ile çalışıyorum:

$o = Doctrine::getTable('Table')->Find(x); 
$copy = $object->copy();
$relations = $o->getRelations();

foreach ($relations as $name => $relation) {
  $copy->$relation = $object->$relation->copy();
} 

$copy->save();

Bu kod çalışır değil, ama yolda olduğunu düşünüyorum.

5 Cevap

Ben derin kopyalama işlevi düzgün çalışması için asla olabilir.

Ben elle Bu gibi benim modellerinden biri için derin bir kopyalama işlevi kodlu

public function copyAndSave ()
{
    $filters = array('id', 'created');

    $survey = $this->copy();

    $survey->Survey_Entries = new Doctrine_Collection("Survey_Model_Entry");
    $survey->Assignment_Assignments = new Doctrine_Collection("Assignment_Model_Assignment");
    $survey->Survey_Questions = new Doctrine_Collection("Survey_Model_Question");

    $survey->save();

    foreach ($this->Survey_Questions as $question)
    {
        $answers = $question->Survey_Answers;
        $newQuestion = $question->copy();
        $newQuestion->survey_surveys_id = $survey->id;
        $newQuestion->save();
        $newAnswers = new Doctrine_Collection("Survey_Model_Answer");

        foreach($answers as $answer)
        {
            $answer = $answer->copy();
            $answer->save();
            $answer->survey_questions_id = $newQuestion->id;
            $newAnswers->add($answer);
        }
        $newQuestion->Survey_Answers = $newAnswers;

        $survey->Survey_Questions->add($newQuestion);
    }
    return $survey->save();
}

Sen hakkında okumak copy() here. Olabilir Bu isteğe bağlı bir parametre alır $deep:

$deep
whether to duplicates the objects targeted by the relations

Bu yüzden

$copy = $object->copy(true);

bunu yapmak gerekir.

Üzgünüm, bu konuyu diriltmeyi ediyorsam ...

Ben bir kopya kayıt ve orijinal referansları korumak için gerektiğinde Geçenlerde bir çözüm arayışı içinde kendimi buldum. Benim için iyi oldu Derin bir kopyasını $record->copy(true) kopyalar referanslar. Bu benim çözüm oldu:

$record = Doctrine_Core::getTable('Foo')->find(1);
$copy = $record->copy();

foreach($record->getTable()->getRelations() as $relation) {
    if ($relation instanceof Doctrine_Relation_Association) {
        $ids = array();

        foreach ($relation->fetchRelatedFor($record) as $r) {    
            $ids[] = $r->getId();
        }

        $copy->link($relation->getAlias(), $ids);
    }
}

if ($copy->isValid()) {
    $copy->save();
}

Bu yardımcı olur umarım :)

Bu i nasıl yapılır, ancak bazı düzeltme gereklidir.

    $table = $entidade->getTable();
    $relations = $table->getRelations();
    foreach($relations as $relation => $data) {
        try {
            $entity->loadReference($relation);
        } catch(Exception $e) {
            die($e->getMessage());
        }
    }

Ben Symfony1.4.1 kullanıyorum ve bu Doktrini 1.2.1 (Bence) kullanır.

Ben zaten var olanı bulduğumda tüm kendim yukarıda olduğu bir işlevi yapmak için çalışıyorlar.

Herhangi bir fonksiyon bu deneyin ve sonuçlarına bakmak:

  $tmp=$this->toArray(TRUE);
  var_dump($tmp);
  $this->refreshRelated();
  $tmp=$this->toArray();
  var_dump($tmp);
  $tmp=$this->toArray(TRUE);
  var_dump($tmp);
  exit();

Ben iki farklı şeyler denemek için gidiyorum:

A/ put $this->refreshRelated() into the constructor of all my model objects. B/ write a function that takes an array depicting the object graph that I want populated. Calling the function refereshRelatedGraph($objectGraphArray). With the right structure of the array (having all the appropriate relation names at each level), I could control which relations get populated and which don't. One use for this is to populate only children, not parent relations. The other is for when a ERD/Schema/ObjectGraph has an element that is 'owned' by more than one object (many to many, other special circumstances that I have), I could control which side of the relationships get pre(non lazy) loaded.