warpsale / ws-apigility-doctrine
Warpsale Doctrine integration with Apigility
dev-master
2015-09-14 18:57 UTC
Requires
- php: >=5.4.0
- doctrine/orm: 2.5.1
- xiag/rql-command: v1.0.1
- xiag/rql-parser: v1.0.1
- zendframework/zend-paginator: 2.5.1
This package is not auto-updated.
Last update: 2025-03-29 21:33:29 UTC
README
Warpsale Doctrine integration with Apigility
Installation (with composer):
- Install Apigility;
- Install Doctrine;
- Install doctrine/doctrine-orm-module;
- Install warpsale/ws-apigility-doctrine.
Setup:
- Copy the "_utils/module/Base" folder to the "/module" folder of Apigility;
- Add the "Base" module to the "/config/modules.config.php" Apigility file;
- Append to the "/config/autoload/local.php" Apigility file:
'doctrine' => array( 'connection' => array( 'orm_default' => array( 'driverClass' => 'Doctrine\\DBAL\\Driver\\PDOPgSql\\Driver', 'params' => array( 'host' => 'hostname', 'port' => '5432', 'user' => 'username', 'password' => 'password', 'dbname' => 'database', ), ), ), 'hydrators' => [ 'initializers' => [ 'Base\V1\Model\BaseHydratorInitializer', ], ],
- Create a new API (Geo, for example).
- Create a new REST Service (Region, for example)
- Create the folder "Model" inside the "/module/Geo/src/Geo/V1" Apigility folder and Copy your Doctrine Entity Files. Region.php example:
<?php namespace Geo\V1\Model; use Doctrine\ORM\Mapping as ORM; use Doctrine\Common\Collections\ArrayCollection; use Base\V1\Model\BaseReadEntity; /** * @ORM\Entity(readOnly=true) * @ORM\Table(name="region", * uniqueConstraints={@ORM\UniqueConstraint(name="geo__region__unm49__key", columns={"unm49"})}, * indexes={@ORM\Index(name="geo__region__level__idx", columns={"level"})}, * schema="geo" * ) */ class Region extends BaseReadEntity { /** * @ORM\Id @ORM\Column(type="smallint", options={"comment":"custom shorted hierarchical code"}) * @var int */ private $id; /** * @ORM\Column(type="string", length=3, options={"comment":"united nations UN M.49 code"}) * @var string */ private $unm49; /** * @ORM\ManyToOne(targetEntity="Region", inversedBy="children") * @ORM\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="RESTRICT") * @var int */ private $parent; /** * @ORM\OneToMany(targetEntity="Region", mappedBy="parent") * @ORM\OrderBy({"id"="ASC"}) * @var array */ private $children; /** * @ORM\OneToMany(targetEntity="Country", mappedBy="region") * @ORM\OrderBy({"id"="ASC"}) * @var array */ private $countries; /** * @ORM\Column(type="smallint") * @var int */ private $level; /** * @ORM\Column(type="string", length=32) * @var string */ private $name; /** * @return the $id */ public function getId() { return $this->id; } /** * @return the $unm49 */ public function getUnm49() { return $this->unm49; } /** * @return the $parent */ public function getParent() { return $this->parent; } /** * @return the $children */ public function getChildren() { return $this->children; } /** * @return the $countries */ public function getCountries() { return $this->countries; } /** * @return the $level */ public function getLevel() { return $this->level; } /** * @return the $name */ public function getName() { return $this->name; } public function __construct() { $this->children = new ArrayCollection(); $this->countries = new ArrayCollection(); } }
- append to the "/module/Geo/config/module.config.php" file:
'doctrine' => array( 'driver' => array( 'geo_model' => array( 'class' => 'Doctrine\\ORM\\Mapping\\Driver\\AnnotationDriver', 'cache' => 'array', 'paths' => array( 0 => __DIR__ . '/../src/Geo/V1/Model', ), ), 'orm_default' => array( 'drivers' => array( 'Geo\\V1\\Model' => 'geo_model', ), ), ), ),
- Apply the "DoctrineModule\Stdlib\Hydrator\DoctrineObject" to the "Hydrator Service Name"
- Add "page", "query" and "sort" words to the "Collection Query String Whitelist";
- Change the "Entity Class" to "Geo\V1\Model\Region" and, after the service created, delete the file "/module/Geo/src/Geo/V1/Rest/Region/RegionEntity.php" of Apigility;
- This is a readonly example, so in sections "HTTP Entity Methods" and "HTTP Collection Methods", select the "GET" options;
- In "Page Size Parameter", write "results";
- Save;
- Create the file "RegionMapper.php" inside the "/module/Geo/src/Geo/V1/Rest/Region" Apigility folder;
- Write the following code:
<?php namespace Geo\V1\Rest\Region; use Doctrine\ORM\EntityManager; use Doctrine\ORM\Tools\Pagination\Paginator; use DoctrineORMModule\Paginator\Adapter\DoctrinePaginator; use WSApigilityDoctrine\DoctrineFilter; use WSApigilityDoctrine\DoctrineSort; use WSApigilityDoctrine\ReadMapperInterface; use Geo\V1\Model\Region as RegionEntity; class RegionMapper implements ReadMapperInterface { protected $em; public function __construct(EntityManager $em) { $this->em = $em; } public function fetch($id) { $qb = $this->em->createQueryBuilder(); $qb->select('e') ->from(RegionEntity::class, 'e') ->where('e.id = :id'); $qb->setParameters(array( 'id' => $id )); return $qb->getQuery()->getOneOrNullResult(); } public function fetchAll($params = array()) { $qb = $this->em->createQueryBuilder(); $qb->select('e') ->from(RegionEntity::class, 'e') ->leftJoin('e.parent', 'p') ->add('orderBy', 'e.level ASC, e.id ASC'); // QUERY (RQL) AND SORT DoctrineFilter::filter($qb, $params); DoctrineSort::sort($qb, $params); // PAGINATE RESULTS $paginator = new Paginator($qb, $fetchJoinCollection = true); $adapter = new DoctrinePaginator($paginator); return new RegionCollection($adapter); } }
- edit the "/module/Geo/src/Geo/V1/Rest/Region/RegionResource.php" Apigility file and:
- create the "mapper" protected propety:
protected $mapper;
* create a constructor:
public function __construct(RegionMapper $mapper) { $this->mapper = $mapper; }
* change the "GET" methods:
/** * Fetch a resource * * @param mixed $id * @return ApiProblem|mixed */ public function fetch($id) { return $this->mapper->fetch($id); } /** * Fetch all or a subset of resources * * @param array $params * @return ApiProblem|mixed */ public function fetchAll($params = array()) { return $this->mapper->fetchAll($params); }
- edit the "/module/Geo/src/Geo/V1/Rest/Region/RegionResourceFactory.php" Apigility file:
<?php namespace Geo\V1\Rest\Region; use Doctrine\ORM\EntityManager; use Geo\V1\Rest\Region\RegionMapper; use Geo\V1\Rest\Region\RegionResource; class RegionResourceFactory { public function __invoke($services) { $em = $services->get(EntityManager::class); $mapper = new RegionMapper($em); return new RegionResource($mapper); } }