How to make doctrine and ZF2 form annotations work together
doctrine-orm, php, zend-framework2
Solution
Solved it!
It's necessary to register autoload namespace, since Doctrine uses its own autoload mechanism. I needed to make use of AnnnotationRegistry and its registerAutoloadNamespace method. It accepts the namespace containing annotations (Zend\Form\Annotation) and the base directory of the root namespace (in my case C:\Program Files\Zend\Apache2\htdocs\CommunicationApp\vendor\ZF2\library), as its parameters. More information here: Doctrine Annotations
My Entity now looks like this (and works with both Doctrine and Zend Form annotations):
namespace Users\Entity;
use Doctrine\ORM\Mapping as ORM;
use Zend\Form\Annotation;
use Doctrine\Common\Annotations\AnnotationRegistry;
$pathToZF2Library = __DIR__.'/../../../../../vendor/ZF2/library/';
AnnotationRegistry::registerAutoloadNamespace('Zend\Form\Annotation', $pathToZF2Library);
/**
* @ORM\Entity
* @ORM\Table(name="users")
* @Annotation\Name("Users")
*/
class User {
/**
* @ORM\Id @ORM\Column(type="integer")
* @ORM\GeneratedValue
* @Annotation\Type("Zend\Form\Element\Hidden")
*/
protected $id;
/**
* @ORM\Column(type="string")
* @Annotation\Type("Zend\Form\Element\Text")
* @Annotation\Filter({"name":"StripTags"})
* @Annotation\Filter({"name":"StringTrim"})
* @Annotation\Validator({"name":"Alnum", "options": {"allowWhiteSpace":"true"}})
* @Annotation\Validator({"name":"StringLength", "options": {"min":"2", "max":"25"}})
* @Annotation\Options({"label":"Username: "})
*/
protected $username;
/**
* @ORM\Column(type="string")
* @Annotation\Type("Zend\Form\Element\Email")
* @Annotation\Filter({"name":"StripTags"})
* @Annotation\Filter({"name":"StringTrim"})
* @Annotation\Validator({"name":"EmailAddress", "options": {"domain":"true"}})
* @Annotation\Options({"label":"Email: "})
*/
protected $email;
/**
* @ORM\Column(type="string")
* @Annotation\Type("Zend\Form\Element\Password")
* @Annotation\Filter({"name":"StripTags"})
* @Annotation\Filter({"name":"StringTrim"})
* @Annotation\Options({"label":"Password: "})
*/
protected $password;
public function __construct() {
}
public function setId($id) {
$this->id = $id;
}
public function getId() {
return $this->id;
}
public function setUsername($username) {
$this->username = $username;
}
public function getUsername() {
return $this->username;
}
public function setEmail($email) {
$this->email = $email;
}
public function getEmail() {
return $this->email;
}
public function setPassword($password) {
$this->password = $password;
}
public function getPassword() {
return $this->password;
}
}
Problem
I am trying to make Doctrine annotations work together with ZF2 Form annotations. My controller looks like this: ``` namespace Users\Controller; use Zend\Mvc\Controller\AbstractActionController; use Zend\View\Model\ViewModel; //Doctrine Stuff use Doctrine\ORM\Tools\Setup; use Doctrine\ORM\EntityManager; use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator; use DoctrineORMModule\Form\Annotation\AnnotationBuilder; class IndexController extends AbstractActionController { private $entityManager; public function getEntityManager() { if (!$this->entityManager) { $paths = array ( realpath ( dirname ( __FILE__ ) . '/../Entity' ) ); $isDevMode = true; // the connection configuration $dbParams = array ( 'driver' => 'pdo_mysql', 'user' => 'root', 'password' => 'my_password', 'dbname' => 'commapp' ); $config = Setup::createAnnotationMetadataConfiguration ( $paths, $isDevMode, null, null, false ); $this->entityManager = EntityManager::create ( $dbParams, $config ); } return $this->entityManager; } public function updateAction() { $entityManager = $this->getEntityManager (); $repository = $entityManager->getRepository ( 'Users\Entity\User' ); $id = $this->params ()->fromRoute ( 'id' ); $user = $repository->findOneBy (array('id' => $id)); $builder = new AnnotationBuilder ( $entityManager ); $form = $builder->createForm ( $user ); $form->setHydrator ( new DoctrineHydrator ( $entityManager, 'Users\Entity\User' ) ); $form->bind ( $user ); $send = new Element ( 'send' ); $send->setValue ( 'Create' ); // submit $send->setAttributes ( array ('type' => 'submit' ) ); $form->add ( $send ); $view = new ViewModel (); $view->setVariable ( 'form', $form ); $view->setVariable ( 'id', $id ); return $view; } } ``` and the Entity looks like this: ``` namespace Users\Entity; use Doctrine\ORM\Mapping as ORM; use Zend\Form\Annotation as Form; /** * @ORM\Entity * @ORM\Table(name="users") * @Form\Name("user") * @Form\Hydrator("Zend\Stdlib\Hydrator\ObjectProperty") */ class User { /** * @var int * @ORM\Id @ORM\Column(name="id", type="integer") * @ORM\GeneratedValue * @Form\Exclude() */ protected $id; /** * @var string * @ORM\Column(name="user_name", type="string", length=255, nullable=false) * @Form\Filter({"name":"StringTrim"}) * @Form\Validator({"name":"StringLength", "options":{"min":1, "max":25}}) * @Form\Validator({"name":"Regex", "options":{"pattern":"/^[a-zA-Z][a-zA-Z0-9_-]{0,24}$/"}}) * @Form\Attributes({"type":"text"}) * @Form\Options({"label":"Username:"}) */ protected $username; /** * @var string * @ORM\Column(name="email", type="string", length=255, unique=true) * @Form\Type("Zend\Form\Element\Email") * @Form\Options({"label":"Your email address:"}) */ protected $email; } ``` When I enter the URL commapp/users/index/update/1, I should get the form displayed for the user of ID=1. Instead I get the `Doctrine\Common\Annotations\AnnotationException`, with message: `[Semantical Error] The annotation "@Zend\Form\Annotation\Name" in class Users\Entity\User does not exist, or could not be auto-loaded.` I can't see what I'm doing wrong...?