diff --git a/src/Sylius/Bundle/ResourceBundle/Controller/ResourceController.php b/src/Sylius/Bundle/ResourceBundle/Controller/ResourceController.php index 41a81032e2..c6c239e042 100644 --- a/src/Sylius/Bundle/ResourceBundle/Controller/ResourceController.php +++ b/src/Sylius/Bundle/ResourceBundle/Controller/ResourceController.php @@ -26,22 +26,31 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; * * @author Paweł Jędrzejewski */ -abstract class ResourceController extends Controller implements ResourceControllerInterface +class ResourceController extends Controller implements ResourceControllerInterface { - /** - * Get one resource. - * - * @param Request $request - * - * @return Response - */ - public function getAction(Request $request) + protected $bundlePrefix; + protected $resourceName; + protected $templateNamespace; + + public function __construct($bundlePrefix, $resourceName, $templateNamespace) { - $identifier = $this->getIdentifierValue($request); - $resource = $this->findResourceOr404($identifier); + $this->bundlePrefix = $bundlePrefix; + $this->resourceName = $resourceName; + $this->templateNamespace = $templateNamespace; + } + + /** + * Get single resource. + */ + public function getAction() + { + $criteria = $this->getCriteria(); + $criteria[$this->getIdentifierName()] = $this->getIdentifierValue(); + + $resource = $this->findResourceOr404($criteria); $view = View::create() - ->setTemplate($this->getFullTemplateName('show')) + ->setTemplate($this->getFullTemplateName('show.html')) ->setTemplateVar($this->getResourceName()) ->setData($resource) ; @@ -50,23 +59,37 @@ abstract class ResourceController extends Controller implements ResourceControll } /** - * Get all paginated resourcees. - * - * @param Request $request - * - * @return Response + * Get collection (paginated by default) of resources. */ public function getCollectionAction(Request $request) { - $paginator = $this->getManager()->createPaginator(); - $paginator->setCurrentPage($request->query->get('page', 1), true, true); + $criteria = $this->getCriteria(); + $sorting = $this->getSorting(); - $resources = $paginator->getCurrentPageResults(); + if ($this->isPaginated()) { + $paginator = $this + ->getRepository() + ->paginate($criteria, $sorting) + ; - $data = $this->isHtmlRequest() ? array(Pluralization::pluralize($this->getResourceName()) => $resources, 'paginator' => $paginator) : $resourcees; + $paginator->setCurrentPage($request->query->get('page', 1), true, true); + $resources = $paginator->getCurrentPageResults(); + + $pluralName = Pluralization::pluralize($this->getResourceName()); + + $data = $this->isHtmlRequest() ? array( + $pluralName => $resources, + 'paginator' => $paginator + ) : $resources; + } else { + $data = $this + ->getRepository() + ->getCollection($criteria, $sorting) + ; + } $view = View::create() - ->setTemplate($this->getFullTemplateName('list')) + ->setTemplate($this->getFullTemplateName('list.html')) ->setData($data) ; @@ -86,22 +109,23 @@ abstract class ResourceController extends Controller implements ResourceControll $form = $this->createResourceForm($resource); if ($request->isMethod('POST') && $form->bind($request)->isValid()) { - $this->getManipulator()->create($resource); - $this->setFlash('success', sprintf("%s has been created", ucfirst($this->getResourceName()))); + $this->getManager()->persist($resource); return $this->redirectToResource($resource); } - $htmlView = View::create() + if (!$this->isHtmlRequest()) { + return $this->handleView(View::create($form)); + } + + $view = View::create() ->setTemplate($this->getFullTemplateName('create.html')) ->setData(array( $this->getResourceName() => $resource, - 'form' => $form->createView() + 'form' => $form->createView() )) ; - $view = $this->isHtmlRequest() ? $htmlView : View::create($form); - return $this->handleView($view); } @@ -124,16 +148,18 @@ abstract class ResourceController extends Controller implements ResourceControll return $this->redirectToResource($resource); } - $htmlView = View::create() - ->setTemplate($this->getFullTemplateName('update.html')) + if (!$this->isHtmlRequest()) { + return $this->handleView(View::create($form)); + } + + $view = View::create() + ->setTemplate($this->getFullTemplateName('create.html')) ->setData(array( $this->getResourceName() => $resource, - 'form' => $form->createView() + 'form' => $form->createView() )) ; - $view = $this->isHtmlRequest() ? $htmlView : View::create($form); - return $this->handleView($view); } @@ -226,13 +252,23 @@ abstract class ResourceController extends Controller implements ResourceControll /** * Get resource manager. * - * @return ManagerInterface + * @return ResourceManagerInterface */ protected function getManager() { return $this->get($this->getServiceName('manager')); } + /** + * Get resource repository. + * + * @return ResourceRepositoryInterface + */ + protected function getRepository() + { + return $this->get($this->getServiceName('repository')); + } + protected function getServiceName($name) { return sprintf('%s.%s.%s', $this->getBundlePrefix(), $name, $this->getResourceName()); @@ -242,17 +278,15 @@ abstract class ResourceController extends Controller implements ResourceControll * Tries to find resource with given id. * Throws special 404 exception when unsuccessful. * - * @param mixed $id The resource identifier + * @param array $criteria Criteria * * @return ResourceInterface * * @throws NotFoundHttpException */ - protected function findResourceOr404($identifier) + protected function findResourceOr404(array $criteria) { - $criteria = array($this->getIdentifierName() => $this->getIdentifierValue()); - - if (!$resource = $this->getManager()->findOneBy($criteria)) { + if (!$resource = $this->getRepository()->get($criteria)) { throw new NotFoundHttpException('Requested resource does not exist'); } @@ -266,25 +300,33 @@ abstract class ResourceController extends Controller implements ResourceControll protected function getIdentifierValue() { - if (!$identifier = $this->getRequest()->get($this->getIdentifierName())) { + if (null === $identifier = $this->getRequest()->get($this->getIdentifierName())) { throw new NotFoundHttpException('No resource identifier supplied'); } return $identifier; } + protected function isPaginated() + { + return (Boolean) $this->getRequest()->attributes->get('_sylius.paginate', true); + } + + protected function getCriteria() + { + return $this->getRequest()->get('_sylius.criteria', array()); + } + + protected function getSorting() + { + return $this->getRequest()->get('_sylius.sorting', array()); + } + protected function renderResponse($templateName, array $parameters = array()) { return $this->render($this->getFullTemplateName($templateName), $parameters); } - /** - * Get full template name. - * - * @param string - * - * @return string - */ protected function getFullTemplateName($name) { $template = $this->getRequest()->attributes->get('_sylius.template'); @@ -300,53 +342,38 @@ abstract class ResourceController extends Controller implements ResourceControll ); } - /** - * Get engine. - * - * @return string - */ protected function getEngine() { return $this->container->getParameter(sprintf('%s.engine', $this->getBundlePrefix())); } - /** - * Check if request accepts html format. - * - * @return Boolean - */ protected function isHtmlRequest() { return 'html' === $this->getRequest()->getRequestFormat(); } - /** - * Convert view to a response object. - * - * @param View $view - * - * @return Response - */ protected function handleView(View $view) { return $this->get('fos_rest.view_handler')->handle($view); } - /** - * Get name of the form type to use. - * - * @return string - */ protected function getResourceFormType() { return sprintf('%s_%s', $this->getBundlePrefix(), $this->getResourceName()); } - /** - * Get templates namespace. - * - * @return string - */ - abstract protected function getTemplateNamespace(); - abstract protected function getBundlePrefix(); + protected function getTemplateNamespace() + { + return $this->templateNamespace; + } + + protected function getBundlePrefix() + { + return $this->bundlePrefix; + } + + protected function getResourceName() + { + return $this->resourceName; + } } diff --git a/src/Sylius/Bundle/ResourceBundle/Manager/Doctrine/DoctrineResourceManager.php b/src/Sylius/Bundle/ResourceBundle/Manager/Doctrine/DoctrineResourceManager.php index 350b49d68a..301db80c81 100644 --- a/src/Sylius/Bundle/ResourceBundle/Manager/Doctrine/DoctrineResourceManager.php +++ b/src/Sylius/Bundle/ResourceBundle/Manager/Doctrine/DoctrineResourceManager.php @@ -20,15 +20,13 @@ use Sylius\Bundle\ResourceBundle\Model\ResourceInterface; * * @author Paweł Jędrzejewski */ -abstract class DoctrineResourceManager extends ResourceManager implements DoctrineResourceManagerInterface +class DoctrineResourceManager extends ResourceManager implements DoctrineResourceManagerInterface { protected $objectManager; - protected $objectRepository; public function __construct(ObjectManager $objectManager, $class) { $this->objectManager = $objectManager; - $this->objectRepository = $objectManager->getRepository($class); parent::__construct($class); } @@ -57,33 +55,8 @@ abstract class DoctrineResourceManager extends ResourceManager implements Doctri } } - public function find($id) - { - return $this->objectRepository->find($id); - } - - public function findOneBy(array $criteria) - { - return $this->objectRepository->findOneBy($criteria); - } - - public function findAll() - { - return $this->objectRepository->findAll(); - } - - public function findBy(array $criteria) - { - return $this->objectRepository->findBy($criteria); - } - public function getObjectManager() { return $this->objectManager; } - - public function getObjectRepository() - { - return $this->objectRepository; - } } diff --git a/src/Sylius/Bundle/ResourceBundle/Manager/Doctrine/DoctrineResourceManagerInterface.php b/src/Sylius/Bundle/ResourceBundle/Manager/Doctrine/DoctrineResourceManagerInterface.php index 1397cd75ee..ef80db20b5 100644 --- a/src/Sylius/Bundle/ResourceBundle/Manager/Doctrine/DoctrineResourceManagerInterface.php +++ b/src/Sylius/Bundle/ResourceBundle/Manager/Doctrine/DoctrineResourceManagerInterface.php @@ -21,5 +21,4 @@ use Sylius\Bundle\ResourceBundle\Manager\ResourceManagerInterface; interface DoctrineResourceManagerInterface extends ResourceManagerInterface { function getObjectManager(); - function getObjectRepository(); } diff --git a/src/Sylius/Bundle/ResourceBundle/Manager/Doctrine/ORM/ResourceManager.php b/src/Sylius/Bundle/ResourceBundle/Manager/Doctrine/ORM/ResourceManager.php deleted file mode 100644 index dc745edd46..0000000000 --- a/src/Sylius/Bundle/ResourceBundle/Manager/Doctrine/ORM/ResourceManager.php +++ /dev/null @@ -1,30 +0,0 @@ - - */ -class ResourceManager extends DoctrineResourceManager -{ - public function createPaginator() - { - return new Pagerfanta(new DoctrineORMAdapter($this->objectRepository->createQueryBuilder('r'))); - } -} diff --git a/src/Sylius/Bundle/ResourceBundle/Manager/ResourceManagerInterface.php b/src/Sylius/Bundle/ResourceBundle/Manager/ResourceManagerInterface.php index 3661c85cc2..47f19cc49b 100644 --- a/src/Sylius/Bundle/ResourceBundle/Manager/ResourceManagerInterface.php +++ b/src/Sylius/Bundle/ResourceBundle/Manager/ResourceManagerInterface.php @@ -27,13 +27,6 @@ interface ResourceManagerInterface */ function create(); - /** - * Creates a new Pagerfanta instance to paginate the resources. - * - * @return PagerfantaInterface - */ - function createPaginator(); - /** * Persist. * @@ -50,40 +43,6 @@ interface ResourceManagerInterface */ function remove(ResourceInterface $resource, $commit = true); - /** - * Finds resource by id. - * - * @param mixed Identifier - * - * @return ResourceInterface - */ - function find($id); - - /** - * Finds resource by criteria. - * - * @param array $criteria - * - * @return ResourceInterface - */ - function findOneBy(array $criteria); - - /** - * Find all. - * - * @return Collection - */ - function findAll(); - - /** - * Finds resources by criteria. - * - * @param array $criteria - * - * @return array - */ - function findBy(array $criteria); - /** * Get resource class name. * diff --git a/src/Sylius/Bundle/ResourceBundle/Repository/Doctrine/DoctrineResourceRepository.php b/src/Sylius/Bundle/ResourceBundle/Repository/Doctrine/DoctrineResourceRepository.php new file mode 100644 index 0000000000..90aa31eca6 --- /dev/null +++ b/src/Sylius/Bundle/ResourceBundle/Repository/Doctrine/DoctrineResourceRepository.php @@ -0,0 +1,37 @@ + + */ +abstract class DoctrineResourceRepository extends ResourceRepository implements DoctrineResourceRepositoryInterface +{ + protected $objectRepository; + + public function __construct(ObjectRepository $objectRepository, $class) + { + $this->objectRepository = $objectRepository; + + parent::__construct($class); + } + + public function getObjectRepository() + { + return $this->objectRepository; + } +} diff --git a/src/Sylius/Bundle/ResourceBundle/Repository/Doctrine/DoctrineResourceRepositoryInterface.php b/src/Sylius/Bundle/ResourceBundle/Repository/Doctrine/DoctrineResourceRepositoryInterface.php new file mode 100644 index 0000000000..19944f4cbc --- /dev/null +++ b/src/Sylius/Bundle/ResourceBundle/Repository/Doctrine/DoctrineResourceRepositoryInterface.php @@ -0,0 +1,24 @@ + + */ +interface DoctrineResourceRepositoryInterface extends ResourceRepositoryInterface +{ + function getObjectRepository(); +} diff --git a/src/Sylius/Bundle/ResourceBundle/Repository/Doctrine/ORM/ResourceRepository.php b/src/Sylius/Bundle/ResourceBundle/Repository/Doctrine/ORM/ResourceRepository.php new file mode 100644 index 0000000000..d53bf0b79f --- /dev/null +++ b/src/Sylius/Bundle/ResourceBundle/Repository/Doctrine/ORM/ResourceRepository.php @@ -0,0 +1,122 @@ + + */ +class ResourceRepository extends DoctrineResourceRepository +{ + /** + * {@inheritdoc} + */ + public function get(array $criteria) + { + return $this + ->getQueryBuilder($criteria, array()) + ->getQuery() + ->getOneOrNullResult() + ; + } + + /** + * {@inheritdoc} + */ + public function getCollection(array $criteria = array(), array $sorting = array(), $limit = null) + { + $queryBuilder = $this->getQueryBuilder($criteria, $sorting); + + if (null !== $limit) { + $queryBuilder->setMaxResults($limit); + } + + return $queryBuilder + ->getQuery() + ->execute() + ; + } + + /** + * {@inheritdoc} + */ + public function paginate(array $criteria = array(), array $sorting = array()) + { + return new Pagerfanta(new DoctrineORMAdapter($this->getQueryBuilder($criteria, $sorting))); + } + + protected function getQueryBuilder(array $criteria, array $sorting) + { + $queryBuilder = $this->getBasicQueryBuilder(); + + $this->filter($queryBuilder, $criteria); + $this->sort($queryBuilder, $sorting); + + return $queryBuilder; + } + + protected function filter(QueryBuilder $queryBuilder, array $criteria) + { + $reflectionClass = new \ReflectionClass($this->getClass()); + $properties = array_keys($reflectionClass->getDefaultProperties()); + + $i = 0; + foreach ($criteria as $property => $condition) { + if (!is_array($condition)) { + $condition = array('=', $condition); + } + + list($comparison, $value) = $condition; + + if (in_array($property, $properties) && in_array($comparison, array('=', '!=', '>', '<', '>=', '<='))) { + + $formula = sprintf("%s.%s %s :PARAM%d", $this->getAlias(), $property, $comparison, $i); + $queryBuilder + ->andWhere($formula) + ->setParameter('PARAM'.$i, $value) + ; + + $i++; + } + } + } + + protected function sort(QueryBuilder $queryBuilder, array $sorting) + { + $acceptedOrders = array('asc', 'desc'); + + foreach ($sorting as $property => $order) { + if (in_array(strtolower($order), $acceptedOrders)) { + $queryBuilder->orderBy($this->getAlias().'.'.$property, $order); + } + } + } + + protected function getBasicQueryBuilder() + { + return $this + ->getObjectRepository() + ->createQueryBuilder($this->getAlias()) + ; + } + + protected function getAlias() + { + return 'r'; + } +} diff --git a/src/Sylius/Bundle/ResourceBundle/Repository/ResourceRepository.php b/src/Sylius/Bundle/ResourceBundle/Repository/ResourceRepository.php new file mode 100644 index 0000000000..7df8c476e4 --- /dev/null +++ b/src/Sylius/Bundle/ResourceBundle/Repository/ResourceRepository.php @@ -0,0 +1,32 @@ + + */ +abstract class ResourceRepository implements ResourceRepositoryInterface +{ + protected $class; + + public function __construct($class) + { + $this->class = $class; + } + + public function getClass() + { + return $this->class; + } +} diff --git a/src/Sylius/Bundle/ResourceBundle/Repository/ResourceRepositoryInterface.php b/src/Sylius/Bundle/ResourceBundle/Repository/ResourceRepositoryInterface.php new file mode 100644 index 0000000000..fad98b8f50 --- /dev/null +++ b/src/Sylius/Bundle/ResourceBundle/Repository/ResourceRepositoryInterface.php @@ -0,0 +1,54 @@ + + */ +interface ResourceRepositoryInterface +{ + /** + * Finds resource by identifier. + * + * @param array $criteria + * + * @return ResourceInterface + */ + function get(array $criteria); + + /** + * Finds resource by criteria. + * + * @param array $criteria + * + * @return ResourceInterface + */ + function getCollection(array $criteria = array(), array $sorting = array(), $limit = null); + + /** + * Creates a new Pagerfanta instance to paginate the resources. + * + * @return PagerfantaInterface + */ + function paginate(array $criteria = array(), array $sorting = array()); + + /** + * Get resource class name. + * + * @return string + */ + function getClass(); +}