Zend Framework 2 - Hydrator-Strategie für Lehre Beziehung nicht funktioniert
Wie bereits erwähnt hier ich Baue eine custom Hydratation Strategie für den Umgang mit meinen verwandten Objekten in einem select-Feld in ein Formular.
Meine form sieht wie folgt aus:
$builder = new AnnotationBuilder($entityManager);
$form = $builder->createForm(new MyEntity());
$form->add(new MyFieldSet());
$hydrator = new ClassMethodsHydrator();
$hydrator->addStrategy('my_attribute', new MyHydrationStrategy());
$form->setHydrator($hydrator);
$form->get('my_attribute')->setValueOptions(
$entityManager->getRepository('SecEntity\Entity\SecEntity')->fetchAllAsArray()
);
, Wenn ich einen neuen MyEntity
über die addAction
funktioniert alles Super.
Schrieb ich fetchAllAsArray()
zu füllen meine selectbox. Es lebt in meinem SecEntityRepository:
public function fetchAllAsArray() {
$objects = $this->createQueryBuilder('s')
->add('select', 's.id, s.name')
->add('orderBy', 's.name ASC')
->getQuery()
->getResult();
$list = array();
foreach($objects as $obj) {
$list[$obj['id']] = $obj['name'];
}
return $list;
}
Aber in der Bearbeiten-Fall die extract()
- Funktion funktioniert nicht. Ich bin nicht an dem Punkt, wo ich etwas sehen, von hydrate()
also lasse ich es für jetzt.
Meine hydrator-Strategie sieht wie folgt aus:
class MyHydrationStrategy extends DefaultStrategy
{
public function extract($value) {
print_r($value);
$result = array();
foreach ($value as $instance) {
print_r($instance);
$result[] = $instance->getId();
}
return $result;
}
public function hydrate($value) {
...
}
Das problem ist wie folgt:
Fatal error: Call to a member function getId() on a non-object
Den print_r($value)
gibt loads von Zeug, beginnend mit
DoctrineORMModule\Proxy__CG__\SecEntity\Entity\SecEntity Objekt
folgenden mit etwas über BasicEntityPersister und irgendwo in dem Chaos sind meine referenzierten Entitäten.
Den print_r($instance)
druckt nichts. Es ist einfach nur leer. Daher denke ich mal ist die Fehlermeldung echt... aber warum kann ich nicht Durchlaufen diese Objekte?
Irgendwelche Ideen?
Edit:
Bezug zu @Sam:
Mein Attribut in der Entität:
/**
* @ORM\ManyToOne(targetEntity="Path/To/Entity", inversedBy="whatever")
* @ORM\JoinColumn(name="attribute_id", referencedColumnName="id")
* @Form\Attributes({"type":"hidden"})
*
*/
protected $attribute;
Meine neue selectbox:
$form->add(array(
'name' => 'attribute',
'type' => 'DoctrineModule\Form\Element\ObjectSelect',
'attributes' => array(
'required' => true
),
'options' => array(
'label' => 'MyLabel',
'object_manager' => $entityManager,
'target_class' => 'Path/To/Entity',
'property' => 'name'
)
));
Meine Letzte Hoffnung ist, dass ich was falsch mache innerhalb der Steuerung. Weder meine selectbox vorausgewählt noch der Wert gespeichert wird...
...
$obj= $this->getEntityManager()->find('Path/To/Entity', $id);
$builder = new \MyEnity\MyFormBuilder();
$form = $builder->newForm($this->getEntityManager());
$form->setBindOnValidate(false);
$form->bind($obj);
$form->setData($obj->getArrayCopy());
$request = $this->getRequest();
if ($request->isPost()) {
$form->setData($request->getPost());
if ($form->isValid()) {
$form->bindValues();
$this->getEntityManager()->flush();
return $this->redirect()->toRoute('entity');
}
}
Gut 🙂 ich bin nicht Ihrer Existenz bewusst, muss ich zugeben... kennst du ein gutes tutorial für? wenn Sie arbeiten, es ist eine legitime Antwort auf diese Frage würde ich sagen 😉
InformationsquelleAutor Ron | 2013-01-03
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich noch nicht gekommen, um zu schreiben, das tutorial für :S
Ich weiß nicht, ob das funktioniert mit dem annotationbuilder aber! Als die
DoctrineModule\Form\Element\ObjectSelect
Bedürfnisse derEntityManager
zu arbeiten. Die Optionen für dieObjectSelect
sind wie folgt:In diesem Fall nutze ich
$this->getEntityManager()
. Ich richte diese Abhängigkeit beim Aufruf der form aus der Dienste-Verwalter. Ich persönlich Tue immer das, von FactoryClasses. Meine FormFactory sieht wie folgt aus:Und dies ist, wo alle die Magie passiert. Magie, das ist auch für deinen anderen Thread hier auf DAMIT. Zuerst schnappe ich mir den
EntityManager
. Dann habe ich meine form, und injizieren Sie die Abhängigkeit für dieEntityManager
. Ich Tue dies mit meinem eigenen Formular haben, schreiben Sie, und verwenden Sie eine Set-Funktion zu injizieren, dieEntityManager
.Nächstes erstelle ich eine
ClassMethodsHydrator
und fügen Sie zweiHydrationStrategies
. Ich persönlich beantragen müssen, müssen diejenigen, die Strategien für die einzelnenObjectSelect
-Element. Sie kann nicht tun dies auf Ihrer Seite. Versuchen Sie, um zu sehen, ob es funktioniert, ohne es zuerst!Danach erstelle ich den
DoctrineEntity
-Hydrator, injizieren dieEntityManager
sowie meine benutzerdefinierteClassMethodsHydrator
. Auf diese Weise die Strategien werden einfach Hinzugefügt werden.Den rest sollte selbsterklärend sein (trotz der deutschen Klassennamen :D)
Warum die Notwendigkeit für Strategien
Imo, dadurch fehlt etwas von der
DoctrineEntity
derzeit, aber die Dinge sind noch in einem frühen Stadium. Und einmal DoctrineModule-Ausgabe#106 wird sein Leben, die Dinge werden sich auch wieder ändern, wahrscheinlich macht es mehr komfortabel.Strategie sieht wie folgt aus:
So, wenn die
$value
ist nicht numerisch oder null, d.h.: es sollte ein Objekt sein, rufen wir dengetId()
Funktion. Ich persönlich denke, es ist eine gute Idee zu geben, jedes Element seine eigene Strategie, aber wenn Sie sicher sind, dass Sie nicht brauchen, die Strategie zu ändern, zu einem späteren Zeitpunkt können Sie erstellen eine Globale Strategie für mehrere Elemente wieDefaultGetIdStrategy
oder so etwas.All dies ist im Grunde die gute Arbeit Michael Gallego aka Bakura! In den Fall, Sie fallen durch das IRC, nur umarmen, ihn noch einmal 😉
Bearbeiten Eine zusätzliche Ressource mit einem Blick in die Zukunft - aktualisiert hydrator-docs für sehr wahrscheinlich, bald werden enthalten, pull-request
POST
UND in form nach der Bindung! indem Sie Ihre Strategie nicht ändern... Ideen?Tun Sie die ID in deinem Formular? Schwer zu sagen, ohne den ganzen code sonst.
merkwürdigste Sache überhaupt! Ich veränderte meine controller und legen Sie die formElement-Wert manuell auf meine
id
und nachbindValues()
auch manuell auf mein Objekt wieder. es funktioniert...! sehr hässlich, aber bis dahin bin ich leider gezwungen, zu bleiben, um zu dieser Lösung.Sry für meine späte Antwort, eingeschlafen 😀
bindValues()
, Holen Sie das Objekt aus der DB, wie$ent = $repo->find(1)
und dann binden Sie es auf das Formular über$form->bind($ent)
. Mit dieser get-Funktion wird aufgerufen werden, füllen der form mit identischen Elementnamen.so würde ich ändern zu müssen meine getter/setter für die FKs zu handhaben id-vs-Objekt?
InformationsquelleAutor Sam