Skip to content
Snippets Groups Projects
Commit 97d6d07b authored by damjan's avatar damjan
Browse files

[TASK] AttributeController separated to TypeController and PropertyController

parent 0b26024a
No related branches found
No related tags found
No related merge requests found
<?php
namespace SGalinski\TypoScriptBackendBundle\Controller;
use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Util\Codes;
use FOS\RestBundle\View\View;
use SGalinski\TypoScriptBackendBundle\Entity\Attribute;
use SGalinski\TypoScriptBackendBundle\Entity\AttributeRepository;
use SGalinski\TypoScriptBackendBundle\Entity\User;
use SGalinski\TypoScriptBackendBundle\Entity\UserRepository;
use SGalinski\TypoScriptBackendBundle\Exception\InvalidFormException;
use SGalinski\TypoScriptBackendBundle\Form\AttributeType;
use Symfony\Component\Form\FormTypeInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
/**
* The class AttributeController contains REST API methods for interaction with database attribute records.
*
* @package SGalinski\TypoScriptBackendBundle\Controller
*/
class PropertyController extends FOSRestController {
/**
* REST action which returns attribute by id.
* Method: GET, url: /api/attributes/{id}.{_format}
*
* @ApiDoc(
* resource = true,
* description = "Gets a Attribute for a given id",
* output = "SGalinski\TypoScriptBackendBundle\Entity\Attribute",
* statusCodes = {
* 200 = "Returned when successful",
* 404 = "Returned when the page is not found"
* }
* )
*
* @param $id
* @return mixed
*/
public function getAttributeAction($id) {
return $this->getAttributeOr404($id);
}
/**
* REST action which returns type by urlName.
* Method: GET, url: /api/types/{name}.{_format}
*
* @ApiDoc(
* resource = true,
* description = "Gets a Type for a given name",
* output = "SGalinski\TypoScriptBackendBundle\Entity\Attribute",
* statusCodes = {
* 200 = "Returned when successful",
* 404 = "Returned when the page is not found"
* }
* )
*
* @param $urlName
* @return mixed
*/
public function getTypeAction($urlName) {
/** @var AttributeRepository $attributeRepository */
$attributeRepository = $this->getDoctrine()->getRepository('TypoScriptBackendBundle:Attribute');
$attribute = NULL;
try {
$attribute = $attributeRepository->findTypeByUrlNameForeignKeysInsteadOfObjects($urlName);
} catch (\Exception $exception) {
$attribute = NULL;
}
if (!$attribute) {
throw new NotFoundHttpException(sprintf('The resource \'%s\' was not found.', $urlName));
}
return $attribute;
}
/**
* REST action which returns an array of children of an attribute by it's id.
* Returns empty array if there is no children.
* Method: GET, url: /api/attributes/{id}/children.{_format}
*
* @ApiDoc(
* resource = true,
* description = "Gets en array of children of en attribute by it's id.
* Returns empty array if there is no children.
* Only types can have children. And those children are subtypes and properties contained in this type",
* output = "array",
* statusCodes = {
* 200 = "Returned when successful"
* }
* )
*
* @param $id
* @return array
*/
public function getAttributeChildrenAction($id) {
/** @var AttributeRepository $attributeRepository */
$attributeRepository = $this->getDoctrine()->getRepository('TypoScriptBackendBundle:Attribute');
$attributes = $attributeRepository->getChildrenByParentId($id, 'name');
return $attributes;
}
/**
* REST action which returns an array of properties of en attribute by it's id.
* Returns empty array if there is no properties.
* Method: GET, url: /api/attributes/{id}/properties.{_format}
*
* @ApiDoc(
* resource = true,
* description = "Gets en array of properties of en attribute by it's id.
* Returns empty array if there is no properties. Also gets type names of properties.
* Only types can have children. And those children are subtypes and properties contained in this type.
* This method has 2 header parameters:
* version - a TYPO3 version and
* 'typo3group' - typo script group (can be 1, 2 or 3 = normal, page and user group respectively)",
* output = "array",
* statusCodes = {
* 200 = "Returned when successful"
* }
* )
*
* @param Request $request
* @param $id
* @return array example: [{"property":{"id":1163,"name":"wrap","description":"Wraps the links.","minVersion":"1.0",
* example: [{"property":{"id":1163,"name":"wrap","description":"Wraps the links.","minVersion":"1.0",
* "maxVersion":"7.4", "typo3Group":1,"default":"\n","isType":false,"deleted":false,"type_id":"687",
* "parent_id":"1164"}, "type_name":"wrap"}, ...]
*/
public function getAttributePropertiesAction(Request $request, $id) {
$parameters = $request->headers->all();
$typo3Version = array_key_exists('version', $parameters) ? $parameters['version'][0] : NULL;
$typo3Group = array_key_exists('typo3group', $parameters) ? $parameters['typo3group'][0] : NULL;
/** @var AttributeRepository $attributeRepository */
$attributeRepository = $this->getDoctrine()->getRepository('TypoScriptBackendBundle:Attribute');
$attributes = $attributeRepository->getPropertiesByParentIdWithTypeNames(
$id, 'name', $typo3Group, $typo3Version
);
return $attributes;
}
/**
* REST action which lists attributes by version, isType and typo3Group.
* Returns empty array if there is nothing to fetch.
* Method: GET, url: /api/attributes.{_format}
*
* @ApiDoc(
* resource = true,
* description = "Lists attributes by version, isType and typo3Group.",
* output = "array",
* statusCodes = {
* 200 = "Returned when successful"
* }
* )
*
* @param Request $request
* @return array
* @internal param $id
*/
public function getAttributesAction(Request $request) {
$parameters = $request->headers->all();
$version = array_key_exists('version', $parameters) ? $parameters['version'][0] : NULL;
$isType = array_key_exists('istype', $parameters) ? $parameters['istype'][0] : NULL;
$typo3Group = array_key_exists('typo3group', $parameters) ? $parameters['typo3group'][0] : NULL;
$namesOnly = array_key_exists('namesonly', $parameters) ? $parameters['namesonly'][0] : FALSE;
/** @var AttributeRepository $attributeRepository */
$attributeRepository = $this->getDoctrine()->getRepository('TypoScriptBackendBundle:Attribute');
$attributes = $attributeRepository->listAttributes($version, $isType, $typo3Group, $namesOnly, 'name');
return $attributes;
}
/**
* Create a Attribute from the submitted data.
*
* @ApiDoc(
* resource = true,
* description = "Creates a new attribute from the submitted data.",
* input = "SGalinski\TypoScriptBackendBundle\Entity\Attribute",
* statusCodes = {
* 200 = "Returned when successful",
* 400 = "Returned when the form has errors",
* 401 = "Returned when not authenticated",
* 403 = "Returned when not having permissions"
* }
* )
*
* @param Request $request the request object
*
* @return FormTypeInterface|View
*/
public function postAttributeAction(Request $request) {
try {
if (!$this->canEditData($request)) {
throw new AccessDeniedException();
}
$persistedAttribute = $this->createNewAttribute($request);
$routeOptions = [
'id' => $persistedAttribute->getId(),
'_format' => $request->get('_format')
];
return $this->routeRedirectView('api_get_attribute', $routeOptions, Codes::HTTP_CREATED);
} catch (InvalidFormException $exception) {
return $exception->getForm();
}
}
/**
* Update existing attribute from the submitted data or create a new attribute.
* All required fields must be set within request data.
*
* @ApiDoc(
* resource = true,
* input = "SGalinski\TypoScriptBackendBundle\Entity\Attribute",
* statusCodes = {
* 201 = "Returned when the Attribute is created",
* 204 = "Returned when successful",
* 400 = "Returned when the form has errors",
* 401 = "Returned when not authenticated",
* 403 = "Returned when not having permissions"
* }
* )
*
* @param Request $request the request object
* @param int $id the attribute id
*
* @return FormTypeInterface|View
*
* @throws NotFoundHttpException when attribute not exist
*/
public function putAttributeAction(Request $request, $id) {
try {
if (!$this->canEditData($request)) {
throw new AuthenticationException();
}
/** @var AttributeRepository $attributeRepository */
$attributeRepository = $this->getDoctrine()->getRepository('TypoScriptBackendBundle:Attribute');
/** @var Attribute $attribute */
$attribute = $attributeRepository->find($id);
if (!$attribute) {
$statusCode = Codes::HTTP_CREATED;
$attribute = $this->createNewAttribute($request);
} else {
$statusCode = Codes::HTTP_NO_CONTENT;
$attribute = $this->processForm($attribute, $request->request->all(), 'PUT');
}
$routeOptions = [
'id' => $attribute->getId(),
'_format' => $request->get('_format')
];
return $this->routeRedirectView('api_get_attribute', $routeOptions, $statusCode);
} catch (InvalidFormException $exception) {
return $exception->getForm();
}
}
/**
* REST action which deletes attribute by id.
* Method: DELETE, url: /api/attributes/{id}.{_format}
*
* @ApiDoc(
* resource = true,
* description = "Deletes a Attribute for a given id",
* statusCodes = {
* 204 = "Returned when successful",
* 401 = "Returned when not authenticated",
* 403 = "Returned when not having permissions",
* 404 = "Returned when the attribute is not found"
* }
* )
*
* @param Request $request
* @param $id
* @return mixed
*/
public function deleteAttributeAction(Request $request, $id) {
if (!$this->canEditData($request)) {
throw new AuthenticationException();
}
/** @var AttributeRepository $attributeRepository */
$attributeRepository = $this->getDoctrine()->getRepository('TypoScriptBackendBundle:Attribute');
/** @var Attribute $attribute */
$attribute = $attributeRepository->find($id);
if ($attribute) {
$attributeRepository->deleteAttribute($attribute);
} else {
throw new NotFoundHttpException(sprintf('The resource \'%s\' was not found.', $id));
}
}
/**
* Update existing attribute from the submitted data.
*
* @ApiDoc(
* resource = true,
* input = "SGalinski\TypoScriptBackendBundle\Entity\Attribute",
* statusCodes = {
* 204 = "Returned when successful",
* 400 = "Returned when the form has errors",
* 401 = "Returned when not authenticated",
* 403 = "Returned when not having permissions"
* }
* )
*
* @param Request $request the request object
* @param int $id the attribute id
*
* @return FormTypeInterface|View
*
* @throws NotFoundHttpException when attribute does not exist
*/
public function patchAttributeAction(Request $request, $id) {
try {
if (!$this->canEditData($request)) {
throw new AuthenticationException();
}
/** @var Attribute $attribute */
$attribute = $this->getAttributeEntityOr404($id);
$statusCode = Codes::HTTP_NO_CONTENT;
$attribute = $this->processForm($attribute, $request->request->all(), 'PATCH');
$routeOptions = [
'id' => $attribute->getId(),
'_format' => $request->get('_format')
];
return $this->routeRedirectView('api_get_attribute', $routeOptions, $statusCode);
} catch (InvalidFormException $exception) {
return $exception->getForm();
}
}
/**
* Processes the form.
*
* @param Attribute $attribute
* @param array $parameters
* @param String $method
*
* @return Attribute
*
* @throws InvalidFormException
*/
private function processForm(Attribute $attribute, array $parameters, $method = 'PUT') {
$form = $this->createForm(new AttributeType(), $attribute, ['method' => $method]);
$form->submit($parameters, 'PATCH' !== $method);
if ($form->isValid()) {
/** @var Attribute $attribute */
$attribute = $form->getData();
/** @var AttributeRepository $attributeRepository */
$attributeRepository = $this->getDoctrine()->getRepository('TypoScriptBackendBundle:Attribute');
$attributeRepository->persistAttribute($attribute);
return $attribute;
}
throw new InvalidFormException('Invalid submitted data', $form);
}
/**
* Method which returns attribute as en array by id or throws NotFoundHttpException if resource isn't found.
*
* @param $id
* @return array
*/
public function getAttributeOr404($id) {
/** @var AttributeRepository $attributeRepository */
$attributeRepository = $this->getDoctrine()->getRepository('TypoScriptBackendBundle:Attribute');
$attribute = NULL;
try {
$attribute = $attributeRepository->findByIdForeignKeysInsteadOfObjects($id);
} catch (\Exception $exception) {
$attribute = NULL;
}
if (!$attribute) {
throw new NotFoundHttpException(sprintf('The resource \'%s\' was not found.', $id));
}
return $attribute;
}
/**
* Method which returns attribute entity object by id or throws NotFoundHttpException if resource isn't found.
*
* @param $id
* @return mixed
*/
public function getAttributeEntityOr404($id) {
if (!($attribute = $this->getDoctrine()->getRepository('TypoScriptBackendBundle:Attribute')->find($id))) {
throw new NotFoundHttpException(sprintf('The resource \'%s\' was not found.', $id));
}
return $attribute;
}
/**
* Creates new attribute from request parameters and persists it.
*
* @param Request $request
* @return Attribute - persisted attribute
*/
protected function createNewAttribute(Request $request) {
$attribute = new Attribute();
$parameters = $request->request->all();
$persistedAttribute = $this->processForm($attribute, $parameters, 'POST');
return $persistedAttribute;
}
/**
* Checks if client has privileges to edit the data.
* Reads "accesstoken" from request header.
*
* @param Request $request
* @return bool
*/
private function canEditData(Request $request) {
$parameters = $request->headers->all();
$accessToken = array_key_exists('accesstoken', $parameters) ? $parameters['accesstoken'][0] : NULL;
if ($accessToken === NULL) {
throw new AuthenticationCredentialsNotFoundException();
}
/** @var UserRepository $userRepository */
$userRepository = $this->getDoctrine()->getRepository('TypoScriptBackendBundle:User');
/** @var User $user */
$user = $userRepository->findOneBy(['token' => $accessToken]);
if ($user === NULL) {
throw new AuthenticationCredentialsNotFoundException();
}
return $user->isAdmin();
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment