[11/06/2024] Les premières modifs + installation de quelques modules indispensables

This commit is contained in:
2024-06-11 14:57:59 +02:00
parent 5ac5653ae5
commit 77cf2c7cc6
1626 changed files with 171457 additions and 131 deletions

View File

@@ -0,0 +1,16 @@
<?php
namespace OpenApi\Controller\Admin;
use Thelia\Controller\Admin\BaseAdminController;
abstract class BaseAdminOpenApiController extends BaseAdminController
{
const GROUP_CREATE = 'create';
const GROUP_READ = 'read';
const GROUP_UPDATE = 'update';
const GROUP_DELETE = 'delete';
}

View File

@@ -0,0 +1,45 @@
<?php
namespace OpenApi\Controller\Admin;
use OpenApi\Form\ConfigForm;
use OpenApi\OpenApi;
use Thelia\Controller\Admin\BaseAdminController;
use Symfony\Component\Routing\Annotation\Route;
use Thelia\Core\Template\ParserContext;
use Thelia\Log\Tlog;
/**
* @Route("/admin/module/OpenApi", name="config_configuration")
*/
class ConfigurationController extends BaseAdminController
{
/**
* @Route("/save", name="_save", methods="POST")
*/
public function saveAction(ParserContext $parserContext)
{
$configForm = $this->createForm(ConfigForm::getName());
try {
$form = $this->validateForm($configForm);
$data = implode(',', array_keys($form->get('enable_config')->getData()));
OpenApi::setConfigValue('config_variables', $data);
return $this->generateSuccessRedirect($configForm);
} catch (\Exception $exception) {
Tlog::getInstance()->error($exception->getMessage());
$configForm->setErrorMessage($exception->getMessage());
$parserContext
->addForm($configForm)
->setGeneralError($exception->getMessage())
;
return $this->generateErrorRedirect($configForm);
}
}
}

View File

@@ -0,0 +1,268 @@
<?php
namespace OpenApi\Controller\Front;
use OpenApi\Annotations as OA;
use OpenApi\Model\Api\Address as OpenApiAddress;
use OpenApi\Model\Api\Customer as OpenApiCustomer;
use OpenApi\Model\Api\ModelFactory;
use OpenApi\OpenApi;
use OpenApi\Service\OpenApiService;
use Symfony\Component\Routing\Annotation\Route;
use Thelia\Core\HttpFoundation\JsonResponse;
use Thelia\Core\HttpFoundation\Request;
use Thelia\Core\Translation\Translator;
use Thelia\Model\Address;
use Thelia\Model\AddressQuery;
/**
* @Route("/address", name="address")
*/
class AddressController extends BaseFrontOpenApiController
{
/**
* @Route("", name="get_address", methods="GET")
*
* @OA\Get(
* path="/address",
* tags={"address"},
* summary="Get current customer addresses",
* @OA\Response(
* response="200",
* description="Success",
* @OA\JsonContent(
* type="array",
* @OA\Items(
* ref="#/components/schemas/Address"
* )
* )
* ),
* @OA\Response(
* response="400",
* description="Bad request",
* @OA\JsonContent(ref="#/components/schemas/Error")
* )
* )
* )
*/
public function getAddress(
OpenApiService $openApiService,
ModelFactory $modelFactory
) {
$currentCustomer = $openApiService->getCurrentCustomer();
$addresses = AddressQuery::create()
->filterByCustomerId($currentCustomer->getId())
->find();
return OpenApiService::jsonResponse(
array_map(
function (Address $address) use ($modelFactory) {
/** @var OpenApiAddress $openApiAddress */
$openApiAddress = $modelFactory->buildModel('Address', $address);
$openApiAddress->validate(self::GROUP_READ);
return $openApiAddress;
},
iterator_to_array($addresses)
)
);
}
/**
* @Route("", name="add_address", methods="POST")
*
* @OA\Post(
* path="/address",
* tags={"address"},
* summary="Add an address to current customer",
* @OA\RequestBody(
* required=true,
* @OA\JsonContent(ref="#/components/schemas/Address")
* ),
* @OA\Response(
* response="200",
* description="Success",
* @OA\JsonContent(
* type="array",
* @OA\Items(
* ref="#/components/schemas/Address"
* )
* )
* ),
* @OA\Response(
* response="400",
* description="Bad request",
* @OA\JsonContent(ref="#/components/schemas/Error")
* )
* )
*/
public function createAddress(
Request $request,
OpenApiService $openApiService,
ModelFactory $modelFactory
) {
$currentCustomer = $openApiService->getCurrentCustomer();
/** @var OpenApiCustomer $openApiCustomer */
$openApiCustomer = $modelFactory->buildModel('Customer', $currentCustomer);
/** @var OpenApiAddress $openApiAddress */
$openApiAddress = $modelFactory->buildModel('Address', $request->getContent());
$openApiAddress
->setCustomer($openApiCustomer)
->validate(self::GROUP_CREATE);
$openApiAddress->getLabel() ?: $openApiAddress->setLabel(Translator::getInstance()->trans('Main Address'));
/** @var Address $theliaAddress */
$theliaAddress = $openApiAddress->toTheliaModel();
$oldDefaultAddress = AddressQuery::create()->filterByCustomer($currentCustomer)->filterByIsDefault(true)->findOne();
if (null === $oldDefaultAddress || $openApiAddress->getIsDefault()) {
$theliaAddress->makeItDefault();
}
$theliaAddress->save();
return OpenApiService::jsonResponse($openApiAddress->setId($theliaAddress->getId()));
}
/**
* @Route("/{id}", name="update_address", methods="PATCH")
*
* @OA\Patch(
* path="/address/{id}",
* tags={"address"},
* summary="Update address",
* @OA\Parameter(
* name="id",
* in="path",
* required=true,
* @OA\Schema(
* type="integer"
* )
* ),
* @OA\RequestBody(
* required=true,
* @OA\JsonContent(ref="#/components/schemas/Address")
* ),
* @OA\Response(
* response="200",
* description="Success",
* @OA\JsonContent(ref="#/components/schemas/Address")
* )
* ),
* @OA\Response(
* response="400",
* description="Bad request",
* @OA\JsonContent(ref="#/components/schemas/Error")
* )
* )
*/
public function updateAddress(
Request $request,
OpenApiService $openApiService,
ModelFactory $modelFactory,
$id
) {
$currentCustomer = $openApiService->getCurrentCustomer();
$theliaAddress = AddressQuery::create()
->filterByCustomerId($currentCustomer->getId())
->filterById($id)
->findOne();
if (null === $theliaAddress) {
throw $openApiService->buildOpenApiException(
Translator::getInstance()->trans('Invalid data', [], OpenApi::DOMAIN_NAME),
Translator::getInstance()->trans(Translator::getInstance()->trans("No address found for id $id for the current customer.", [], OpenApi::DOMAIN_NAME), [], OpenApi::DOMAIN_NAME)
);
}
/** @var OpenApiCustomer $openApiCustomer */
$openApiCustomer = $modelFactory->buildModel('Customer', $currentCustomer);
/** @var OpenApiAddress $openApiAddress */
$openApiAddress = $modelFactory->buildModel('Address', $request->getContent());
$openApiAddress
->setId($id)
->setCustomer($openApiCustomer)
->validate(self::GROUP_UPDATE);
/** @var Address $theliaAddress */
$theliaAddress = $openApiAddress->toTheliaModel();
$oldDefaultAddress = AddressQuery::create()->filterByCustomer($currentCustomer)->filterByIsDefault(true)->findOne();
$alreadyDefault = false;
/*
* Force a default address to stay as default
* Because we can't unset a default address, this is only done when a new address is set as default
*/
if (null !== $oldDefaultAddress && $oldDefaultAddress->getId() === $theliaAddress->getId()) {
$alreadyDefault = true;
$theliaAddress->setIsDefault(true);
}
if ((null === $oldDefaultAddress || $openApiAddress->getIsDefault()) && !$alreadyDefault) {
$theliaAddress->makeItDefault();
}
$theliaAddress
->save();
return new JsonResponse($openApiAddress);
}
/**
* @Route("/{id}", name="delete_address", methods="DELETE")
*
* @OA\Delete(
* path="/address/{id}",
* tags={"address"},
* summary="Delete address",
* @OA\Parameter(
* name="id",
* in="path",
* required=true,
* @OA\Schema(
* type="integer"
* )
* ),
* @OA\Response(
* response="204",
* description="Success"
* ),
* @OA\Response(
* response="400",
* description="Bad request",
* @OA\JsonContent(ref="#/components/schemas/Error")
* )
* )
*/
public function deleteAddress(
OpenApiService $openApiService,
ModelFactory $modelFactory,
$id
) {
$currentCustomer = $openApiService->getCurrentCustomer();
$theliaAddress = AddressQuery::create()
->filterByCustomerId($currentCustomer->getId())
->filterById($id)
->findOne();
if (null === $theliaAddress || $theliaAddress->getIsDefault()) {
$errorDescription = $theliaAddress ? 'Impossible to delete the default address.' : "No address found for id $id for the current customer.";
throw $openApiService->buildOpenApiException(
Translator::getInstance()->trans('Invalid data', [], OpenApi::DOMAIN_NAME),
Translator::getInstance()->trans($errorDescription, [], OpenApi::DOMAIN_NAME)
);
}
$theliaAddress->delete();
return new JsonResponse('Success', 204);
}
}

View File

@@ -0,0 +1,147 @@
<?php
/*
* This file is part of the Thelia package.
* http://www.thelia.net
*
* (c) OpenStudio <info@thelia.net>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace OpenApi\Controller\Front;
use OpenApi\Annotations as OA;
use OpenApi\Model\Api\Customer as OpenApiCustomer;
use OpenApi\Model\Api\ModelFactory;
use OpenApi\OpenApi;
use OpenApi\Service\OpenApiService;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Thelia\Action\BaseAction;
use Thelia\Core\Event\Customer\CustomerLoginEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\HttpFoundation\Request;
use Thelia\Core\Security\SecurityContext;
use Thelia\Core\Security\Token\CookieTokenProvider;
use Thelia\Core\Translation\Translator;
use Thelia\Model\ConfigQuery;
use Thelia\Model\CustomerQuery;
/**
* @Route("", name="auth")
*/
class AuthController extends BaseFrontOpenApiController
{
/**
* @Route("/login", name="login", methods="POST")
*
* @OA\Post(
* path="/login",
* tags={"customer"},
* summary="Log in a customer",
* security={},
* @OA\RequestBody(
* @OA\MediaType(
* mediaType="application/json",
* @OA\Schema(
* @OA\Property(
* property="email",
* type="string"
* ),
* @OA\Property(
* property="password",
* type="string"
* ),
* @OA\Property(
* property="rememberMe",
* type="boolean"
* ),
* )
* )
* ),
* @OA\Response(
* response="200",
* description="Success",
* @OA\JsonContent(ref="#/components/schemas/Customer")
* ),
* @OA\Response(
* response="400",
* description="Bad request",
* @OA\JsonContent(ref="#/components/schemas/Error")
* )
* )
*/
public function customerLogin(
Request $request,
SecurityContext $securityContext,
EventDispatcherInterface $dispatcher,
ModelFactory $modelFactory
) {
if ($securityContext->hasCustomerUser()) {
throw new \Exception(Translator::getInstance()->trans('A user is already connected. Please disconnect before trying to login in another account.'));
}
$data = json_decode($request->getContent(), true);
$customer = CustomerQuery::create()
->filterByEmail($data['email'])
->findOne()
;
if ($customer === null || !$customer->checkPassword($data['password'])) {
throw new \Exception(Translator::getInstance()->trans('Your username/password pair, does not correspond to any account', [], OpenApi::DOMAIN_NAME));
}
$dispatcher->dispatch(new CustomerLoginEvent($customer), TheliaEvents::CUSTOMER_LOGIN);
/* If the rememberMe property is set to true, we create a new cookie to store the information */
if (true === (bool) $data['rememberMe']) {
(new CookieTokenProvider())->createCookie(
$customer,
ConfigQuery::read('customer_remember_me_cookie_name', 'crmcn'),
ConfigQuery::read('customer_remember_me_cookie_expiration', 2592000 /* 1 month */)
);
}
/** @var OpenApiCustomer $openApiCustomer */
$openApiCustomer = $modelFactory->buildModel('Customer', $customer);
$openApiCustomer->setDefaultAddressId($customer->getDefaultAddress()->getId());
return OpenApiService::jsonResponse($openApiCustomer);
}
/**
* @Route("/logout", name="logout", methods="POST")
*
* @OA\Post(
* path="/logout",
* tags={"customer"},
* summary="Log out a customer",
*
* @OA\Response(
* response="204",
* description="Success",
* ),
* @OA\Response(
* response="400",
* description="Bad request",
* @OA\JsonContent(ref="#/components/schemas/Error")
* )
* )
*/
public function customerLogout(
SecurityContext $securityContext,
EventDispatcherInterface $dispatcher
) {
if (!$securityContext->hasCustomerUser()) {
throw new \Exception(Translator::getInstance()->trans('No user is currently logged in.'));
}
$dispatcher->dispatch((new BaseAction()), TheliaEvents::CUSTOMER_LOGOUT);
(new CookieTokenProvider())->clearCookie(ConfigQuery::read('customer_remember_me_cookie_name', 'crmcn'));
return OpenApiService::jsonResponse('Success', 204);
}
}

View File

@@ -0,0 +1,16 @@
<?php
namespace OpenApi\Controller\Front;
use Thelia\Controller\Front\BaseFrontController;
abstract class BaseFrontOpenApiController extends BaseFrontController
{
const GROUP_CREATE = 'create';
const GROUP_READ = 'read';
const GROUP_UPDATE = 'update';
const GROUP_DELETE = 'delete';
}

View File

@@ -0,0 +1,356 @@
<?php
namespace OpenApi\Controller\Front;
use OpenApi\Annotations as OA;
use OpenApi\Model\Api\ModelFactory;
use OpenApi\OpenApi;
use OpenApi\Service\OpenApiService;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Thelia\Core\Event\Cart\CartEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\HttpFoundation\JsonResponse;
use Thelia\Core\HttpFoundation\Request;
use Thelia\Core\Translation\Translator;
use Thelia\Model\Cart;
use Thelia\Model\CartItemQuery;
use Thelia\Model\ConfigQuery;
use Thelia\Model\ProductSaleElements;
use Thelia\Model\ProductSaleElementsQuery;
/**
* @Route("/cart", name="cart")
*/
class CartController extends BaseFrontOpenApiController
{
/**
* @Route("", name="get_cart", methods="GET")
*
* @OA\Get(
* path="/cart",
* tags={"cart"},
* summary="Get cart currently in session",
* @OA\Response(
* response="200",
* description="Success",
* @OA\JsonContent(ref="#/components/schemas/Cart")
* ),
* @OA\Response(
* response="400",
* description="Bad request",
* @OA\JsonContent(ref="#/components/schemas/Error")
* )
* )
*/
public function getCart(OpenApiService $openApiService)
{
return $this->createResponseFromCart($openApiService);
}
/**
* @Route("/add", name="add_cartitem", methods="POST")
*
* @OA\Post(
* path="/cart/add",
* tags={"cart"},
* summary="Add a PSE in a cart",
*
* @OA\RequestBody(
* @OA\MediaType(
* mediaType="application/json",
* @OA\Schema(
* @OA\Property(
* property="pseId",
* type="integer"
* ),
* @OA\Property(
* property="quantity",
* type="integer"
* ),
* @OA\Property(
* property="append",
* type="boolean"
* ),
* @OA\Property(
* property="newness",
* type="boolean"
* ),
* example={"pseId": 18, "quantity": 2, "append": true, "newness": true}
* )
* )
* ),
* @OA\Response(
* response="200",
* description="Success",
* @OA\JsonContent(
* @OA\Items(
* type="object",
* @OA\Property(
* property="cart",
* ref="#/components/schemas/Cart"
* ),
* @OA\Property(
* property="cartItem",
* ref="#/components/schemas/CartItem"
* )
* )
* )
* ),
* @OA\Response(
* response="400",
* description="Bad request",
* @OA\JsonContent(ref="#/components/schemas/Error")
* )
* )
*/
public function cartAddCartItem(
Request $request,
EventDispatcherInterface $dispatcher,
OpenApiService $openApiService,
ModelFactory $modelFactory
) {
$cart = $request->getSession()->getSessionCart($dispatcher);
if (null === $cart) {
throw new \Exception(Translator::getInstance()->trans('No cart found', [], OpenApi::DOMAIN_NAME));
}
$event = new CartEvent($cart);
$this->updateCartEventFromJson($request->getContent(), $event);
$dispatcher->dispatch($event, TheliaEvents::CART_ADDITEM);
return OpenApiService::jsonResponse([
'cart' => $openApiService->getCurrentOpenApiCart(),
'cartItem' => $modelFactory->buildModel('CartItem', $event->getCartItem()),
]);
}
/**
* @Route("/{cartItemId}", name="delete_cartitem", methods="DELETE")
*
* @OA\Delete(
* path="/cart/{cartItemId}",
* tags={"cart"},
* summary="Delete an item in the current cart",
* @OA\Parameter(
* name="cartItemId",
* in="path",
* required=true,
* @OA\Schema(
* type="integer"
* )
* ),
* @OA\Response(
* response="200",
* description="Success",
* @OA\JsonContent(
* @OA\Items(
* type="object",
* @OA\Property(
* property="cart",
* ref="#/components/schemas/Cart"
* ),
* @OA\Property(
* property="cartItem",
* ref="#/components/schemas/CartItem"
* )
* )
* )
* ),
* @OA\Response(
* response="400",
* description="Bad request",
* @OA\JsonContent(ref="#/components/schemas/Error")
* )
* )
*/
public function cartDeleteCartItem(
Request $request,
EventDispatcherInterface $dispatcher,
OpenApiService $openApiService,
$cartItemId
) {
$cart = $request->getSession()->getSessionCart($dispatcher);
if (null === $cart) {
throw new \Exception(Translator::getInstance()->trans('No cart found', [], OpenApi::DOMAIN_NAME));
}
$cartItem = CartItemQuery::create()->filterById($cartItemId)->findOne();
if (null === $cartItem) {
throw new \Exception(Translator::getInstance()->trans('Deletion impossible : this cart item does not exists.', [], OpenApi::DOMAIN_NAME));
}
$cartEvent = new CartEvent($cart);
$cartEvent->setCartItemId($cartItemId);
$dispatcher->dispatch(
$cartEvent,
TheliaEvents::CART_DELETEITEM
);
return $this->createResponseFromCart($openApiService);
}
/**
* @Route("/{cartItemId}", name="update_cartitem", methods="PATCH")
*
* @OA\Patch(
* path="/cart/{cartItemId}",
* tags={"cart"},
* summary="Modify an item in the current cart",
* @OA\Parameter(
* name="cartItemId",
* in="path",
* required=true,
* @OA\Schema(
* type="integer"
* )
* ),
* @OA\RequestBody(
* @OA\MediaType(
* mediaType="application/json",
* @OA\Schema(
* @OA\Property(
* property="quantity",
* type="integer"
* ),
* example={"quantity": 0}
* )
* )
* ),
* @OA\Response(
* response="200",
* description="Success",
* @OA\JsonContent(ref="#/components/schemas/Cart")
* ),
* @OA\Response(
* response="400",
* description="Bad request",
* @OA\JsonContent(ref="#/components/schemas/Error")
* )
* )
*/
public function cartUpdateCartItem(
Request $request,
EventDispatcherInterface $dispatcher,
ModelFactory $modelFactory,
OpenApiService $openApiService,
$cartItemId
) {
$cart = $request->getSession()->getSessionCart($dispatcher);
if (null === $cart) {
throw new \Exception(Translator::getInstance()->trans('No cart found', [], OpenApi::DOMAIN_NAME));
}
$cartItem = CartItemQuery::create()->filterById($cartItemId)->findOne();
if (null === $cartItem) {
throw new \Exception(Translator::getInstance()->trans('Modification impossible : this cart item does not exists.', [], OpenApi::DOMAIN_NAME));
}
/* Check if cart item belongs to user's cart */
if (!$cartItem || $cartItem->getCartId() !== $cart->getId()) {
throw new \Exception(Translator::getInstance()->trans("This cartItem doesn't belong to this cart.", [], OpenApi::DOMAIN_NAME));
}
$event = new CartEvent($cart);
$event->setCartItemId($cartItemId);
if ($request->get('quantity') === 0) {
$dispatcher->dispatch(
$event,
TheliaEvents::CART_DELETEITEM
);
} else {
$this->updateCartEventFromJson($request->getContent(), $event);
$dispatcher->dispatch($event, TheliaEvents::CART_UPDATEITEM);
}
return OpenApiService::jsonResponse([
'cart' => $openApiService->getCurrentOpenApiCart(),
'cartItem' => $modelFactory->buildModel('CartItem', $event->getCartItem()),
]);
}
/**
* Create a new JSON response of an OpenApi cart and returns it, from a Thelia Cart.
*
* @param Cart $cart
*
* @return JsonResponse
*
* @throws \Propel\Runtime\Exception\PropelException
*/
protected function createResponseFromCart(OpenApiService $openApiService)
{
return OpenApiService::jsonResponse($openApiService->getCurrentOpenApiCart());
}
/**
* @param int $quantity
*
* @return bool
*/
protected function checkAvailableStock(ProductSaleElements $pse, $quantity)
{
if ($pse && $quantity) {
return $quantity > $pse->getQuantity() && ConfigQuery::checkAvailableStock() && !$pse->getProduct()->getVirtual() === 0;
}
throw new \Exception(Translator::getInstance()->trans('A PSE is needed in the POST request to add an item to the cart.'));
}
/**
* Update a Cart Event from a json.
*
* @param $json
*
* @throws \Exception
*/
protected function updateCartEventFromJson($json, CartEvent $event): void
{
$data = json_decode($json, true);
if (!isset($data['quantity'])) {
throw new \Exception(Translator::getInstance()->trans('A quantity is needed in the POST request to add an item to the cart.'));
}
/* If the function was called from the PATCH route, we just update the quantity and return */
if ($cartItemId = $event->getCartItemId()) {
$cartItem = CartItemQuery::create()->filterById($cartItemId)->findOne();
if ($this->checkAvailableStock($cartItem->getProductSaleElements(), $data['quantity'])) {
throw new \Exception(Translator::getInstance()->trans('Desired quantity exceed available stock'));
}
$event->setQuantity($data['quantity']);
return;
}
/* If the function was called from the POST route, we need to set the pseId and append properties, as we need a new CartItem */
if (!isset($data['pseId'])) {
throw new \Exception(Translator::getInstance()->trans('A PSE is needed in the POST request to add an item to the cart.'));
}
if (!isset($data['append'])) {
throw new \Exception(Translator::getInstance()->trans('You need to set the append value in the POST request to add an item to the cart.'));
}
$pse = ProductSaleElementsQuery::create()->findPk($data['pseId']);
if ($this->checkAvailableStock($pse, $data['quantity'])) {
throw new \Exception(Translator::getInstance()->trans('Desired quantity exceed available stock'));
}
/** If newness then force new cart_item id */
$newness = isset($data['newness']) ? (bool) $data['newness'] : false;
$event
->setProduct($pse->getProductId())
->setProductSaleElementsId($data['pseId'])
->setQuantity($data['quantity'])
->setAppend($data['append'])
->setNewness($newness)
;
}
}

View File

@@ -0,0 +1,147 @@
<?php
namespace OpenApi\Controller\Front;
use OpenApi\Annotations as OA;
use OpenApi\Model\Api\ModelFactory;
use OpenApi\Service\OpenApiService;
use OpenApi\Service\SearchService;
use Symfony\Component\Routing\Annotation\Route;
use Thelia\Core\HttpFoundation\Request;
/**
* @Route("/category", name="category")
*/
class CategoryController extends BaseFrontOpenApiController
{
/**
* @Route("/search", name="_search", methods="GET")
*
* @OA\Get(
* path="/category/search",
* tags={"Category", "Search"},
* summary="Search categories",
* @OA\Parameter(
* name="id",
* in="query",
* @OA\Schema(
* type="integer"
* )
* ),
* @OA\Parameter(
* name="ids[]",
* in="query",
* @OA\Schema(
* type="array",
* @OA\Items(
* type="integer"
* )
* )
* ),
* @OA\Parameter(
* name="parentsIds[]",
* in="query",
* @OA\Schema(
* type="array",
* @OA\Items(
* type="integer"
* )
* )
* ),
* @OA\Parameter(
* name="visible",
* in="query",
* @OA\Schema(
* type="boolean",
* default="true"
* )
* ),
* @OA\Parameter(
* name="locale",
* in="query",
* description="Current locale by default",
* @OA\Schema(
* type="string"
* )
* ),
* @OA\Parameter(
* name="title",
* in="query",
* @OA\Schema(
* type="string"
* )
* ),
* @OA\Parameter(
* name="description",
* in="query",
* @OA\Schema(
* type="string"
* )
* ),
* @OA\Parameter(
* name="chapo",
* in="query",
* @OA\Schema(
* type="string"
* )
* ),
* @OA\Parameter(
* name="postscriptum",
* in="query",
* @OA\Schema(
* type="string"
* )
* ),
* @OA\Parameter(
* name="limit",
* in="query",
* @OA\Schema(
* type="integer",
* default="20"
* )
* ),
* @OA\Parameter(
* name="offset",
* in="query",
* @OA\Schema(
* type="integer"
* )
* ),
* @OA\Parameter(
* name="order",
* in="query",
* @OA\Schema(
* type="string",
* enum={"alpha", "alpha_reverse", "created_at", "created_at_reverse"},
* default="alpha"
* )
* ),
* @OA\Response(
* response="200",
* description="Success",
* @OA\JsonContent(
* type="array",
* @OA\Items(
* ref="#/components/schemas/Category"
* )
* )
* ),
* @OA\Response(
* response="400",
* description="Bad request",
* @OA\JsonContent(ref="#/components/schemas/Error")
* )
* )
*/
public function search(
Request $request,
ModelFactory $modelFactory,
SearchService $searchService
) {
$query = $searchService->baseSearchItems("category", $request);
$categories = $query->find();
return OpenApiService::jsonResponse(
array_map(fn ($category) => $modelFactory->buildModel('Category', $category), iterator_to_array($categories))
);
}
}

View File

@@ -0,0 +1,318 @@
<?php
namespace OpenApi\Controller\Front;
use Front\Front;
use OpenApi\Annotations as OA;
use OpenApi\Model\Api\Checkout;
use OpenApi\Model\Api\ModelFactory;
use OpenApi\OpenApi;
use OpenApi\Service\OpenApiService;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Thelia\Core\Event\Delivery\DeliveryPostageEvent;
use Thelia\Core\Event\Order\OrderEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\HttpFoundation\Request;
use Thelia\Core\HttpFoundation\Session\Session;
use Thelia\Core\Security\SecurityContext;
use Thelia\Core\Translation\Translator;
use Thelia\Model\AddressQuery;
use Thelia\Model\AreaDeliveryModuleQuery;
use Thelia\Model\Cart;
use Thelia\Model\ConfigQuery;
use Thelia\Model\ModuleQuery;
use Thelia\Model\Order;
use Thelia\Module\Exception\DeliveryException;
/**
* @Route("/checkout")
*/
class CheckoutController extends BaseFrontOpenApiController
{
/**
* @Route("", name="set_checkout", methods="POST")
* @OA\Post(
* path="/checkout",
* tags={"checkout"},
* summary="Validate and set an checkout",
* @OA\RequestBody(
* required=true,
* @OA\JsonContent(
* allOf={
* @OA\Schema(@OA\Property(property="needValidate", type="boolean", default=false)),
* @OA\Schema(ref="#/components/schemas/Checkout")
* }
* )
* ),
* @OA\Response(
* response="200",
* description="Success",
* @OA\JsonContent(ref="#/components/schemas/Checkout")
* ),
* @OA\Response(
* response="400",
* description="Success",
* @OA\JsonContent(ref="#/components/schemas/Error")
* )
* )
*/
public function setCheckout(
Request $request,
Session $session,
EventDispatcherInterface $dispatcher,
SecurityContext $securityContext,
OpenApiService $openApiService,
ModelFactory $modelFactory
) {
// Allow to check if a customer is logged
$openApiService->getCurrentCustomer();
$cart = $session->getSessionCart($dispatcher);
if ($cart === null || $cart->countCartItems() === 0) {
throw new \Exception(Translator::getInstance()->trans('Cart is empty', [], OpenApi::DOMAIN_NAME));
}
if (true === ConfigQuery::checkAvailableStock()) {
if (!$this->checkStockNotEmpty($cart)) {
throw new \Exception(Translator::getInstance()->trans('Not enough stock', [], OpenApi::DOMAIN_NAME));
}
}
$decodedContent = json_decode($request->getContent(), true);
/** @var Checkout $checkout */
$checkout = $modelFactory->buildModel('Checkout', $decodedContent);
if (isset($decodedContent['needValidate']) && true === $decodedContent['needValidate']) {
$checkout->checkIsValid();
}
$order = $this->getOrder($request);
$orderEvent = new OrderEvent($order);
$this->setOrderDeliveryPart(
$request,
$session,
$dispatcher,
$securityContext,
$checkout,
$orderEvent
);
$this->setOrderInvoicePart(
$dispatcher,
$securityContext,
$checkout,
$orderEvent
);
$responseCheckout = $checkout
->createFromOrder($orderEvent->getOrder());
return OpenApiService::jsonResponse($responseCheckout);
}
/**
* @Route("", name="get_checkout", methods="GET")
* @OA\Get(
* path="/checkout",
* tags={"checkout"},
* summary="get current checkout",
* @OA\Response(
* response="200",
* description="Success",
* @OA\JsonContent(ref="#/components/schemas/Checkout"),
* )
* )
*/
public function getCheckout(
Request $request,
ModelFactory $modelFactory
) {
$order = $this->getOrder($request);
/** @var Checkout $checkout */
$checkout = ($modelFactory->buildModel('Checkout'))
->createFromOrder($order);
$checkout->setPickupAddress($request->getSession()->get(OpenApi::PICKUP_ADDRESS_SESSION_KEY));
return OpenApiService::jsonResponse($checkout);
}
protected function setOrderDeliveryPart(
Request $request,
Session $session,
EventDispatcherInterface $dispatcher,
SecurityContext $securityContext,
Checkout $checkout,
OrderEvent $orderEvent
): void {
$cart = $session->getSessionCart($dispatcher);
$deliveryAddress = AddressQuery::create()->findPk($checkout->getDeliveryAddressId());
$deliveryModule = ModuleQuery::create()->findPk($checkout->getDeliveryModuleId());
/** In case of pickup point delivery, we cannot use a Thelia address since it won't exist, so we get one from the request */
$pickupAddress = $checkout->getPickupAddress();
if (null !== $deliveryAddress) {
if ($deliveryAddress->getCustomerId() !== $securityContext->getCustomerUser()->getId()) {
throw new \Exception(
Translator::getInstance()->trans(
'Delivery address does not belong to the current customer',
[],
Front::MESSAGE_DOMAIN
)
);
}
}
if (null !== $pickupAddress && $deliveryAddress && $deliveryModule) {
if (null === AreaDeliveryModuleQuery::create()->findByCountryAndModule(
$deliveryAddress->getCountry(),
$deliveryModule
)) {
throw new \Exception(
Translator::getInstance()->trans(
'Delivery module cannot be use with selected delivery address',
[],
Front::MESSAGE_DOMAIN
)
);
}
}
$postage = null;
if ($deliveryAddress && $deliveryModule) {
$moduleInstance = $deliveryModule->getDeliveryModuleInstance($this->container);
$deliveryPostageEvent = new DeliveryPostageEvent($moduleInstance, $cart, $deliveryAddress);
$dispatcher->dispatch(
$deliveryPostageEvent,
TheliaEvents::MODULE_DELIVERY_GET_POSTAGE
);
if (!$deliveryPostageEvent->isValidModule()) {
throw new DeliveryException(
Translator::getInstance()->trans('The delivery module is not valid.', [], Front::MESSAGE_DOMAIN)
);
}
$postage = $deliveryPostageEvent->getPostage();
}
$orderEvent->setDeliveryAddress($deliveryAddress !== null ? $deliveryAddress->getId() : $securityContext->getCustomerUser()?->getDefaultAddress()?->getId());
$orderEvent->setDeliveryModule($deliveryModule?->getId());
$orderEvent->setPostage($postage !== null ? $postage->getAmount() : 0.0);
$orderEvent->setPostageTax($postage !== null ? $postage->getAmountTax() : 0.0);
$orderEvent->setPostageTaxRuleTitle($postage !== null ? $postage->getTaxRuleTitle() : '');
$dispatcher->dispatch($orderEvent, TheliaEvents::ORDER_SET_DELIVERY_ADDRESS);
$dispatcher->dispatch($orderEvent, TheliaEvents::ORDER_SET_POSTAGE);
$dispatcher->dispatch($orderEvent, TheliaEvents::ORDER_SET_DELIVERY_MODULE);
if ($deliveryAddress && $deliveryModule) {
$this->checkValidDelivery();
}
$request->getSession()->set(OpenApi::PICKUP_ADDRESS_SESSION_KEY, json_encode($pickupAddress));
}
protected function setOrderInvoicePart(
EventDispatcherInterface $dispatcher,
SecurityContext $securityContext,
Checkout $checkout,
OrderEvent $orderEvent
): void {
$billingAddress = AddressQuery::create()->findPk($checkout->getBillingAddressId());
if ($billingAddress) {
if ($billingAddress->getCustomerId() !== $securityContext->getCustomerUser()->getId()) {
throw new \Exception(
Translator::getInstance()->trans(
'Invoice address does not belong to the current customer',
[],
Front::MESSAGE_DOMAIN
)
);
}
}
$paymentModule = ModuleQuery::create()->findPk($checkout->getPaymentModuleId());
$orderEvent->setInvoiceAddress($billingAddress !== null ? $billingAddress->getId() : null);
$orderEvent->setPaymentModule($paymentModule !== null ? $paymentModule->getId() : null);
$dispatcher->dispatch($orderEvent, TheliaEvents::ORDER_SET_INVOICE_ADDRESS);
$dispatcher->dispatch($orderEvent, TheliaEvents::ORDER_SET_PAYMENT_MODULE);
// Only check invoice is module and address is set
if ($billingAddress && $paymentModule) {
$this->checkValidInvoice();
}
}
protected function getOrder(Request $request)
{
$session = $request->getSession();
if (null !== $order = $session->getOrder()) {
return $order;
}
$order = new Order();
$session->setOrder($order);
return $order;
}
protected function checkValidDelivery(): void
{
$order = $this->getSession()->getOrder();
if (null === $order
||
null === $order->getChoosenDeliveryAddress()
||
null === $order->getDeliveryModuleId()
||
null === AddressQuery::create()->findPk($order->getChoosenDeliveryAddress())
||
null === ModuleQuery::create()->findPk($order->getDeliveryModuleId())) {
throw new \Exception(Translator::getInstance()->trans('Invalid delivery', [], OpenApi::DOMAIN_NAME));
}
}
protected function checkValidInvoice(): void
{
$order = $this->getSession()->getOrder();
if (null === $order
||
null === $order->getChoosenInvoiceAddress()
||
null === $order->getPaymentModuleId()
||
null === AddressQuery::create()->findPk($order->getChoosenInvoiceAddress())
||
null === ModuleQuery::create()->findPk($order->getPaymentModuleId())) {
throw new \Exception(Translator::getInstance()->trans('Invalid invoice', [], OpenApi::DOMAIN_NAME));
}
}
protected function checkStockNotEmpty(Cart $cart)
{
$cartItems = $cart->getCartItems();
foreach ($cartItems as $cartItem) {
$pse = $cartItem->getProductSaleElements();
$product = $cartItem->getProduct();
if ($pse->getQuantity() <= 0 && $product->getVirtual() !== 1) {
return false;
}
}
return true;
}
}

View File

@@ -0,0 +1,54 @@
<?php
namespace OpenApi\Controller\Front;
use OpenApi\Annotations as OA;
use OpenApi\OpenApi;
use Symfony\Component\Routing\Annotation\Route;
use Thelia\Core\HttpFoundation\JsonResponse;
use Thelia\Core\HttpFoundation\Request;
use Thelia\Core\Translation\Translator;
use Thelia\Model\ConfigQuery;
/**
* @Route("/config", name="config")
*/
class ConfigController extends BaseFrontOpenApiController
{
/**
* @Route("/{key}", name="get_config", methods="GET")
*
* @OA\Get(
* path="/config/{key}",
* tags={"config"},
* summary="Get a config value by it's key",
* @OA\Parameter(
* name="key",
* in="path",
* required=true,
* @OA\Schema(
* type="string"
* )
* ),
* @OA\Response(
* response="200",
* description="Success",
* @OA\JsonContent(type="string")
* ),
* @OA\Response(
* response="400",
* description="Bad request",
* @OA\JsonContent(ref="#/components/schemas/Error")
* )
* )
*/
public function getConfig($key)
{
$config = ConfigQuery::create()->filterByName($key)->findOne();
if ($config && in_array($config->getId(), explode(',', OpenApi::getConfigValue('config_variables')))) {
return new JsonResponse($config->getValue());
}
return new JsonResponse(Translator::getInstance()->trans('You are not allowed to access this config'), 401);
}
}

View File

@@ -0,0 +1,187 @@
<?php
namespace OpenApi\Controller\Front;
use Exception;
use OpenApi\Annotations as OA;
use OpenApi\Model\Api\ModelFactory;
use OpenApi\OpenApi;
use OpenApi\Service\OpenApiService;
use OpenApi\Service\SearchService;
use Symfony\Component\Routing\Annotation\Route;
use Thelia\Core\HttpFoundation\JsonResponse;
use Thelia\Core\HttpFoundation\Request;
use Thelia\Core\Translation\Translator;
use Thelia\Model\ContentQuery;
/**
* @Route("/content", name="content")
*/
class ContentController extends BaseFrontOpenApiController
{
/**
* @Route("/search", name="content_search", methods="GET")
*
* @OA\Get(
* path="/content/search",
* tags={"Content", "Search"},
* summary="Search contents",
* @OA\Parameter(
* name="id",
* in="query",
* @OA\Schema(
* type="integer"
* )
* ),
* @OA\Parameter(
* name="ids[]",
* in="query",
* @OA\Schema(
* type="array",
* @OA\Items(
* type="integer"
* )
* )
* ),
* @OA\Parameter(
* name="visible",
* in="query",
* @OA\Schema(
* type="boolean",
* default="true"
* )
* ),
* @OA\Parameter(
* name="locale",
* in="query",
* description="Current locale by default",
* @OA\Schema(
* type="string"
* )
* ),
* @OA\Parameter(
* name="title",
* in="query",
* @OA\Schema(
* type="string"
* )
* ),
* @OA\Parameter(
* name="description",
* in="query",
* @OA\Schema(
* type="string"
* )
* ),
* @OA\Parameter(
* name="chapo",
* in="query",
* @OA\Schema(
* type="string"
* )
* ),
* @OA\Parameter(
* name="postscriptum",
* in="query",
* @OA\Schema(
* type="string"
* )
* ),
* @OA\Parameter(
* name="limit",
* in="query",
* @OA\Schema(
* type="integer",
* default="20"
* )
* ),
* @OA\Parameter(
* name="offset",
* in="query",
* @OA\Schema(
* type="integer"
* )
* ),
* @OA\Parameter(
* name="order",
* in="query",
* @OA\Schema(
* type="string",
* enum={"alpha", "alpha_reverse", "created_at", "created_at_reverse"},
* default="alpha"
* )
* ),
* @OA\Response(
* response="200",
* description="Success",
* @OA\JsonContent(
* type="array",
* @OA\Items(
* ref="#/components/schemas/Content"
* )
* )
* ),
* @OA\Response(
* response="400",
* description="Bad request",
* @OA\JsonContent(ref="#/components/schemas/Error")
* )
* )
*/
public function search(
Request $request,
ModelFactory $modelFactory,
SearchService $searchService
) {
$query = $searchService->baseSearchItems("content", $request);
$contents = $query->find();
return OpenApiService::jsonResponse(
array_map(fn ($content) => $modelFactory->buildModel('Content', $content), iterator_to_array($contents))
);
}
/**
* @Route("/{id}", name="get_content", methods="GET", requirements={"collectionId"="\d+"})
*
* @OA\Get(
* path="/content/{id}",
* tags={"content"},
* summary="Get content values by ID",
* @OA\Parameter(
* name="id",
* in="path",
* required=true,
* example="1",
* @OA\Schema(
* type="integer"
* )
* ),
* @OA\Response(
* response="200",
* description="Success",
* @OA\JsonContent(ref="#/components/schemas/Content")
* ),
* @OA\Response(
* response="400",
* description="Bad request",
* @OA\JsonContent(ref="#/components/schemas/Error")
* )
* )
*
* @throws Exception
*/
public function getContent(ModelFactory $modelFactory, $id)
{
$content = ContentQuery::create()
->findOneById($id);
$apiContent = $modelFactory->buildModel('Content', $content);
if (null === $content) {
throw new Exception(Translator::getInstance()->trans('Content does not exist.', [], OpenApi::DOMAIN_NAME));
}
return new JsonResponse($apiContent);
}
}

View File

@@ -0,0 +1,180 @@
<?php
namespace OpenApi\Controller\Front;
use Exception;
use OpenApi\Annotations as OA;
use OpenApi\Model\Api\Coupon;
use OpenApi\Model\Api\ModelFactory;
use OpenApi\OpenApi;
use OpenApi\Service\OpenApiService;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\EventDispatcher\Event;
use Thelia\Core\Event\Coupon\CouponConsumeEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\HttpFoundation\Request;
use Thelia\Core\HttpFoundation\Session\Session;
use Thelia\Core\Translation\Translator;
use Thelia\Exception\UnmatchableConditionException;
use Thelia\Model\CouponQuery;
/**
* @Route("/coupon", name="coupon")
*/
class CouponController extends BaseFrontOpenApiController
{
/**
* @Route("", name="submit_coupon", methods="POST")
*
* @OA\Post(
* path="/coupon",
* tags={"coupon"},
* summary="Submit a coupon",
*
* @OA\RequestBody(
* @OA\MediaType(
* mediaType="application/json",
* @OA\Schema(
* @OA\Property(
* property="code",
* type="string"
* ),
* )
* )
* ),
* @OA\Response(
* response="200",
* description="Success",
* @OA\JsonContent(ref="#/components/schemas/Coupon")
* ),
* @OA\Response(
* response="400",
* description="Bad request",
* @OA\JsonContent(ref="#/components/schemas/Error")
* )
* )
*/
public function submitCoupon(
Request $request,
EventDispatcherInterface $dispatcher,
ModelFactory $modelFactory
) {
$cart = $request->getSession()->getSessionCart($dispatcher);
if (null === $cart) {
throw new \Exception(Translator::getInstance()->trans('No cart found', [], OpenApi::DOMAIN_NAME));
}
/** @var Coupon $openApiCoupon */
$openApiCoupon = $modelFactory->buildModel('Coupon', $request->getContent());
if (null === $openApiCoupon->getCode()) {
throw new \Exception(Translator::getInstance()->trans('Coupon code cannot be null', [], OpenApi::DOMAIN_NAME));
}
/** We verify that the given coupon actually exists in the base */
$theliaCoupon = CouponQuery::create()->filterByCode($openApiCoupon->getCode())->findOne();
if (null === $theliaCoupon) {
throw new \Exception(Translator::getInstance()->trans('No coupons were found for this coupon code.', [], OpenApi::DOMAIN_NAME));
}
try {
$event = new CouponConsumeEvent($openApiCoupon->getCode());
$dispatcher->dispatch($event, TheliaEvents::COUPON_CONSUME);
$openApiCoupon = $modelFactory->buildModel('Coupon', $theliaCoupon);
} catch (UnmatchableConditionException $exception) {
throw new \Exception(Translator::getInstance()->trans('You should sign in or register to use this coupon.', [], OpenApi::DOMAIN_NAME));
}
return OpenApiService::jsonResponse($openApiCoupon);
}
/**
* @Route("/clear_all", name="clear_all_coupon", methods="GET")
*
* @OA\Get(
* path="/coupon/clear_all",
* tags={"coupon"},
* summary="Clear all coupons",
*
* @OA\Response(
* response="200",
* description="Success",
* @OA\JsonContent(ref="#/components/schemas/Cart")
* ),
* @OA\Response(
* response="400",
* description="Bad request",
* @OA\JsonContent(ref="#/components/schemas/Error")
* )
* )
*/
public function clearAllCoupon(
Request $request,
EventDispatcherInterface $dispatcher,
ModelFactory $modelFactory
) {
$cart = $request->getSession()->getSessionCart($dispatcher);
try {
$dispatcher->dispatch((new Event()), TheliaEvents::COUPON_CLEAR_ALL);
} catch (\Exception $exception) {
throw new \Exception(Translator::getInstance()->trans('An error occurred while clearing coupons : ') . $exception->getMessage());
}
return OpenApiService::jsonResponse($modelFactory->buildModel('Cart', $cart));
}
/**
* @Route("/clear/{id}", name="clear_coupon", methods="GET")
*
* @OA\Get(
* path="/coupon/clear/{id}",
* tags={"coupon"},
* summary="Clear a specific coupon from cart",
* @OA\Parameter(
* name="id",
* in="path",
* required=true,
* example="1",
* @OA\Schema(
* type="integer"
* )
* ),
* @OA\Response(
* response="200",
* description="Success",
* @OA\JsonContent(ref="#/components/schemas/Cart")
* ),
* @OA\Response(
* response="400",
* description="Bad request",
* @OA\JsonContent(ref="#/components/schemas/Error")
* )
* )
*/
public function clearCoupon(
EventDispatcherInterface $dispatcher,
ModelFactory $modelFactory,
Session $session,
$id
) {
$cart = $session->getSessionCart($dispatcher);
try {
$coupon = CouponQuery::create()->findOneById($id);
if (null === $coupon) {
throw new Exception();
}
$consumedCoupons = $session->getConsumedCoupons();
unset($consumedCoupons[$coupon->getCode()]);
$session->setConsumedCoupons($consumedCoupons);
} catch (Exception $e) {
throw new Exception(Translator::getInstance()->trans('An error occurred while clearing coupon ' . $id . ' : ') . $e->getMessage());
}
return OpenApiService::jsonResponse($modelFactory->buildModel('Cart', $cart));
}
}

View File

@@ -0,0 +1,230 @@
<?php
/*
* This file is part of the Thelia package.
* http://www.thelia.net
*
* (c) OpenStudio <info@thelia.net>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace OpenApi\Controller\Front;
use OpenApi\Annotations as OA;
use OpenApi\Model\Api\Address as OpenApiAddress;
use OpenApi\Model\Api\Customer as OpenApiCustomer;
use OpenApi\Model\Api\ModelFactory;
use OpenApi\OpenApi;
use OpenApi\Service\OpenApiService;
use Propel\Runtime\Propel;
use Symfony\Component\Routing\Annotation\Route;
use Thelia\Core\HttpFoundation\Request;
use Thelia\Core\Security\SecurityContext;
use Thelia\Core\Translation\Translator;
use Thelia\Model\Address;
use Thelia\Model\Customer;
/**
* @Route("/customer", name="customer")
*/
class CustomerController extends BaseFrontOpenApiController
{
/**
* @Route("", name="get_customer", methods="GET")
*
* @OA\Get(
* path="/customer",
* tags={"customer"},
* summary="Get current customer",
* @OA\Response(
* response="200",
* description="Success",
* @OA\JsonContent(
* type="array",
* @OA\Items(
* ref="#/components/schemas/Customer"
* )
* )
* ),
* @OA\Response(
* response="400",
* description="Bad request",
* @OA\JsonContent(ref="#/components/schemas/Error")
* )
* )
* )
*/
public function getCustomer(
OpenApiService $openApiService,
ModelFactory $modelFactory
) {
$currentCustomer = $openApiService->getCurrentCustomer();
/** @var OpenApiCustomer $openApiCustomer */
$openApiCustomer = $modelFactory->buildModel('Customer', $currentCustomer);
$openApiCustomer->validate(self::GROUP_READ);
return OpenApiService::jsonResponse($openApiCustomer);
}
/**
* @Route("", name="add_customer", methods="POST")
*
* @OA\Post(
* path="/customer",
* tags={"customer"},
* summary="Create a new customer",
* @OA\RequestBody(
* @OA\MediaType(
* mediaType="application/json",
* @OA\Schema(
* @OA\Property(
* property="customer",
* type="object",
* ref="#/components/schemas/Customer",
* ),
* @OA\Property(
* property="address",
* type="object",
* ref="#/components/schemas/Address",
* ),
* @OA\Property(
* property="password",
* type="string",
* ),
* ),
* ),
* ),
* @OA\Response(
* response="200",
* description="Success",
* @OA\JsonContent(
* type="array",
* @OA\Items(
* ref="#/components/schemas/Customer"
* )
* )
* ),
* @OA\Response(
* response="400",
* description="Bad request",
* @OA\JsonContent(ref="#/components/schemas/Error")
* )
* )
*/
public function createCustomer(Request $request, ModelFactory $modelFactory)
{
$data = json_decode($request->getContent(), true);
/** @var OpenApiCustomer $openApiCustomer */
$openApiCustomer = $modelFactory->buildModel('Customer', $data['customer']);
$openApiCustomer->validate(self::GROUP_CREATE);
/** We create a Propel transaction to save the customer and get its ID necessary for the validation
* of the address without actually commiting to the base until everything is in order.
*/
$con = Propel::getConnection();
$con->beginTransaction();
try {
/** @var Customer $theliaCustomer */
$theliaCustomer = $openApiCustomer->toTheliaModel();
$theliaCustomer->setPassword($data['password'])->save();
$openApiCustomer->setId($theliaCustomer->getId());
/** We must catch the validation exception if it is thrown to rollback the Propel transaction before throwing the exception again */
/** @var OpenApiAddress $openApiAddress */
$openApiAddress = $modelFactory->buildModel('Address', $data['address']);
$openApiAddress->setCustomer($openApiCustomer)->validate(self::GROUP_CREATE);
/** @var Address $theliaAddress */
$theliaAddress = $openApiAddress->toTheliaModel();
$theliaAddress
->setLabel(Translator::getInstance()->trans('Main Address', [], OpenApi::DOMAIN_NAME))
->setIsDefault(1)
->save()
;
} catch (\Exception $exception) {
$con->rollBack();
throw $exception;
}
/* If everything went fine, we actually commit the changes to the base. */
$con->commit();
$openApiCustomer->setDefaultAddressId($theliaAddress->getId());
return OpenApiService::jsonResponse($openApiCustomer);
}
/**
* @Route("", name="update_customer", methods="PATCH")
*
* @OA\Patch(
* path="/customer",
* tags={"customer"},
* summary="Edit the current customer",
* @OA\RequestBody(
* @OA\MediaType(
* mediaType="application/json",
* @OA\Schema(
* @OA\Property(
* property="customer",
* type="object",
* ref="#/components/schemas/Customer",
* ),
* @OA\Property(
* property="password",
* type="string",
* ),
* ),
* ),
* ),
* @OA\Response(
* response="200",
* description="Success",
* @OA\JsonContent(
* type="array",
* @OA\Items(
* ref="#/components/schemas/Customer"
* )
* )
* ),
* @OA\Response(
* response="400",
* description="Bad request",
* @OA\JsonContent(ref="#/components/schemas/Error")
* )
* )
*/
public function updateCustomer(
Request $request,
SecurityContext $securityContext,
OpenApiService $openApiService,
ModelFactory $modelFactory
) {
$currentCustomer = $openApiService->getCurrentCustomer();
$data = json_decode($request->getContent(), true);
/** @var OpenApiCustomer $openApiCustomer */
$openApiCustomer = $modelFactory->buildModel('Customer', $data['customer']);
$openApiCustomer->setId($currentCustomer->getId())->validate(self::GROUP_UPDATE);
/** @var Customer $theliaCustomer */
$theliaCustomer = $openApiCustomer->toTheliaModel();
$theliaCustomer->setNew(false);
if (\array_key_exists('password', $data) && null !== $newPassword = $data['password']) {
$theliaCustomer->setPassword($newPassword);
}
$theliaCustomer->save();
$securityContext->setCustomerUser($theliaCustomer);
return OpenApiService::jsonResponse($openApiCustomer);
}
}

View File

@@ -0,0 +1,403 @@
<?php
namespace OpenApi\Controller\Front;
use OpenApi\Annotations as OA;
use OpenApi\Events\DeliveryModuleOptionEvent;
use OpenApi\Events\OpenApiEvents;
use OpenApi\Model\Api\DeliveryModule;
use OpenApi\Model\Api\ModelFactory;
use OpenApi\OpenApi;
use OpenApi\Service\OpenApiService;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Thelia\Core\Event\Delivery\DeliveryPostageEvent;
use Thelia\Core\Event\Delivery\PickupLocationEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\HttpFoundation\JsonResponse;
use Thelia\Core\HttpFoundation\Request;
use Thelia\Core\Security\SecurityContext;
use Thelia\Core\Translation\Translator;
use Thelia\Model\AddressQuery;
use Thelia\Model\AreaDeliveryModuleQuery;
use Thelia\Model\Cart;
use Thelia\Model\CountryQuery;
use Thelia\Model\Module;
use Thelia\Model\ModuleQuery;
use Thelia\Model\PickupLocation;
use Thelia\Model\StateQuery;
use Thelia\Module\AbstractDeliveryModule;
use Thelia\Module\BaseModule;
use Thelia\Module\Exception\DeliveryException;
/**
* @Route("/delivery", name="delivery")
*/
class DeliveryController extends BaseFrontOpenApiController
{
/**
* @Route("/pickup-locations", name="delivery_pickup_locations", methods="GET")
*
* @OA\Get(
* path="/delivery/pickup-locations",
* tags={"delivery"},
* summary="Get the list of all available pickup locations for a specific address, by default from all modules or filtered by an array of delivery modules id",
* @OA\Parameter(
* name="address",
* in="query",
* @OA\Schema(
* type="string"
* )
* ),
* @OA\Parameter(
* name="city",
* in="query",
* @OA\Schema(
* type="string"
* )
* ),
* @OA\Parameter(
* name="zipCode",
* in="query",
* @OA\Schema(
* type="string"
* )
* ),
* @OA\Parameter(
* name="stateId",
* in="query",
* @OA\Schema(
* type="integer"
* )
* ),
* @OA\Parameter(
* name="countryId",
* in="query",
* @OA\Schema(
* type="integer"
* )
* ),
* @OA\Parameter(
* name="radius",
* description="Radius in meters to filter pickup locations",
* in="query",
* @OA\Schema(
* type="integer"
* )
* ),
* @OA\Parameter(
* name="maxRelays",
* description="Max number of relays returned by the module, if applicable",
* in="query",
* @OA\Schema(
* type="integer"
* )
* ),
* @OA\Parameter(
* name="orderWeight",
* description="Total weight of the order in grams (eg: 1000 for 1kg)",
* in="query",
* @OA\Schema(
* type="integer"
* )
* ),
* @OA\Parameter(
* name="moduleIds[]",
* description="To filter pickup locations by modules",
* in="query",
* @OA\Schema(
* type="array",
* @OA\Items(
* type="integer"
* )
* )
* ),
* @OA\Response(
* response="200",
* description="Success",
* @OA\JsonContent(
* type="array",
* @OA\Items(
* ref="#/components/schemas/PickupLocation"
* )
* )
* ),
* @OA\Response(
* response="400",
* description="Bad request",
* @OA\JsonContent(ref="#/components/schemas/Error")
* )
* )
*/
public function getPickupLocations(Request $request, EventDispatcherInterface $dispatcher)
{
$state = $request->get('stateId') ? (StateQuery::create())->filterById($request->get('stateId'))->findOne() : null;
$country = $request->get('countryId') ? (CountryQuery::create())->filterById($request->get('countryId'))->findOne() : null;
$pickupLocationEvent = new PickupLocationEvent(
null,
$request->get('radius'),
$request->get('maxRelays'),
$request->get('address'),
$request->get('city'),
$request->get('zipCode'),
$request->get('orderWeight'),
$state,
$country,
$request->get('moduleIds')
);
$dispatcher->dispatch($pickupLocationEvent, TheliaEvents::MODULE_DELIVERY_GET_PICKUP_LOCATIONS);
return OpenApiService::jsonResponse(
array_map(
fn (PickupLocation $pickupLocation) => $pickupLocation->toArray(),
$pickupLocationEvent->getLocations()
)
);
}
/**
* @Route("/simple-modules", name="delivery_simple_modules", methods="GET")
*
* @OA\Get(
* path="/delivery/simple-modules",
* tags={"delivery", "modules"},
* summary="List all delivery modules as simple list (without postages and options)",
* @OA\Response(
* response="200",
* description="Success",
* @OA\JsonContent(
* type="array",
* @OA\Items(
* ref="#/components/schemas/DeliveryModule"
* )
* )
* ),
* @OA\Response(
* response="400",
* description="Bad request",
* @OA\JsonContent(ref="#/components/schemas/Error")
* )
* )
*/
public function getSimpleDeliveryModules(ModelFactory $modelFactory)
{
$modules = ModuleQuery::create()
->filterByActivate(1)
->filterByType(BaseModule::DELIVERY_MODULE_TYPE)
->find();
return OpenApiService::jsonResponse(
array_map(
function (Module $module) use ($modelFactory) {
/** @var AbstractDeliveryModule $moduleInstance */
$moduleInstance = $module->getDeliveryModuleInstance($this->container);
/** @var DeliveryModule $deliveryModule */
$deliveryModule = $modelFactory->buildModel('DeliveryModule', $module);
$deliveryModule->setDeliveryMode($moduleInstance->getDeliveryMode());
return $deliveryModule;
},
iterator_to_array($modules)
)
);
}
/**
* @Route("/modules", name="delivery_modules", methods="GET")
*
* @OA\Get(
* path="/delivery/modules",
* tags={"delivery", "modules"},
* summary="List all available delivery modules",
* @OA\Parameter(
* name="addressId",
* in="query",
* @OA\Schema(
* type="string"
* )
* ),
* @OA\Parameter(
* name="moduleId",
* in="query",
* @OA\Schema(
* type="string"
* )
* ),
* @OA\Response(
* response="200",
* description="Success",
* @OA\JsonContent(
* type="array",
* @OA\Items(
* ref="#/components/schemas/DeliveryModule"
* )
* )
* ),
* @OA\Response(
* response="400",
* description="Bad request",
* @OA\JsonContent(ref="#/components/schemas/Error")
* )
* )
*/
public function getDeliveryModules(
Request $request,
SecurityContext $securityContext,
EventDispatcherInterface $dispatcher,
ModelFactory $modelFactory
) {
$deliveryAddress = $this->getDeliveryAddress($request, $securityContext);
if (null === $deliveryAddress) {
throw new \Exception(Translator::getInstance()->trans('You must either pass an address id or have a customer connected', [], OpenApi::DOMAIN_NAME));
}
$cart = $request->getSession()->getSessionCart($dispatcher);
$country = $deliveryAddress->getCountry();
$state = $deliveryAddress->getState();
$moduleQuery = ModuleQuery::create()
->filterByActivate(1)
->filterByType(BaseModule::DELIVERY_MODULE_TYPE);
if (null !== $moduleId = $request->get('moduleId')) {
$moduleQuery->filterById($moduleId);
}
$modules = $moduleQuery->find();
$class = $this;
return OpenApiService::jsonResponse(
array_map(
fn ($module) => $class->getDeliveryModule($module, $dispatcher, $cart, $modelFactory, $deliveryAddress, $country, $state),
iterator_to_array($modules)
)
);
}
/**
* @Route("/set-delivery", name="set_delivery_modules", methods="GET")
*
* @OA\Get(
* path="/delivery/set-delivery",
* tags={"delivery", "modules"},
* summary="Set delivery module on session to calculate postage",
* @OA\Parameter(
* name="delivery_module_id",
* in="query",
* @OA\Schema(
* type="integer"
* )
* ),
* @OA\Response(
* response="200",
* description="Success",
* ),
* @OA\Response(
* response="400",
* description="Bad request",
* @OA\JsonContent(ref="#/components/schemas/Error")
* )
* )
*/
public function setDeliveryModules(Request $request)
{
$deliveryModuleId = $request->get('delivery_module_id');
$session = $request->getSession();
$order = $session->getOrder();
if (!$order) {
return new JsonResponse();
}
$order->setDeliveryModuleId($deliveryModuleId);
$session->setOrder($order);
return new JsonResponse();
}
protected function getDeliveryModule(
Module $theliaDeliveryModule,
EventDispatcherInterface $dispatcher,
Cart $cart,
ModelFactory $modelFactory,
$address,
$country,
$state
) {
$areaDeliveryModule = AreaDeliveryModuleQuery::create()
->findByCountryAndModule($country, $theliaDeliveryModule, $state);
$isCartVirtual = $cart->isVirtual();
$isValid = true;
if (false === $isCartVirtual && null === $areaDeliveryModule) {
$isValid = false;
}
$moduleInstance = $theliaDeliveryModule->getDeliveryModuleInstance($this->container);
if (true === $isCartVirtual && false === $moduleInstance->handleVirtualProductDelivery()) {
$isValid = false;
}
$deliveryPostageEvent = new DeliveryPostageEvent($moduleInstance, $cart, $address, $country, $state);
try {
$dispatcher->dispatch(
$deliveryPostageEvent,
TheliaEvents::MODULE_DELIVERY_GET_POSTAGE
);
} catch (DeliveryException $exception) {
$isValid = false;
}
if (!$deliveryPostageEvent->isValidModule()) {
$isValid = false;
}
$deliveryModuleOptionEvent = new DeliveryModuleOptionEvent($theliaDeliveryModule, $address, $cart, $country, $state);
$dispatcher->dispatch(
$deliveryModuleOptionEvent,
OpenApiEvents::MODULE_DELIVERY_GET_OPTIONS
);
/** @var DeliveryModule $deliveryModule */
$deliveryModule = $modelFactory->buildModel('DeliveryModule', $theliaDeliveryModule);
$deliveryModule
->setDeliveryMode($deliveryPostageEvent->getDeliveryMode())
->setValid($isValid)
->setOptions($deliveryModuleOptionEvent->getDeliveryModuleOptions())
;
return $deliveryModule;
}
protected function getDeliveryAddress(Request $request, SecurityContext $securityContext)
{
$addressId = $request->get('addressId');
if (null === $addressId) {
$addressId = $request->getSession()->getOrder()->getChoosenDeliveryAddress();
}
if (null !== $addressId) {
$address = AddressQuery::create()->findPk($addressId);
if (null !== $address) {
return $address;
}
}
// If no address in request or in order take customer default address
$currentCustomer = $securityContext->getCustomerUser();
if (null === $currentCustomer) {
return null;
}
return $currentCustomer->getDefaultAddress();
}
}

View File

@@ -0,0 +1,147 @@
<?php
namespace OpenApi\Controller\Front;
use OpenApi\Annotations as OA;
use OpenApi\Model\Api\ModelFactory;
use OpenApi\Service\OpenApiService;
use OpenApi\Service\SearchService;
use Symfony\Component\Routing\Annotation\Route;
use Thelia\Core\HttpFoundation\Request;
/**
* @Route("/folder", name="folder")
*/
class FolderController extends BaseFrontOpenApiController
{
/**
* @Route("/search", name="_search", methods="GET")
*
* @OA\Get(
* path="/folder/search",
* tags={"Folder", "Search"},
* summary="Search folders",
* @OA\Parameter(
* name="id",
* in="query",
* @OA\Schema(
* type="integer"
* )
* ),
* @OA\Parameter(
* name="ids[]",
* in="query",
* @OA\Schema(
* type="array",
* @OA\Items(
* type="integer"
* )
* )
* ),
* @OA\Parameter(
* name="parentsIds[]",
* in="query",
* @OA\Schema(
* type="array",
* @OA\Items(
* type="integer"
* )
* )
* ),
* @OA\Parameter(
* name="visible",
* in="query",
* @OA\Schema(
* type="boolean",
* default="true"
* )
* ),
* @OA\Parameter(
* name="locale",
* in="query",
* description="Current locale by default",
* @OA\Schema(
* type="string"
* )
* ),
* @OA\Parameter(
* name="title",
* in="query",
* @OA\Schema(
* type="string"
* )
* ),
* @OA\Parameter(
* name="description",
* in="query",
* @OA\Schema(
* type="string"
* )
* ),
* @OA\Parameter(
* name="chapo",
* in="query",
* @OA\Schema(
* type="string"
* )
* ),
* @OA\Parameter(
* name="postscriptum",
* in="query",
* @OA\Schema(
* type="string"
* )
* ),
* @OA\Parameter(
* name="limit",
* in="query",
* @OA\Schema(
* type="integer",
* default="20"
* )
* ),
* @OA\Parameter(
* name="offset",
* in="query",
* @OA\Schema(
* type="integer"
* )
* ),
* @OA\Parameter(
* name="order",
* in="query",
* @OA\Schema(
* type="string",
* enum={"alpha", "alpha_reverse", "created_at", "created_at_reverse"},
* default="alpha"
* )
* ),
* @OA\Response(
* response="200",
* description="Success",
* @OA\JsonContent(
* type="array",
* @OA\Items(
* ref="#/components/schemas/Folder"
* )
* )
* ),
* @OA\Response(
* response="400",
* description="Bad request",
* @OA\JsonContent(ref="#/components/schemas/Error")
* )
* )
*/
public function search(
Request $request,
ModelFactory $modelFactory,
SearchService $searchService
) {
$query = $searchService->baseSearchItems("folder", $request);
$folders = $query->find();
return OpenApiService::jsonResponse(
array_map(fn ($folder) => $modelFactory->buildModel('Folder', $folder), iterator_to_array($folders))
);
}
}

View File

@@ -0,0 +1,115 @@
<?php
namespace OpenApi\Controller\Front;
use OpenApi\Annotations as OA;
use OpenApi\Model\Api\ModelFactory;
use OpenApi\Model\Api\PaymentModule;
use OpenApi\Service\OpenApiService;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Thelia\Core\Event\Payment\IsValidPaymentEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\HttpFoundation\Request;
use Thelia\Model\Cart;
use Thelia\Model\Lang;
use Thelia\Model\Module;
use Thelia\Model\ModuleQuery;
use Thelia\Module\BaseModule;
/**
* @Route("/payment", name="payment")
*/
class PaymentController extends BaseFrontOpenApiController
{
/**
* @Route("/modules", name="payment_modules", methods="GET")
*
* @OA\Get(
* path="/payment/modules",
* tags={"payment", "modules"},
* summary="List all available payment modules",
* @OA\Parameter(
* name="orderId",
* in="query",
* @OA\Schema(
* type="string"
* )
* ),
* @OA\Parameter(
* name="moduleId",
* in="query",
* @OA\Schema(
* type="string"
* )
* ),
* @OA\Response(
* response="200",
* description="Success",
* @OA\JsonContent(
* type="array",
* @OA\Items(
* ref="#/components/schemas/PaymentModule"
* )
* )
* ),
* @OA\Response(
* response="400",
* description="Bad request",
* @OA\JsonContent(ref="#/components/schemas/Error")
* )
* )
*/
public function getPaymentModules(
EventDispatcherInterface $dispatcher,
ModelFactory $modelFactory,
Request $request
) {
$cart = $request->getSession()->getSessionCart($dispatcher);
$lang = $request->getSession()->getLang();
$moduleQuery = ModuleQuery::create()
->filterByActivate(1)
->filterByType(BaseModule::PAYMENT_MODULE_TYPE)
->orderByPosition();
if (null !== $moduleId = $request->get('moduleId')) {
$moduleQuery->filterById($moduleId);
}
$modules = $moduleQuery->find();
// Return formatted valid payment
return OpenApiService::jsonResponse(
array_map(
fn ($module) => $this->getPaymentModule($dispatcher, $modelFactory, $module, $cart, $lang),
iterator_to_array($modules)
)
);
}
protected function getPaymentModule(
EventDispatcherInterface $dispatcher,
ModelFactory $modelFactory,
Module $paymentModule,
Cart $cart,
Lang $lang
) {
$paymentModule->setLocale($lang->getLocale());
$moduleInstance = $paymentModule->getPaymentModuleInstance($this->container);
$isValidPaymentEvent = new IsValidPaymentEvent($moduleInstance, $cart);
$dispatcher->dispatch(
$isValidPaymentEvent,
TheliaEvents::MODULE_PAYMENT_IS_VALID
);
/** @var PaymentModule $paymentModule */
$paymentModule = $modelFactory->buildModel('PaymentModule', $paymentModule);
$paymentModule->setValid($isValidPaymentEvent->isValidModule())
->setCode($moduleInstance->getCode())
->setMinimumAmount($isValidPaymentEvent->getMinimumAmount())
->setMaximumAmount($isValidPaymentEvent->getMaximumAmount());
return $paymentModule;
}
}

View File

@@ -0,0 +1,213 @@
<?php
namespace OpenApi\Controller\Front;
use OpenApi\Annotations as OA;
use OpenApi\Model\Api\ModelFactory;
use OpenApi\Service\OpenApiService;
use Propel\Runtime\ActiveQuery\Criteria;
use Symfony\Component\Routing\Annotation\Route;
use Thelia\Core\HttpFoundation\Request;
use Thelia\Model\ProductQuery;
/**
* @Route("/product", name="product")
*/
class ProductController extends BaseFrontOpenApiController
{
/**
* @Route("/search", name="product_search", methods="GET")
*
* @OA\Get(
* path="/product/search",
* tags={"Product", "Search"},
* summary="Search products",
* @OA\Parameter(
* name="id",
* in="query",
* @OA\Schema(
* type="integer"
* )
* ),
* @OA\Parameter(
* name="ids[]",
* in="query",
* @OA\Schema(
* type="array",
* @OA\Items(
* type="integer"
* )
* )
* ),
* @OA\Parameter(
* name="reference",
* in="query",
* @OA\Schema(
* type="string"
* )
* ),
* @OA\Parameter(
* name="visible",
* in="query",
* @OA\Schema(
* type="boolean",
* default="true"
* )
* ),
* @OA\Parameter(
* name="locale",
* in="query",
* description="Current locale by default",
* @OA\Schema(
* type="string"
* )
* ),
* @OA\Parameter(
* name="title",
* in="query",
* @OA\Schema(
* type="string"
* )
* ),
* @OA\Parameter(
* name="description",
* in="query",
* @OA\Schema(
* type="string"
* )
* ),
* @OA\Parameter(
* name="chapo",
* in="query",
* @OA\Schema(
* type="string"
* )
* ),
* @OA\Parameter(
* name="postscriptum",
* in="query",
* @OA\Schema(
* type="string"
* )
* ),
* @OA\Parameter(
* name="limit",
* in="query",
* @OA\Schema(
* type="integer",
* default="20"
* )
* ),
* @OA\Parameter(
* name="offset",
* in="query",
* @OA\Schema(
* type="integer"
* )
* ),
* @OA\Parameter(
* name="order",
* in="query",
* @OA\Schema(
* type="string",
* enum={"alpha", "alpha_reverse", "created_at", "created_at_reverse"},
* default="alpha"
* )
* ),
* @OA\Response(
* response="200",
* description="Success",
* @OA\JsonContent(
* type="array",
* @OA\Items(
* ref="#/components/schemas/Product"
* )
* )
* ),
* @OA\Response(
* response="400",
* description="Bad request",
* @OA\JsonContent(ref="#/components/schemas/Error")
* )
* )
*/
public function search(
Request $request,
ModelFactory $modelFactory
) {
$productQuery = ProductQuery::create();
if (null !== $id = $request->get('id')) {
$productQuery->filterById($id);
}
if (null !== $ids = $request->get('ids')) {
$productQuery->filterById($ids, Criteria::IN);
}
if (null !== $reference = $request->get('reference')) {
$productQuery->filterByRef($reference);
}
$productQuery->filterByVisible((bool) json_decode(json_encode($request->get('visible', true))));
$order = $request->get('order', 'alpha');
$locale = $request->get('locale', $request->getSession()->getLang()->getLocale());
$title = $request->get('title');
$description = $request->get('description');
$chapo = $request->get('chapo');
$postscriptum = $request->get('postscriptum');
$productQuery
->limit($request->get('limit', 20))
->offset($request->get('offset', 0));
switch ($order) {
case 'created':
$productQuery->orderByCreatedAt();
break;
case 'created_reverse':
$productQuery->orderByCreatedAt(Criteria::DESC);
break;
}
if (null !== $title || null !== $description || null !== $chapo || null !== $postscriptum) {
$productI18nQuery = $productQuery
->useProductI18nQuery()
->filterByLocale($locale);
if (null !== $title) {
$productI18nQuery->filterByTitle('%'.$title.'%', Criteria::LIKE);
}
if (null !== $description) {
$productI18nQuery->filterByDescription('%'.$description.'%', Criteria::LIKE);
}
if (null !== $chapo) {
$productI18nQuery->filterByChapo('%'.$chapo.'%', Criteria::LIKE);
}
if (null !== $postscriptum) {
$productI18nQuery->filterByPostscriptum('%'.$postscriptum.'%', Criteria::LIKE);
}
switch ($order) {
case 'alpha':
$productI18nQuery->orderByTitle();
break;
case 'alpha_reverse':
$productI18nQuery->orderByTitle(Criteria::DESC);
break;
}
$productI18nQuery->endUse();
}
$products = $productQuery->find();
$products = array_map(fn ($product) => $modelFactory->buildModel('Product', $product), iterator_to_array($products));
return OpenApiService::jsonResponse($products);
}
}

View File

@@ -0,0 +1,56 @@
<?php
namespace OpenApi\Controller;
use OpenApi\Annotations as OA;
use Thelia\Core\HttpFoundation\JsonResponse;
use function OpenApi\scan;
use Symfony\Component\Routing\Annotation\Route;
use Thelia\Controller\Front\BaseFrontController;
use Thelia\Core\HttpFoundation\Request;
/**
* @OA\Info(title="Thelia Open Api", version="0.1")
*/
class OpenApiController extends BaseFrontController
{
/**
* @Route("/doc", name="documentation")
*/
public function getDocumentation(Request $request)
{
header('Access-Control-Allow-Origin: *');
$annotations = scan([
THELIA_MODULE_DIR.'/*/Model/Api',
THELIA_MODULE_DIR.'/*/EventListener',
THELIA_MODULE_DIR.'/*/Controller',
]);
$annotations = json_decode($annotations->toJson(), true);
$modelAnnotations = $annotations['components']['schemas'];
foreach ($modelAnnotations as $modelName => $modelAnnotation) {
$isExtend = preg_match('/.*(Extend)(.*)/', $modelName, $matches);
if (!$isExtend) {
continue;
}
$modelExtendedName = $matches[2];
$modelAnnotations[$modelExtendedName] = array_replace_recursive($modelAnnotations[$modelExtendedName], $modelAnnotation);
unset($modelAnnotations[$modelName]);
}
$annotations['components']['schemas'] = $modelAnnotations;
$host = $request->getSchemeAndHttpHost();
$annotations['servers'] = [
['url' => $host.'/open_api'],
['url' => $host.'/index_dev.php/open_api'],
];
return $this->render('swagger-ui', [
'spec' => json_encode($annotations),
]);
}
}