<?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\Coin;
use App\Ox\HoardBundle\Form\CoinType;
use App\Ox\HoardBundle\Entity\Image;
use App\Ox\HoardBundle\Entity\CoinImage;
/**
* coin controller.
*
* @Route("/coin")
*/
class CoinController extends AbstractController
{
private $security;
public function __construct(Security $security)
{
$this->security = $security;
}
/**
* Suggest obverse inscription
* @Route("/suggest/obv/insc", name="suggest_obverse_inscription", methods={"GET"})
*/
public function suggestObvInsc(Request $request)
{
$em = $this->getDoctrine()->getManager();
$q = $request->get('q');
$query = $em -> createQuery("SELECT DISTINCT c.obverseInscription from OxHoardBundle:Coin c WHERE c.obverseInscription LIKE :query")
->setParameter('query', $q.'%');
$results = $query->getArrayResult();
return new JsonResponse($results);
}
/**
* Suggest obverse mint mark
* @Route("/suggest/obv/mint", name="suggest_obverse_mintmark", methods={"GET"})
*/
public function suggestObvMint(Request $request)
{
$em = $this->getDoctrine()->getManager();
$q = $request->get('q');
$query = $em -> createQuery("SELECT DISTINCT c.obverseMintMark from OxHoardBundle:Coin c WHERE c.obverseMintMark LIKE :query")
->setParameter('query', $q.'%');
$results = $query->getArrayResult();
return new JsonResponse($results);
}
/**
* Suggest obverse description
* @Route("/suggest/obv/desc", name="suggest_obverse_description", methods={"GET"})
*/
public function suggestObvDesc(Request $request)
{
$em = $this->getDoctrine()->getManager();
$q = $request->get('q');
$query = $em -> createQuery("SELECT DISTINCT c.obverseDescription from OxHoardBundle:Coin c WHERE c.obverseDescription LIKE :query")
->setParameter('query', $q.'%');
$results = $query->getArrayResult();
return new JsonResponse($results);
}
/**
* Suggest reverse inscription
* @Route("/suggest/rev/insc", name="suggest_reverse_inscription", methods={"GET"})
*/
public function suggestRevInsc(Request $request)
{
$em = $this->getDoctrine()->getManager();
$q = $request->get('q');
$query = $em -> createQuery("SELECT DISTINCT c.reverseInscription from OxHoardBundle:Coin c WHERE c.reverseInscription LIKE :query")
->setParameter('query', $q.'%');
$results = $query->getArrayResult();
return new JsonResponse($results);
}
/**
* Suggest reverse mint mark
* @Route("/suggest/rev/mint", name="suggest_reverse_mintmark", methods={"GET"})
*/
public function suggestRevMint(Request $request)
{
$em = $this->getDoctrine()->getManager();
$q = $request->get('q');
$query = $em -> createQuery("SELECT DISTINCT c.reverseMintMark from OxHoardBundle:Coin c WHERE c.reverseMintMark LIKE :query")
->setParameter('query', $q.'%');
$results = $query->getArrayResult();
return new JsonResponse($results);
}
/**
* Suggest reverse description
* @Route("/suggest/rev/desc", name="suggest_reverse_description", methods={"GET"})
*/
public function suggestRevDesc(Request $request)
{
$em = $this->getDoctrine()->getManager();
$q = $request->get('q');
$query = $em -> createQuery("SELECT DISTINCT c.reverseDescription from OxHoardBundle:Coin c WHERE c.reverseDescription LIKE :query")
->setParameter('query', $q.'%');
$results = $query->getArrayResult();
return new JsonResponse($results);
}
/**
* Suggest person based on period
* @Route("/suggest/person", name="suggest_person", methods={"GET"})
*/
public function suggestPerson(Request $request)
{
$em = $this->getDoctrine()->getManager();
$pid = $request->get('period');
$reignids_str = $request->get('reign');
$q = $request->get('q');
$queryBuilder = $em->createQueryBuilder();
if(isset($reignids_str)) {
$reignids = explode(",", $reignids_str);
$queryBuilder->select('ocre, p')
->from('OxHoardBundle:OcreLookup', 'ocre')
->leftJoin('ocre.reign', 'r')
->leftJoin('ocre.person', 'p')
->where('r.id IN (:reigns)')
->setParameter('reigns', $reignids);
if($q) {
$queryBuilder->andWhere('r.reign LIKE :query')
->setParameter('query', '%'.$q.'%');
}
$query = $queryBuilder->getQuery();
$ocres = $query->getArrayResult();
//extract just the reigns
$results = [];
foreach($ocres as $ocre) {
if(!in_array($ocre['person'], $results)) {
$results[] = $ocre['person'];
}
}
}
if(!isset($reignids_str) || empty($results)) {
$queryBuilder = $em->createQueryBuilder();
$queryBuilder->select('p')
->from('OxHoardBundle:Person', 'p');
if($pid) {
$queryBuilder->leftJoin('p.period1', 'period1')
->leftJoin('p.period2', 'period2')
->leftJoin('p.period3', 'period3')
->where('period1.id = :period')
->orWhere('period2.id = :period')
->orWhere('period3.id = :period')
->orWhere('period1.id is NULL AND period2.id is NULL AND period3.id is NULL')
->setParameter('period', $pid)
->orderBy('p.person', 'ASC')
;
}
if($q) {
$queryBuilder->andWhere('p.person LIKE :query')
->setParameter('query', '%'.$q.'%');
}
$query = $queryBuilder->getQuery();
$results = $query->getArrayResult();
$response = [];
}
foreach($results as $result) {
if($result['title']) {
$result['person'] = $result['person'].' ('.$result['title'].')';
}
$response[] = $result;
}
return new JsonResponse($response);
}
/**
* Suggest reign based on period
* @Route("/suggest/reign", name="suggest_reign", methods={"GET"})
*/
public function suggestReign(Request $request)
{
$em = $this->getDoctrine()->getManager();
$pid = $request->get('period');
$personids_str = $request->get('person');
$q = $request->get('q');
$queryBuilder = $em->createQueryBuilder();
if(isset($personids_str)) {
$personids = explode(",", $personids_str);
$queryBuilder->select('ocre, r')
->from('OxHoardBundle:OcreLookup', 'ocre')
->leftJoin('ocre.reign', 'r')
->leftJoin('ocre.person', 'p')
->where('p.id IN (:persons)')
->setParameter('persons', $personids);
if($q) {
$queryBuilder->andWhere('r.reign LIKE :query')
->setParameter('query', '%'.$q.'%');
}
$query = $queryBuilder->getQuery();
$ocres = $query->getArrayResult();
//extract just the reigns
$results = [];
foreach($ocres as $ocre) {
if(!in_array($ocre['reign'], $results)) {
$results[] = $ocre['reign'];
}
}
}
if(!isset($personids_str) || empty($results)) {
$queryBuilder = $em->createQueryBuilder();
//suggest based on period
$queryBuilder->select('r')
->from('OxHoardBundle:Reign', 'r');
if($pid) {
$queryBuilder->leftJoin('r.period1', 'period1')
->leftJoin('r.period2', 'period2')
->where('period1.id = :period')
->orWhere('period2.id = :period')
->orWhere('period1.id is NULL AND period2.id is NULL')
->setParameter('period', $pid)
->orderBy('r.startDate', 'ASC')
->addOrderBy('r.endDate', 'ASC');
}
if($q) {
$queryBuilder->andWhere('r.reign LIKE :query')
->setParameter('query', '%'.$q.'%');
}
$query = $queryBuilder->getQuery();
$results = $query->getArrayResult();
}
return new JsonResponse($results);
}
/**
* Suggest mint based on period
* @Route("/suggest/mint", name="suggest_mint", methods={"GET"})
*/
public function suggestMint(Request $request)
{
$em = $this->getDoctrine()->getManager();
$pid = $request->get('period');
$q = $request->get('q');
$queryBuilder = $em->createQueryBuilder();
$queryBuilder->select('m')
->from('OxHoardBundle:Mint', 'm');
if($pid) {
$queryBuilder->leftJoin('m.period1', 'period1')
->leftJoin('m.period2', 'period2')
->leftJoin('m.period3', 'period3')
->leftJoin('m.period4', 'period4')
->where('period1.id = :period')
->orWhere('period2.id = :period')
->orWhere('period3.id = :period')
->orWhere('period4.id = :period')
->orWhere('period1.id is NULL AND period2.id is NULL AND period3.id is NULL AND period4.id is NULL')
->setParameter('period', $pid)
->orderBy('m.mint', 'ASC');
}
if($q) {
$queryBuilder->andWhere('m.mint LIKE :query')
->setParameter('query', '%'.$q.'%');
}
$query = $queryBuilder->getQuery();
$results = $query->getArrayResult();
return new JsonResponse($results);
}
/**
* @Route("/ocre", name="ocre_autocomplete", methods={"GET"})
*/
public function getOcreLookup(Request $request) {
//get the parameters
$reign_id = $request->get('reign');
$person_id = $request->get('person');
$mint_id = $request->get('mint');
if(!$reign_id) {
return new JsonResponse(array('error' => 'no reign id supplied'));
}
if(!$person_id) {
return new JsonResponse(array('error' => 'no person id supplied'));
}
$em = $this->getDoctrine()->getManager();
$reign = $em->getRepository('OxHoardBundle:Reign')->find($reign_id);
if(!$reign) {
//return error
return new JsonResponse(array('error' => 'reign not found'));
}
$person = $em->getRepository('OxHoardBundle:Person')->find($person_id);
if(!$person) {
return new JsonResponse(array('error' => 'person not found'));
}
//if a mint was specified get the mint
if($mint_id) {
$mint = $em->getRepository('OxHoardBundle:Mint')->find($mint_id);
if(!$mint) {
return new JsonResponse(array('error' => 'mint not found'));
}
}
//first try lookup without mint
$result = $em->getRepository('OxHoardBundle:OcreLookup')->findBy(array(
'reign' => $reign,
'person' => $person
));
$count = count($result);
// return new JsonResponse($count);
if($count == 1) {
$lookup = $result[0];
} else if($count < 1) {
$lookup = null;
} else {
//multiple matches, try with mint, or ask user to supply if necessary
if($mint_id && $mint) {
$result = $em->getRepository('OxHoardBundle:OcreLookup')->findBy(array(
'reign' => $reign,
'person' => $person,
'mint' => $mint
));
$count = count($result);
if($count == 1) {
$lookup = $result[0];
} else if($count < 1) {
$lookup = null;
} else {
//multiple matches, user should specify mint
return new JsonResponse(array(
'error' => 'multiple matches',
'message' => 'Multiple matches were found even with mint included. Check OCRE table.'
));
}
} else {
return new JsonResponse(array(
'error' => 'mint required',
'message' => 'Multiple matches were found but a mint was not specified, please specify a mint and try again.'
));
}
}
$return = array();
$return['reign'] = $reign->getReign();
$return['person'] = $person->getPerson();
if($mint_id && $mint) {
$return['mint'] = $mint->getMint();
}
if(!$lookup) {
$return['error'] = 'no results found';
} else {
$return['ocre'] = $lookup->getOcrePrefix();
}
return new JsonResponse($return);
}
/**
* @Route("/suggest/coin", name="suggest_coin", methods={"GET"})
*/
public function suggestCoin(Request $request)
{
//first try to find a coin with hoard_id = null
$qb_noHoard = $this->GetCoinMatchQueryBuilder($request);
$qb_noHoard->andWhere("c.hoard IS NULL");
$coins = $qb_noHoard->getQuery()->getResult();
if(count($coins) == 0) {
//none with null hoard - instead find most recent one
$qb_mostRecent = $this->GetCoinMatchQueryBuilder($request);
$qb_mostRecent->orderBy('c.modifiedDate', 'DESC');
$qb_mostRecent->setMaxResults(1);
$coins = $qb_mostRecent->getQuery()->getResult();
}
// echo '<pre>'; print_r($qb->getDql()); echo '</pre>';
if(count($coins) > 0) {
$coin = $coins[0];
$mints = $coin->getMints();
$mintsArray = array();
foreach ($mints as $mint) {
$mintsArray[] = $mint->getId();
}
$denominations = $coin->getDenominations();
$denominationsArray = array();
foreach ($denominations as $denomination) {
$denominationsArray[] = $denomination->getId();
}
$persons = $coin->getPersons();
$personsArray = array();
foreach ($persons as $person) {
$personsArray[] = $person->getId();
}
$reigns = $coin->getReigns();
$reignsArray = array();
foreach ($reigns as $reign) {
$reignsArray[] = $reign->getId();
}
if ($coins) {
$response['success'] = true;
$response['coin'] = array(
'id' => $coin->getId(),
'startingDate' => $coin->getStartingDate(),
'endingDate' => $coin->getEndingDate(),
'dateText' => $coin->getDateText(),
'issue' => $coin->getIssue(),
'officina' => $coin->getOfficina(),
'obverseInscription' => $coin->getObverseInscription(),
'obverseMintMark' => $coin->getObverseMintMark(),
'obverseDescription' => $coin->getObverseDescription(),
'reverseInscription' => $coin->getReverseInscription(),
'reverseMintMark' => $coin->getReverseMintMark(),
'reverseDescription' => $coin->getReverseDescription(),
'persons' => $personsArray,
'reigns' => $reignsArray,
'mints' => $mintsArray,
'denominations' => $denominationsArray,
);
}
} else {
$response['success'] = false;
$response['msg'] = 'No matching coin was found';
}
return new JsonResponse($response);
}
private function GetCoinMatchQueryBuilder($request) {
$em = $this->getDoctrine()->getManager();
$periodId = $request->query->get('period');
$reignIds = $request->query->get('reigns');
$personIds = $request->query->get('persons');
$denominationIds = $request->query->get('denominations');
$mintIds = $request->query->get('mints');
$refId = $request->query->get('ref');
$refStr = $request->query->get('refStr');
$qb = $em->createQueryBuilder();
$isRomanRepublicCoin = $periodId == 20;
$qb->select('c')
->from('OxHoardBundle:Coin', 'c');
$response = array();
if($periodId) {
$qb->leftJoin('c.period', 'period')
->andWhere('period.id = :period')
->setParameter('period', $periodId);
//different rules if roman republic coin
if($isRomanRepublicCoin ) {
$response['isRomanRepublicCoin'] = true;
}
} else {
//period is required
$response['success'] = false;
$response['msg'] = 'No period supplied';
return new JsonResponse($response);
}
$qb->leftJoin('c.coinReferences', 'coinReferences');
if($refId) {
$qb->leftJoin('coinReferences.reference', 'reference')
->andWhere('reference.id = :coinRef')
->setParameter('coinRef', $refId);
} else {
//reference is required
$response['success'] = false;
$response['msg'] = 'No reference supplied';
return new JsonResponse($response);
}
if ($refStr) {
$qb->andWhere('coinReferences.reference_str = :refStr')
->setParameter('refStr', $refStr);
} else {
//reference string is required
$response['success'] = false;
$response['msg'] = 'No reference string has been entered';
return new JsonResponse($response);
}
$params = array();
if($isRomanRepublicCoin) {
//no check on mints etc
} else {
//check for matches against the mints, persons, reigns, denominations for non republican era coins
if ($reignIds) {
//construct a query to search through all reigns
$qb->leftJoin('c.reigns', 'reign');
$reignIdsArray = explode(',', $reignIds);
$subQuery = "";
foreach ($reignIdsArray as $index => $reignId) {
$id = intval($reignId);
$reign = $em->getRepository('OxHoardBundle:Reign')->find($reignId);
if ($reign) {
if ($index > 0) {
$subQuery .= " OR ";
}
$subQuery .= 'reign.id = :reign_' . $index;
$params['reign_' . $index] = $reign;
}
}
$qb->andWhere($subQuery);
}
if ($mintIds) {
//construct a query to search through all mints
$qb->leftJoin('c.mints', 'mint');
$mintIdsArray = explode(',', $mintIds);
$subQuery = "";
foreach ($mintIdsArray as $index => $mintId) {
$id = intval($mintId);
$mint = $em->getRepository('OxHoardBundle:Mint')->find($mintId);
if ($mint) {
if ($index > 0) {
$subQuery .= " OR ";
}
$subQuery .= 'mint.id = :mint_' . $index;
$params['mint_' . $index] = $mint;
}
}
$qb->andWhere($subQuery);
}
if ($personIds) {
//construct a query to search through all persons
$qb->leftJoin('c.persons', 'person');
$personIdsArray = explode(',', $personIds);
$subQuery = "";
foreach ($personIdsArray as $index => $personId) {
$id = intval($personId);
$person = $em->getRepository('OxHoardBundle:Person')->find($personId);
if ($person) {
if ($index > 0) {
$subQuery .= " OR ";
}
$subQuery .= 'person.id = :person_' . $index;
$params['person_' . $index] = $person;
}
}
$qb->andWhere($subQuery);
}
if ($denominationIds) {
//construct a query to search through all denominations
$qb->leftJoin('c.denominations', 'denomination');
$denominationIdsArray = explode(',', $denominationIds);
$subQuery = "";
foreach ($denominationIdsArray as $index => $denominationId) {
$id = intval($denominationId);
$denomination = $em->getRepository('OxHoardBundle:Denomination')->find($denominationId);
if ($denomination) {
if ($index > 0) {
$subQuery .= " OR ";
}
$subQuery .= 'denomination.id = :denomination_' . $index;
$params['denomination_' . $index] = $denomination;
}
}
$qb->andWhere($subQuery);
}
}
//Only match coins where inscription/description fields are not null
$qb->andWhere('c.obverseInscription IS NOT NULL')
->andWhere('c.obverseDescription IS NOT NULL')
->andWhere('c.reverseInscription IS NOT NULL')
->andWhere('c.reverseDescription IS NOT NULL');
foreach($params as $key=>$value) {
$qb->setParameter($key, $value);
}
return $qb;
}
/**
* Lists all Coin entities.
*
* @Route("/", name="coin", methods={"GET"})
* @Template()
*/
public function indexAction(Request $request)
{
$limit = 20;
$em = $this->getDoctrine()->getManager();
$em->getFilters()->enable('softdeleteable');
$dql = 'SELECT c FROM OxHoardBundle:Coin c';
$query = $em->createQuery($dql)
->setFirstResult(0)
->setMaxResults($limit);
$paginator = $this->get('knp_paginator');
$pagination = $paginator->paginate(
$query,
$request->query->getInt('page', 1)/*page number*/,
$limit/*limit per page*/
);
// parameters to template
return $this->render('@OxHoardBundle/coin/list.html.twig', array('pagination' => $pagination));
}
/**
* //coins are created via the hoard controller's ajax_add_coin method (or via disaggregate)
* @Route("coin_create")
* @Template()
*/
public function createAction()
{
return array();
}
/**
* Deletes a Coin entity.
*
* @Route("/{id}", name="coin_delete", methods={"DELETE"})
*/
public function deleteAction(Request $request, $id)
{
$form = $this->createDeleteForm($id, null);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('OxHoardBundle:Coin')->find($id);
$this->checkAccess($entity, 'delete');
//referer will be passed in the URL. If it isn't present, get it from the header.
$referer = $request->get('referer');
if(!$referer)
{
$referer = $request->headers->get('referer');
}
if (!$entity) {
throw $this->createNotFoundException('Unable to find Coin entity.');
}
$em->remove($entity);
$em->flush();
/// No longer returning to the hoard, since the update coin page is now always opened in a new tab,
// redirecting to the hoard is a bad idea.
// //redirect to original referer, with #coins at the end, so that the page knows to open to an appropriate position
// return $this->redirect($referer.'#coins');
return $this->redirect($this->generateUrl('hoard'));
}
return $this->redirect($this->generateUrl('hoard'));
}
/**
* Disaggregate a Coin entity.
*
* @Route("/{id}/disaggregate", name="coin_disaggregate", methods={"POST"})
*/
public function disaggregateAction(Request $request, $id)
{
$form = $this->createDisaggregateForm($id, null);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('OxHoardBundle:Coin')->find($id);
$this->checkAccess($entity, 'delete');
//referer will be passed in the URL. If it isn't present, get it from the header.
$referer = $request->get('referer');
if(!$referer)
{
$referer = $request->headers->get('referer');
}
if (!$entity) {
throw $this->createNotFoundException('Unable to find Coin entity.');
}
$quantity = $entity->getQuantity();
if ($quantity > 1) {
$entity->setQuantity(1);
for ($i = 1; $i < $quantity; $i++) {
$clone = clone $entity;
//flag this as modified (even though it's technically being created, it's probably useful to track original creator in 'created')
$clone->setModified($this->getUser());
$em->persist($clone);
// clone all CoinAdditionalFields for the coin and set CoinAdditionalFields' oin to cloned coin
$additionalFieldsId = $entity->getCoinAdditionalFields();
foreach ($additionalFieldsId as $additionalFieldId) {
$additionalField = $em->getRepository('OxHoardBundle:CoinAdditionalField')->find($additionalFieldId);
$cloneAdditionalField = clone $additionalField;
$cloneAdditionalField->setCoin($clone);
$em->persist($cloneAdditionalField);
}
// clone all CoinReferences for the coin and set CoinReferences' coin to cloned coin
$referencesId = $entity->getCoinReferences();
foreach ($referencesId as $referenceId) {
$reference = $em->getRepository('OxHoardBundle:CoinReference')->find($referenceId);
$cloneReference = clone $reference;
$cloneReference->setCoin($clone);
$em->persist($cloneReference);
}
}
$em->flush();
}
$request->getSession()
->getFlashBag()
->add('success', 'Coin record has been disaggregated.');
/// No longer returning to the hoard, since the update coin page is now always opened in a new tab,
// redirecting to the hoard is a bad idea.
// //redirect to original referer, with #coins at the end, so that the page knows to open to an appropriate position
// return $this->redirect($referer.'#coins');
return $this->redirect($this->generateUrl('coin_show', array('id' => $id)));
}
return $this->redirect($this->generateUrl('hoard'));
}
/**
* Remove an existing coin image
* @Route("/{id}/ajax_remove_image/{typeId}", name="ajax_remove_coin_image", methods={"POST"})
*/
public function removeImage($id, $typeId)
{
$em=$this->getDoctrine()->getManager();
$coin = $em->getRepository('OxHoardBundle:Coin')->find($id);
$this->checkAccess($coin, 'edit');
$type = $em->getRepository('OxHoardBundle:CoinImageType')->find($typeId);
$coinImage = $em->getRepository('OxHoardBundle:CoinImage')->findOneBy(array(
'coin' => $coin,
'type' => $type
));
$em->remove($coinImage);
$em->flush();
return new JsonResponse( array(
'success' => 1,
'type' => $typeId
));
}
/**
* Adds a new image file, creating an Image entity, a CoinImage entity
*
* @Route("/{id}/ajax_add_image/{typeId}", methods={"POST"})
*/
public function addImage(Request $request, $id, $typeId)
{
$em = $this->getDoctrine()->getManager();
$file = $request->files->get('image');
$coin = $em->getRepository('OxHoardBundle:Coin')->find($id);
$this->checkAccess($coin, 'edit');
//validate the file - TODO
//build new filename
$type = $em->getRepository('OxHoardBundle:CoinImageType')->find($typeId);
$ext = $file->guessExtension();
$fileName = $id.$type->getAbbreviation().'.'.$ext;
//move to desired location with desired name
$destPath = $this->getPermanentCoinImageUploadDir();
$file = $file->move($destPath, $fileName);
//create Image
$image = new Image();
$image->setFileName($fileName);
$em->persist($image);
//find existing coinImage of that type for that coin
$coinImage = $em->getRepository('OxHoardBundle:CoinImage')->findOneBy(array(
'coin' => $coin,
'type' => $type
));
//create CoinImage with appropriate type
if(!$coinImage)
{
$coinImage = new CoinImage();
$coinImage->setType($type);
$coinImage->setCoin($coin);
$em->persist($coinImage);
}
$coinImage->setImage($image);
//flush em
//mark as unvalidated since it has changed
if(!$this->userIsAdmin())
{
if($coin->getHoard())
{
$coin->getHoard()->markUnvalidatedByAdmin();
}
}
$em->flush();
$typeAbbr = $type->getAbbreviation();
//fudge for the fact that symfony doesn't like the empty string in its routes.
if($typeAbbr == '') { $typeAbbr = 'c'; }
$url = $this->get('router')->generate('coin_image', array(
'coin_id' => $id,
'coin_image_type' => $typeAbbr,
'ext' => $ext
));
//return response
return new JsonResponse(
array('file' => $fileName, 'url' => $url)
);
}
/**
* @Route("/{id}/edit", name="coin_edit", methods={"GET"})
* @Template()
*/
public function editAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
//referer will be passed in the URL. If it isn't present, get it from the header.
$referer = $request->get('referer');
if(!$referer)
{
$referer = $request->headers->get('referer');
}
$coin = $em->getRepository('OxHoardBundle:Coin')->find($id);
if (!$coin)
{
throw $this->createNotFoundException('Unable to find Coin entity.');
}
$this->checkAccess($coin, 'edit');
$editForm = $this->createEditForm($coin, $referer);
$deleteForm = $this->createDeleteForm($id, $referer);
$disaggregateForm = $this->createDisaggregateForm($id, $referer);
$isAjax = $request->isXmlHttpRequest();
$template = ($isAjax ? '@OxHoardBundle/coin/edit_form.html.twig' : '@OxHoardBundle/coin/edit.html.twig');
$referenceTypes = $em->createQuery('SELECT rt FROM OxHoardBundle:ReferenceType rt ORDER BY rt.referenceType')->getResult();
return $this->render($template, array(
'ajax' => $isAjax,
'coin' => $coin,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
'disaggregate_form' => $disaggregateForm->createView(),
'images' => $this->getImages($coin),
'reference_types' => $referenceTypes
));
}
/****
* Get a list of image file names/ids for the given coin entity
*/
private function getImages(Coin $entity) {
$coinImages = $entity->getCoinImages();
$images = array();
$folder = '/uploads/images/coins/';
$obverseCoinImage = $coinImages->filter(
function($entry) {
$type = $entry->getType();
return $entry->getType()->getAbbreviation()=="o";
}
)->first();
if($obverseCoinImage)
{
$obverseImage = $obverseCoinImage->getImage();
if($obverseImage)
{
$images['obverse'] = $folder.$obverseImage->getFilename();
}
}
$reverseCoinImage = $coinImages->filter(
function($entry) {
return $entry->getType()->getAbbreviation()=="r";
}
)->first();
if($reverseCoinImage)
{
$reverseImage = $reverseCoinImage->getImage();
if($reverseImage)
{
$images['reverse'] = $folder.$reverseImage->getFilename();
}
}
$bothCoinImage = $coinImages->filter(
function($entry) {
return $entry->getType()->getAbbreviation()=="";
}
)->first();
if($bothCoinImage)
{
$bothImage = $bothCoinImage->getImage();
if($bothImage)
{
$images['both'] = $folder.$bothImage->getFilename();
}
}
return $images;
}
/**
* Creates a form to delete a Coin entity by id.
*
* @param mixed $id The entity id
*
* @return \Symfony\Component\Form\Form The form
*/
private function createDeleteForm($id, $referer)
{
$action = $this->generateUrl('coin_delete', array('id' => $id));
if($referer) {
$action .= '?referer='.$referer;
}
return $this->createFormBuilder()
->setAction($action)
->setMethod('DELETE')
->add('submit', ButtonType::class, array(
'label' => 'Delete this coin',
'attr' => array(
'class' => 'delete-button btn btn-danger'
)
))
->getForm()
;
}
/**
* Creates a form to disaggregate a Coin group by id.
*
* @param mixed $id The entity id
*
* @return \Symfony\Component\Form\Form The form
*/
private function createDisaggregateForm($id, $referer)
{
$action = $this->generateUrl('coin_disaggregate', array('id' => $id));
if($referer) {
$action .= '?referer='.$referer;
}
return $this->createFormBuilder()
->setAction($action)
->setMethod('POST')
->add('submit', SubmitType::class, array(
'label' => 'Disaggregate coins',
'attr' => array(
'class' => 'disaggregate-button'
)
))
->getForm()
;
}
/**
* Creates a form to edit a Coin entity.
*
* @param Coin $entity The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createEditForm(Coin $entity, $referer)
{
$containers = $entity->getHoard()->getContainers();
$layers = new \Doctrine\Common\Collections\ArrayCollection();
foreach($containers as $container)
{
$containerLayers = $container->getLayers();
foreach($containerLayers as $layer)
{
$layers[] = $layer;
}
}
$action = $this->generateUrl('coin_update',
array(
'id' => $entity->getId()
));
if($referer) {
$action .= '?referer='.$referer;
}
$form = $this->createForm(CoinType::class, $entity, array(
'action' => $action,
'containers' => $containers,
'layers' => $layers,
'em' => $this->getDoctrine()->getManager(),
));
$form->add('submit', SubmitType::class, array(
'label' => 'Update',
'attr' => array('class' => 'update-button')
));
return $form;
}
/**
* Edits an existing Coin entity.
*
* @Route("/{id}", name="coin_update", methods={"POST"}) PUT doesn't seem to work...
* @Template("@OxHoardBundle/coin/edit.html.twig")
*/
public function updateAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$em->getFilters()->enable('softdeleteable');
$coin = $em->getRepository('OxHoardBundle:Coin')->find($id);
$this->checkAccess($coin, 'edit');
if (!$coin) {
throw $this->createNotFoundException('Unable to find Coin entity.');
}
//referer will be passed in the URL. If it isn't present, get it from the header.
$referer = $request->get('referer');
if(!$referer)
{
$referer = $request->headers->get('referer');
}
$deleteForm = $this->createDeleteForm($id, $referer);
$editForm = $this->createEditForm($coin, $referer);
$editForm->handleRequest($request);
if ($editForm->isValid()) {
//mark as unvalidated since it has changed
if(!$this->userIsAdmin())
{
if($coin->getHoard())
{
$coin->getHoard()->markUnvalidatedByAdmin();
}
}
//persist images
$coinImages = $coin->getCoinImages();
foreach($coinImages as $coinImage)
{
if($coinImage->getImage()){
$em->persist($coinImage);
}
}
//persist references
$coinReferences = $coin->getCoinReferences();
foreach($coinReferences as $ref)
{
if ($ref->getReference() === null && $ref->getReferenceStr() === null && $ref->getComment() === null) {
$ref->setDeleted(true);
}
if($ref->getDeleted())
{
//do soft delete
//persist deleted flag
$em->persist($ref);
//clear the link with the coin
$ref->setCoin(null);
//flush before removing
$em->flush();
$em->remove($ref);
}
else
{
$ref->setCoin($coin);
$em->persist($ref);
}
}
//persist additional fields
$coinAdditionalFields = $coin->getCoinAdditionalFields();
foreach($coinAdditionalFields as $field)
{
if($field->getDeleted())
{
//do soft delete
//persist deleted flag
$em->persist($field);
//clear link with coin
$field->setCoin(null);
$em->flush();
$em->remove($field);
}
else
{
$field->setCoin($coin);
$em->persist($field);
}
}
$coin->setModified($this->getUser());
$em->flush();
$request->getSession()
->getFlashBag()
->add('success', 'Coin has been updated');
/// No longer returning to the hoard, since the update coin page is now always opened in a new tab,
// redirecting to the hoard is a bad idea.
// //redirect to original referer, with #coins at the end, so that the page knows to open to an appropriate position
// return $this->redirect($referer.'#coins');
return $this->redirect($this->generateUrl('coin_show', array('id' => $id)));
}
else {
$request->getSession()
->getFlashBag()
->add('error', 'Error updating coin!');
}
$referenceTypes = $em->createQuery('SELECT rt FROM OxHoardBundle:ReferenceType rt ORDER BY rt.referenceType')->getResult();
return array(
'coin' => $coin,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
'images' => $this->getImages($coin),
'reference_types' => $referenceTypes
);
}
/**
* Finds and displays a coin entity.
*
* @Route("/{id}", name="coin_show", methods={"GET"})
* @Template()
*/
public function showAction($id)
{
$em = $this->getDoctrine()->getManager();
$coin = $em->getRepository('OxHoardBundle:Coin')->find($id);
$this->checkAccess($coin, 'view_coins');
if (!$coin) {
throw $this->createNotFoundException('Unable to find Coin entity.');
}
// $deleteForm = $this->createDeleteForm($id);
$images = $this->getImages($coin);
return array(
'coin' => $coin,
'images' => $images,
// 'delete_form' => $deleteForm->createView(),
);
}
/**
* 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 getPermanentCoinImageUploadDir() {
return '/srv/hoards_coin_images';
}
}