added API functions to save meta fields (#1063)
This commit is contained in:
@@ -12,6 +12,7 @@ declare(strict_types=1);
|
|||||||
namespace App\API;
|
namespace App\API;
|
||||||
|
|
||||||
use App\Entity\Activity;
|
use App\Entity\Activity;
|
||||||
|
use App\Event\ActivityMetaDefinitionEvent;
|
||||||
use App\Form\API\ActivityApiEditForm;
|
use App\Form\API\ActivityApiEditForm;
|
||||||
use App\Repository\ActivityRepository;
|
use App\Repository\ActivityRepository;
|
||||||
use App\Repository\Query\ActivityQuery;
|
use App\Repository\Query\ActivityQuery;
|
||||||
@@ -22,6 +23,7 @@ use FOS\RestBundle\View\View;
|
|||||||
use FOS\RestBundle\View\ViewHandlerInterface;
|
use FOS\RestBundle\View\ViewHandlerInterface;
|
||||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
|
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
|
||||||
use Swagger\Annotations as SWG;
|
use Swagger\Annotations as SWG;
|
||||||
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||||
@@ -36,16 +38,21 @@ class ActivityController extends BaseApiController
|
|||||||
/**
|
/**
|
||||||
* @var ActivityRepository
|
* @var ActivityRepository
|
||||||
*/
|
*/
|
||||||
protected $repository;
|
private $repository;
|
||||||
/**
|
/**
|
||||||
* @var ViewHandlerInterface
|
* @var ViewHandlerInterface
|
||||||
*/
|
*/
|
||||||
protected $viewHandler;
|
private $viewHandler;
|
||||||
|
/**
|
||||||
|
* @var EventDispatcherInterface
|
||||||
|
*/
|
||||||
|
private $dispatcher;
|
||||||
|
|
||||||
public function __construct(ViewHandlerInterface $viewHandler, ActivityRepository $repository)
|
public function __construct(ViewHandlerInterface $viewHandler, ActivityRepository $repository, EventDispatcherInterface $dispatcher)
|
||||||
{
|
{
|
||||||
$this->viewHandler = $viewHandler;
|
$this->viewHandler = $viewHandler;
|
||||||
$this->repository = $repository;
|
$this->repository = $repository;
|
||||||
|
$this->dispatcher = $dispatcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -169,14 +176,15 @@ class ActivityController extends BaseApiController
|
|||||||
|
|
||||||
$activity = new Activity();
|
$activity = new Activity();
|
||||||
|
|
||||||
|
$event = new ActivityMetaDefinitionEvent($activity);
|
||||||
|
$this->dispatcher->dispatch($event, ActivityMetaDefinitionEvent::class);
|
||||||
|
|
||||||
$form = $this->createForm(ActivityApiEditForm::class, $activity);
|
$form = $this->createForm(ActivityApiEditForm::class, $activity);
|
||||||
|
|
||||||
$form->submit($request->request->all());
|
$form->submit($request->request->all());
|
||||||
|
|
||||||
if ($form->isValid()) {
|
if ($form->isValid()) {
|
||||||
$entityManager = $this->getDoctrine()->getManager();
|
$this->repository->saveActivity($activity);
|
||||||
$entityManager->persist($activity);
|
|
||||||
$entityManager->flush();
|
|
||||||
|
|
||||||
$view = new View($activity, 200);
|
$view = new View($activity, 200);
|
||||||
$view->getContext()->setGroups(['Default', 'Entity', 'Activity']);
|
$view->getContext()->setGroups(['Default', 'Entity', 'Activity']);
|
||||||
@@ -218,6 +226,8 @@ class ActivityController extends BaseApiController
|
|||||||
* @param Request $request
|
* @param Request $request
|
||||||
* @param string $id
|
* @param string $id
|
||||||
* @return Response
|
* @return Response
|
||||||
|
* @throws \Doctrine\ORM\ORMException
|
||||||
|
* @throws \Doctrine\ORM\OptimisticLockException
|
||||||
*/
|
*/
|
||||||
public function patchAction(Request $request, string $id)
|
public function patchAction(Request $request, string $id)
|
||||||
{
|
{
|
||||||
@@ -231,6 +241,9 @@ class ActivityController extends BaseApiController
|
|||||||
throw new AccessDeniedHttpException('User cannot update activity');
|
throw new AccessDeniedHttpException('User cannot update activity');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$event = new ActivityMetaDefinitionEvent($activity);
|
||||||
|
$this->dispatcher->dispatch($event, ActivityMetaDefinitionEvent::class);
|
||||||
|
|
||||||
$form = $this->createForm(ActivityApiEditForm::class, $activity);
|
$form = $this->createForm(ActivityApiEditForm::class, $activity);
|
||||||
|
|
||||||
$form->setData($activity);
|
$form->setData($activity);
|
||||||
@@ -243,13 +256,67 @@ class ActivityController extends BaseApiController
|
|||||||
return $this->viewHandler->handle($view);
|
return $this->viewHandler->handle($view);
|
||||||
}
|
}
|
||||||
|
|
||||||
$entityManager = $this->getDoctrine()->getManager();
|
$this->repository->saveActivity($activity);
|
||||||
$entityManager->persist($activity);
|
|
||||||
$entityManager->flush();
|
|
||||||
|
|
||||||
$view = new View($activity, Response::HTTP_OK);
|
$view = new View($activity, Response::HTTP_OK);
|
||||||
$view->getContext()->setGroups(['Default', 'Entity', 'Activity']);
|
$view->getContext()->setGroups(['Default', 'Entity', 'Activity']);
|
||||||
|
|
||||||
return $this->viewHandler->handle($view);
|
return $this->viewHandler->handle($view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value of a meta-field for an existing activity.
|
||||||
|
*
|
||||||
|
* @SWG\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Sets the value of an existing/configured meta-field. You cannot create unknown meta-fields, if the given name is not a configured meta-field, this will return an exception.",
|
||||||
|
* @SWG\Schema(ref="#/definitions/ActivityEntity")
|
||||||
|
* )
|
||||||
|
* @SWG\Parameter(
|
||||||
|
* name="id",
|
||||||
|
* in="path",
|
||||||
|
* type="integer",
|
||||||
|
* description="Activity record ID to set the meta-field value for",
|
||||||
|
* required=true,
|
||||||
|
* )
|
||||||
|
* @Rest\RequestParam(name="name", strict=true, nullable=false, description="The meta-field name")
|
||||||
|
* @Rest\RequestParam(name="value", strict=true, nullable=false, description="The meta-field value")
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @param ParamFetcherInterface $paramFetcher
|
||||||
|
* @return Response
|
||||||
|
* @throws \Doctrine\ORM\ORMException
|
||||||
|
* @throws \Doctrine\ORM\OptimisticLockException
|
||||||
|
*/
|
||||||
|
public function metaAction($id, ParamFetcherInterface $paramFetcher)
|
||||||
|
{
|
||||||
|
$activity = $this->repository->find($id);
|
||||||
|
|
||||||
|
if (null === $activity) {
|
||||||
|
throw new NotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->isGranted('edit', $activity)) {
|
||||||
|
throw new AccessDeniedHttpException('You are not allowed to update this activity');
|
||||||
|
}
|
||||||
|
|
||||||
|
$event = new ActivityMetaDefinitionEvent($activity);
|
||||||
|
$this->dispatcher->dispatch($event, ActivityMetaDefinitionEvent::class);
|
||||||
|
|
||||||
|
$name = $paramFetcher->get('name');
|
||||||
|
$value = $paramFetcher->get('value');
|
||||||
|
|
||||||
|
if (null === ($meta = $activity->getMetaField($name))) {
|
||||||
|
throw new \InvalidArgumentException('Unknown meta-field requested');
|
||||||
|
}
|
||||||
|
|
||||||
|
$meta->setValue($value);
|
||||||
|
|
||||||
|
$this->repository->saveActivity($activity);
|
||||||
|
|
||||||
|
$view = new View($activity, 200);
|
||||||
|
$view->getContext()->setGroups(['Default', 'Entity', 'Project']);
|
||||||
|
|
||||||
|
return $this->viewHandler->handle($view);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ declare(strict_types=1);
|
|||||||
namespace App\API;
|
namespace App\API;
|
||||||
|
|
||||||
use App\Entity\Customer;
|
use App\Entity\Customer;
|
||||||
|
use App\Event\CustomerMetaDefinitionEvent;
|
||||||
use App\Form\API\CustomerApiEditForm;
|
use App\Form\API\CustomerApiEditForm;
|
||||||
use App\Repository\CustomerRepository;
|
use App\Repository\CustomerRepository;
|
||||||
use App\Repository\Query\CustomerQuery;
|
use App\Repository\Query\CustomerQuery;
|
||||||
@@ -22,6 +23,7 @@ use FOS\RestBundle\View\View;
|
|||||||
use FOS\RestBundle\View\ViewHandlerInterface;
|
use FOS\RestBundle\View\ViewHandlerInterface;
|
||||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
|
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
|
||||||
use Swagger\Annotations as SWG;
|
use Swagger\Annotations as SWG;
|
||||||
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||||
@@ -36,16 +38,21 @@ class CustomerController extends BaseApiController
|
|||||||
/**
|
/**
|
||||||
* @var CustomerRepository
|
* @var CustomerRepository
|
||||||
*/
|
*/
|
||||||
protected $repository;
|
private $repository;
|
||||||
/**
|
/**
|
||||||
* @var ViewHandlerInterface
|
* @var ViewHandlerInterface
|
||||||
*/
|
*/
|
||||||
protected $viewHandler;
|
private $viewHandler;
|
||||||
|
/**
|
||||||
|
* @var EventDispatcherInterface
|
||||||
|
*/
|
||||||
|
private $dispatcher;
|
||||||
|
|
||||||
public function __construct(ViewHandlerInterface $viewHandler, CustomerRepository $repository)
|
public function __construct(ViewHandlerInterface $viewHandler, CustomerRepository $repository, EventDispatcherInterface $dispatcher)
|
||||||
{
|
{
|
||||||
$this->viewHandler = $viewHandler;
|
$this->viewHandler = $viewHandler;
|
||||||
$this->repository = $repository;
|
$this->repository = $repository;
|
||||||
|
$this->dispatcher = $dispatcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -148,14 +155,15 @@ class CustomerController extends BaseApiController
|
|||||||
|
|
||||||
$customer = new Customer();
|
$customer = new Customer();
|
||||||
|
|
||||||
|
$event = new CustomerMetaDefinitionEvent($customer);
|
||||||
|
$this->dispatcher->dispatch($event, CustomerMetaDefinitionEvent::class);
|
||||||
|
|
||||||
$form = $this->createForm(CustomerApiEditForm::class, $customer);
|
$form = $this->createForm(CustomerApiEditForm::class, $customer);
|
||||||
|
|
||||||
$form->submit($request->request->all());
|
$form->submit($request->request->all());
|
||||||
|
|
||||||
if ($form->isValid()) {
|
if ($form->isValid()) {
|
||||||
$entityManager = $this->getDoctrine()->getManager();
|
$this->repository->saveCustomer($customer);
|
||||||
$entityManager->persist($customer);
|
|
||||||
$entityManager->flush();
|
|
||||||
|
|
||||||
$view = new View($customer, 200);
|
$view = new View($customer, 200);
|
||||||
$view->getContext()->setGroups(['Default', 'Entity', 'Customer']);
|
$view->getContext()->setGroups(['Default', 'Entity', 'Customer']);
|
||||||
@@ -197,6 +205,8 @@ class CustomerController extends BaseApiController
|
|||||||
* @param Request $request
|
* @param Request $request
|
||||||
* @param string $id
|
* @param string $id
|
||||||
* @return Response
|
* @return Response
|
||||||
|
* @throws \Doctrine\ORM\ORMException
|
||||||
|
* @throws \Doctrine\ORM\OptimisticLockException
|
||||||
*/
|
*/
|
||||||
public function patchAction(Request $request, string $id)
|
public function patchAction(Request $request, string $id)
|
||||||
{
|
{
|
||||||
@@ -210,6 +220,9 @@ class CustomerController extends BaseApiController
|
|||||||
throw new AccessDeniedHttpException('User cannot update customer');
|
throw new AccessDeniedHttpException('User cannot update customer');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$event = new CustomerMetaDefinitionEvent($customer);
|
||||||
|
$this->dispatcher->dispatch($event, CustomerMetaDefinitionEvent::class);
|
||||||
|
|
||||||
$form = $this->createForm(CustomerApiEditForm::class, $customer);
|
$form = $this->createForm(CustomerApiEditForm::class, $customer);
|
||||||
|
|
||||||
$form->setData($customer);
|
$form->setData($customer);
|
||||||
@@ -222,13 +235,67 @@ class CustomerController extends BaseApiController
|
|||||||
return $this->viewHandler->handle($view);
|
return $this->viewHandler->handle($view);
|
||||||
}
|
}
|
||||||
|
|
||||||
$entityManager = $this->getDoctrine()->getManager();
|
$this->repository->saveCustomer($customer);
|
||||||
$entityManager->persist($customer);
|
|
||||||
$entityManager->flush();
|
|
||||||
|
|
||||||
$view = new View($customer, Response::HTTP_OK);
|
$view = new View($customer, Response::HTTP_OK);
|
||||||
$view->getContext()->setGroups(['Default', 'Entity', 'Customer']);
|
$view->getContext()->setGroups(['Default', 'Entity', 'Customer']);
|
||||||
|
|
||||||
return $this->viewHandler->handle($view);
|
return $this->viewHandler->handle($view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value of a meta-field for an existing customer.
|
||||||
|
*
|
||||||
|
* @SWG\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Sets the value of an existing/configured meta-field. You cannot create unknown meta-fields, if the given name is not a configured meta-field, this will return an exception.",
|
||||||
|
* @SWG\Schema(ref="#/definitions/CustomerEntity")
|
||||||
|
* )
|
||||||
|
* @SWG\Parameter(
|
||||||
|
* name="id",
|
||||||
|
* in="path",
|
||||||
|
* type="integer",
|
||||||
|
* description="Customer record ID to set the meta-field value for",
|
||||||
|
* required=true,
|
||||||
|
* )
|
||||||
|
* @Rest\RequestParam(name="name", strict=true, nullable=false, description="The meta-field name")
|
||||||
|
* @Rest\RequestParam(name="value", strict=true, nullable=false, description="The meta-field value")
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @param ParamFetcherInterface $paramFetcher
|
||||||
|
* @return Response
|
||||||
|
* @throws \Doctrine\ORM\ORMException
|
||||||
|
* @throws \Doctrine\ORM\OptimisticLockException
|
||||||
|
*/
|
||||||
|
public function metaAction($id, ParamFetcherInterface $paramFetcher)
|
||||||
|
{
|
||||||
|
$customer = $this->repository->find($id);
|
||||||
|
|
||||||
|
if (null === $customer) {
|
||||||
|
throw new NotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->isGranted('edit', $customer)) {
|
||||||
|
throw new AccessDeniedHttpException('You are not allowed to update this customer');
|
||||||
|
}
|
||||||
|
|
||||||
|
$event = new CustomerMetaDefinitionEvent($customer);
|
||||||
|
$this->dispatcher->dispatch($event, CustomerMetaDefinitionEvent::class);
|
||||||
|
|
||||||
|
$name = $paramFetcher->get('name');
|
||||||
|
$value = $paramFetcher->get('value');
|
||||||
|
|
||||||
|
if (null === ($meta = $customer->getMetaField($name))) {
|
||||||
|
throw new \InvalidArgumentException('Unknown meta-field requested');
|
||||||
|
}
|
||||||
|
|
||||||
|
$meta->setValue($value);
|
||||||
|
|
||||||
|
$this->repository->saveCustomer($customer);
|
||||||
|
|
||||||
|
$view = new View($customer, 200);
|
||||||
|
$view->getContext()->setGroups(['Default', 'Entity', 'Customer']);
|
||||||
|
|
||||||
|
return $this->viewHandler->handle($view);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ declare(strict_types=1);
|
|||||||
namespace App\API;
|
namespace App\API;
|
||||||
|
|
||||||
use App\Entity\Project;
|
use App\Entity\Project;
|
||||||
|
use App\Event\ProjectMetaDefinitionEvent;
|
||||||
use App\Form\API\ProjectApiEditForm;
|
use App\Form\API\ProjectApiEditForm;
|
||||||
use App\Repository\ProjectRepository;
|
use App\Repository\ProjectRepository;
|
||||||
use App\Repository\Query\ProjectQuery;
|
use App\Repository\Query\ProjectQuery;
|
||||||
@@ -22,6 +23,7 @@ use FOS\RestBundle\View\View;
|
|||||||
use FOS\RestBundle\View\ViewHandlerInterface;
|
use FOS\RestBundle\View\ViewHandlerInterface;
|
||||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
|
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
|
||||||
use Swagger\Annotations as SWG;
|
use Swagger\Annotations as SWG;
|
||||||
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||||
@@ -36,16 +38,21 @@ class ProjectController extends BaseApiController
|
|||||||
/**
|
/**
|
||||||
* @var ProjectRepository
|
* @var ProjectRepository
|
||||||
*/
|
*/
|
||||||
protected $repository;
|
private $repository;
|
||||||
/**
|
/**
|
||||||
* @var ViewHandlerInterface
|
* @var ViewHandlerInterface
|
||||||
*/
|
*/
|
||||||
protected $viewHandler;
|
private $viewHandler;
|
||||||
|
/**
|
||||||
|
* @var EventDispatcherInterface
|
||||||
|
*/
|
||||||
|
private $dispatcher;
|
||||||
|
|
||||||
public function __construct(ViewHandlerInterface $viewHandler, ProjectRepository $repository)
|
public function __construct(ViewHandlerInterface $viewHandler, ProjectRepository $repository, EventDispatcherInterface $dispatcher)
|
||||||
{
|
{
|
||||||
$this->viewHandler = $viewHandler;
|
$this->viewHandler = $viewHandler;
|
||||||
$this->repository = $repository;
|
$this->repository = $repository;
|
||||||
|
$this->dispatcher = $dispatcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -154,14 +161,15 @@ class ProjectController extends BaseApiController
|
|||||||
|
|
||||||
$project = new Project();
|
$project = new Project();
|
||||||
|
|
||||||
|
$event = new ProjectMetaDefinitionEvent($project);
|
||||||
|
$this->dispatcher->dispatch($event, ProjectMetaDefinitionEvent::class);
|
||||||
|
|
||||||
$form = $this->createForm(ProjectApiEditForm::class, $project);
|
$form = $this->createForm(ProjectApiEditForm::class, $project);
|
||||||
|
|
||||||
$form->submit($request->request->all());
|
$form->submit($request->request->all());
|
||||||
|
|
||||||
if ($form->isValid()) {
|
if ($form->isValid()) {
|
||||||
$entityManager = $this->getDoctrine()->getManager();
|
$this->repository->saveProject($project);
|
||||||
$entityManager->persist($project);
|
|
||||||
$entityManager->flush();
|
|
||||||
|
|
||||||
$view = new View($project, 200);
|
$view = new View($project, 200);
|
||||||
$view->getContext()->setGroups(['Default', 'Entity', 'Project']);
|
$view->getContext()->setGroups(['Default', 'Entity', 'Project']);
|
||||||
@@ -203,6 +211,8 @@ class ProjectController extends BaseApiController
|
|||||||
* @param Request $request
|
* @param Request $request
|
||||||
* @param string $id
|
* @param string $id
|
||||||
* @return Response
|
* @return Response
|
||||||
|
* @throws \Doctrine\ORM\ORMException
|
||||||
|
* @throws \Doctrine\ORM\OptimisticLockException
|
||||||
*/
|
*/
|
||||||
public function patchAction(Request $request, string $id)
|
public function patchAction(Request $request, string $id)
|
||||||
{
|
{
|
||||||
@@ -216,6 +226,9 @@ class ProjectController extends BaseApiController
|
|||||||
throw new AccessDeniedHttpException('User cannot update project');
|
throw new AccessDeniedHttpException('User cannot update project');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$event = new ProjectMetaDefinitionEvent($project);
|
||||||
|
$this->dispatcher->dispatch($event, ProjectMetaDefinitionEvent::class);
|
||||||
|
|
||||||
$form = $this->createForm(ProjectApiEditForm::class, $project);
|
$form = $this->createForm(ProjectApiEditForm::class, $project);
|
||||||
|
|
||||||
$form->setData($project);
|
$form->setData($project);
|
||||||
@@ -228,13 +241,67 @@ class ProjectController extends BaseApiController
|
|||||||
return $this->viewHandler->handle($view);
|
return $this->viewHandler->handle($view);
|
||||||
}
|
}
|
||||||
|
|
||||||
$entityManager = $this->getDoctrine()->getManager();
|
$this->repository->saveProject($project);
|
||||||
$entityManager->persist($project);
|
|
||||||
$entityManager->flush();
|
|
||||||
|
|
||||||
$view = new View($project, Response::HTTP_OK);
|
$view = new View($project, Response::HTTP_OK);
|
||||||
$view->getContext()->setGroups(['Default', 'Entity', 'Project']);
|
$view->getContext()->setGroups(['Default', 'Entity', 'Project']);
|
||||||
|
|
||||||
return $this->viewHandler->handle($view);
|
return $this->viewHandler->handle($view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value of a meta-field for an existing project.
|
||||||
|
*
|
||||||
|
* @SWG\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Sets the value of an existing/configured meta-field. You cannot create unknown meta-fields, if the given name is not a configured meta-field, this will return an exception.",
|
||||||
|
* @SWG\Schema(ref="#/definitions/ProjectEntity")
|
||||||
|
* )
|
||||||
|
* @SWG\Parameter(
|
||||||
|
* name="id",
|
||||||
|
* in="path",
|
||||||
|
* type="integer",
|
||||||
|
* description="Project record ID to set the meta-field value for",
|
||||||
|
* required=true,
|
||||||
|
* )
|
||||||
|
* @Rest\RequestParam(name="name", strict=true, nullable=false, description="The meta-field name")
|
||||||
|
* @Rest\RequestParam(name="value", strict=true, nullable=false, description="The meta-field value")
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @param ParamFetcherInterface $paramFetcher
|
||||||
|
* @return Response
|
||||||
|
* @throws \Doctrine\ORM\ORMException
|
||||||
|
* @throws \Doctrine\ORM\OptimisticLockException
|
||||||
|
*/
|
||||||
|
public function metaAction($id, ParamFetcherInterface $paramFetcher)
|
||||||
|
{
|
||||||
|
$project = $this->repository->find($id);
|
||||||
|
|
||||||
|
if (null === $project) {
|
||||||
|
throw new NotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->isGranted('edit', $project)) {
|
||||||
|
throw new AccessDeniedHttpException('You are not allowed to update this project');
|
||||||
|
}
|
||||||
|
|
||||||
|
$event = new ProjectMetaDefinitionEvent($project);
|
||||||
|
$this->dispatcher->dispatch($event, ProjectMetaDefinitionEvent::class);
|
||||||
|
|
||||||
|
$name = $paramFetcher->get('name');
|
||||||
|
$value = $paramFetcher->get('value');
|
||||||
|
|
||||||
|
if (null === ($meta = $project->getMetaField($name))) {
|
||||||
|
throw new \InvalidArgumentException('Unknown meta-field requested');
|
||||||
|
}
|
||||||
|
|
||||||
|
$meta->setValue($value);
|
||||||
|
|
||||||
|
$this->repository->saveProject($project);
|
||||||
|
|
||||||
|
$view = new View($project, 200);
|
||||||
|
$view->getContext()->setGroups(['Default', 'Entity', 'Project']);
|
||||||
|
|
||||||
|
return $this->viewHandler->handle($view);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ namespace App\API;
|
|||||||
use App\Configuration\TimesheetConfiguration;
|
use App\Configuration\TimesheetConfiguration;
|
||||||
use App\Entity\Timesheet;
|
use App\Entity\Timesheet;
|
||||||
use App\Entity\User;
|
use App\Entity\User;
|
||||||
|
use App\Event\TimesheetMetaDefinitionEvent;
|
||||||
use App\Form\API\TimesheetApiEditForm;
|
use App\Form\API\TimesheetApiEditForm;
|
||||||
use App\Repository\Query\TimesheetQuery;
|
use App\Repository\Query\TimesheetQuery;
|
||||||
use App\Repository\TagRepository;
|
use App\Repository\TagRepository;
|
||||||
@@ -30,6 +31,7 @@ use FOS\RestBundle\View\ViewHandlerInterface;
|
|||||||
use Pagerfanta\Pagerfanta;
|
use Pagerfanta\Pagerfanta;
|
||||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
|
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
|
||||||
use Swagger\Annotations as SWG;
|
use Swagger\Annotations as SWG;
|
||||||
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||||
@@ -47,27 +49,31 @@ class TimesheetController extends BaseApiController
|
|||||||
/**
|
/**
|
||||||
* @var TimesheetRepository
|
* @var TimesheetRepository
|
||||||
*/
|
*/
|
||||||
protected $repository;
|
private $repository;
|
||||||
/**
|
/**
|
||||||
* @var ViewHandlerInterface
|
* @var ViewHandlerInterface
|
||||||
*/
|
*/
|
||||||
protected $viewHandler;
|
private $viewHandler;
|
||||||
/**
|
/**
|
||||||
* @var TimesheetConfiguration
|
* @var TimesheetConfiguration
|
||||||
*/
|
*/
|
||||||
protected $configuration;
|
private $configuration;
|
||||||
/**
|
/**
|
||||||
* @var UserDateTimeFactory
|
* @var UserDateTimeFactory
|
||||||
*/
|
*/
|
||||||
protected $dateTime;
|
private $dateTime;
|
||||||
/**
|
/**
|
||||||
* @var TagRepository
|
* @var TagRepository
|
||||||
*/
|
*/
|
||||||
protected $tagRepository;
|
private $tagRepository;
|
||||||
/**
|
/**
|
||||||
* @var TrackingModeService
|
* @var TrackingModeService
|
||||||
*/
|
*/
|
||||||
protected $trackingModeService;
|
private $trackingModeService;
|
||||||
|
/**
|
||||||
|
* @var EventDispatcherInterface
|
||||||
|
*/
|
||||||
|
private $dispatcher;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
ViewHandlerInterface $viewHandler,
|
ViewHandlerInterface $viewHandler,
|
||||||
@@ -75,7 +81,8 @@ class TimesheetController extends BaseApiController
|
|||||||
UserDateTimeFactory $dateTime,
|
UserDateTimeFactory $dateTime,
|
||||||
TimesheetConfiguration $configuration,
|
TimesheetConfiguration $configuration,
|
||||||
TagRepository $tagRepository,
|
TagRepository $tagRepository,
|
||||||
TrackingModeService $trackingModeService
|
TrackingModeService $trackingModeService,
|
||||||
|
EventDispatcherInterface $dispatcher
|
||||||
) {
|
) {
|
||||||
$this->viewHandler = $viewHandler;
|
$this->viewHandler = $viewHandler;
|
||||||
$this->repository = $repository;
|
$this->repository = $repository;
|
||||||
@@ -83,6 +90,7 @@ class TimesheetController extends BaseApiController
|
|||||||
$this->dateTime = $dateTime;
|
$this->dateTime = $dateTime;
|
||||||
$this->tagRepository = $tagRepository;
|
$this->tagRepository = $tagRepository;
|
||||||
$this->trackingModeService = $trackingModeService;
|
$this->trackingModeService = $trackingModeService;
|
||||||
|
$this->dispatcher = $dispatcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getTrackingMode(): TrackingModeInterface
|
protected function getTrackingMode(): TrackingModeInterface
|
||||||
@@ -282,6 +290,9 @@ class TimesheetController extends BaseApiController
|
|||||||
$timesheet->setUser($this->getUser());
|
$timesheet->setUser($this->getUser());
|
||||||
$timesheet->setBegin($this->dateTime->createDateTime());
|
$timesheet->setBegin($this->dateTime->createDateTime());
|
||||||
|
|
||||||
|
$event = new TimesheetMetaDefinitionEvent($timesheet);
|
||||||
|
$this->dispatcher->dispatch($event, TimesheetMetaDefinitionEvent::class);
|
||||||
|
|
||||||
$mode = $this->getTrackingMode();
|
$mode = $this->getTrackingMode();
|
||||||
|
|
||||||
$form = $this->createForm(TimesheetApiEditForm::class, $timesheet, [
|
$form = $this->createForm(TimesheetApiEditForm::class, $timesheet, [
|
||||||
@@ -305,9 +316,7 @@ class TimesheetController extends BaseApiController
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$entityManager = $this->getDoctrine()->getManager();
|
$this->repository->save($timesheet);
|
||||||
$entityManager->persist($timesheet);
|
|
||||||
$entityManager->flush();
|
|
||||||
|
|
||||||
$view = new View($timesheet, 200);
|
$view = new View($timesheet, 200);
|
||||||
$view->getContext()->setGroups(['Default', 'Entity', 'Timesheet']);
|
$view->getContext()->setGroups(['Default', 'Entity', 'Timesheet']);
|
||||||
@@ -362,6 +371,9 @@ class TimesheetController extends BaseApiController
|
|||||||
throw new AccessDeniedHttpException('You are not allowed to update this timesheet');
|
throw new AccessDeniedHttpException('You are not allowed to update this timesheet');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$event = new TimesheetMetaDefinitionEvent($timesheet);
|
||||||
|
$this->dispatcher->dispatch($event, TimesheetMetaDefinitionEvent::class);
|
||||||
|
|
||||||
$mode = $this->getTrackingMode();
|
$mode = $this->getTrackingMode();
|
||||||
|
|
||||||
$form = $this->createForm(TimesheetApiEditForm::class, $timesheet, [
|
$form = $this->createForm(TimesheetApiEditForm::class, $timesheet, [
|
||||||
@@ -382,9 +394,7 @@ class TimesheetController extends BaseApiController
|
|||||||
return $this->viewHandler->handle($view);
|
return $this->viewHandler->handle($view);
|
||||||
}
|
}
|
||||||
|
|
||||||
$entityManager = $this->getDoctrine()->getManager();
|
$this->repository->save($timesheet);
|
||||||
$entityManager->persist($timesheet);
|
|
||||||
$entityManager->flush();
|
|
||||||
|
|
||||||
$view = new View($timesheet, Response::HTTP_OK);
|
$view = new View($timesheet, Response::HTTP_OK);
|
||||||
$view->getContext()->setGroups(['Default', 'Entity', 'Timesheet']);
|
$view->getContext()->setGroups(['Default', 'Entity', 'Timesheet']);
|
||||||
@@ -588,8 +598,8 @@ class TimesheetController extends BaseApiController
|
|||||||
/** @var User $user */
|
/** @var User $user */
|
||||||
$user = $this->getUser();
|
$user = $this->getUser();
|
||||||
|
|
||||||
$entry = new Timesheet();
|
$copyTimesheet = new Timesheet();
|
||||||
$entry
|
$copyTimesheet
|
||||||
->setBegin($this->dateTime->createDateTime())
|
->setBegin($this->dateTime->createDateTime())
|
||||||
->setUser($user)
|
->setUser($user)
|
||||||
->setActivity($timesheet->getActivity())
|
->setActivity($timesheet->getActivity())
|
||||||
@@ -598,29 +608,29 @@ class TimesheetController extends BaseApiController
|
|||||||
|
|
||||||
if (null !== ($copy = $paramFetcher->get('copy'))) {
|
if (null !== ($copy = $paramFetcher->get('copy'))) {
|
||||||
if (in_array($copy, ['rates', 'all'])) {
|
if (in_array($copy, ['rates', 'all'])) {
|
||||||
$entry->setHourlyRate($timesheet->getHourlyRate());
|
$copyTimesheet->setHourlyRate($timesheet->getHourlyRate());
|
||||||
$entry->setFixedRate($timesheet->getFixedRate());
|
$copyTimesheet->setFixedRate($timesheet->getFixedRate());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_array($copy, ['description', 'all'])) {
|
if (in_array($copy, ['description', 'all'])) {
|
||||||
$entry->setDescription($timesheet->getDescription());
|
$copyTimesheet->setDescription($timesheet->getDescription());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_array($copy, ['tags', 'all'])) {
|
if (in_array($copy, ['tags', 'all'])) {
|
||||||
foreach ($timesheet->getTags() as $tag) {
|
foreach ($timesheet->getTags() as $tag) {
|
||||||
$entry->addTag($tag);
|
$copyTimesheet->addTag($tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_array($copy, ['meta', 'all'])) {
|
if (in_array($copy, ['meta', 'all'])) {
|
||||||
foreach ($timesheet->getMetaFields() as $metaField) {
|
foreach ($timesheet->getMetaFields() as $metaField) {
|
||||||
$metaNew = clone $metaField;
|
$metaNew = clone $metaField;
|
||||||
$entry->setMetaField($metaNew);
|
$copyTimesheet->setMetaField($metaNew);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$errors = $validator->validate($entry);
|
$errors = $validator->validate($copyTimesheet);
|
||||||
|
|
||||||
if (count($errors) > 0) {
|
if (count($errors) > 0) {
|
||||||
throw new BadRequestHttpException($errors[0]->getPropertyPath() . ' = ' . $errors[0]->getMessage());
|
throw new BadRequestHttpException($errors[0]->getPropertyPath() . ' = ' . $errors[0]->getMessage());
|
||||||
@@ -631,11 +641,9 @@ class TimesheetController extends BaseApiController
|
|||||||
$this->configuration->getActiveEntriesHardLimit()
|
$this->configuration->getActiveEntriesHardLimit()
|
||||||
);
|
);
|
||||||
|
|
||||||
$entityManager = $this->getDoctrine()->getManager();
|
$this->repository->save($copyTimesheet);
|
||||||
$entityManager->persist($entry);
|
|
||||||
$entityManager->flush();
|
|
||||||
|
|
||||||
$view = new View($entry, 200);
|
$view = new View($copyTimesheet, 200);
|
||||||
$view->getContext()->setGroups(['Default', 'Entity', 'Timesheet']);
|
$view->getContext()->setGroups(['Default', 'Entity', 'Timesheet']);
|
||||||
|
|
||||||
return $this->viewHandler->handle($view);
|
return $this->viewHandler->handle($view);
|
||||||
@@ -659,6 +667,8 @@ class TimesheetController extends BaseApiController
|
|||||||
*
|
*
|
||||||
* @param int $id
|
* @param int $id
|
||||||
* @return Response
|
* @return Response
|
||||||
|
* @throws \Doctrine\ORM\ORMException
|
||||||
|
* @throws \Doctrine\ORM\OptimisticLockException
|
||||||
*/
|
*/
|
||||||
public function exportAction($id)
|
public function exportAction($id)
|
||||||
{
|
{
|
||||||
@@ -677,9 +687,63 @@ class TimesheetController extends BaseApiController
|
|||||||
|
|
||||||
$timesheet->setExported(!$timesheet->isExported());
|
$timesheet->setExported(!$timesheet->isExported());
|
||||||
|
|
||||||
$entityManager = $this->getDoctrine()->getManager();
|
$this->repository->save($timesheet);
|
||||||
$entityManager->persist($timesheet);
|
|
||||||
$entityManager->flush();
|
$view = new View($timesheet, 200);
|
||||||
|
$view->getContext()->setGroups(['Default', 'Entity', 'Timesheet']);
|
||||||
|
|
||||||
|
return $this->viewHandler->handle($view);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value of a meta-field for an existing timesheet.
|
||||||
|
*
|
||||||
|
* @SWG\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Sets the value of an existing/configured meta-field. You cannot create unknown meta-fields, if the given name is not a configured meta-field, this will return an exception.",
|
||||||
|
* @SWG\Schema(ref="#/definitions/TimesheetEntity")
|
||||||
|
* )
|
||||||
|
* @SWG\Parameter(
|
||||||
|
* name="id",
|
||||||
|
* in="path",
|
||||||
|
* type="integer",
|
||||||
|
* description="Timesheet record ID to set the meta-field value for",
|
||||||
|
* required=true,
|
||||||
|
* )
|
||||||
|
* @Rest\RequestParam(name="name", strict=true, nullable=false, description="The meta-field name")
|
||||||
|
* @Rest\RequestParam(name="value", strict=true, nullable=false, description="The meta-field value")
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @param ParamFetcherInterface $paramFetcher
|
||||||
|
* @return Response
|
||||||
|
* @throws \Doctrine\ORM\ORMException
|
||||||
|
* @throws \Doctrine\ORM\OptimisticLockException
|
||||||
|
*/
|
||||||
|
public function metaAction($id, ParamFetcherInterface $paramFetcher)
|
||||||
|
{
|
||||||
|
$timesheet = $this->repository->find($id);
|
||||||
|
|
||||||
|
if (null === $timesheet) {
|
||||||
|
throw new NotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->isGranted('edit', $timesheet)) {
|
||||||
|
throw new AccessDeniedHttpException('You are not allowed to update this timesheet');
|
||||||
|
}
|
||||||
|
|
||||||
|
$event = new TimesheetMetaDefinitionEvent($timesheet);
|
||||||
|
$this->dispatcher->dispatch($event, TimesheetMetaDefinitionEvent::class);
|
||||||
|
|
||||||
|
$name = $paramFetcher->get('name');
|
||||||
|
$value = $paramFetcher->get('value');
|
||||||
|
|
||||||
|
if (null === ($meta = $timesheet->getMetaField($name))) {
|
||||||
|
throw new \InvalidArgumentException('Unknown meta-field requested');
|
||||||
|
}
|
||||||
|
|
||||||
|
$meta->setValue($value);
|
||||||
|
|
||||||
|
$this->repository->save($timesheet);
|
||||||
|
|
||||||
$view = new View($timesheet, 200);
|
$view = new View($timesheet, 200);
|
||||||
$view->getContext()->setGroups(['Default', 'Entity', 'Timesheet']);
|
$view->getContext()->setGroups(['Default', 'Entity', 'Timesheet']);
|
||||||
|
|||||||
@@ -26,6 +26,26 @@ use Pagerfanta\Pagerfanta;
|
|||||||
|
|
||||||
class ActivityRepository extends EntityRepository
|
class ActivityRepository extends EntityRepository
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @param mixed $id
|
||||||
|
* @param null $lockMode
|
||||||
|
* @param null $lockVersion
|
||||||
|
* @return Activity|null
|
||||||
|
*/
|
||||||
|
public function find($id, $lockMode = null, $lockVersion = null)
|
||||||
|
{
|
||||||
|
/** @var Activity|null $activity */
|
||||||
|
$activity = parent::find($id, $lockMode, $lockVersion);
|
||||||
|
if (null === $activity) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$loader = new ActivityLoader($this->getEntityManager());
|
||||||
|
$loader->loadResults([$activity]);
|
||||||
|
|
||||||
|
return $activity;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Activity $activity
|
* @param Activity $activity
|
||||||
* @throws ORMException
|
* @throws ORMException
|
||||||
|
|||||||
@@ -28,6 +28,26 @@ use Pagerfanta\Pagerfanta;
|
|||||||
|
|
||||||
class CustomerRepository extends EntityRepository
|
class CustomerRepository extends EntityRepository
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @param mixed $id
|
||||||
|
* @param null $lockMode
|
||||||
|
* @param null $lockVersion
|
||||||
|
* @return Customer|null
|
||||||
|
*/
|
||||||
|
public function find($id, $lockMode = null, $lockVersion = null)
|
||||||
|
{
|
||||||
|
/** @var Customer|null $customer */
|
||||||
|
$customer = parent::find($id, $lockMode, $lockVersion);
|
||||||
|
if (null === $customer) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$loader = new CustomerLoader($this->getEntityManager());
|
||||||
|
$loader->loadResults([$customer]);
|
||||||
|
|
||||||
|
return $customer;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Customer $customer
|
* @param Customer $customer
|
||||||
* @throws ORMException
|
* @throws ORMException
|
||||||
|
|||||||
@@ -25,11 +25,28 @@ use Doctrine\ORM\Query;
|
|||||||
use Doctrine\ORM\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
use Pagerfanta\Pagerfanta;
|
use Pagerfanta\Pagerfanta;
|
||||||
|
|
||||||
/**
|
|
||||||
* Class ProjectRepository
|
|
||||||
*/
|
|
||||||
class ProjectRepository extends EntityRepository
|
class ProjectRepository extends EntityRepository
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @param mixed $id
|
||||||
|
* @param null $lockMode
|
||||||
|
* @param null $lockVersion
|
||||||
|
* @return Project|null
|
||||||
|
*/
|
||||||
|
public function find($id, $lockMode = null, $lockVersion = null)
|
||||||
|
{
|
||||||
|
/** @var Project|null $project */
|
||||||
|
$project = parent::find($id, $lockMode, $lockVersion);
|
||||||
|
if (null === $project) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$loader = new ProjectLoader($this->getEntityManager());
|
||||||
|
$loader->loadResults([$project]);
|
||||||
|
|
||||||
|
return $project;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Project $project
|
* @param Project $project
|
||||||
* @throws ORMException
|
* @throws ORMException
|
||||||
|
|||||||
@@ -22,6 +22,20 @@ use Pagerfanta\Pagerfanta;
|
|||||||
|
|
||||||
class TeamRepository extends EntityRepository
|
class TeamRepository extends EntityRepository
|
||||||
{
|
{
|
||||||
|
public function find($id, $lockMode = null, $lockVersion = null)
|
||||||
|
{
|
||||||
|
/** @var Team|null $team */
|
||||||
|
$team = parent::find($id, $lockMode, $lockVersion);
|
||||||
|
if (null === $team) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$loader = new TeamLoader($this->getEntityManager());
|
||||||
|
$loader->loadResults([$team]);
|
||||||
|
|
||||||
|
return $team;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Team $team
|
* @param Team $team
|
||||||
* @throws ORMException
|
* @throws ORMException
|
||||||
|
|||||||
@@ -35,6 +35,26 @@ class TimesheetRepository extends EntityRepository
|
|||||||
public const STATS_QUERY_ACTIVE = 'active';
|
public const STATS_QUERY_ACTIVE = 'active';
|
||||||
public const STATS_QUERY_MONTHLY = 'monthly';
|
public const STATS_QUERY_MONTHLY = 'monthly';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed $id
|
||||||
|
* @param null $lockMode
|
||||||
|
* @param null $lockVersion
|
||||||
|
* @return Timesheet|null
|
||||||
|
*/
|
||||||
|
public function find($id, $lockMode = null, $lockVersion = null)
|
||||||
|
{
|
||||||
|
/** @var Timesheet|null $timesheet */
|
||||||
|
$timesheet = parent::find($id, $lockMode, $lockVersion);
|
||||||
|
if (null === $timesheet) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$loader = new TimesheetLoader($this->getEntityManager());
|
||||||
|
$loader->loadResults([$timesheet]);
|
||||||
|
|
||||||
|
return $timesheet;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Timesheet $timesheet
|
* @param Timesheet $timesheet
|
||||||
* @throws \Doctrine\ORM\ORMException
|
* @throws \Doctrine\ORM\ORMException
|
||||||
|
|||||||
@@ -151,6 +151,14 @@ abstract class APIControllerBaseTest extends ControllerBaseTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function assertEntityNotFoundForPatch(string $role, string $url, array $data)
|
protected function assertEntityNotFoundForPatch(string $role, string $url, array $data)
|
||||||
|
{
|
||||||
|
return $this->assertExceptionForPatchAction($role, $url, $data, [
|
||||||
|
'code' => 404,
|
||||||
|
'message' => 'Not found'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function assertExceptionForPatchAction(string $role, string $url, array $data, array $expectedErrors)
|
||||||
{
|
{
|
||||||
$client = $this->getClientForAuthenticatedUser($role);
|
$client = $this->getClientForAuthenticatedUser($role);
|
||||||
|
|
||||||
@@ -158,15 +166,10 @@ abstract class APIControllerBaseTest extends ControllerBaseTest
|
|||||||
$response = $client->getResponse();
|
$response = $client->getResponse();
|
||||||
$this->assertFalse($response->isSuccessful());
|
$this->assertFalse($response->isSuccessful());
|
||||||
|
|
||||||
$expected = [
|
$this->assertEquals($expectedErrors['code'], $client->getResponse()->getStatusCode());
|
||||||
'code' => 404,
|
|
||||||
'message' => 'Not found'
|
|
||||||
];
|
|
||||||
|
|
||||||
$this->assertEquals(404, $client->getResponse()->getStatusCode());
|
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
$expected,
|
$expectedErrors,
|
||||||
json_decode($client->getResponse()->getContent(), true)
|
json_decode($client->getResponse()->getContent(), true)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ use App\Entity\Activity;
|
|||||||
use App\Entity\Customer;
|
use App\Entity\Customer;
|
||||||
use App\Entity\Project;
|
use App\Entity\Project;
|
||||||
use App\Entity\User;
|
use App\Entity\User;
|
||||||
|
use App\Tests\Mocks\ActivityTestMetaFieldSubscriberMock;
|
||||||
use Symfony\Bundle\FrameworkBundle\Client;
|
use Symfony\Bundle\FrameworkBundle\Client;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
@@ -219,6 +220,54 @@ class ActivityControllerTest extends APIControllerBaseTest
|
|||||||
$this->assertApiCallValidationError($response, ['project']);
|
$this->assertApiCallValidationError($response, ['project']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testMetaActionThrowsNotFound()
|
||||||
|
{
|
||||||
|
$this->assertEntityNotFoundForPatch(User::ROLE_ADMIN, '/api/activities/42/meta', []);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMetaActionThrowsExceptionOnMissingName()
|
||||||
|
{
|
||||||
|
return $this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/activities/1/meta', ['value' => 'X'], [
|
||||||
|
'code' => 400,
|
||||||
|
'message' => 'Parameter "name" of value "NULL" violated a constraint "This value should not be null."'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMetaActionThrowsExceptionOnMissingValue()
|
||||||
|
{
|
||||||
|
return $this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/activities/1/meta', ['name' => 'X'], [
|
||||||
|
'code' => 400,
|
||||||
|
'message' => 'Parameter "value" of value "NULL" violated a constraint "This value should not be null."'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMetaActionThrowsExceptionOnMissingMetafield()
|
||||||
|
{
|
||||||
|
return $this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/activities/1/meta', ['name' => 'X', 'value' => 'Y'], [
|
||||||
|
'code' => 500,
|
||||||
|
'message' => 'Unknown meta-field requested'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMetaAction()
|
||||||
|
{
|
||||||
|
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
|
||||||
|
$client->getContainer()->get('event_dispatcher')->addSubscriber(new ActivityTestMetaFieldSubscriberMock());
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'name' => 'metatestmock',
|
||||||
|
'value' => 'another,testing,bar'
|
||||||
|
];
|
||||||
|
$this->request($client, '/api/activities/1/meta', 'PATCH', [], json_encode($data));
|
||||||
|
|
||||||
|
$this->assertTrue($client->getResponse()->isSuccessful());
|
||||||
|
|
||||||
|
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
|
||||||
|
/** @var Activity $activity */
|
||||||
|
$activity = $em->getRepository(Activity::class)->find(1);
|
||||||
|
$this->assertEquals('another,testing,bar', $activity->getMetaField('metatestmock')->getValue());
|
||||||
|
}
|
||||||
|
|
||||||
protected function assertStructure(array $result, $full = true)
|
protected function assertStructure(array $result, $full = true)
|
||||||
{
|
{
|
||||||
$expectedKeys = [
|
$expectedKeys = [
|
||||||
|
|||||||
@@ -9,7 +9,9 @@
|
|||||||
|
|
||||||
namespace App\Tests\API;
|
namespace App\Tests\API;
|
||||||
|
|
||||||
|
use App\Entity\Customer;
|
||||||
use App\Entity\User;
|
use App\Entity\User;
|
||||||
|
use App\Tests\Mocks\CustomerTestMetaFieldSubscriberMock;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -161,6 +163,54 @@ class CustomerControllerTest extends APIControllerBaseTest
|
|||||||
$this->assertApiCallValidationError($response, ['currency']);
|
$this->assertApiCallValidationError($response, ['currency']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testMetaActionThrowsNotFound()
|
||||||
|
{
|
||||||
|
$this->assertEntityNotFoundForPatch(User::ROLE_ADMIN, '/api/customers/42/meta', []);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMetaActionThrowsExceptionOnMissingName()
|
||||||
|
{
|
||||||
|
return $this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/customers/1/meta', ['value' => 'X'], [
|
||||||
|
'code' => 400,
|
||||||
|
'message' => 'Parameter "name" of value "NULL" violated a constraint "This value should not be null."'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMetaActionThrowsExceptionOnMissingValue()
|
||||||
|
{
|
||||||
|
return $this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/customers/1/meta', ['name' => 'X'], [
|
||||||
|
'code' => 400,
|
||||||
|
'message' => 'Parameter "value" of value "NULL" violated a constraint "This value should not be null."'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMetaActionThrowsExceptionOnMissingMetafield()
|
||||||
|
{
|
||||||
|
return $this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/customers/1/meta', ['name' => 'X', 'value' => 'Y'], [
|
||||||
|
'code' => 500,
|
||||||
|
'message' => 'Unknown meta-field requested'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMetaAction()
|
||||||
|
{
|
||||||
|
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
|
||||||
|
$client->getContainer()->get('event_dispatcher')->addSubscriber(new CustomerTestMetaFieldSubscriberMock());
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'name' => 'metatestmock',
|
||||||
|
'value' => 'another,testing,bar'
|
||||||
|
];
|
||||||
|
$this->request($client, '/api/customers/1/meta', 'PATCH', [], json_encode($data));
|
||||||
|
|
||||||
|
$this->assertTrue($client->getResponse()->isSuccessful());
|
||||||
|
|
||||||
|
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
|
||||||
|
/** @var Customer $customer */
|
||||||
|
$customer = $em->getRepository(Customer::class)->find(1);
|
||||||
|
$this->assertEquals('another,testing,bar', $customer->getMetaField('metatestmock')->getValue());
|
||||||
|
}
|
||||||
|
|
||||||
protected function assertStructure(array $result, $full = true)
|
protected function assertStructure(array $result, $full = true)
|
||||||
{
|
{
|
||||||
$expectedKeys = [
|
$expectedKeys = [
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ use App\Entity\Customer;
|
|||||||
use App\Entity\Project;
|
use App\Entity\Project;
|
||||||
use App\Entity\User;
|
use App\Entity\User;
|
||||||
use App\Repository\Query\VisibilityQuery;
|
use App\Repository\Query\VisibilityQuery;
|
||||||
|
use App\Tests\Mocks\ProjectTestMetaFieldSubscriberMock;
|
||||||
use Symfony\Bundle\FrameworkBundle\Client;
|
use Symfony\Bundle\FrameworkBundle\Client;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
@@ -211,6 +212,54 @@ class ProjectControllerTest extends APIControllerBaseTest
|
|||||||
$this->assertApiCallValidationError($response, ['customer']);
|
$this->assertApiCallValidationError($response, ['customer']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testMetaActionThrowsNotFound()
|
||||||
|
{
|
||||||
|
$this->assertEntityNotFoundForPatch(User::ROLE_ADMIN, '/api/projects/42/meta', []);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMetaActionThrowsExceptionOnMissingName()
|
||||||
|
{
|
||||||
|
return $this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/projects/1/meta', ['value' => 'X'], [
|
||||||
|
'code' => 400,
|
||||||
|
'message' => 'Parameter "name" of value "NULL" violated a constraint "This value should not be null."'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMetaActionThrowsExceptionOnMissingValue()
|
||||||
|
{
|
||||||
|
return $this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/projects/1/meta', ['name' => 'X'], [
|
||||||
|
'code' => 400,
|
||||||
|
'message' => 'Parameter "value" of value "NULL" violated a constraint "This value should not be null."'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMetaActionThrowsExceptionOnMissingMetafield()
|
||||||
|
{
|
||||||
|
return $this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/projects/1/meta', ['name' => 'X', 'value' => 'Y'], [
|
||||||
|
'code' => 500,
|
||||||
|
'message' => 'Unknown meta-field requested'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMetaAction()
|
||||||
|
{
|
||||||
|
$client = $this->getClientForAuthenticatedUser(User::ROLE_ADMIN);
|
||||||
|
$client->getContainer()->get('event_dispatcher')->addSubscriber(new ProjectTestMetaFieldSubscriberMock());
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'name' => 'metatestmock',
|
||||||
|
'value' => 'another,testing,bar'
|
||||||
|
];
|
||||||
|
$this->request($client, '/api/projects/1/meta', 'PATCH', [], json_encode($data));
|
||||||
|
|
||||||
|
$this->assertTrue($client->getResponse()->isSuccessful());
|
||||||
|
|
||||||
|
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
|
||||||
|
/** @var Project $project */
|
||||||
|
$project = $em->getRepository(Project::class)->find(1);
|
||||||
|
$this->assertEquals('another,testing,bar', $project->getMetaField('metatestmock')->getValue());
|
||||||
|
}
|
||||||
|
|
||||||
protected function assertStructure(array $result, $full = true)
|
protected function assertStructure(array $result, $full = true)
|
||||||
{
|
{
|
||||||
$expectedKeys = [
|
$expectedKeys = [
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ use App\Entity\TimesheetMeta;
|
|||||||
use App\Entity\User;
|
use App\Entity\User;
|
||||||
use App\Tests\DataFixtures\TimesheetFixtures;
|
use App\Tests\DataFixtures\TimesheetFixtures;
|
||||||
use App\Tests\Mocks\Security\UserDateTimeFactoryFactory;
|
use App\Tests\Mocks\Security\UserDateTimeFactoryFactory;
|
||||||
|
use App\Tests\Mocks\TimesheetTestMetaFieldSubscriberMock;
|
||||||
use App\Timesheet\UserDateTimeFactory;
|
use App\Timesheet\UserDateTimeFactory;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
@@ -619,7 +620,7 @@ class TimesheetControllerTest extends APIControllerBaseTest
|
|||||||
|
|
||||||
public function testStopThrowsNotFound()
|
public function testStopThrowsNotFound()
|
||||||
{
|
{
|
||||||
$this->assertEntityNotFound(User::ROLE_USER, '/api/timesheets/11/stop', 'PATCH');
|
$this->assertEntityNotFoundForPatch(User::ROLE_USER, '/api/timesheets/11/stop', []);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testStopNotAllowedForUser()
|
public function testStopNotAllowedForUser()
|
||||||
@@ -782,7 +783,7 @@ class TimesheetControllerTest extends APIControllerBaseTest
|
|||||||
|
|
||||||
public function testRestartThrowsNotFound()
|
public function testRestartThrowsNotFound()
|
||||||
{
|
{
|
||||||
$this->assertEntityNotFound(User::ROLE_USER, '/api/timesheets/42/restart', 'PATCH');
|
$this->assertEntityNotFoundForPatch(User::ROLE_USER, '/api/timesheets/42/restart', []);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testExportAction()
|
public function testExportAction()
|
||||||
@@ -821,7 +822,55 @@ class TimesheetControllerTest extends APIControllerBaseTest
|
|||||||
|
|
||||||
public function testExportThrowsNotFound()
|
public function testExportThrowsNotFound()
|
||||||
{
|
{
|
||||||
$this->assertEntityNotFound(User::ROLE_ADMIN, '/api/timesheets/42/export', 'PATCH');
|
$this->assertEntityNotFoundForPatch(User::ROLE_ADMIN, '/api/timesheets/42/export', []);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMetaActionThrowsNotFound()
|
||||||
|
{
|
||||||
|
$this->assertEntityNotFoundForPatch(User::ROLE_ADMIN, '/api/timesheets/42/meta', []);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMetaActionThrowsExceptionOnMissingName()
|
||||||
|
{
|
||||||
|
return $this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/timesheets/1/meta', ['value' => 'X'], [
|
||||||
|
'code' => 400,
|
||||||
|
'message' => 'Parameter "name" of value "NULL" violated a constraint "This value should not be null."'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMetaActionThrowsExceptionOnMissingValue()
|
||||||
|
{
|
||||||
|
return $this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/timesheets/1/meta', ['name' => 'X'], [
|
||||||
|
'code' => 400,
|
||||||
|
'message' => 'Parameter "value" of value "NULL" violated a constraint "This value should not be null."'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMetaActionThrowsExceptionOnMissingMetafield()
|
||||||
|
{
|
||||||
|
return $this->assertExceptionForPatchAction(User::ROLE_ADMIN, '/api/timesheets/1/meta', ['name' => 'X', 'value' => 'Y'], [
|
||||||
|
'code' => 500,
|
||||||
|
'message' => 'Unknown meta-field requested'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMetaAction()
|
||||||
|
{
|
||||||
|
$client = $this->getClientForAuthenticatedUser(User::ROLE_USER);
|
||||||
|
$client->getContainer()->get('event_dispatcher')->addSubscriber(new TimesheetTestMetaFieldSubscriberMock());
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'name' => 'metatestmock',
|
||||||
|
'value' => 'another,testing,bar'
|
||||||
|
];
|
||||||
|
$this->request($client, '/api/timesheets/1/meta', 'PATCH', [], json_encode($data));
|
||||||
|
|
||||||
|
$this->assertTrue($client->getResponse()->isSuccessful());
|
||||||
|
|
||||||
|
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
|
||||||
|
/** @var Timesheet $timesheet */
|
||||||
|
$timesheet = $em->getRepository(Timesheet::class)->find(1);
|
||||||
|
$this->assertEquals('another,testing,bar', $timesheet->getMetaField('metatestmock')->getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function assertDefaultStructure(array $result, $full = true)
|
protected function assertDefaultStructure(array $result, $full = true)
|
||||||
|
|||||||
Reference in New Issue
Block a user