<?php
namespace App\Ox\HoardBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\ButtonType;
use App\Ox\HoardBundle\Entity\HObject;
use App\Ox\HoardBundle\Entity\ObjectImage;
use App\Ox\HoardBundle\Entity\Image;
use App\Ox\HoardBundle\Form\ObjectType;
/**
* Object controller
*
* @Route("/object")
*/
class ObjectController extends AbstractController
{
private $security;
public function __construct(Security $security)
{
$this->security = $security;
}
/**
* @Route("/{id}/edit", name="object_edit", methods={"GET"})
* @Template("@OxHoardBundle/hObject/edit.html.twig")
*/
public function editAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$object = $em->getRepository('OxHoardBundle:HObject')->find($id);
$this->checkAccess($object, 'edit');
if(!$object) {
throw $this->createNotFoundException('Unable to find object entity.');
}
// $deleteForm = $this->createDeleteForm($id);
$editForm = $this->createEditForm($object);
$isAjax = $request->isXmlHttpRequest();
$template = ($isAjax ? '@OxHoardBundle/hObject/edit_form.html.twig' : '@OxHoardBundle/hObject/edit.html.twig');
$referenceTypes = $em->createQuery('SELECT rt FROM OxHoardBundle:ReferenceType rt ORDER BY rt.referenceType')->getResult();
return $this->render($template, array(
'ajax' => $request->isXmlHttpRequest(),
'object' => $object,
'edit_form' => $editForm->createView(),
// 'delete_form' => $deleteForm->createView(),
'reference_types' => $referenceTypes
));
}
/**
* Creates a form to delete an Object entity by id.
*
* @param mixed $id The entity id
*
* @return \Symfony\Component\Form\Form The form
*/
private function createDeleteForm($id)
{
return $this->createFormBuilder()
->setAction($this->generateUrl('object_delete', array('id' => $id)))
->setMethod('DELETE')
->add('submit', ButtonType::class, array(
'label' => 'Delete this object',
'attr' => array(
'class' => 'delete-button btn-danger'
)
))
->getForm()
;
}
/**
* Creates a form to edit an Object entity.
*
* @param HObject $entity The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createEditForm(HObject $entity)
{
$form = $this->createForm(ObjectType::class, $entity, array(
'action' => $this->generateUrl('object_update', array('id' => $entity->getId())),
'method' => 'PUT',
'hoard' => $entity->getHoard()
));
$form->add('submit', SubmitType::class, array('label' => 'Update'));
return $form;
}
/**
* Edits an existing Object entity.
*
* @Route("/{id}", name="object_update", methods={"PUT"}) PUT doesn't seem to work...
* @Template("@OxHoardBundle/hObject/edit.html.twig")
*/
public function updateAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$object = $em->getRepository('OxHoardBundle:HObject')->find($id);
$this->checkAccess($object, 'edit');
if (!$object) {
throw $this->createNotFoundException('Unable to find Object entity.');
}
// $deleteForm = $this->createDeleteForm($id);
$editForm = $this->createEditForm($object);
$editForm->handleRequest($request);
if ($editForm->isValid()) {
//mark as unvalidated since it has changed
if(!$this->userIsAdmin())
{
if($object->getHoard())
{
$object->getHoard()->markUnvalidatedByAdmin();
}
}
//persist object references
$objectReferences = $object->getObjectReferences();
foreach($objectReferences as $ref)
{
if($ref->getDeleted())
{
//do soft delete
//persist deleted flag
$em->persist($ref);
//clear link to object
$ref->setObject(null);
//flush before removing;
$em->flush();
$em->remove($ref);
}
else
{
$ref->setObject($object);
$em->persist($ref);
}
}
$em->flush();
return $this->redirect($this->generateUrl('object_show', array('id' => $id)));
} else {
$referenceTypes = $em->createQuery('SELECT rt FROM OxHoardBundle:ReferenceType rt ORDER BY rt.referenceType')->getResult();
return $this->render('@OxHoardBundle/hObject/edit_form.html.twig', array(
'object' => $object,
'edit_form' => $editForm->createView(),
'reference_types' => $referenceTypes
));
}
$referenceTypes = $em->createQuery('SELECT rt FROM OxHoardBundle:ReferenceType rt ORDER BY rt.referenceType')->getResult();
return array(
'object' => $object,
'edit_form' => $editForm->createView(),
// 'delete_form' => $deleteForm->createView(),
'reference_types' => $referenceTypes
);
}
/**
* Finds and displays an object entity.
*
* @Route("/{id}", name="object_show", methods={"GET"})
* @Template("@OxHoardBundle/hObject/show.html.twig")
*/
public function showAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$object = $em->getRepository('OxHoardBundle:HObject')->find($id);
$this->checkAccess($object, 'view');
if (!$object) {
throw $this->createNotFoundException('Unable to find Object entity.');
}
$isAjax = $request->isXmlHttpRequest();
$template = ($isAjax ? '@OxHoardBundle/hObject/show_modal.html.twig' : '@OxHoardBundle/hObject/show.html.twig');
return $this->render($template, array(
'object' => $object,
));
}
/**
* Adds a new image file, creating an Image entity, and an ObjectImage entity
*
* @Route("/{id}/ajax_add_image", methods={"POST"})
*/
public function ajaxAddImage(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$file = $request->files->get('image');
$object = $em->getRepository('OxHoardBundle:HObject')->find($id);
//validate the file - TODO
$this->checkAccess($object, 'edit');
//move to desired location/name
$count = $object->getObjectImages()->count();
$fileName = $id.$count.'.'.$file->guessExtension();
$file = $file->move($this->getPermanentObjectImageUploadDir(), $fileName);
//create Image entity
$image = new Image();
$image->setFileName($fileName);
$em->persist($image);
//create ObjectImage entity
$objectImage = new ObjectImage();
$objectImage->setObject($object);
$objectImage->setImage($image);
$em->persist($objectImage);
//mark as unvalidated since it has changed
if(!$this->userIsAdmin())
{
if($object->getHoard())
{
$object->getHoard()->markUnvalidatedByAdmin();
}
}
$em->persist($object);
$em->flush();
return new JsonResponse(array(
'fileName'=>$fileName,
'object_image_id'=>$objectImage->getId()
));
}
/**
* soft-delete the given object image from the object
*
* @Route("/{id}/ajax_remove_image/{objectImage_id}", methods={"POST"})
*/
public function ajaxRemoveImage(Request $request, $id, $objectImage_id)
{
$em = $this->getDoctrine()->getManager();
$object = $em->getRepository('OxHoardBundle:HObject')->find($id);
$this->checkAccess($object, 'edit');
if(!$object)
{
return $this->removeImageFailed('Object not found');
}
$objectImage = $em->getRepository('OxHoardBundle:ObjectImage')->find($objectImage_id);
if(!$objectImage)
{
return $this->removeImageFailed('Object Image not found');
}
if($objectImage->getObject() != $object)
{
return $this->removeImageFailed('Image does not belong to specified object');
}
//Remove the objectImage (performs soft delete)
$em->remove($objectImage);
//mark as unvalidated since it has changed
if(!$this->userIsAdmin())
{
if($object->getHoard())
{
$object->getHoard()->markUnvalidatedByAdmin();
}
}
$em->flush();
return new JsonResponse( array(
'removedImage'=>$objectImage_id,
));
}
private function removeImageFailed($reason)
{
return new JsonResponse( array(
'removedImage'=>null,
'error'=> $reason
));
}
/**
* checks permission of user's current request
*
* @param mixed $entity The entity being validated
*
* @param string $attribute - 'view' or 'edit' or 'delete'
* @return boolean
*
* @throws \Symfony\Component\Security\Core\Exception\AccessDeniedException
*/
private function checkAccess($entity, $attribute) {
// call security voter(s)
if (false === $this->security->isGranted($attribute, $entity->getHoard())) {
throw new AccessDeniedException('Unauthorised access!');
}
return true;
}
private function userIsAdmin() {
if($this->getUser() && ($this->getUser()->hasRole('ROLE_ADMIN') || $this->getUser()->hasRole('ROLE_SUPER_ADMIN')))
{
return true;
}
return false;
}
private function getPermanentObjectImageUploadDir() {
return '/srv/hoards_object_images';
}
}