Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Product reviews API #8772

Merged
merged 24 commits into from
Jan 5, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
0f6966a
[Product Reviews API] - add API for product reviews
paulstoicareea Oct 4, 2017
c660fa9
[Documentation][API] - add product reviews api docs
paulstoicareea Oct 4, 2017
fb337a6
[Product Reviews API]: accept/reject endpoints with state machine
paulstoicareea Oct 5, 2017
0e2ccc9
[Unit Testing]: ProductReviewApi Controller
paulstoicareea Oct 5, 2017
0151d20
[Documentation]: add in toctree and map Product Reviews API
paulstoicareea Oct 5, 2017
9785c0e
[Documentation]: minor changes
paulstoicareea Oct 9, 2017
4aa26f9
[Product Reviews API] - minor changes
paulstoicareea Oct 9, 2017
de75e27
[Documentation]: fix malformed tables Product reviews API
paulstoicareea Oct 9, 2017
ca4a90a
[Product Reviews API] - minor changes for tests
paulstoicareea Oct 9, 2017
3c1048f
[Product Reviews API] - add API for product reviews
paulstoicareea Oct 4, 2017
bc07098
[Documentation][API] - add product reviews api docs
paulstoicareea Oct 4, 2017
5e41ae6
[Product Reviews API]: accept/reject endpoints with state machine
paulstoicareea Oct 5, 2017
e998b59
[Unit Testing]: ProductReviewApi Controller
paulstoicareea Oct 5, 2017
dd37af3
[Documentation]: add in toctree and map Product Reviews API
paulstoicareea Oct 5, 2017
0228602
[Documentation]: minor changes
paulstoicareea Oct 9, 2017
d571b9c
[Product Reviews API] - minor changes
paulstoicareea Oct 9, 2017
3933ed2
[Documentation]: fix malformed tables Product reviews API
paulstoicareea Oct 9, 2017
3cf247a
[Product Reviews API] - minor changes for tests
paulstoicareea Oct 9, 2017
859021c
[Documentation]: texts improvments Product reviews API
paulstoicareea Nov 17, 2017
ca795cb
Product review API syntax improvments
paulstoicareea Nov 17, 2017
78d2c96
Product Review API tests: review creation real inputs
paulstoicareea Nov 18, 2017
aca53a4
[Product Reviews API] - add API for product reviews
paulstoicareea Oct 4, 2017
27086bd
fix product reviews api test methods names, expected response
paulstoicareea Dec 5, 2017
e386f37
product reviews api test remove author, fix indentation
paulstoicareea Jan 4, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
[Product Reviews API] - add API for product reviews
  • Loading branch information
paulstoicareea committed Nov 17, 2017
commit 3c1048f9562028ebe0963d8b13c7fd097ed75950
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<?php

/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Sylius\Bundle\AdminApiBundle\Controller;

use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Doctrine\ORM\EntityManagerInterface;
use Sylius\Component\Core\Repository\ProductReviewRepositoryInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Sylius\Component\Review\Model\ReviewInterface;

/**
* @author Paul Stoica <paul.stoica18@gmail.com>
*/
final class UpdateProductReviewStatusController
{
/**
* @var ProductReviewRepositoryInterface
*/
private $productReviewRepository;

/**
* @var EntityManagerInterface
*/
private $manager;

/**
* @param RepositoryInterface $productReviewRepository
* @param EntityManagerInterface $manager
*/
public function __construct(
RepositoryInterface $productReviewRepository,
EntityManagerInterface $manager
) {
$this->productReviewRepository = $productReviewRepository;
$this->manager = $manager;
}

/**
* @param Request $request
*
* @return JsonResponse
*/
public function acceptProductReviewAction(Request $request): JsonResponse
{
$reviewId = $request->get('id');
$productCode = $request->get('productCode');

if (!in_array($request->getMethod(), ['POST', 'PUT', 'PATCH'], true) && (null === $reviewId || null === $productCode)) {
return new JsonResponse(null, Response::HTTP_NO_CONTENT);
}

/** @var ReviewInterface $productReview */
$productReview = $this->productReviewRepository->findOneByIdAndProductCode(
$reviewId,
$productCode
);

$productReview->setStatus(ReviewInterface::STATUS_ACCEPTED);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should never do setStatus but use State Machine instead. :) http://docs.sylius.org/en/latest/book/architecture/state_machine.html

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, I will make the change.


$this->manager->persist($productReview);
$this->manager->flush();

return new JsonResponse(null, Response::HTTP_NO_CONTENT);
}

/**
* @param Request $request
*
* @return JsonResponse
*/
public function rejectProductReviewAction(Request $request): JsonResponse
{
$reviewId = $request->get('id');
$productCode = $request->get('productCode');

if (!in_array($request->getMethod(), ['POST', 'PUT', 'PATCH'], true) && (null === $reviewId || null === $productCode)) {
return new JsonResponse(null, Response::HTTP_NO_CONTENT);
}

/** @var ReviewInterface $productReview */
$productReview = $this->productReviewRepository->findOneByIdAndProductCode(
$reviewId,
$productCode
);

$productReview->setStatus(ReviewInterface::STATUS_REJECTED);

$this->manager->persist($productReview);
$this->manager->flush();

return new JsonResponse(null, Response::HTTP_NO_CONTENT);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ imports:
- { resource: "@SyliusAdminApiBundle/Resources/config/grids/payments.yml" }
- { resource: "@SyliusAdminApiBundle/Resources/config/grids/product.yml" }
- { resource: "@SyliusAdminApiBundle/Resources/config/grids/product_variant.yml" }
- { resource: "@SyliusAdminApiBundle/Resources/config/grids/product_review.yml" }
- { resource: "@SyliusAdminApiBundle/Resources/config/grids/promotion.yml" }
- { resource: "@SyliusAdminApiBundle/Resources/config/grids/shipments.yml" }
- { resource: "@SyliusAdminApiBundle/Resources/config/grids/taxon.yml" }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
#
# @author Paul Stoica <paul.stoica18@gmail.com>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are not using author docblocks anymore, because they are just redundant (data can be fetched from git history), please remove it from here and other files


sylius_grid:
grids:
sylius_admin_api_product_review:
driver:
name: doctrine/orm
options:
class: "%sylius.model.product_review.class%"
repository:
method: createQueryBuilderByProductCode
arguments: ["%locale%", $productCode]
sorting:
date: desc
fields:
date:
type: datetime
label: sylius.ui.date
path: createdAt
sortable: createdAt
options:
format: d-m-Y H:i:s
title:
type: string
label: sylius.ui.title
sortable: ~
rating:
type: string
label: sylius.ui.rating
sortable: ~
status:
type: twig
label: sylius.ui.status
reviewSubject:
type: string
label: sylius.ui.product
author:
type: string
label: sylius.ui.customer
filters:
title:
type: string
label: sylius.ui.title
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ sylius_api_product_variant:
resource: "@SyliusAdminApiBundle/Resources/config/routing/product_variant.yml"
prefix: /products/{productCode}

sylius_api_product_review:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess that sylius_api_product_review should be before sylius_api_product_taxon_position to keep alphabetical order

resource: "@SyliusAdminApiBundle/Resources/config/routing/product_review.yml"
prefix: /products/{productCode}

sylius_api_promotion:
resource: "@SyliusAdminApiBundle/Resources/config/routing/promotion.yml"

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
#
# @author Paul Stoica <paul.stoica18@gmail.com>

sylius_admin_api_product_review:
resource: |
path: 'reviews'
grid: sylius_admin_api_product_review
alias: sylius.product_review
section: admin_api
only: ['index']
serialization_version: $version
vars:
route:
parameters:
productCode: $productCode
type: sylius.resource_api

sylius_admin_api_product_review_create:
path: /reviews/
methods: [POST]
defaults:
_controller: sylius.controller.product_review:createAction
_sylius:
serialization_groups: [Default, Detailed]
serialization_version: $version
section: admin_api
form: Sylius\Bundle\CoreBundle\Form\Type\Product\ProductReviewType
factory:
method: createForSubject
arguments:
- expr:notFoundOnNull(service('sylius.repository.product').findOneByCode($productCode))

sylius_admin_api_product_review_update:
path: /reviews/{id}
methods: [PUT, PATCH]
defaults:
_controller: sylius.controller.product_review:updateAction
_sylius:
serialization_version: $version
section: admin_api
form: Sylius\Bundle\CoreBundle\Form\Type\Product\ProductReviewType
repository:
method: findOneByIdAndProductCode
arguments: [$id, $productCode]

sylius_admin_api_product_review_delete:
path: /reviews/{id}
methods: [DELETE]
defaults:
_controller: sylius.controller.product_review:deleteAction
_sylius:
serialization_version: $version
section: admin_api
repository:
method: findOneByIdAndProductCode
arguments: [$id, $productCode]
csrf_protection: false

sylius_admin_api_product_review_show:
path: /reviews/{code}
methods: [GET]
defaults:
_controller: sylius.controller.product_review:showAction
_sylius:
serialization_version: $version
section: admin_api
serialization_groups: [Default, Detailed]
repository:
method: findOneByIdAndProductCode
arguments: [$code, $productCode]

sylius_admin_api_product_review_accept:
path: /reviews/{id}/accept
methods: [POST, PUT, PATCH]
defaults:
_controller: sylius.controller.update_product_review_status:acceptProductReviewAction

sylius_admin_api_product_review_reject:
path: /reviews/{id}/reject
methods: [POST, PUT, PATCH]
defaults:
_controller: sylius.controller.update_product_review_status:rejectProductReviewAction
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,9 @@
<argument type="service" id="fos_rest.view_handler" />
<argument type="service" id="sylius.registry.shipping_calculator" />
</service>
<service id="sylius.controller.update_product_review_status" class="Sylius\Bundle\AdminApiBundle\Controller\UpdateProductReviewStatusController">
<argument type="service" id="sylius.repository.product_review" />
<argument type="service" id="doctrine.orm.entity_manager" />
</service>
</services>
</container>
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@

namespace Sylius\Bundle\CoreBundle\Doctrine\ORM;

use Doctrine\ORM\QueryBuilder;
use Sylius\Bundle\ResourceBundle\Doctrine\ORM\EntityRepository;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Repository\ProductReviewRepositoryInterface;
use Sylius\Component\Review\Model\ReviewInterface;

/**
* @author Mateusz Zalewski <mateusz.zalewski@lakion.com>
* @author Paul Stoica <paul.stoica18@gmail.com>
*/
class ProductReviewRepository extends EntityRepository implements ProductReviewRepositoryInterface
{
Expand Down Expand Up @@ -60,4 +62,34 @@ public function findAcceptedByProductSlugAndChannel(string $slug, string $locale
->getResult()
;
}

/**
* {@inheritdoc}
*/
public function createQueryBuilderByProductCode(string $locale, string $productCode): QueryBuilder
{
return $this->createQueryBuilder('o')
->innerJoin('o.reviewSubject', 'product')
->innerJoin('product.translations', 'translation')
->andWhere('translation.locale = :locale')
->andWhere('product.code = :productCode')
->setParameter('locale', $locale)
->setParameter('productCode', $productCode)
;
}

/**
* {@inheritdoc}
*/
public function findOneByIdAndProductCode(string $id, string $productCode): ?ReviewInterface {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

string $id and { should be in the next line

return $this->createQueryBuilder('o')
->innerJoin('o.reviewSubject', 'product')
->andWhere('product.code = :productCode')
->andWhere('o.id = :id')
->setParameter('productCode', $productCode)
->setParameter('id', $id)
->getQuery()
->getOneOrNullResult()
;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@

namespace Sylius\Component\Core\Repository;

use Doctrine\ORM\QueryBuilder;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Sylius\Component\Review\Model\ReviewInterface;

/**
* @author Mateusz Zalewski <mateusz.zalewski@lakion.com>
* @author Paul Stoica <paul.stoica18@gmail.com>
*/
interface ProductReviewRepositoryInterface extends RepositoryInterface
{
Expand All @@ -38,4 +40,20 @@ public function findLatestByProductId($productId, int $count): array;
* @return array|ReviewInterface[]
*/
public function findAcceptedByProductSlugAndChannel(string $slug, string $locale, ChannelInterface $channel): array;

/**
* @param string $locale
* @param string $productCode
*
* @return QueryBuilder
*/
public function createQueryBuilderByProductCode(string $locale, string $productCode): QueryBuilder;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding methods to an interface is a BC break.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pamil, in this case how can proceed next? Should we put the methods only into the ProductReviewRepository?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to our proposed BC promise (#8901), it isn't a BC break 🎉


/**
* @param integer $id
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mixed $id

* @param string $productCode
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doubled space after string

*
* @return ReviewInterface|null
*/
public function findOneByIdAndProductCode(string $id, string $productCode): ?ReviewInterface;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

string $id

}