<?php
namespace AppBundle\Controller;
use AppBundle\Exception\NotAllowedException;
use AppBundle\Exception\ResourceNotFoundException;
use AppBundle\Repository\AbstractEditableRepository;
use AppBundle\Repository\AbstractRepository;
use AppBundle\Services\ApiDataCollectorService;
use AppBundle\Services\ClassDefinitionService;
use AppBundle\Services\ExportService;
use AppBundle\Services\SftpFileTransferService;
use AppBundle\Services\TranslationService;
use Exception;
use Pimcore\Config;
use Pimcore\Controller\FrontendController;
use Pimcore\Model\DataObject;
use Pimcore\Model\DataObject\Concrete;
use Pimcore\Model\DataObject\Order;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
class DataObjectRestController extends FrontendController
{
const REPOSITORY_NAMESPACE = 'AppBundle\Repository';
/**
* @Route("/api-v1/{className}/get/{id}", name="rest_get", methods={"GET"})
* @param Request $request
* @return JsonResponse
* @throws NotAllowedException
* @throws ResourceNotFoundException
*/
public function getAction(Request $request)
{
$object = Concrete::GetById($request->get('id'));
if (!$object) {
ApiDataCollectorService::setData([$request->get('id') => ResourceNotFoundException::DEFAULT_MESSAGE]);
throw new ResourceNotFoundException(ResourceNotFoundException::DEFAULT_MESSAGE);
}
if ($object->getClassName() != ucfirst($request->get('className'))) {
ApiDataCollectorService::setData([$request->get('id') => ResourceNotFoundException::DEFAULT_MESSAGE]);
throw new ResourceNotFoundException(ResourceNotFoundException::DEFAULT_MESSAGE);
}
/** @var AbstractRepository $repo */
$repo = self::REPOSITORY_NAMESPACE . '\\' . ucfirst(trim($request->get('className'))) . 'Repository';
if (!class_exists($repo)) {
ApiDataCollectorService::setData([$request->get('className') => NotAllowedException::DEFAULT_MESSAGE]);
throw new NotAllowedException(NotAllowedException::DEFAULT_MESSAGE);
}
return $this->json([
'success' => true,
'data' => $repo::toArray($object)
]);
}
/**
* @Route("/api-v1/{className}/get-list/", name="rest_get_list", methods={"GET"})
* @param Request $request
* @return JsonResponse
* @throws Exception
*/
public function getListAction(Request $request)
{
$result = [];
$user = null;
$userId = $request->query->get('user_id');
if ($userId) {
$user = DataObject\User::getById($userId);
}
/** @var AbstractRepository $class */
$class = self::REPOSITORY_NAMESPACE . '\\' . ucfirst(trim($request->get('className'))) . 'Repository';
if (!class_exists($class)) {
ApiDataCollectorService::setData([$request->get('className') => NotAllowedException::DEFAULT_MESSAGE]);
throw new NotAllowedException(NotAllowedException::DEFAULT_MESSAGE);
}
$offset = $request->query->get('offset', 0);
$limit = $request->query->get('limit', 1000);
$orderKey = $request->query->get('orderKey', 'oo_id');
$order = $request->query->get('order', 'asc');
$filters = $request->query->get('filter', '');
// Add user on repository in order to filter user dependent data
$class::setUser($user);
$decodedFilters = rawurldecode($filters);
$arrayFilters = json_decode($decodedFilters, true);
$list = $class::getApiList($offset, $limit, $orderKey, $order, $arrayFilters);
foreach ($list['data'] as $item) {
$result[] = $class::toArray($item);
}
return $this->json([
'success' => true,
'data' => $result,
'totalItem' => $list['totalItem']
]);
}
/**
* @Route("/api-v1/{className}/export", name="rest_export", methods={"POST"})
* @param string $className
* @param Request $request
* @param ExportService $exportService
* @return JsonResponse
* @throws NotAllowedException
*/
public function export(string $className, Request $request, ExportService $exportService)
{
$values = json_decode($request->getContent(), true);
$ids = $values['ids'];
$user = null;
$userId = $request->query->get('user_id');
if ($userId) {
$user = DataObject\User::getById($userId);
} else {
throw new NotAllowedException();
}
$exportService
->setUser($user)
->setClassName($className);
$file = $exportService->run($ids);
$response = [
'success' => true,
'message' => '',
'data' => $file
];
return $this->json($response);
}
/**
* @Route("/api-v1/{className}/", name="rest_route", methods={"POST","PATCH","DELETE"})
* @param Request $request
* @return JsonResponse
* @throws NotAllowedException
*/
public function genericAction(Request $request)
{
$values = json_decode($request->getContent(), true);
$data = null;
/** @var AbstractEditableRepository $repo */
$repo = self::REPOSITORY_NAMESPACE . '\\' . ucfirst(trim($request->get('className'))) . 'Repository';
if (!class_exists($repo)) {
// not allowed because it is the existence of editable repo which define the edition right
ApiDataCollectorService::setData([$request->get('className') => NotAllowedException::DEFAULT_MESSAGE]);
throw new NotAllowedException();
}
switch ($request->getMethod()) {
case Request::METHOD_POST:
$method = 'create';
break;
case Request::METHOD_PATCH:
$method = 'update';
break;
case Request::METHOD_DELETE:
$method = 'delete';
break;
default:
ApiDataCollectorService::setData([$request->getMethod() => NotAllowedException::DEFAULT_MESSAGE]);
throw new NotAllowedException();
break;
}
if (!method_exists($repo, $method)) {
ApiDataCollectorService::setData([$method => NotAllowedException::DEFAULT_MESSAGE]);
throw new NotAllowedException();
}
$userId = $request->query->get('user_id');
if ($userId) {
$user = DataObject\User::getById($userId);
$repo::setUser($user);
}
$object = $repo::$method($values);
switch ($method) {
case 'delete':
// in case of delete we need to extract correct message
$mess = TranslationService::getWebsiteTranslation("L'élément a bien été supprimé");
if (isset($values['ids']) && count($values['ids']) > 1) {
$mess = TranslationService::getWebsiteTranslation('Les éléments ont bien été supprimés');
}
$dataArray = ApiDataCollectorService::getData();
if (!empty($dataArray) && isset($dataArray['data'])) { // cas des suppressions partielles
if(isset($dataArray['globalMessage']) && !is_null($dataArray['globalMessage'])){
$mess = $dataArray['globalMessage'];
}
ApiDataCollectorService::setData($dataArray['data']);
}
$response = [
'success' => true,
'message' => $mess,
'data' => ApiDataCollectorService::getData()
];
break;
case 'create':
case 'update':
default:
$response = [
'success' => true,
'data' => $repo::toArray($object)
];
break;
}
return $this->json($response);
}
/**
* @Route("/api-v1/class-definition/{className}/{attribute}", name="rest_get_attribute", methods={"GET"})
* @param String $className
* @param String $attribute
* @param Request $request
* @return JsonResponse
* @throws NotAllowedException
* @throws ResourceNotFoundException
*/
public function getAttributeDefinitionAction(string $className, string $attribute, Request $request)
{
$result = ClassDefinitionService::getSelectValues($className, $attribute);
return $this->json([
'success' => true,
'data' => $result
]);
}
/**
* @Route("/api-v1/class-definition/{className}/{attribute}/create-from-path",
* name="rest_create-from-path_attribute",
* methods={"POST"}
* )
* @param String $className
* @param String $attribute
* @param Request $request
* @return JsonResponse
* @throws NotAllowedException
* @throws ResourceNotFoundException
*/
public function createAssetFromSourceAction(string $className, string $attribute, Request $request)
{
$path = $request->request->get('path');
$filename = $request->request->get('filename');
$result = ClassDefinitionService::createAssetFromPath(
$className,
$attribute,
$path,
$filename
);
return $this->json([
'success' => true,
'data' => $result
]);
}
/**
* @Route("/api-v1/order/download-pdf/{orderId}",
* name="rest-download-order-pdf",
* methods={"GET"}
* )
* @param string $orderId
* @return JsonResponse
* @throws Exception
*/
public function downloadOrderPdf(string $orderId)
{
$order = Order::getById($orderId);
if ($order) {
$localPath = implode(
DIRECTORY_SEPARATOR,
[
PIMCORE_TEMPORARY_DIRECTORY,
'lv-order-pdf',
$orderId
]);
$pdfPath = $order->getPdf();
SftpFileTransferService::transferFileFromTwist($pdfPath, $localPath);
$domain = Config::getSystemConfiguration('general')['domain'];
if (empty($domain)) {
throw new Exception('Domain is not defined in System configuration > general > domain');
}
$partPart = explode('/', $pdfPath);
$filename = end($partPart);
$url = $domain . '/var/tmp/lv-order-pdf/' . $orderId . '/' . $filename;
return $this->json([
'success' => true,
'message' => '',
'data' => $url
]);
}
}
}