<?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\HttpFoundation\File\File;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\ButtonType;
use Knp\Component\Pager\PaginatorInterface;
use App\Ox\HoardBundle\Entity\Reference;
use App\Ox\HoardBundle\Form\ReferenceType;
/**
* Reference controller.
*
* @Route("/reference")
*/
class ReferenceController extends AbstractController
{
/**
* Suggest
* @Route("/suggest", name="suggest_reference", methods={"GET"})
*/
public function suggestReference(Request $request)
{
$em = $this->getDoctrine()->getManager();
//get query params
$query = $request->get('q');
$typeID = $request->get('type');
$queryBuilder = $em->createQueryBuilder();
$queryBuilder->select('r.title, r.id, r.authors, r.year, r.abbreviation, r.sortValue')
->from('OxHoardBundle:Reference', 'r')
->orderBy('r.sortValue', 'DESC')
->addOrderBy('r.authors', 'ASC')
->addOrderBy('r.abbreviation', 'ASC')
->addOrderBy('r.title', 'ASC')
;
//match query against year, title or authors
if($query) {
$queryBuilder = $queryBuilder->where('r.title LIKE :query')
->orWhere('r.abbreviation LIKE :query')
->orWhere('r.authors LIKE :query')
->orWhere('r.year LIKE :query')
->setParameter('query', '%'.$query.'%')
;
}
//check type
if($typeID) {
$type = $em->getRepository('OxHoardBundle:ReferenceType')->find($typeID);
$queryBuilder = $queryBuilder->andWhere('r.referenceType = :refType')
->setParameter('refType', $type);
}
$query = $queryBuilder->getQuery();
$queryResult = $query->getArrayResult();
$response = array();
foreach($queryResult as $result) {
//compile the text version of the reference
$text = '';
if($result['abbreviation']) { $text .= $result['abbreviation']; }
else {
if( $result['authors'] ) { $text.=$result['authors'].' - '; }
if( $result['year'] ) { $text.=$result['year'].' - '; }
if( $result['title'] ) {
$text.=$result['title'];
} else {
$text.='Untitled';
}
}
$result['text'] = $text;
$response[] = $result;
}
return new JsonResponse($response);
}
/**
* Lists all Reference entities.
*
* @Route("/", name="reference", methods={"GET"})
* @Template()
*/
public function indexAction(Request $request, PaginatorInterface $paginator)
{
$limit = 20;
$em = $this->getDoctrine()->getManager();
$em->getFilters()->enable('softdeleteable');
$queryBuilder = $em->createQueryBuilder();
$queryBuilder->select('r, type')
->from('OxHoardBundle:Reference', 'r')
->leftJoin('r.referenceType', 'type');
$activeTab = $request->query->get('active-tab');
if ($activeTab == '#tabs-2') {
// advanced search
$title = $request->query->get('title');
if ($title) {
$queryBuilder->andWhere('r.title LIKE :chosenTitle')
->setParameter('chosenTitle', '%'.$title.'%');
}
$titleEdition = $request->query->get('title-edition');
if ($titleEdition) {
$queryBuilder->andWhere('r.titleEdition LIKE :chosenTitleEdition')
->setParameter('chosenTitleEdition', '%'.$titleEdition.'%');
}
$abbreviation = $request->query->get('abbreviation');
if ($abbreviation) {
$queryBuilder->andWhere('r.abbreviation LIKE :chosenAbbreviation')
->setParameter('chosenAbbreviation', '%'.$abbreviation.'%');
}
$yearFrom = $request->query->get('year-from');
if ($yearFrom) {
$queryBuilder->andWhere('r.year >= :chosenYearFrom')
->setParameter('chosenYearFrom', $yearFrom);
}
$yearTo = $request->query->get('year-to');
if ($yearTo) {
$queryBuilder->andWhere('r.year <= :chosenYearTo')
->setParameter('chosenYearTo', $yearTo);
}
$referenceType = null;
$referenceTypeId = $request->query->get('reference-type');
if($referenceTypeId) {
$referenceType = $em->getRepository('OxHoardBundle:ReferenceType')->find($referenceTypeId);
if ($referenceType) {
$queryBuilder->andWhere('r.referenceType = :chosenReferenceType')
->setParameter('chosenReferenceType', $referenceType);
}
}
$author = $request->query->get('author');
if ($author) {
$queryBuilder->andWhere('r.authors LIKE :chosenAuthor')
->setParameter('chosenAuthor', '%'.$author.'%');
}
$internalNote = $request->query->get('internal-note');
if ($internalNote) {
$queryBuilder->andWhere('r.internalNote LIKE :chosenInternalNote')
->setParameter('chosenInternalNote', '%'.$internalNote.'%');
}
$volume = $request->query->get('volume');
if ($volume) {
$queryBuilder->andWhere('r.volume = :chosenVolume')
->setParameter('chosenVolume', $volume);
}
} else { //simple search
if(isset($_GET['search']))
{
$searchValue = $_GET['search'];
$queryBuilder->where('r.title LIKE :search')
->orWhere('r.authors LIKE :search')
->orWhere('r.abbreviation LIKE :search')
->orWhere('r.titleEdition LIKE :search')
->setParameter('search','%'.$searchValue.'%');
}
}
$query = $queryBuilder->getQuery()
->setFirstResult(0)
->setMaxResults($limit);
$pagination = $paginator->paginate(
$query,
$request->query->getInt('page', 1),/* page number */
$limit
);
$isAuthenticated = false;
if($this->getUser()) {
$isAuthenticated = true;
}
$sortFields = array();
if ($isAuthenticated) {
$sortFields[] = array('label' => 'ID', 'key' => 'r.id', 'defaultDirection' => 'asc');
}
$sortFields = array_merge($sortFields, array(
array('label' => 'Author', 'key' => 'r.authors', 'defaultDirection' => 'asc'),
array('label' => 'Year', 'key' => 'r.year', 'defaultDirection' => 'desc'),
array('label' => 'Title', 'key' => 'r.title', 'defaultDirection' => 'asc'),
array('label' => 'Title (journal, series)', 'key' => 'r.titleEdition', 'defaultDirection' => 'asc'),
));
if ($isAuthenticated) {
$sortFields[] = array('label' => 'Sort Value', 'key' => 'r.sortValue', 'defaultDirection' => 'desc');
}
$isAdmin = $this->userIsAdmin();
$referenceTypes = $em->createQuery('SELECT rt FROM OxHoardBundle:ReferenceType rt ORDER BY rt.referenceType')->getResult();
return $this->render('@OxHoardBundle/reference/list.html.twig', array(
'pagination' => $pagination,
'sort_fields' => $sortFields,
'is_authenticated' => $isAuthenticated,
'is_admin' => $isAdmin,
'reference_types' => $referenceTypes,
// 'filtered_type' => $filteredType,
// 'abbreviations' => $onlyAbbreviated,
// 'own_column_only' => $ownColumnOnly,
'search_term' => isset($searchValue)?$searchValue:null,
'title' => isset($title) ? $title : null,
'title_edition' => isset($titleEdition) ? $titleEdition : null,
'abbreviation' => isset($abbreviation) ? $abbreviation : null,
'volume' => isset($volume) ? $volume : null,
'year_from' => isset($yearFrom) ? $yearFrom : null,
'year_to' => isset($yearTo) ? $yearTo : null,
'reference_type' => isset($referenceTypeId) ? $referenceTypeId : null,
'author' => isset($author) ? $author : null,
'internalNote' => isset($internalNote) ? $internalNote : null,
'active_tab' => isset($activeTab) ? $activeTab: "#tabs-1",
));
}
/**
* Creates a new Reference entity.
*
* @Route("/", name="reference_create", methods={"POST"})
* @Template("@OxHoardBundle/reference/new.html.twig")
*/
public function createAction(Request $request)
{
//only logged in users can create
if(!$this->getUser()) {
throw new AccessDeniedException("Only logged in contributors may create a reference entry");
}
$reference = new Reference();
$form = $this->createCreateForm($reference);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($reference);
$em->flush();
return $this->redirect($this->generateUrl('reference_show', array('id' => $reference->getId())));
}
return array(
'reference' => $reference,
'form' => $form->createView(),
);
}
/**
* Creates a form to create a Reference entity.
*
* @param Reference $reference The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createCreateForm(Reference $reference)
{
$form = $this->createForm(ReferenceType::class, $reference, array(
'action' => $this->generateUrl('reference_create'),
'method' => 'POST',
));
$form->add('submit', SubmitType::class, array('label' => 'Create'));
return $form;
}
/**
* Displays a form to create a new Reference entity.
*
* @Route("/new", name="reference_new", methods={"GET"})
* @Template()
*/
public function newAction()
{
//only logged in users can create
if(!$this->getUser()) {
throw new AccessDeniedException("Only logged in contributors may create a reference entry");
}
$reference = new Reference();
$form = $this->createCreateForm($reference);
return $this->render('@OxHoardBundle/reference/new.html.twig', array(
'reference' => $reference,
'edit_form' => $form->createView(),
'is_admin' => $this->userIsAdmin(),
));
}
/**
* Finds and displays a Reference entity.
*
* @Route("/{id}", name="reference_show", methods={"GET"})
* @Template()
*/
public function showAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$reference = $em->getRepository('OxHoardBundle:Reference')->find($id);
// if the hoard is not fount check if it soft-deleted
if (!$reference) {
$em->getFilters()->disable('softdeleteable');
$reference = $em->getRepository('OxHoardBundle:Reference')->find($id);
$em->getFilters()->enable('softdeleteable');
// if it is not soft-deleted return "not found"
if (!$reference) {
throw $this->createNotFoundException('Unable to find Reference entity.');
} else {
// else check if it is really soft-deleted and redirect ti the redirectId
$redirect_id = $reference->getRedirectToReference();
if ($reference->getDeletedAt() && $redirect_id) {
return $this->redirect($this->generateUrl('reference_show', array('id' => $redirect_id)));
} else {
throw $this->createNotFoundException('Unable to find Reference entity.');
}
}
}
// $isAuthenticated = false;
// if($this->getUser()) {
// $isAuthenticated = true;
// }
$isAuthenticated = false;
if($this->getUser()) {
$isAuthenticated = true;
}
$hoards = [];
foreach($reference->getHoardReferences() as $hoardReference) {
$hoardId = $hoardReference->getHoard()->getId();
$em->getFilters()->disable('softdeleteable');
$hoard = $em->getRepository('OxHoardBundle:Hoard')->find($hoardId);
if (!$hoard->getDeletedAt()) {
if ($isAuthenticated || ($hoard->getValidatedByUser())) {
$hoards[] = $hoard;
}
}
$em->getFilters()->enable('softdeleteable');
}
usort($hoards, array($this, "cmp"));
$deleteForm = $this->createDeleteForm($id);
$referer = $request->get('referer');
if(!$referer) {
$referer = $request->headers->get('referer');
}
if (!strpos($referer, "/reference/")) {
$referer = null;
}
if (strpos($referer, "/edit")) {
$referer = null;
}
return array(
'reference' => $reference,
'hoards' => $hoards,
'delete_form' => $deleteForm->createView(),
'is_authorised_to_edit' => $this->checkAccess($reference, 'edit', false),
'is_authenticated' => $isAuthenticated,
'referer' => $referer,
);
}
function cmp($a, $b)
{
$aCountry = $a->getCountries()[0].'';
$bCountry = $b->getCountries()[0].'';
$aName = $a.'';
$bName = $b.'';
$aStr = $aCountry . $aName;
$bStr = $bCountry . $bName;
return strcasecmp($aStr,$bStr);
}
/**
* Displays a form to edit an existing Reference entity.
*
* @Route("/{id}/edit", name="reference_edit", methods={"GET"})
* @Template()
*/
public function editAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$reference = $em->getRepository('OxHoardBundle:Reference')->find($id);
if (!$reference) {
throw $this->createNotFoundException('Unable to find Reference entity.');
}
$this->checkAccess($reference, 'edit');
$editForm = $this->createEditForm($reference, $request);
$deleteForm = $this->createDeleteForm($id);
$hoards = $request->getSession()->get('hoards');
$coins = $request->getSession()->get('coins');
$objects = $request->getSession()->get('objects');
$request->getSession()->clear('hoards');
$request->getSession()->clear('coins');
$request->getSession()->clear('objects');
return array(
'hoards' => $hoards,
'coins' => $coins,
'objects' => $objects,
'reference' => $reference,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
'is_admin' => $this->userIsAdmin(),
);
}
/**
* Creates a form to edit a Reference entity.
*
* @param Reference $reference The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createEditForm(Reference $reference, $request)
{
$referer = $request->get('referer');
if(!$referer)
{
$referer = $request->headers->get('referer');
}
$action = $this->generateUrl('reference_update', array('id' => $reference->getId()));
if($referer) {
$action .= '?referer='.$referer;
}
$form = $this->createForm(ReferenceType::class, $reference, array(
'action' => $action,
'method' => 'PUT',
));
if($this->userIsAdmin())
{
$form->add('hasOwnColumn');
}
$form->add('submit', SubmitType::class, array('label' => 'Update'));
return $form;
}
/**
* Edits an existing Reference entity.
*
* @Route("/{id}", name="reference_update", methods={"PUT"})
* @Template("@OxHoardBundle/reference/edit.html.twig")
*/
public function updateAction(Request $request, $id)
{
// echo $request->get('referer');exit;
$em = $this->getDoctrine()->getManager();
$reference = $em->getRepository('OxHoardBundle:Reference')->find($id);
if (!$reference) {
throw $this->createNotFoundException('Unable to find Reference entity.');
}
$this->checkAccess($reference, 'edit');
$deleteForm = $this->createDeleteForm($id);
$editForm = $this->createEditForm($reference, $request);
$editForm->handleRequest($request);
$hoards = [];
$coins = [];
$objects = [];
if ($editForm->isValid()) {
$em->flush();
$referer = $request->get('referer');
if(!$referer) {
$referer = $request->headers->get('referer');
}
$page = $request->get('page');
if(isset($page)) {
$referer .= '&page=' . $page;
}
return $this->redirect($referer);
}
return array(
'hoards' => $hoards,
'coins' => $coins,
'objects' => $objects,
'reference' => $reference,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
);
}
/**
* Deletes a Reference entity.
*
* @Route("/{id}", name="reference_delete", methods={"DELETE"})
*/
public function deleteAction(Request $request, $id)
{
$form = $this->createDeleteForm($id);
$form->handleRequest($request);
if ($form->isValid()) {
try {
$em = $this->getDoctrine()->getManager();
$reference = $em->getRepository('OxHoardBundle:Reference')->find($id);
if (!$reference) {
throw $this->createNotFoundException('Unable to find Reference entity.');
}
if (!$this->getUser() || !($this->getUser()->hasRole('ROLE_ADMIN') || $this->getUser()->hasRole('ROLE_SUPER_ADMIN'))) {
$request->getSession()->getFlashBag()
->add('error', 'Unable to delete Reference. Only admins can delete references.');
return $this->redirect($this->generateUrl('reference_edit', array('id' => $reference->getId())));
}
// check whether it is in use
$queryBuilder = $em->createQueryBuilder();
$queryBuilder->select('hrdref, h')
->from('OxHoardBundle:HoardReference', 'hrdref')
->leftJoin('hrdref.hoard', 'h')
->leftJoin('hrdref.reference', 'r')
->where('r.id = :query')
->setParameter('query', $id);
$query = $queryBuilder->getQuery();
$hoards = $query->getResult();
$queryBuilder = $em->createQueryBuilder();
$queryBuilder->select('coiref, h')
->from('OxHoardBundle:CoinReference', 'coiref')
->leftJoin('coiref.coin', 'h')
->leftJoin('coiref.reference', 'r')
->where('r.id = :query')
->setParameter('query', $id);
$query = $queryBuilder->getQuery();
$coins = $query->getResult();
$queryBuilder = $em->createQueryBuilder();
$queryBuilder->select('objref, o')
->from('OxHoardBundle:ObjectReference', 'objref')
->leftJoin('objref.object', 'o')
->leftJoin('objref.reference', 'r')
->where('r.id = :query')
->setParameter('query', $id);
$query = $queryBuilder->getQuery();
$objects = $query->getResult();
if(count($hoards) > 0 || count($coins) > 0 || count($objects) > 0) {
$request->getSession()->set('hoards', $hoards);
$request->getSession()->set('coins', $coins);
$request->getSession()->set('objects', $objects);
return $this->redirect($this->generateUrl('reference_edit', array('id' => $reference->getId())));
} else {
$em->remove($reference);
$em->flush();
return $this->redirect($this->generateUrl('reference'));
}
} catch (\Exception $e) {
//an exception is thrown if the entity is used by any non-deleted coins. Tell the user that this is probably the case.
$request->getSession()
->getFlashBag()
->add('error', 'Unable to delete Reference. It may currently be in use on a coin, object or hoard.');
return $this->redirect($this->generateUrl('reference_edit', array('id' => $reference->getId())));
}
}
return $this->redirect($this->generateUrl('reference'));
}
/**
* Creates a form to delete a Reference 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('reference_delete', array('id' => $id)))
->setMethod('DELETE')
->add('submit', ButtonType::class, array(
'label' => 'Delete this reference',
'attr' => array(
'class' => 'delete-button btn btn-danger'
)
))
->getForm()
;
}
/**
* Upload a new pdf file for the reference
*
* @Route("/{id}/ajax_add_file", methods={"POST"})
*/
public function setFile(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$file = $request->files->get('file');
$reference = $em->getRepository('OxHoardBundle:Reference')->find($id);
if(!$reference)
{
throw $this->createNotFoundException('Unable to find Reference entity.');
}
if(!$file->getMimeType() == 'application/pdf')
{
return new JsonResponse(array('success'=> 0, 'error'=> 'Invalid file type. Only pdf files may be uploaded'));
}
$isValid = true;
//build new fileName
$now = new \DateTime();
$nowString = $now->format('Ymd-His');
$fileName = $id.'-'.$nowString.'.'.$file->guessExtension();
$file = $file->move($this->getPermanentReferenceRootDir(), $fileName);
$reference->setFilePath($fileName);
$em->flush();
return new JsonResponse( array('success' => 1, 'filepath' => $reference->getFilePath()));
}
/**
* Retrieve pdf file
* @Route("/{id}/file", name="reference_file", requirements={"id": "\d+"}, methods={"GET"})
*/
public function getFile($id)
{
$em = $this->getDoctrine()->getManager();
$reference = $em->getRepository('OxHoardBundle:Reference')->find($id);
if(!$reference)
{
throw $this->createNotFoundException('Unable to find Reference entity.');
}
if(!$reference->getIsFilePublic() && !$this->getUser())
{
throw $this->createNotFoundException('Unable to find Reference file.');
}
$pdf = new File($this->getPermanentReferenceRootDir().$reference->getFilePath());
$file = $pdf->openFile();
$contents = file_get_contents($file->getRealPath());
$response = new Response($contents);
$response->headers->set('Content-Type', $pdf->getMimeType());
$response->headers->set('Content-Length', $file->getSize());
$response->headers->set('ETag', md5($contents));
$response->headers->set('Last-Modified', $reference->getModifiedDate()->format('D, d M Y H:i:s T'));
return $response;
}
/**
* Delete pdf file
* @Route("/{id}/ajax_delete_file", methods={"POST"})
*/
public function deleteFile(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$reference = $em->getRepository('OxHoardBundle:Reference')->find($id);
if(!$reference)
{
throw $this->createNotFoundException('Unable to find Reference entity.');
}
$this->checkAccess($reference, 'edit');
$pdf = new File($this->getPermanentReferenceRootDir().$reference->getFilePath());
$filesystem = new Filesystem();
$filesystem->remove($pdf);
$reference->setFilePath(null);
$em->flush();
return new JsonResponse( array('success' => 1));
}
private function cleanZenonField($input) {
//use a regex to strip any extraneous punctuation chars from the end
// e.g. "London :" --> "London"
// e.g. "Ionian magistrates. Caracalla or Elagabalus? -." -> "Ionian magistrates. Caracalla or Elagabalus?"
$cleanRegex = '/(.*)(\s+[^\w\d\s]*\s*)$/';
$matches = null;
if( preg_match($cleanRegex, $input, $matches)) {
return $matches[1];
} else {
//match failed (it really shouldn't though)
return $input;
}
}
//return an array of strings from matches for the given tag (e.g. '300') and code (e.g. 'a')
private function extractZenonParam($xpath, $tag, $code, $clean = true) {
$query = '//marc:datafield[@tag="'.$tag.'"]';
if($code) {
$query .= '/marc:subfield[@code="'.$code.'"]';
}
$els = $xpath->query($query);
$resp = [];
foreach($els as $el) {
$content = $el->textContent;
if($clean) {
$resp[] = $this->cleanZenonField($content);
} else {
$resp[] = $content;
}
}
return $resp;
}
/**
* Look up zenon reference
* @Route("/zenon_lookup/{id}", name="zenon_lookup", methods={"GET"})
*/
public function zenonLookupAction($id) {
$output = $this->getZenonInfo($id);
return new JsonResponse($output);
}
// given an array of strings ["A", "B", "C", "D"], join them as "A, B, C and D"
private function joinZenonEntries($entries) {
$out = "";
$len = count($entries);
foreach($entries as $i => $entry) {
if($i === 0) {
//first
$out .= $entry;
} else if($i < $len -1) {
//middle
$out .= ", ".$entry;
} else {
//last
$out .= " and ".$entry;
}
}
return $out;
}
private function getZenonInfo($id) {
// $url = "http://opac.dainst.org/OAI?verb=GetRecord&identifier=oai:dai-all:DAI01-".$id."&metadataPrefix=marc21";
$url = "https://zenon.dainst.org/Record/".$id."/Export?style=MARCXML";
$defaults = array(
CURLOPT_URL => $url,
CURLOPT_HEADER => 0,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_TIMEOUT => 4
);
$ch = curl_init();
curl_setopt_array($ch, $defaults);
if( ! $result = curl_exec($ch))
{
return new JsonResponse("Error querying zenon");
}
curl_close($ch);
$xmlDoc = new \DOMDocument();
$xmlDoc->loadXml($result);
$xpath = new \DomXPath($xmlDoc);
$xpath->registerNamespace('marc', 'http://www.loc.gov/MARC21/slim');
// $xpath->registerNamespace('', 'http://www.openarchives.org/OAI/2.0/');
//extract the relevant fields
//tag 245a = Title
//tag 245b = Subtitle
//tag 110 = Corporate authors
//tag 100a = author
//tag 710a = Other authors
// see http://zenon.dainst.org/Record/000294077 where other authors is at 700a
//tag 260a = place
//tag 260b = publisher
//tag 260c = publication year
//tag 440a = Title Edition?
//tag 995n = Included in = Title edition
//tag 300a = pages
//tag 440v = volume
//tag 700a = additional authors
//tag 995b = included in zenon ID
//Assuming any field could yield multiple results from zenon (authors, editors often will)
// concatenate all results with a comma
$output = [
'zenon_url' => $url
];
$errs = $xmlDoc->getElementsByTagName('error');
if($errs->length) {
$output['zenon_error'] = $errs->item(0)->textContent;
} else {
//title
$titles = $this->extractZenonParam($xpath, '245', 'a', false);
$subtitles = $this->extractZenonParam($xpath, '245', 'b', false);
//combine subtitles. Unlikely to be more than one of each, but just in case
// $output['title'] = $this->cleanZenonField(implode(', ', $titles) ." ". implode(', ', $subtitles));
$output['title'] = $this->cleanZenonField($this->joinZenonEntries($titles) ." ". $this->joinZenonEntries($subtitles));
//authors
$mainAuthors = $this->extractZenonParam($xpath, '100', 'a');
$output['mainAuthors'] = $this->joinZenonEntries($mainAuthors);
$additionalAuthors = $this->extractZenonParam($xpath, '700', 'a');
$output['additionalAuthors'] = $this->joinZenonEntries($additionalAuthors);
$allAuthors = array_merge($mainAuthors, $additionalAuthors);
$output['authors'] = $this->joinZenonEntries($allAuthors);
//place
$places = $this->extractZenonParam($xpath, '260', 'a');
$output['place'] = $this->joinZenonEntries($places);
//publisher
$publishers = $this->extractZenonParam($xpath, '260', 'a');
$output['publisher'] = $this->joinZenonEntries($publishers);
//publication year
$pubYears = $this->extractZenonParam($xpath, '260', 'c');
$output['year'] = $this->joinZenonEntries($pubYears);
//title edition, might be tag 440a or 995n (for a chapter)
$titleEds = $this->extractZenonParam($xpath, '440', 'a');
// don't use the 995 field - get by following link to parent
// if(count($titleEds) == 0) {
// $titleEds = $this->extractZenonParam($xpath, '995', 'n');
// }
$output['titleEdition'] = $this->joinZenonEntries($titleEds);
//pages
$pagesSet = $this->extractZenonParam($xpath, '300', 'a');
$output['pages'] = $this->joinZenonEntries($pagesSet);
//volume - might be tag 440v, or if this is a parent record representing a volume, tag 245n
$volumes = $this->extractZenonParam($xpath, '440', 'v');
if(count($volumes) == 0) {
$volumes = $this->extractZenonParam($xpath, '245', 'n');
}
$output['volume'] = $this->joinZenonEntries($volumes);
//additional authors
$additionalAuthors = $this->extractZenonParam($xpath, '700', 'a');
$output['additionalAuthors'] = $this->joinZenonEntries($additionalAuthors);
// get further info from the publication which this is included in (e.g. for article / chapter)
$parentIds = $this->extractZenonParam($xpath, '995', 'b');
if(count($parentIds) > 0) {
//assume only 1 parent
$parentId = $parentIds[0];
$parentData = $this->getZenonInfo($parentId);
if(!isset($output['place']) || $output['place'] == '') {
$output['place'] = $parentData['place'];
}
if(!isset($output['publisher']) || $output['publisher'] == '') {
$output['publisher'] = $parentData['publisher'];
}
if(!isset($output['year']) || $output['year'] == '') {
$output['year'] = $parentData['year'];
}
if(!isset($output['editors']) || $output['editors'] == '') {
$output['editors'] = $parentData['additionalAuthors'];
}
// Use the author of the parent reference as editor of this reference?
if(!isset($output['volume']) || $output['volume'] == '') {
$output['volume'] = $parentData['volume'];
}
if(!isset($output['titleEdition']) || $output['titleEdition'] == '') {
$output['titleEdition'] = $parentData['title'];
}
}
}
return $output;
}
/**
* Look up ocre reference
* @Route("/ocre_lookup/{id}", name="ocre_lookup", methods={"GET"})
*/
public function ocreLookupAction($id) {
$output = $this->getOcreInfo($id);
if (is_array($output) && $output['error_code']) {
return new JsonResponse($output['error'], $output['error_code']);
} else {
return new JsonResponse($output);
}
}
private function getOcreInfo($id) {
$url = "http://numismatics.org/ocre/id/". $id .".jsonld";
$defaults = array(
CURLOPT_URL => $url,
CURLOPT_HEADER => 0,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_TIMEOUT => 4
);
$ch = curl_init();
curl_setopt_array($ch, $defaults);
$result = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if($httpCode != "200")
{
return [
'error' => 'Error querying '. $url,
'error_code' => $httpCode
];
}
$output = json_decode($result);
return $output;
}
/**
* checks permission of user's current request
*
* @param mixed $entity The entity being validated
*
* @param string $attribute - 'view' or 'edit' or 'delete'
*
* @param boolean $throwException - whether to throw an exception if false - defaults to true
*
* @return boolean
*
* @throws \Symfony\Component\Security\Core\Exception\AccessDeniedException
*/
private function checkAccess($entity, $attribute, $throwException = true) {
// call security voter(s)
if (!$this->getUser()) {
if ($throwException) {
throw new AccessDeniedException('Unauthorised access!');
}
return false;
}
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 getPermanentReferenceRootDir() {
return "/srv/hoards_references/";
}
}