-
-
Save adamculp/1a17b42eb9914a30155072e65599ff21 to your computer and use it in GitHub Desktop.
Working example of PHP Doctrine 2 ManyToOne with corresponding OneToMany association.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace Banks\Entity; | |
use Doctrine\ORM\Mapping as ORM; | |
use Doctrine\Common\Collections\ArrayCollection; | |
use Doctrine\Common\Collections\Collection; | |
use Branches\Entity\Branch; | |
/** | |
* https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/basic-mapping.html | |
* | |
* @ORM\Entity | |
* @ORM\Table(name="banks") | |
**/ | |
class Bank | |
{ | |
/** | |
* @ORM\Id | |
* @ORM\Column(type="integer", name="id", nullable=false) | |
* @ORM\GeneratedValue(strategy="IDENTITY") | |
*/ | |
protected $id; | |
/** | |
* A Bank could have Many Branches | |
* | |
* @ORM\OneToMany(targetEntity="Branches\Entity\Branch", mappedBy="bank") | |
* | |
*/ | |
protected $branches; | |
/** | |
* @ORM\Column(type="string", nullable=true) | |
*/ | |
protected $name; | |
/** | |
* @param bool $recursive | |
* @return array|mixed | |
*/ | |
public function getBank($recursive=true) | |
{ | |
return [ | |
'id' => $this->id, | |
'name' => $this->name, | |
'branches' => $this->withBranches($recursive), | |
]; | |
} | |
/** | |
* @param $recursive | |
* @return mixed|array | |
*/ | |
public function withBranches($recursive) | |
{ | |
if ($recursive) { | |
return $this->getBranches()->map(function(Branch $branch) { | |
// clears $branch->institution() to prevent infinite recursion | |
$branch->resetBank(); | |
return $branch->getBranch(); | |
})->toArray(); | |
} | |
return ['see_parent']; | |
} | |
/** | |
* Institution constructor. | |
*/ | |
public function __construct() | |
{ | |
$this->branches = new ArrayCollection(); | |
} | |
/** | |
* @return Collection | |
*/ | |
public function getBranches(): Collection | |
{ | |
return $this->branches; | |
} | |
use Branches\Entity\Branch; | |
// ... Other getter/setters removed | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace Branches\Entity; | |
use Doctrine\ORM\Mapping as ORM; | |
/** | |
* https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/basic-mapping.html | |
* | |
* @ORM\Entity | |
* @ORM\Table(name="branches") | |
**/ | |
class Branch | |
{ | |
/** | |
* @ORM\Id | |
* @ORM\Column(type="integer", nullable=false) | |
* @ORM\GeneratedValue(strategy="IDENTITY") | |
*/ | |
protected $id; | |
/** | |
* A Branch has one Bank | |
* | |
* @ORM\ManyToOne(targetEntity="Banks\Entity\Bank", inversedBy="branches") | |
* @ORM\JoinColumn(name="bank_id", referencedColumnName="id") | |
*/ | |
protected $bank; | |
/** | |
* @ORM\Column(type="integer", nullable=false) | |
*/ | |
protected $bank_id; | |
/** | |
* @ORM\Column(type="string", nullable=true) | |
*/ | |
protected $name; | |
/** | |
* @param bool $recursive | |
* @return array | |
*/ | |
public function getBranch($recursive=true) | |
{ | |
return [ | |
'id' => $this->id, | |
'bank_id' => $this->bank_id, | |
'name' => $this->name, | |
// getBank returns an object which json_encode can't handle | |
'bank' => $this->getBank($recursive) | |
]; | |
} | |
/** | |
* @param $recursive | |
* @return mixed|array | |
*/ | |
public function getBank($recursive) | |
{ | |
if ($recursive) | |
{ | |
return $this->bank; | |
} | |
return $this->bank->getBank(false); | |
} | |
public function setBank($bank) | |
{ | |
$this->bank = $bank; | |
} | |
/** | |
* Resets Bank Object in ManyToOne relationship to prevent infinite recursion | |
* | |
*/ | |
public function resetBank(): void | |
{ | |
$this->bank = ['see_parent']; | |
} | |
// ... Other getter/setters removed | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace Branches\Handler; | |
use Psr\Container\ContainerInterface; | |
use Zend\Expressive\Helper\ServerUrlHelper; | |
use Doctrine\ORM\EntityManager; | |
use Doctrine\ORM\EntityRepository; | |
use Branches\Entity\Branch; | |
use Banks\Entity\Bank; | |
use Psr\Http\Message\ResponseInterface; | |
use Psr\Http\Message\ServerRequestInterface; | |
use Psr\Http\Server\RequestHandlerInterface; | |
use Zend\Diactoros\Response\JsonResponse; | |
use Zend\Diactoros\Response\RedirectResponse; | |
class BranchesCreateHandler implements RequestHandlerInterface | |
{ | |
protected $entityManager; | |
protected $entityRepository; | |
protected $entity; | |
protected $urlHelper; | |
protected $bank; | |
/** | |
* the following are gained from the referring Factory, which gets them this way | |
* | |
* $entityManager = $container->get(EntityManager::class); | |
* $urlHelper = $container->get(ServerUrlHelper::class); | |
* $entityManager->getConfiguration()->addEntityNamespace('Branch', 'Branches\Entity'); | |
* $entityRepository = $entityManager->getRepository('Branch:Branch'); | |
* $entity = new Branch(); | |
* $bank = new Bank(); | |
*/ | |
public function __construct( | |
EntityManager $entityManager, | |
EntityRepository $entityRepository, | |
Branch $entity, | |
ServerUrlHelper $urlHelper, | |
Bank $bank, | |
) { | |
$this->entityManager = $entityManager; | |
$this->entityRepository = $entityRepository; | |
$this->entity = $entity; | |
$this->urlHelper = $urlHelper; | |
$this->bank = $bank; | |
} | |
/** | |
* {@inheritDoc} | |
*/ | |
public function handle(ServerRequestInterface $request) : ResponseInterface | |
{ | |
$body = $request->getParsedBody()['Request']['Branches']; | |
if (empty($body)) { | |
// redirect to '/branches/' as a GET request | |
return new RedirectResponse('/branches/'); | |
} | |
$this->entity->setBank($bank); | |
$this->entity->setBankId($body['bank_id']); | |
$this->entity->setName($body['name']); | |
$this->entity->setAddress1($body['address1']); | |
$this->entity->setAddress2($body['address2']); | |
$this->entity->setCity($body['city']); | |
$this->entity->setZoneId($body['zone_id']); | |
$this->entity->setZip($body['zip']); | |
$this->entity->setEmail($body['email']); | |
$this->entity->setPhone($body['phone']); | |
$this->entity->setIsActive(1); | |
$this->entity->setCreated(new \DateTime("now")); | |
$this->entity->setModified(new \DateTime("now")); | |
// if I print_r($this->entity) I see all fields just set above. | |
try { | |
$this->entityManager->persist($this->entity); | |
$this->entityManager->flush(); | |
// receiving error saying "Integrity constraint violation: 1048 Column 'bank_id' cannot be null" | |
// if I remove the ManyToOne association on bank_id in Branch Entity, all works fine | |
} catch(\Exception $e) { | |
echo $e->getMessage(); | |
} | |
$result['Result']['Branches'] = $this->entity->getBranch(); | |
if (empty($result['Result']['Branches'])) { | |
echo "Not Created.\n"; | |
exit(1); | |
} | |
return new JsonResponse($result, 201); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace Branches\Handler; | |
use Zend\Expressive\Helper\ServerUrlHelper; | |
use Doctrine\ORM\EntityManager; | |
use Doctrine\ORM\EntityRepository; | |
use Psr\Http\Message\ResponseInterface; | |
use Psr\Http\Message\ServerRequestInterface; | |
use Psr\Http\Server\RequestHandlerInterface; | |
use Zend\Diactoros\Response\JsonResponse; | |
class BranchesViewHandler implements RequestHandlerInterface | |
{ | |
protected $entityManager; | |
protected $entityRepository; | |
protected $urlHelper; | |
public function __construct( | |
EntityManager $entityManager, | |
EntityRepository $entityRepository | |
) { | |
$this->entityManager = $entityManager; | |
$this->entityRepository = $entityRepository; | |
} | |
/** | |
* {@inheritDoc} | |
*/ | |
public function handle(ServerRequestInterface $request) : ResponseInterface | |
{ | |
// returns entityRepository with Configuration and Repository already set for Entity | |
$return = $this->entityRepository->find($request->getAttribute('id')); | |
if ($return === null) { | |
echo "Not found.\n"; | |
exit(1); | |
} | |
$result['Result']['Branch'] = $return->getBranch(false); | |
return new JsonResponse($result); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment