Product
<?php
namespace App\ArgumentResolver;
use App\Classes\RestCode;
use App\Entity\Product;
use App\Exception\ArgumentResolverException;
use App\Service\JWTPayload;
use Doctrine\ORM\EntityManagerInterface;
use Exception;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface;
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
/**
* Class CategoryProductResolver
* @package App\ArgumentResolver
*/
class ProductResolver implements ArgumentValueResolverInterface
{
/** @var EntityManagerInterface */
private EntityManagerInterface $em;
/** @var JWTPayload */
private JWTPayload $WTPayload;
/**
* CategoryProductResolver constructor.
* @param EntityManagerInterface $em
*/
public function __construct(EntityManagerInterface $em, JWTPayload $JWTPayload)
{
$this->em = $em;
$this->WTPayload = $JWTPayload;
}
/**
* @inheritDoc
* @throws ArgumentResolverException
*/
public function supports(Request $request, ArgumentMetadata $argument)
{
if (Product::class == $argument->getType()) {
if (!$request->get('product_id', false))
{
throw new ArgumentResolverException("Один из указанных параметров отсутствует или недействителен.", RestCode::INVALID_PARAMETERS);
}
return true;
}
return false;
}
/**
* @inheritDoc
* @throws Exception
*/
public function resolve(Request $request, ArgumentMetadata $argument)
{
$product = $this->em->getRepository(Product::class)
->getById(
$request->get("product_id", 0),
$this->WTPayload->has('sale_point_id') ? $this->WTPayload->get('sale_point_id', '/\d+/', 0) : 0
);
if (!is_a($product, Product::class)) {
throw new ArgumentResolverException("Продукт не найден.", RestCode::PRODUCT_NOT_FOUND);
}
yield $product;
}
}
Можно только поабстрактней сделать, чобы любая сущность попадала и проверялась, если указзали, а не для каждой делатьсвой,
Product
product_id
(например)Product
GET /products.getById?product_id=1&lang=en HTTP/1.1
Host: 127.0.0.100:8012
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1ODM2MDI3ODAsIm5iZiI6MTU4MzYwMjc4MSwiZXhwIjoxNTgzNjM4NzgwLCJ1c2VyX2lkIjoxLCJzYWxlX3BvaW50X2lkIjoxfQ.NXgD5GJq1bktVnVi38zbsW6xtXvA1dGBoN5YaTfl2-o
GET /products.getById?product_id=1&lang=ru HTTP/1.1
Host: 127.0.0.100:8011
{
"code": 0,
"data": {
"categories": [
{
"id": 3,
"name": "Горячие напитки",
"image_url": "http://127.0.0.100:8013/sale_point_1/categories/52b9792086f8f70763c2301ad4c34c8b-5e63547e39edd.png"
}
],
"images": [
{
"id": 3,
"url": "http://127.0.0.100:8013/sale_point_1/products/ed8252ef39def9b5bad534db15fa3ba1-5e63c8b0b0c8d.jpg"
}
],
"state": false,
"old_price": "0.00",
"price": "100.00",
"short_description": "Чай — напиток, получаемый варкой, завариванием и/или настаиванием листа чайного куста, который предварительно подготавливается специальным образом.",
"name": "Чай",
"id": 1,
"recommendations": [],
"serial_number": "S1-5E63B30560400",
"rating": 1.1,
"long_description": "Чай — напиток, получаемый варкой, завариванием и/или настаиванием листа чайного куста, который предварительно подготавливается специальным образом. Чай — также сам лист чайного куста, обработанный и подготовленный для приготовления напитка. "
}
}
{
"code": 2000,
"msg": "Продукт не найден.",
"request": {
"http_method": "GET",
"request_method": "/products.getById",
"parameters": []
}
}
/**
* @param CategoryProduct $entity
* @param PreFlushEventArgs $eventArgs
* @return string
*/
public function save(CategoryProduct $entity, $eventArgs)
{
if ($this->computed === false) {
if ($this->support()) {
foreach ($this->white_mime_list as $mmt => $ext) {
if ($mmt == $this->getMimeType()) {
$file_name = sprintf("%s-%s.%s", md5($this->getImageContentBase64()), uniqid(), $ext);
$relative_path = sprintf("/sale_point_%s/categories/%s", $entity->getSalePoint()->getId(), $file_name);
$absolute_path = sprintf("%s%s", $this->images_directory, $relative_path);
if (!is_dir(dirname($absolute_path))) {
mkdir(dirname($absolute_path), 0777, true);
}
$entity->setImage($relative_path);
$this->computed = true;
$eventArgs->getEntityManager()->getUnitOfWork()->computeChangeSets();
@file_put_contents($absolute_path, base64_decode($this->getImageContentBase64()));
}
}
}
}
}
$eventArgs->getEntityManager()->getUnitOfWork()->computeChangeSets();
/**
* @param CategoryProduct $entity
* @param PreFlushEventArgs $eventArgs
* @return string
*/
public function save(CategoryProduct $entity, PreFlushEventArgs $eventArgs)
{
if ($this->support()) {
foreach ($this->white_mime_list as $mmt => $ext) {
if ($mmt == $this->getMimeType()) {
$file_name = sprintf("%s-%s.%s", md5($this->getImageContentBase64()), uniqid(), $ext);
$relative_path = sprintf("/sale_point_%s/categories/%s", $entity->getSalePoint()->getId(), $file_name);
$absolute_path = sprintf("%s%s", $this->images_directory, $relative_path);
if (!is_dir(dirname($absolute_path))) {
mkdir(dirname($absolute_path), 0777, true);
}
$entity->setImage($relative_path);
$eventArgs->getEntityManager()->getUnitOfWork()->recomputeSingleEntityChangeSet($eventArgs->getEntityManager()->getClassMetadata(CategoryProduct::class), $entity);
@file_put_contents($absolute_path, base64_decode($this->getImageContentBase64()));
}
}
}
}
{
"category_id": "1",
"name": "Бургеры",
"description": "Описание",
"image": {
"mime_type": "image/png",
"content": "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"
}
}
prePersist срабатывает перед инсертом новой сущности в базу.
Было бы не плохо иметь специальный метод, который возвращает эти самые привилегии списком.
А уже потом, в (мобильном приложении, сайте) на основе полученных данных скрывать те или иные разделы.
# Development configuration
version: "3.7"
services:
...
# Database
db:
image: percona:latest
container_name: rapp.db
restart: on-failure
ports:
- 127.0.0.100:3306:3306
expose:
- 3306
networks:
- api
volumes:
- ./docker/mysql/dumps:/var/mysql/dumps
- ./docker/mysql/test-data:/var/mysql/test-data
env_file:
- ./docker/mysql/.env
- ./docker/.env
...
Для публичного доступа (для просмотра)
В полезной нагрузке идентификатор точки продаж.