<?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 Doctrine\ORM\Query\Expr\Select;
use Doctrine\ORM\Query\Expr\From;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\ButtonType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Knp\Component\Pager\PaginatorInterface;
use App\Ox\HoardBundle\Entity\Hoard;
use App\Ox\HoardBundle\Entity\HObject;
use App\Ox\HoardBundle\Entity\Coin;
use App\Ox\HoardBundle\Entity\Container;
use App\Ox\HoardBundle\Entity\HoardCoinCount;
use App\Ox\HoardBundle\Entity\HoardImage;
use App\Ox\HoardBundle\Entity\OcreLookup;
use App\Ox\HoardBundle\Form\HoardType;
use App\Ox\HoardBundle\Form\HoardSearchType;
use App\Ox\HoardBundle\Form\SummaryCoinType;
use App\Ox\HoardBundle\Form\SearchType;
/**
* Hoard controller.
*
* @Route("/search")
*/
class SearchController extends AbstractController
{
private $security;
public function __construct(Security $security)
{
$this->security = $security;
}
/**
* Show an excel-like editing interface for a list of hoards
*
* @Route("/editmultiple", name="hoard_bulk_edit", methods={"GET"})
* @Template()
*/
public function massEditAction(Request $request) {
$em = $this->getDoctrine()->getManager();
//get all available options for the various dropdowns
$data = array();
$data['hoardTypes'] = $em->getRepository('OxHoardBundle:HoardType')->findAll();
$data['countries'] = $em->getRepository('OxHoardBundle:Country')->findAll();
$data['provinces'] = $em->getRepository('OxHoardBundle:Province')->findAll();
$data['findSpotLocationDetails'] = $em->getRepository('OxHoardBundle:FindSpotLocationDetail')->findAll();
$data['ancientPlaces'] = $em->getRepository('OxHoardBundle:AncientPlace')->findAll();
$data['reigns'] = $em->getRepository('OxHoardBundle:Reign')->findAll();
$data['discoveryMethods'] = $em->getRepository('OxHoardBundle:DiscoveryMethod')->findAll();
$data['discoveryLandUses'] = $em->getRepository('OxHoardBundle:DiscoveryLandUse')->findAll();
$data['archaeologyRecoveryMethods'] = $em->getRepository('OxHoardBundle:ArchaeologyRecoveryMethod')->findAll();
$data['archaeologySiteContexts'] = $em->getRepository('OxHoardBundle:ArchaeologySiteContext')->findAll();
$data['archaeologySiteContextDetails'] = $em->getRepository('OxHoardBundle:ArchaeologySiteContextDetail')->findAll();
$data['archaeologyPeriods'] = $em->getRepository('OxHoardBundle:ArchaeologyPeriod')->findAll();
$data['archaeologyContextNatures'] = $em->getRepository('OxHoardBundle:ArchaeologyContextNature')->findAll();
$data['coinLevelDatas'] = $em->getRepository('OxHoardBundle:CoinLevelData')->findAll();
$data['ratings'] = $em->getRepository('OxHoardBundle:Rating')->findAll();
$data['hideWhats'] = $em->getRepository('OxHoardBundle:HideWhat')->findAll();
$data['hideFroms'] = $em->getRepository('OxHoardBundle:HideFrom')->findAll();
return array(
'data' => $data
);
}
/**
* Lists all Hoard entities.
*
* @Route("/", name="hoard", methods={"GET", "POST"})
* @Template()
*/
public function indexAction(Request $request, PaginatorInterface $paginator, $isCoinsChart = false) {
$activeTab = 0; // Default to Search tab
// var_dump($request);
// var_dump($request->query);
$search_type = $request->query->get('search_type');
$format = $request->query->get('format');
$initialSliderValues = array();
$initialSliderValues['hoardDiscoveryYearRangeStart'] = $this->getMinDiscoveryDate();
$initialSliderValues['hoardDiscoveryYearRangeEnd'] = $this->getMaxDiscoveryDate();
$initialSliderValues['hoardTerminalYearRangeStart'] = $this->getMinTerminalDate();
$initialSliderValues['hoardTerminalYearRangeEnd'] = $this->getMaxTerminalDate();
$initialSliderValues['hoardOpeningYearRangeStart'] = $this->getMinOpeningDate();
$initialSliderValues['hoardOpeningYearRangeEnd'] = $this->getMaxOpeningDate();
$initialSliderValues['hoardArchaeologyContextDateRangeStart'] = $this->getMinArchaeologyContextDate();
$initialSliderValues['hoardArchaeologyContextDateRangeEnd'] = $this->getMaxArchaeologyContextDate();
$coinminmax = $this->getMinMaxCoinDate();
$initialSliderValues['coinYearRangeStart'] = $coinminmax['min1'];
$initialSliderValues['coinYearRangeEnd'] = $coinminmax['max1'];
$initialSliderValues['hoardCoinCountMin'] = 0;
$initialSliderValues['hoardCoinCountMax'] = 100000;
$isAdmin = $this->userIsAdmin();
$isAuthenticated = false;
if($this->getUser()) {
$isAuthenticated = true;
}
$searchHasCoinFields = false;
$limit = 20;
$em = $this->getDoctrine()->getManager();
$em->getFilters()->enable('softdeleteable');
if(isset($request->query->get('ox_hs')['rules']) && strlen($request->query->get('ox_hs')['rules'])) {
// this is an advanced search
// check if coin fields are included in the search set $searchHasCoinFields
$rulesStr = $request->query->get('ox_hs')['rules'];
if ( strpos($rulesStr, '"field":"coin') || strpos($rulesStr, '"field":"c.') ) {
$searchHasCoinFields = true;
}
$rules = json_decode($rulesStr, true);
$doctrineQueryBuilder = $this->buildQuery($rules, $search_type, $format);
$activeTab = 3; // Set tab to Results tab
}
else {
// this is a simple search
if ($request->query->get('ox_hs')) {
foreach ($request->query->get('ox_hs') as $key => $value) {
// check if coin fields are included in the search set $searchHasCoinFields
if (substr( $key, 0, 8 ) === "coinYear") {
if ($value != $initialSliderValues[$key]) {
$searchHasCoinFields = true;
}
}
elseif (substr( $key, 0, 4 ) === "coin") {
if ($value && $value != "") {
$searchHasCoinFields = true;
}
}
}
}
$doctrineQueryBuilder = $em->createQueryBuilder()
->andWhere('h IS NOT NULL'); // always exclude deleted hoards (this leftJoin('c.hoard', 'h') will include coins from deleted hoards)
$didJoinCoins = false;
if ($format == 'csv-coins' || $format == 'csv') {
if ($format == 'csv-coins') {
$doctrineQueryBuilder->select('h, c')->from('OxHoardBundle:Hoard', 'h')->leftJoin('h.coins', 'c');
$didJoinCoins = true;
} elseif ($format == 'csv') {
if ($search_type == 'search-coins' ) {
$doctrineQueryBuilder->select('h')->from('OxHoardBundle:Hoard', 'h')->leftJoin('h.coins', 'c');
$didJoinCoins = true;
} else {
$doctrineQueryBuilder->select('h')->from('OxHoardBundle:Hoard', 'h');
}
}
} else {
if ($search_type == 'search-coins' ) {
$doctrineQueryBuilder->select('c, h')->from('OxHoardBundle:Coin', 'c')->leftJoin('c.hoard', 'h');
$didJoinCoins = true;
} else {
$doctrineQueryBuilder->select('h')->from('OxHoardBundle:Hoard', 'h');
}
}
if (($search_type == 'search-coins' && $format != 'csv') ||
$format == 'csv-coins') {
$doctrineQueryBuilder
->addSelect('hcountriessort') // countries are going to be used for the results order
->leftJoin('h.countries', 'hcountriessort');
}
$coinValues = array();
// find coin-related query params to join Coins if needed
if (!empty($request->query->get('ox_hs'))) {
foreach ($request->query->get('ox_hs') as $key => $value) {
if (is_array($value) or strlen($value)) {
if (strpos($key, 'coin') === 0) {
$coinValues[$key] = $value;
}
}
}
}
//ignore coin year range if set to initial values
if(isset($coinValues['coinYearRangeStart']) && $coinValues['coinYearRangeStart'] == $initialSliderValues['coinYearRangeStart']) {
unset($coinValues['coinYearRangeStart']);
}
if(isset($coinValues['coinYearRangeEnd']) && $coinValues['coinYearRangeEnd'] == $initialSliderValues['coinYearRangeEnd']) {
unset($coinValues['coinYearRangeEnd']);
}
// only join coins to hoards if coins fields were used
if (!$didJoinCoins && count($coinValues) > 0) {
$doctrineQueryBuilder->leftJoin('h.coins', 'c');
}
// If the request is a POST, read the POST parameters from the search form and construct a search query
$hoardValues = array();
$coinValues = array();
$queryParameters = array();
if (!empty($request->query->get('ox_hs'))) {
$this->constructSearchQuery($request, $doctrineQueryBuilder, $activeTab,
$hoardValues, $coinValues, $queryParameters, $initialSliderValues);
}
//apply the 'only mine'
if (isset($request->query->get('ox_hs')['showOnlyUsersHoards'])) {
$doctrineQueryBuilder->andWhere('(h.created = :queryUser) OR (h.modified = :queryUser)')
->setParameter('queryUser', $this->getUser());
}
foreach ($queryParameters as $key => $value) {
$doctrineQueryBuilder->setParameter($key, $value);
}
}
// Add handling of boundaries set for maps.
$boundary = isset($request->query->get('ox_hs')["boundary"]) ?
$request->query->get('ox_hs')["boundary"] :
null;
if ($boundary) {
$doctrineQueryBuilder->andWhere('ST_Contains(ST_GEOMFROMTEXT(\'Polygon((' . $boundary . '))\'), Point(h.findSpotLatitude, h.findSpotLongitude)) = true');
}
if (!$isAuthenticated) {
// public can only see hoards which are validated by the user,
// and which are either not hidden, or don't have everything hidden
$doctrineQueryBuilder->andWhere('(h.validatedByUser = true) AND (h.hideFrom = 3 OR h.hideWhat < 3 OR h.hideWhat IS NULL)');
// if coin fields are included in the search
if ($searchHasCoinFields) {
// public can only see hoards with coins which are validated by the user,
// and which are either not hidden, or don't have anything hidden
$doctrineQueryBuilder->andWhere('(h.coinDataValidatedByUser = true) AND (h.hideFrom = 3 OR h.hideWhat IS NULL)');
}
}
// decide the order of the items
if ($format == 'csv-coins') {
$doctrineQueryBuilder->orderBy('hcountriessort.country', 'ASC');
$doctrineQueryBuilder->orderBy('h.findSpotName', 'ASC');
$doctrineQueryBuilder->orderBy('h.id', 'DESC');
}
else if ($format == 'csv'|| $search_type != 'search-coins') {
$sort = $request->query->get('sort');
if ($this->getUser() && !$sort) {
$sort = 'h.modifiedDate';
}
$sortDirection = $request->query->get('direction');
if (!$sortDirection){
// default to ascending except for modified/creationDate
if ($sort=='h.modifiedDate' || $sort=='h.creationDate') {
$sortDirection = "DESC";
}
else {
$sortDirection = "ASC";
}
}
if ($sort) {
$doctrineQueryBuilder->orderBy($sort, $sortDirection);
}
}
else {
$doctrineQueryBuilder->orderBy('hcountriessort.country', 'ASC');
$doctrineQueryBuilder->orderBy('h.findSpotName', 'ASC');
$doctrineQueryBuilder->orderBy('h.id', 'DESC');
}
// if the indexAcion was called to produce the coin entries for the charts
if ($isCoinsChart) {
$doctrineQuery = $doctrineQueryBuilder->getQuery();
return $doctrineQuery->getResult();
}
$MAX_HOARDS_IN_CHART = 5000;
$doctrineQueryBuilderAllRows = clone $doctrineQueryBuilder;
$doctrineQuery = $doctrineQueryBuilder->getQuery();
// we have to use paginator to find if results are more than 1001 bacause doctrine distinct doesn't work as expected:
// https://stackoverflow.com/questions/50199102/setmaxresults-does-not-works-fine-when-doctrine-query-has-join
$paginatorAllRows = $paginator->paginate(
$doctrineQueryBuilderAllRows->getQuery(),
$request->query->getInt('page', 1),
$MAX_HOARDS_IN_CHART+1
);
$c = count($paginatorAllRows);
$allHoards = array();
$allHoardResults = array();
$hoardsOverEditLimit = true;
$hoardsOverChartLimit = true;
if ($c < 1000) {
$hoardsOverEditLimit = false;
}
if ($c <= $MAX_HOARDS_IN_CHART) {
$hoardsOverChartLimit = false;
$doctrineQueryBuilderAllRows->distinct();
$doctrineQueryAllRows = $doctrineQueryBuilderAllRows->getQuery();
$allHoardResults = $doctrineQueryAllRows->getResult();
foreach (array_slice($allHoardResults, 0, 1000) as $hoard) {
$h = array();
$h['id'] = $hoard->getId();
if ($this->checkAccess($hoard, 'edit', false)) {
$h['permission'] = true;
} else {
$h['permission'] = false;
}
array_push($allHoards, $h);
}
}
if ($format == 'csv') {
//join up all of the relevant tables
$doctrineQueryBuilder ->addSelect(
'partial type.{id, hoardType}',
'coinCount',
'partial countries.{id, country}',
'partial province.{id, province}',
'partial coinLevelData.{id, coinLevelData}',
'partial ancientPlace.{id, ancientPlace}',
'partial location_detail.{id, findSpotLocationDetail}',
'partial reign1.{id, reign}',
'partial reign2.{id, reign}',
'partial disc_method.{id, discoveryMethod}',
'partial disc_landuse.{id, discoveryLandUse}',
'partial recovery_method.{id, archaeologyRecoveryMethod}',
'partial site_context.{id, archaeologySiteContext}',
'partial site_context_details.{id, archaeologySiteContextDetail}',
'partial arch_period.{id, archaeologyPeriod}',
'partial arch_end_period.{id, archaeologyPeriod}',
'partial context_natures.{id, title}',
'partial findspot_rating.{id, rating}',
'partial contextual_rating.{id, rating}',
'partial rating.{id, rating}',
'partial containers.{id, container}',
'partial objects.{id, object}',
'partial hoardReferences.{id, reference_str}',
'partial references.{id, abbreviation, authors, year, title}',
'partial refType.{id}',
)
->leftJoin('h.hoardType', 'type')
->leftJoin('h.coinCount', 'coinCount')
->leftJoin('h.countries', 'countries')
->leftJoin('h.province', 'province')
->leftJoin('h.coinLevelData', 'coinLevelData')
->leftJoin('h.ancientPlace', 'ancientPlace')
->leftJoin('h.findSpotLocationDetail', 'location_detail')
->leftJoin('h.closingReign1', 'reign1')
->leftJoin('h.closingReign2', 'reign2')
->leftJoin('h.discoveryMethod', 'disc_method')
->leftJoin('h.discoveryLandUse', 'disc_landuse')
->leftJoin('h.archaeologyRecoveryMethod', 'recovery_method')
->leftJoin('h.archaeologySiteContext', 'site_context')
->leftJoin('h.archaeologySiteContextDetails', 'site_context_details')
->leftJoin('h.archaeologyPeriod', 'arch_period')
->leftJoin('h.archaeologyContextNatures', 'context_natures')
->leftJoin('h.archaeologyEndPeriod', 'arch_end_period')
->leftJoin('h.findSpotRating', 'findspot_rating')
->leftJoin('h.contextualRating', 'contextual_rating')
->leftJoin('h.rating', 'rating')
->leftJoin('h.containers', 'containers')
->leftJoin('h.objects', 'objects')
->leftJoin('h.hoardReferences', 'hoardReferences')
->leftJoin('hoardReferences.reference', 'references')
->leftJoin('references.referenceType', 'refType')
;
$data = $doctrineQueryBuilder->getQuery()->getArrayResult();
//loop over hoards and flag if they should be hidden
foreach($data as &$hoard) {
if($isAuthenticated) {
$hoard['can_see_location'] = true;
} else {
$hoard['can_see_location'] = !$hoard['hideLocation'];
}
$hoardOnlineDatabases = array();
$hoard['hoardReferences'] = array_filter($hoard['hoardReferences'], function($reference) use (&$hoardOnlineDatabases) {
if ($reference && $reference['reference'] &&
$reference['reference']['referenceType'] &&
$reference['reference']['referenceType']['id'] &&
$reference['reference']['referenceType']['id'] != '11') { // reference's type is a "Permalink in other online database"
return true;
} else {
$hoardOnlineDatabases[] = $reference;
return false;
}
});
$hoard['hoardOnlineDatabases'] = $hoardOnlineDatabases;
}
return $this->outputCSV($data, 'hoard_export');
}
if ($format == 'csv-coins') {
$doctrineQueryBuilder ->addSelect('
partial cp.{id, period},
partial cd.{id, denomination},
partial cmat.{id, material},
partial cmint.{id, mint},
partial cr.{id, reign},
partial cpers.{id, person, title},
partial ccond.{id, condition},
partial ca.{id, aspect},
partial container.{id, container},
partial coinAdditionalFields.{id, comment},
partial additionalFields.{id, additionalField, description},
partial coinRefs.{id, reference_str, comment},
partial refs.{id, abbreviation, authors, year, title, sortValue, hasOwnColumn}
'
);
$doctrineQueryBuilder
->leftJoin('c.period', 'cp')
->leftJoin('c.denominations', 'cd')
->leftJoin('cd.material', 'cmat')
->leftJoin('c.mints', 'cmint')
->leftJoin('c.reigns', 'cr')
->leftJoin('c.persons', 'cpers')
->leftJoin('c.condition', 'ccond')
->leftJoin('c.aspects', 'ca')
->leftJoin('c.container', 'container')
->leftJoin('c.coinAdditionalFields', 'coinAdditionalFields')
->leftJoin('coinAdditionalFields.additionalField', 'additionalFields')
->leftJoin('c.coinReferences', 'coinRefs')
->leftJoin('coinRefs.reference', 'refs')
;
$data = $doctrineQueryBuilder->getQuery()->getArrayResult();
$refData = $this->processHoardDataForCSV($data);
return $this->outputCSV($data, 'coins_export', true, $refData);
}
$coinTotalQuantity = null;
if ($search_type == 'search-coins') {
$doctrineQueryBuilderCoinQuantity = clone $doctrineQueryBuilder;
$coinTotalQuantityQuery = $doctrineQueryBuilderCoinQuantity
->select("c.id, c.quantity as q")
->getQuery()
->getArrayResult();
$uniqQuantities = array_unique($coinTotalQuantityQuery, SORT_REGULAR);
$coinTotalQuantity = array_sum(array_column($uniqQuantities, 'q'));
}
$pagination = $paginator->paginate(
$doctrineQuery,
$request->query->getInt('page', 1)/*page number*/,
$limit/*limit per page*/
);
$sortFields = array(
array('label' => 'Hoard number', 'key' => 'h.id'),
array('label' => 'Find Spot Name', 'key' => 'h.findSpotName'),
array('label' => 'Discovery Year', 'key' => 'h.discoveryYear1'),
array('label' => 'Terminal Year', 'key' => 'h.terminalYear1'),
array('label' => 'Opening Year', 'key' => 'h.openingYear1'),
array('label' => 'Date of Context', 'key' => 'h.archaeologyContextDate1'),
array('label' => 'Date Added', 'key' => 'h.creationDate'),
array('label' => 'Date Modified', 'key' => 'h.modifiedDate')
);
$searchForm = $this->createSearchForm();
$searchForm->handleRequest($request);
$hoardDiscoveryYearRangeStart = $initialSliderValues['hoardDiscoveryYearRangeStart'];
if (isset($hoardValues['hoardDiscoveryYearRangeStart'])) {
$hoardDiscoveryYearRangeStart = $hoardValues['hoardDiscoveryYearRangeStart'];
}
$hoardDiscoveryYearRangeEnd = $initialSliderValues['hoardDiscoveryYearRangeEnd'];
if (isset($hoardValues['hoardDiscoveryYearRangeEnd'])) {
$hoardDiscoveryYearRangeEnd = $hoardValues['hoardDiscoveryYearRangeEnd'] ;
}
$hoardTerminalYearRangeStart = $initialSliderValues['hoardTerminalYearRangeStart'];
if (isset($hoardValues['hoardTerminalYearRangeStart'])) {
$hoardTerminalYearRangeStart = $hoardValues['hoardTerminalYearRangeStart'] ;
}
$hoardTerminalYearRangeEnd = $initialSliderValues['hoardTerminalYearRangeEnd'];
if (isset($hoardValues['hoardTerminalYearRangeEnd'])) {
$hoardTerminalYearRangeEnd = $hoardValues['hoardTerminalYearRangeEnd'] ;
}
$hoardOpeningYearRangeStart = $initialSliderValues['hoardOpeningYearRangeStart'];
if (isset($hoardValues['hoardOpeningYearRangeStart'])) {
$hoardOpeningYearRangeStart = $hoardValues['hoardOpeningYearRangeStart'] ;
}
$hoardOpeningYearRangeEnd = $initialSliderValues['hoardOpeningYearRangeEnd'];
if (isset($hoardValues['hoardOpeningYearRangeEnd'])) {
$hoardOpeningYearRangeEnd = $hoardValues['hoardOpeningYearRangeEnd'] ;
}
$hoardArchaeologyContextDateRangeStart = $initialSliderValues['hoardArchaeologyContextDateRangeStart'];
if (isset($hoardValues['hoardArchaeologyContextDateRangeStart'])) {
$hoardArchaeologyContextDateRangeStart = $hoardValues['hoardArchaeologyContextDateRangeStart'];
}
$hoardArchaeologyContextDateRangeEnd = $initialSliderValues['hoardArchaeologyContextDateRangeEnd'];
if (isset($hoardValues['hoardArchaeologyContextDateRangeEnd'])) {
$hoardArchaeologyContextDateRangeEnd = $hoardValues['hoardArchaeologyContextDateRangeEnd'] ;
}
$coinYearRangeStart = $initialSliderValues['coinYearRangeStart'];
if (isset($coinValues['coinYearRangeStart'])) {
$coinYearRangeStart = $coinValues['coinYearRangeStart'];
}
$coinYearRangeEnd = $initialSliderValues['coinYearRangeEnd'];
if (isset($coinValues['coinYearRangeEnd'])) {
$coinYearRangeEnd = $coinValues['coinYearRangeEnd'];
}
$hoardCoinCountMin = $initialSliderValues['hoardCoinCountMin'];
if (isset($hoardValues['hoardCoinCountMin'])) {
$hoardCoinCountMin = $hoardValues['hoardCoinCountMin'] ;
}
$hoardCoinCountMax = $initialSliderValues['hoardCoinCountMax'];
if (isset($hoardValues['hoardCoinCountMax'])) {
$hoardCoinCountMax = $hoardValues['hoardCoinCountMax'] ;
}
foreach ($pagination as $hoard) {
if ($this->checkAccess($hoard, 'edit', false)) {
$hoard->isEditableByUser = true;
}
else {
$hoard->isEditableByUser = false;
}
}
$queryOptions = $this->queryOptions();
// use the coins or hoards template depending on the search type
if ($search_type == 'search-coins') {
$search_template = '@OxHoardBundle/search/coinslist.html.twig';
}
else {
$search_template = '@OxHoardBundle/search/list.html.twig';
}
// parameters to template
return $this->render($search_template,
array(
'pagination' => $pagination,
'is_authenticated' => $isAuthenticated,
'is_authorised_to_create' => $this->userIsAuthorisedToCreate(),
'is_authorised_to_import' => $this->userIsImporter(),
'is_admin' => $isAdmin,
'sort_fields' => $sortFields,
'current_sort' => $sort ?? NULL,
'current_sort_direction' => $sortDirection ?? NULL,
'search_form' => $searchForm->createView(),
'active_tab' => $activeTab,
'hoardDiscoveryYearRangeStart' => $hoardDiscoveryYearRangeStart,
'hoardDiscoveryYearRangeEnd' => $hoardDiscoveryYearRangeEnd,
'hoardTerminalYearRangeStart' => $hoardTerminalYearRangeStart,
'hoardTerminalYearRangeEnd' => $hoardTerminalYearRangeEnd,
'hoardOpeningYearRangeStart' => $hoardOpeningYearRangeStart,
'hoardOpeningYearRangeEnd' => $hoardOpeningYearRangeEnd,
'coinYearRangeStart' => $coinYearRangeStart,
'coinYearRangeEnd' => $coinYearRangeEnd,
'hoardArchaeologyContextDateRangeStart' => $hoardArchaeologyContextDateRangeStart,
'hoardArchaeologyContextDateRangeEnd' => $hoardArchaeologyContextDateRangeEnd,
'hoardCoinCountMin' => $hoardCoinCountMin,
'hoardCoinCountMax' => $hoardCoinCountMax,
'initialHoardDiscoveryYearRangeStart' => $initialSliderValues['hoardDiscoveryYearRangeStart'],
'initialHoardDiscoveryYearRangeEnd' => $initialSliderValues['hoardDiscoveryYearRangeEnd'],
'initialHoardTerminalYearRangeStart' => $initialSliderValues['hoardTerminalYearRangeStart'],
'initialHoardTerminalYearRangeEnd' => $initialSliderValues['hoardTerminalYearRangeEnd'],
'initialHoardOpeningYearRangeStart' => $initialSliderValues['hoardOpeningYearRangeStart'],
'initialHoardOpeningYearRangeEnd' => $initialSliderValues['hoardOpeningYearRangeEnd'],
'initialHoardArchaeologyContextDateRangeStart' => $initialSliderValues['hoardArchaeologyContextDateRangeStart'],
'initialHoardArchaeologyContextDateRangeEnd' => $initialSliderValues['hoardArchaeologyContextDateRangeEnd'],
'initialHoardCoinCountMin' => $initialSliderValues['hoardCoinCountMin'],
'initialHoardCoinCountMax' => $initialSliderValues['hoardCoinCountMax'],
'initialCoinYearRangeStart' => $initialSliderValues['coinYearRangeStart'],
'initialCoinYearRangeEnd' => $initialSliderValues['coinYearRangeEnd'],
'initialCoinYearRangeStart' => $initialSliderValues['coinYearRangeStart'],
'initialCoinYearRangeEnd' => $initialSliderValues['coinYearRangeEnd'],
'queryOptions' => $queryOptions,
'allHoardResults' => $allHoards,
'hoardsOverEditLimit' => $hoardsOverEditLimit,
'hoardsOverChartLimit' => $hoardsOverChartLimit,
// 'allHoardsChart' => $allHoardChartResults,
'allHoardsChart' => $allHoardResults,
'coinTotalQuantity' => $coinTotalQuantity,
'queryString' => $request->getQueryString(),
'search_type' => $search_type
));
}
/**
* creates csv and appropriate page response for csv of supplied query
*
*/
private function outputCSV(Array $data, $prefix=null, $exportCoins=false, $refData=null) {
if($prefix == null) {
$prefix = "export";
}
$filename = $prefix."_".date("Y_m_d_His").".csv";
if($exportCoins) {
//build an array of column headings for the reference columns
if($refData) {
$refHeadings = [];
foreach($refData['own_column_references'] as $o_c_ref) {
if(isset($o_c_ref['abbreviation'])) {
$refHeadings[] = $o_c_ref['abbreviation'] . ' Reference';
} else {
$refHeadings[] = $o_c_ref['title'] . ' Reference';
}
}
for($i=1; $i <= $refData['num_other_references']; $i++) {
$refHeadings[] = 'Other Reference '.$i;
}
}
$response = $this->render('@OxHoardBundle/coin/csvExport.html.twig', array(
'data' => $data,
// 'numRefs' => 10,
'ref_headings' => $refHeadings,
'num_ref_columns' => count($refHeadings)
));
} else {
$response = $this->render('@OxHoardBundle/hoard/csvExport.html.twig', array(
'is_authenticated' => !!$this->getUser(),
'data' => $data
));
}
$response->headers->set('Content-Type', 'text/csv');
$response->setStatusCode(200);
$response->setCharset('UTF-8');
$response->headers->set('Content-Type', 'text/csv');
$response->headers->set('Content-Description', 'Hoards Export');
$response->headers->set('Content-Disposition', 'attachment; filename='.$filename);
$response->headers->set('Content-Transfer-Encoding', 'binary');
$response->headers->set('Pragma', 'no-cache');
$response->headers->set('Expires', '0');
return $response;
}
/**
* Creates a form to search Hoard entities.
*
* @return \Symfony\Component\Form\Form The form
*/
private function createSearchForm()
{
$form = $this->createForm(SearchType::class, null, array(
'action' => $this->generateUrl('hoard'),
'method' => 'GET',
));
if($this->getUser()) {
// $form->add('hoardHideLocation', ChoiceType::class, array(
// 'choices' => array('Yes' => true, 'No' => false),
// 'required' => false,
// ));
//add the validated by user option
$form->add('hoardValidatedByUser', ChoiceType::class, array(
'choices' => array('Yes' => true, 'No' => false),
'required' => false,
));
$form->add('hoardCoinDataValidatedByUser', ChoiceType::class, array(
'choices' => array('Yes' => true, 'No' => false),
'required' => false,
));
$form->add('showOnlyUsersHoards', CheckboxType::class, array(
'required' => false
));
}
if($this->userIsAdmin()) {
//add the validated by user option
$form->add('hoardValidatedByAdmin', ChoiceType::class, array(
'choices' => array('Yes' => true, 'No' => false),
'required' => false,
));
$form->add('hoardCoinDataValidatedByAdmin', ChoiceType::class, array(
'choices' => array('Yes' => true, 'No' => false),
'required' => false,
));
}
$form->add('rules', HiddenType::class, array());
$form->add('boundary', HiddenType::class, array());
// these fields have to be added to the for to make this message dissapear:
// "This form should not contain extra fields.""
// $form->add('hoardDiscoveryYearRangeStart', 'text', array('label' => '', 'required' => false))
// ->add('hoardDiscoveryYearRangeEnd', 'text')
// ->add('hoardTerminalYearRangeStart', 'text')
// ->add('hoardTerminalYearRangeEnd', 'text')
// ->add('coinYearRangeStart', 'text')
// ->add('coinYearRangeEnd', 'text')
// ->add('hoardCoinCountMin', 'text')
// ->add('hoardCoinCountMax', 'text');
$form->add('submit', SubmitType::class, array('label' => 'Search hoards'));
$form->add('coin_submit', SubmitType::class, array('label' => 'Search coins'));
return $form;
}
//process the hoard data
// This sorts the coins and normalises the references to consistent columns
private function processHoardDataForCSV(&$data) {
$seenOwnColumnReferences = [];
$seenOtherReferences = [];
//sort the references by sort value
foreach($data as &$hoard) {
foreach($hoard['coins'] as &$coin) {
//get the sort value
$reigns = $coin['reigns'];
if ($reigns && count($reigns)) {
// just look at first reign
$reign = $reigns[0];
$lookups = isset($reign['ocreLookups']) ?
$reign['ocreLookups'] :
[];
foreach($lookups as $lookup) {
$coinPersons = [];
foreach($coin['persons'] as $person) {
$coinPersons[] = $person['id'];
}
if (in_array($lookup['person']['id'], $coinPersons)) {
// check mint if necessary
if (isset($lookup['mint'])) {
// see if it matches
$coinMints = [];
foreach ($coin['mints'] as $mint) {
$coinMints[] = $mint['id'];
}
if (in_array($lookup['mint']['id'], $coinMints)) {
// this is a match
$coin['sortValue'] = $lookup['sortValue'];
}
}
else {
// this is a match
$coin['sortValue'] = $lookup['sortValue'];
}
}
}
}
// echo '<pre>'; print_r($coin); echo '</pre>';
//note which references are seen
// keep separate arrays of references which should have their own column
foreach($coin['coinReferences'] as $coinRef) {
$ref = $coinRef['reference'];
if($ref) {
if($coinRef['reference']['hasOwnColumn']) {
if(!in_array($ref, $seenOwnColumnReferences)) {
$seenOwnColumnReferences[] = $ref;
}
} else {
if(!in_array($ref, $seenOtherReferences)) {
$seenOtherReferences[] = $ref;
}
}
}
}
usort($coin['coinReferences'], array($this,"compareRefs"));
}
//now sort coins by their sort value
usort($seenOwnColumnReferences, array($this,"compareSeenRefs"));
usort($hoard['coins'], array($this,"compareCoins"));
// var_dump($hoard);
}
//at this point we have a list of coin references seen in this dataset, and the coin references are sorted
//rewrite the coin references with the references in the relevant columns
$maxOtherReferences = 0;
foreach($data as &$hoard) {
foreach($hoard['coins'] as &$coin) {
//keyed array of those references which should have their own column
$newOwnColumnCoinReferences = [];
//plain array of all other references
$newOtherCoinReferences = [];
$coinReferences = $coin['coinReferences'];
foreach($coinReferences as $coinRef) {
if(isset($coinRef['reference']) && $coinRef['reference']['hasOwnColumn']) {
$key = $coinRef['reference']['id'];
$newOwnColumnCoinReferences[$key] = $coinRef;
} else {
$newOtherCoinReferences[] = $coinRef;
}
}
//now build the full array of references
$newCoinReferences = [];
// var_dump($seenOwnColumnReferences);
foreach($seenOwnColumnReferences as $ownColumnRef) {
$val = '';
// var_dump($seenOwnColumnReferences);
if(isset($newOwnColumnCoinReferences[$ownColumnRef['id']])) {
$val = $newOwnColumnCoinReferences[$ownColumnRef['id']];
} else {
$val = array();
}
$newCoinReferences[] = $val;
}
//keep track of how many columns we need
if(count($newOtherCoinReferences) > $maxOtherReferences) {
$maxOtherReferences = count($newOtherCoinReferences);
}
//add the non-own-column references
$newCoinReferences = array_merge($newCoinReferences, $newOtherCoinReferences);
$coin['coinReferences'] = $newCoinReferences;
}
}
//return some data about the references seen
return array(
'own_column_references' => $seenOwnColumnReferences,
'num_other_references' => $maxOtherReferences
);
}
function compareCoins($a, $b) {
//compare period
if (isset($a['period'])) { $periodA = $a['period']['id']; } else { $periodA = 0; }
if (isset($b['period'])) { $periodB = $b['period']['id']; } else { $periodB = 0; }
if($periodA < $periodB) { return -1; }
else if($periodB < $periodA ) { return 1; }
else {
if(isset($a['sortValue'])) { $sortA = $a['sortValue']; } else { $sortA = 0; }
if(isset($b['sortValue'])) { $sortB = $b['sortValue']; } else { $sortB = 0; }
//periods are equal, compare by ocre table
if($sortA > $sortB) { return 1; }
else if($sortB > $sortA) { return -1; }
else {
//same ocre prefix
//todo compare ric reference value
$refValueA = $this->getSortableRef($a);
if($refValueA) {
$refValueB = $this->getSortableRef($b);
if($refValueB) {
//compare numerical part
$numA = intval($refValueA['num']);
$numB = intval($refValueB['num']);
if($numA > $numB) { return 1; }
else if($numB > $numA) {return -1; }
else {
//compare alphabetic part
$lowerA = strtolower($refValueA['char']);
$lowerB = strtolower($refValueB['char']);
if($lowerA < $lowerB) { return -1; }
else if($lowerB < $lowerA) { return 1; }
else return 0;
}
}
}
return 0;
}
}
}
//given an array of coinData, get the most relevant reference as an array of numerical part and alphabetic part
function getSortableRef($coinArray) {
// var_dump($coinArray);
foreach($coinArray['coinReferences'] as $coinRef) {
if(isset($coinRef['reference'])) {
$refs = ['RIC', 'RIC (2nd ed.)', 'RRC', 'RPC'];
if(in_array($coinRef['reference']['abbreviation'], $refs)) {
//this is a reference we care about sorting on
//extract the numerical and alphabetic components
$matches = null;
if (preg_match('/(\d+)\/(\d+)(\w*)/', $coinRef['reference_str'], $matches)) {
//RRC reference format e.g. 123/1b
//derive a number that can be used to compare
$num = $matches[1] * 1000 + $matches[2];
$refData = array(
'num' => $num,
'char' => $matches[3]
);
return $refData;
} else if (preg_match('/(\d+)(\w*)/', $coinRef['reference_str'], $matches)) {
//RIC reference format e.g. 123a (or somethings 123a/b or )
$refData = array(
'num' => $matches[1],
'char' => $matches[2]
);
return $refData;
}
}
}
}
return null;
}
//order coinreference array data by sortvalue of the reference (decreasing)
function compareSeenRefs($a, $b) {
if($a['sortValue'] > $b['sortValue']) {
return -1;
} else if ($a['sortValue'] == $b['sortValue']) {
return 0;
} else {
return 1;
}
}
//order coinreference array data by sortvalue of the reference (decreasing)
function compareRefs($a, $b) {
if($a['reference']['sortValue'] > $b['reference']['sortValue']) {
return -1;
} else if ($a['reference']['sortValue'] == $b['reference']['sortValue']) {
return 0;
} else {
return 1;
}
}
private function getMinDiscoveryDate() {
return 900;
// $em = $this->getDoctrine()->getManager();
//
// // Generate the coin summaries
// $queryBuilder = $em->createQueryBuilder();
// $queryBuilder->select('MIN(h.discoveryYear1) as min1, MIN(h.discoveryYear2) as min2')
// ->from('OxHoardBundle:Hoard', 'h');
//
// $query = $queryBuilder->getQuery();
//
// $queryResult = $query->getArrayResult();
//
// if(count($queryResult)) {
// return min($queryResult[0]);
// }
// else {
// return 1750;
// }
}
private function getMaxDiscoveryDate() {
return date("Y");
// $em = $this->getDoctrine()->getManager();
//
// // Generate the coin summaries
// $queryBuilder = $em->createQueryBuilder();
// $queryBuilder->select('MAX(h.discoveryYear1) as max1, MAX(h.discoveryYear2) as max2')
// ->from('OxHoardBundle:Hoard', 'h');
//
// $query = $queryBuilder->getQuery();
//
// $queryResult = $query->getArrayResult();
//
// if(count($queryResult)) {
// return max($queryResult[0]);
// }
// else {
// return date("Y");
// }
}
private function getMinTerminalDate() {
//checking every hoard v slow
return -500;
// $em = $this->getDoctrine()->getManager();
//
// // Generate the coin summaries
// $queryBuilder = $em->createQueryBuilder();
// $queryBuilder->select('MIN(h.terminalYear1) as min1, MIN(h.terminalYear2) as min2')
// ->from('OxHoardBundle:Hoard', 'h');
//
// $query = $queryBuilder->getQuery();
//
// $queryResult = $query->getArrayResult();
//
// if(count($queryResult)) {
// return min($queryResult[0]);
// }
// else {
// return -100;
// }
}
private function getMaxTerminalDate() {
//checking every hoard is rather slow.
return 1000;
// $em = $this->getDoctrine()->getManager();
//
// // Generate the coin summaries
// $queryBuilder = $em->createQueryBuilder();
// $queryBuilder->select('MAX(h.terminalYear1) as max1, MAX(h.terminalYear2) as max2')
// ->from('OxHoardBundle:Hoard', 'h');
//
// $query = $queryBuilder->getQuery();
//
// $queryResult = $query->getArrayResult();
//
// if(count($queryResult)) {
// return max($queryResult[0]);
// }
// else {
// return 550;
// }
}
private function getMinOpeningDate() {
return -500;
}
private function getMaxOpeningDate() {
return 1000;
}
private function getMinArchaeologyContextDate() {
return -500;
}
private function getMaxArchaeologyContextDate() {
return 1000;
}
private function getMinMaxCoinDate() {
// $em = $this->getDoctrine()->getManager();
// $qb = $em->createQueryBuilder();
// $qb->select('MAX(c.endingDate) as max1, MIN(c.startingDate) as min1')
// ->from('OxHoardBundle:Coin', 'c');
//
// $query = $qb->getQuery();
// $result = $query->getArrayResult();
// return $result[0];
return array('min1'=>-500, 'max1'=>1000);
}
/**
* 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 (false === $this->security->isGranted($attribute, $entity)) {
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 userIsImporter() {
if($this->getUser() && ($this->getUser()->hasRole('ROLE_IMPORTER')))
{
return true;
}
return $this->userIsAdmin();
}
private function userIsAuthorisedToCreate() {
// user must either be admin or be authorised to edit hoards for at least one country
if($this->userIsAdmin() || ($this->getUser() && count($this->getUser()->getAccessibleCountries()) > 0)) {
return true;
}
return false;
}
/**
* Retrieves coordinates of all the hoards from database
*
* @Route("/ajax_all_hoard_locations", name="ajax_all_hoard_locations", methods={"GET"})
*/
public function ajaxAllHoardLocations()
{
$em = $this->getDoctrine()->getManager();
$queryBuilder = $em -> createQueryBuilder()
->select("h.id, h.findSpotLatitude, h.findSpotLongitude, h.terminalYear1, h.terminalYear2, h.findSpotName, h.validatedByUser")
->from("OxHoardBundle:Hoard", "h")
->where('h.findSpotLatitude IS NOT NULL')
->andWhere('h.findSpotLongitude IS NOT NULL');
//filter list for public to only those 'published' (validated by user)
if(!$this->getUser())
{
//public can see all hoards which are not hidden from the public, and which don't have location hidden
$queryBuilder->andWhere('(h.hideFrom = 3 OR h.hideWhat < 3 OR h.hideWhat IS NULL)')
->andWhere('(h.hideLocation IS NULL OR h.hideLocation != 1)')
;
}
$query = $queryBuilder->getQuery();
$allHoards = $query -> getArrayResult();
return new JsonResponse(
$allHoards
);
}
/***
* Given a rules array, biuld a doctrine query
*
*/
private function buildQuery($rules, $search_type, $format) {
$em = $this->getDoctrine()->getManager();
$qb = $em->createQueryBuilder();
// if format=csv select hoards. coins are going to be listed with a hoard.coins loop in the twig template
if ($format == 'csv-coins' || $format == 'csv') {
$qb->add('select', new Select(array('h', 'c')))
->add('from', new From('OxHoardBundle:Hoard', 'h'))
->leftJoin('h.coins', 'c');
} else {
if ($search_type == 'search-coins') {
$qb->add('select', new Select(array('c', 'h')))
->add('from', new From('OxHoardBundle:Coin', 'c'))
->leftJoin('c.hoard', 'h');
} else {
$qb->add('select', new Select(array('h', 'c')))
->add('from', new From('OxHoardBundle:Hoard', 'h'))
->leftJoin('h.coins', 'c');
}
}
if (($search_type == 'search-coins' && $format != 'csv') || $format == 'csv-coins') {
$qb->addSelect('hcountriessort')
->leftJoin('h.countries', 'hcountriessort');
}
//set join flags to false
$this->joinHoardImages = $this->joinHoardCountries = $this->joinHoardArchaeologySiteContextDetail = $this->joinCoinImages = $this->joinCoinPersons =
$this->joinCoinDenominations = $this->joinCoinMints = $this->joinCoinAspects = $this->joinCoinCoinReferences =
$this->joinCoinReferences = $this->joinCoinReigns = $this->joinContainers = $this->joinContainerImages =
$this->joinContainerForms = $this->joinObjects = $this->joinObjectImages =
$this->joinHoardAncientPlaces = $this->joinFindSpotLocationDetails = $this->joinHoardReferences =
$this->joinDiscoveryMethods = $this->joinDiscoveryLandUses = $this->joinNameSimple = $this->joinArchaeologyContextNatures = false;
//build expression recursively
$expr1 = $this->getExpressionForRule($qb, $rules);
$qb->add('where', $expr1);
//join tables if necessary
if ($this->joinHoardCountries) $qb->leftJoin('h.countries', 'hoardCountries');
if ($this->joinHoardArchaeologySiteContextDetail) $qb->leftJoin('h.archaeologySiteContextDetails', 'hoardArchaeologySiteContextDetails');
if ($this->joinHoardImages) $qb->leftJoin('h.hoardImages', 'hoardImages');
if ($this->joinCoinImages) $qb->leftJoin('c.coinImages', 'coinImages');
if ($this->joinCoinPersons) $qb->leftJoin('c.persons', 'coinPersons');
if ($this->joinCoinDenominations) $qb->leftJoin('c.denominations', 'coinDenominations');
if ($this->joinCoinMints) $qb->leftJoin('c.mints', 'coinMints');
if ($this->joinCoinAspects) $qb->leftJoin('c.aspects', 'coinAspects');
if ($this->joinCoinCoinReferences) $qb->leftJoin('c.coinReferences', 'coinCoinReferences');
if ($this->joinCoinReferences) $qb->leftJoin('coinCoinReferences.reference', 'coinReferences');
if ($this->joinCoinReigns) $qb->leftJoin('c.reigns', 'coinReigns');
if ($this->joinContainers) $qb->leftJoin('h.containers', 'containers');
if ($this->joinContainerImages) $qb->leftJoin('containers.containerImages', 'containerImages');
if ($this->joinContainerForms) $qb->leftJoin('containers.containerForm', 'containerForms');
if ($this->joinObjects) $qb->leftJoin('h.objects', 'objects');
if ($this->joinObjectImages) $qb->leftJoin('objects.objectImages', 'objectImages');
if ($this->joinHoardReferences) $qb->leftJoin('h.hoardReferences', 'hoardReferences');
if ($this->joinHoardAncientPlaces) $qb->leftJoin('h.ancientPlace', 'hoardAncientPlaces');
if ($this->joinArchaeologyContextNatures) $qb->leftJoin('h.archaeologyContextNatures', 'hoardArchaeologyContextNatures');
if ($this->joinFindSpotLocationDetails) $qb->leftJoin('h.findSpotLocationDetail', 'hoardFindSpotLocationDetails');
if ($this->joinDiscoveryMethods) $qb->leftJoin('h.discoveryMethod', 'hoardDiscoveryMethods');
if ($this->joinDiscoveryLandUses) $qb->leftJoin('h.discoveryLandUse', 'hoardDiscoveryLandUses');
if ($this->joinNameSimple) $qb->leftJoin('h.nameSimple', 'nameSimple');
return $qb;
}
private function getExpressionForRule($qb, $rule) {
// Recursive function to build up an expression for the rule
// if this is a compound rule, make a boolean expression out of the sub-expressions
// otherwise make an atomic (simple) expression
if(isset($rule['condition'])) {
//compound rule
$rules = $rule['rules'];
switch($rule['condition']) {
case 'AND':
$expr = $qb->expr()->andX();
break;
case 'OR':
$expr = $qb->expr()->orX();
break;
}
foreach($rules as $rule) {
$subexpr = $this->getExpressionForRule($qb, $rule);
$expr->add($subexpr);
}
} else {
//atomic rule
$expr = $this->getExpressionForAtomicRule($qb, $rule);
}
return $expr;
}
private function getExpressionForAtomicRule($qb, $rule) {
// get field
$field = $rule['field'];
// get value
$value = $rule['value'];
// get type
$type = $rule['type'];
$is_array = isset($rule['data']['isArray']) ?
$rule['data']['isArray'] === true :
false;
// get range: if the field is a range (eg discoveryYear1-discoveryYear2)
// then $range is true and $fiald is discoveryYear
$range = false;
$checkCollection = false;
// set join flags to true if necessary
if( $field == 'hoardCountries.id') {
$this->joinHoardCountries = true;
}
if( $field == 'hoardArchaeologySiteContextDetails.id') {
$this->joinHoardArchaeologySiteContextDetail = true;
}
if( $field == 'ancientPlace') {
$this->joinAncientPlaces = true;
}
if( $field == 'hoardArchaeologyContextNatures.id') {
$this->joinArchaeologyContextNatures = true;
}
if( $field == 'findSpotLocationDetail') {
$this->joinFindSpotLocationDetails = true;
}
if( $field == 'discoveryMethod') {
$this->joinDiscoveryMethods = true;
}
if( $field == 'discoveryLandUse') {
$this->joinDiscoveryLandUses = true;
}
if( $field == 'hoardReferences.reference') {
$this->joinHoardReferences = true;
}
if( $field == 'hoardImages') {
$this->joinHoardImages = true;
}
if( $field == 'c.period') {
}
if( $field == 'coinPersons.id') {
$this->joinCoinPersons = true;
}
if( $field == 'coinReigns.id') {
$this->joinCoinReigns = true;
}
if( $field == 'coinDenominations.id') {
$this->joinCoinDenominations = true;
}
if( $field == 'coinDenominations.material') {
$this->joinCoinDenominations = true;
}
if( $field == 'coinMints.id') {
$this->joinCoinMints = true;
}
if( $field == 'coinAspects.id') {
$this->joinCoinAspects = true;
}
if( $field == 'coinReferences.id') {
$this->joinCoinCoinReferences = true;
$this->joinCoinReferences = true;
}
if( $field == 'coinCoinReferences.reference_str') {
$this->joinCoinCoinReferences = true;
$this->joinCoinReferences = true;
$this->joinCoinReferences = true;
}
if( $field == 'coinImages') {
$this->joinCoinImages = true;
}
if( $field == 'containers' || $field == 'containers.container' || $field == 'containers.comment') {
$this->joinContainers = true;
}
if( $field == 'containerImages') {
$this->joinContainers = true;
$this->joinContainerImages = true;
}
if( $field == 'containers.material') {
$this->joinContainers = true;
}
if( $field == 'containers.containerForm') {
$this->joinContainers = true;
$this->joinContainerForms = true;
}
if( $field == 'objects' || $field == 'objects.comment') {
$this->joinObjects = true;
}
if( $field == 'objectImages') {
$this->joinObjects = true;
$this->joinObjectImages = true;
}
if( $field == 'objects.object') {
$this->joinObjects = true;
}
if( $field == 'objects.material') {
$this->joinObjects = true;
}
if( $field == 'h.findSpotName') {
$this->joinNameSimple = true;
}
if (isset($rule['data'])) {
if (isset($rule['data']['range'])) {
$range = $rule['data']['range'];
}
if (isset($rule['data']['checkCollection'])) {
$checkCollection = $rule['data']['checkCollection'];
}
}
if(isset($rule['operator'])) {
$expr = NULL;
if ($field == 'h.findSpotName' && (
$rule['operator'] == 'begins_with' || $rule['operator'] == 'ends_with' ||
$rule['operator'] == 'contains' || $rule['operator'] == 'equal' || 'not_equal'
)) {
switch($rule['operator']) {
case 'contains':
$newValue = '%'.$value.'%';
$expr = "(h.findSpotName LIKE '".$newValue."' OR h.findSpotOtherNames LIKE '".$newValue."' OR nameSimple.name LIKE '".$newValue."')";
break;
case 'equal':
$newValue = $value;
$expr = "(h.findSpotName = '".$newValue."' OR h.findSpotOtherNames = '".$newValue."' OR nameSimple.name = '".$newValue."')";
break;
case 'not_equal':
$newValue = $value;
$expr = "(h.findSpotName <> '".$newValue."' OR h.findSpotOtherNames <> '".$newValue."' OR nameSimple.name <> '".$newValue."')";
break;
}
}
else {
switch($rule['operator']) {
case 'begins_with':
$expr = $qb->expr()->like($field, $qb->expr()->literal($value.'%'));
break;
case 'ends_with':
$expr = $qb->expr()->like($field, $qb->expr()->literal('%'.$value));
case 'contains':
$expr = $qb->expr()->like($field, $qb->expr()->literal('%'.$value.'%'));
break;
case 'equal':
if ($range) {
if ($type == "integer") {
$expr = '(' .$field. '1 <= ' .$value. ' AND ' .$field. '2 >= ' .$value. ') OR ' .$field. '1 = ' .$value .' OR ' .$field. '2 = ' .$value;
break;
}
} else {
if ($type == "string") {
if ($is_array) {
$expr = $field. ' IN (' .$value. ')';
} else {
$expr = $qb->expr()->eq($field, $qb->expr()->literal($value));
}
break;
}
if ($type == "integer" || $type == "double") {
if ($field=="c.period") {
$expr = $field. ' = ' .$value;
} else {
$expr = $field. ' = ' .$value;
}
break;
}
if ($type == "boolean") {
if ($checkCollection) {
if ($value == "true") {
$expr = $field. ' IS NOT NULL';
break;
} else {
$expr = $field. ' IS NULL';
break;
}
}
if ($field == "h.modified") {
$currentUser = $this->getUser()->getId();
$expr = 'h.modified = ' .$currentUser. ' OR h.created = ' .$currentUser;
break;
} else {
$bool_value = $value == false ? '0' : $value;
$expr = $field. ' = ' .$bool_value;
break;
}
}
}
case 'not_equal':
if ($range) {
if ($type == "integer") {
$expr = $field. '1>' .$value.' OR ' .$field. '2<' .$value.' OR (' .$field. '1!=' .$value. 'AND ' .$field. '2 IS NULL) OR (' .$field. '2!=' .$value. ' AND ' .$field. '1 IS NULL)' ;
break;
}
} else {
if ($type == "string") {
$expr = $qb->expr()->neq($field, $qb->expr()->literal($value));
break;
}
if ($type == "integer" || $type == "double") {
$expr = $field. '!=' .$value;
break;
}
}
case 'greater':
if ($range) {
$expr = $field. '1>' .$value. ' OR ' .$field. '2>' .$value ;
break;
} else {
$expr = $field. '>' .$value;
break;
}
case 'less':
if ($range) {
$expr = $field. '2<' .$value. ' OR ' .$field. '1<' .$value ;
break;
} else {
$expr = $field. '<' .$value;
break;
}
case 'is_null':
if ($range) {
if ($type == "integer") {
$expr = $field. '1 IS NULL AND ' .$field. '2 IS NULL' ;
break;
}
} else {
$expr = $field.' IS NULL';
break;
}
case 'is_not_null':
if ($range) {
if ($type == "integer") {
$expr = $field. '1 IS NOT NULL OR ' .$field. '2 IS NOT NULL' ;
break;
}
} else {
$expr = $field.' IS NOT NULL';
break;
}
default:
//error
}
}
if (($field == "h.city" || $field == "h.address") && !$this->getUser()) {
$expr = $expr . ' AND h.hideCity = 0 OR h.hideCity IS NULL';
}
if ($field == "h.county" && !$this->getUser()) {
$expr = $expr . ' AND h.hideCounty = 0 OR h.hideCounty IS NULL';
}
return $expr;
}
else {
// error
}
}
private function queryOptions() {
$em = $this->getDoctrine()->getManager();
//get all available options for the various dropdowns
$data = array();
$data['hoardTypes'] = $em->getRepository('OxHoardBundle:HoardType')->findAll();
$data['countries'] = $em->getRepository('OxHoardBundle:Country')->findAll();
$data['provinces'] = $em->getRepository('OxHoardBundle:Province')->findAll();
$data['ancientPlaces'] = $em->getRepository('OxHoardBundle:AncientPlace')->findAll();
$data['findSpotLocationDetails'] = $em->getRepository('OxHoardBundle:FindSpotLocationDetail')->findAll();
$data['discoveryLandUses'] = $em->getRepository('OxHoardBundle:DiscoveryLandUse')->findAll();
$data['discoveryMethods'] = $em->getRepository('OxHoardBundle:DiscoveryMethod')->findAll();
$data['reigns'] = $em->getRepository('OxHoardBundle:Reign')->findAll();
$data['discoveryMethods'] = $em->getRepository('OxHoardBundle:DiscoveryMethod')->findAll();
$data['discoveryLandUses'] = $em->getRepository('OxHoardBundle:DiscoveryLandUse')->findAll();
$data['archaeologyRecoveryMethods'] = $em->getRepository('OxHoardBundle:ArchaeologyRecoveryMethod')->findAll();
$data['archaeologySiteContexts'] = $em->getRepository('OxHoardBundle:ArchaeologySiteContext')->findAll();
$data['archaeologyRecoveryMethods'] = $em->getRepository('OxHoardBundle:ArchaeologyRecoveryMethod')->findAll();
$data['archaeologySiteContextDetails'] = $em->getRepository('OxHoardBundle:ArchaeologySiteContextDetail')->findAll();
$data['archaeologyPeriods'] = $em->getRepository('OxHoardBundle:ArchaeologyPeriod')->findAll();
$data['archaeologyContextNatures'] = $em->getRepository('OxHoardBundle:ArchaeologyContextNature')->findAll();
$data['coinLevelDatas'] = $em->getRepository('OxHoardBundle:CoinLevelData')->findAll();
$data['ratings'] = $em->getRepository('OxHoardBundle:Rating')->findAll();
$data['hideWhats'] = $em->getRepository('OxHoardBundle:HideWhat')->findAll();
$data['hideFroms'] = $em->getRepository('OxHoardBundle:HideFrom')->findAll();
$data['persons'] = $em->getRepository('OxHoardBundle:Person')->findAll();
$data['period'] = $em->getRepository('OxHoardBundle:Period')->findAll();
$data['reigns'] = $em->getRepository('OxHoardBundle:Reign')->findAll();
$data['mints'] = $em->getRepository('OxHoardBundle:Mint')->findAll();
$data['denominations'] = $em->getRepository('OxHoardBundle:Denomination')->findAll();
$data['materials'] = array(
array("ids" => "23", "name" => "Gold"),
array("ids" => "22,31", "name" => "Silver"),
array("ids" => "7,49,53", "name" => "Bronze"),
);
$data['condition'] = $em->getRepository('OxHoardBundle:Condition')->findAll();
$data['aspects'] = $em->getRepository('OxHoardBundle:Aspect')->findAll();
$data['references'] = $em->getRepository('OxHoardBundle:Reference')->findBy(array(), array('sortValue' => 'DESC', 'authors' => 'ASC', 'title' => 'ASC'));
// var_dump($data['references']);
$data['containerForms'] = $em->getRepository('OxHoardBundle:ContainerForm')->findAll();
return $data;
}
private function constructSearchQuery($request, &$doctrineQueryBuilder, &$activeTab, &$hoardValues, &$coinValues, &$queryParameters, $initialSliderValues)
{
// Construct a query based on all the form values.
// We'll add JOINs and WHERE clauses to the doctrineQueryBuilder object.
// We'll add any parameter values to the queryParameters array, and after this function join them to the existing query (they seemed to get lost if I added them directly to the doctrineQueryBuilder)
// The hardValues and coinValues arrays will contain parameters appropriate to those objects and be populated by this function
if (!empty($request->query->get('ox_hs'))) {
foreach ($request->query->get('ox_hs') as $key => $value) {
if (is_array($value) or strlen($value)) {
if (strpos($key, 'hoard') === 0) {
$hoardValues[$key] = $value;
}
else if (strpos($key, 'coin') === 0) {
$coinValues[$key] = $value;
}
}
}
}
if($this->userIsAdmin()) {
#echo "<pre>hoard params: " . print_r($hoardValues,1) . "</pre>";
#echo "<pre>coin params: " . print_r($coinValues,1) . "</pre>";
}
if (!empty($hoardValues)) {
$isHoardRefJoined = false;
foreach ($hoardValues as $key => $value) {
$field = lcfirst(substr($key, strlen('hoard')));
if ($field == "findSpotName") {
// Search in both findSpotName and findSpotOtherNames fields
$altField = "findSpotOtherNames";
$doctrineQueryBuilder->join('h.nameSimple', 'nameSimple');
$doctrineQueryBuilder->andWhere('h.' .$field. ' LIKE :' .$key. ' OR ' . 'h.' .$altField. ' LIKE :' .$key. ' OR ' . 'nameSimple.name LIKE :' .$key);
$queryParameters[$key] = '%'.$value.'%';
} else if ($field == "type") {
// Search in both findSpotName and findSpotOtherNames fields
$doctrineQueryBuilder->andWhere('h.' . 'hoardType' . ' = :' . $key);
$queryParameters[$key] = $value;
} else if ($field == "countries") {
$doctrineQueryBuilder->join('h.' . 'countries', 'country');
$fieldQuery = "( ";
foreach ($value as $index => $val) {
if ($index > 0) {
$fieldQuery .= " OR ";
}
$fieldQuery .= 'country.id = :' . $key . "_" . $index;
$queryParameters[$key . "_" . $index] = $val;
}
$fieldQuery .= " )";
$doctrineQueryBuilder->andWhere($fieldQuery);
} else if (
$field == "comment" || $field == "credit" || $field == "region" ||
$field == "city" || $field == "county" || $field == "address" ||
$field == "owner" || $field == "findSpotComment" || $field == "finder" ||
$field == "archaeologyNaturalFeatures" || $field == "archaeologyAssociatedFeatures" ||
$field == "archaeologySiteComment" || $field == "internalNote"
) {
$doctrineQueryBuilder->andWhere('h.' . $field . ' LIKE :' . $key);
if (($field == "city" || $field == "address") && !$this->getUser()) {
$doctrineQueryBuilder->andWhere('h.hideCity = 0 OR h.hideCity IS NULL');
}
if ($field == "county" && !$this->getUser()) {
$doctrineQueryBuilder->andWhere('h.hideCounty = 0 OR h.hideCounty IS NULL');
}
$queryParameters[$key] = '%'.$value.'%';
} else if ($field == "archaeologyContextNatures") {
$doctrineQueryBuilder->join('h.' . 'archaeologyContextNatures', 'archaeologyContextNatures');
$fieldQuery = "( ";
foreach ($value as $index => $val) {
if ($index > 0) {
$fieldQuery .= " OR ";
}
$fieldQuery .= 'archaeologyContextNatures.id = :' . $key . "_" . $index;
$queryParameters[$key . "_" . $index] = $val;
}
$fieldQuery .= " )";
$doctrineQueryBuilder->andWhere($fieldQuery);
} else if ($field == "archaeologySiteContextDetails") {
$doctrineQueryBuilder->join('h.' . 'archaeologySiteContextDetails', 'archaeologySiteContextDetail');
$fieldQuery = "( ";
foreach ($value as $index => $val) {
if ($index > 0) {
$fieldQuery .= " OR ";
}
$fieldQuery .= 'archaeologySiteContextDetail.id = :' . $key . "_" . $index;
$queryParameters[$key . "_" . $index] = $val;
}
$fieldQuery .= " )";
$doctrineQueryBuilder->andWhere($fieldQuery);
} else if ($field == "discoveryYearRangeStart") {
if ($hoardValues['hoardDiscoveryYearRangeEnd']) {
if (($hoardValues['hoardDiscoveryYearRangeStart'] == $initialSliderValues['hoardDiscoveryYearRangeStart'])
and ($hoardValues['hoardDiscoveryYearRangeEnd'] == $initialSliderValues['hoardDiscoveryYearRangeEnd'])) {
# Do nothing
} else {
$endKey = "hoardDiscoveryYearRangeEnd";
$endValue = $hoardValues['hoardDiscoveryYearRangeEnd'];
if ($hoardValues['hoardDiscoveryYearRangeStart'] > $initialSliderValues['hoardDiscoveryYearRangeStart']) {
$rangeCondition = ' (h.' . 'discoveryYear1' . ' >= :' . $key;
$rangeCondition .= ' AND h.' . 'discoveryYear1' . ' <= :' . $endKey;
$rangeCondition .= ' )';
$rangeCondition .= ' OR ';
$rangeCondition .= ' (h.' . 'discoveryYear2' . ' >= :' . $key;
$rangeCondition .= ' AND h.' . 'discoveryYear2' . ' <= :' . $endKey;
$rangeCondition .= ' )';
$doctrineQueryBuilder->andWhere($rangeCondition);
$queryParameters[$key] = $value;
$queryParameters[$endKey] = $endValue;
} else {
# just search on end date
$rangeCondition = ' h.' . 'discoveryYear1' . ' <= :' . $endKey;
$rangeCondition .= ' OR ';
$rangeCondition .= ' h.' . 'discoveryYear2' . ' <= :' . $endKey;
$doctrineQueryBuilder->andWhere($rangeCondition);
$queryParameters[$endKey] = $endValue;
}
}
} else {
if ($hoardValues['hoardDiscoveryYearRangeStart'] == $initialSliderValues['hoardDiscoveryYearRangeStart']) {
# Do nothing
} else {
$doctrineQueryBuilder->andWhere('h.' . 'discoveryYear1' . ' = :' . $key);
$queryParameters[$key] = $value;
}
}
} else if ($field == "terminalYearRangeStart") {
if (isset($hoardValues['hoardTerminalYearRangeEnd'])) {
if (($hoardValues['hoardTerminalYearRangeStart'] == $initialSliderValues['hoardTerminalYearRangeStart'])
and ($hoardValues['hoardTerminalYearRangeEnd'] == $initialSliderValues['hoardTerminalYearRangeEnd'])) {
# Do nothing
} else {
$endKey = "hoardTerminalYearRangeEnd";
$endValue = $hoardValues['hoardTerminalYearRangeEnd'];
if (($hoardValues['hoardTerminalYearRangeStart'] > $initialSliderValues['hoardTerminalYearRangeStart'])
and
($hoardValues['hoardTerminalYearRangeEnd'] < $initialSliderValues['hoardTerminalYearRangeEnd'])) {
$rangeCondition = ' (h.' . 'terminalYear1' . ' >= :' . $key;
$rangeCondition .= ' AND h.' . 'terminalYear1' . ' <= :' . $endKey;
$rangeCondition .= ' )';
$rangeCondition .= ' OR ';
$rangeCondition .= ' (h.' . 'terminalYear2' . ' >= :' . $key;
$rangeCondition .= ' AND h.' . 'terminalYear2' . ' <= :' . $endKey;
$rangeCondition .= ' )';
$doctrineQueryBuilder->andWhere($rangeCondition);
$queryParameters[$key] = $value;
$queryParameters[$endKey] = $endValue;
} else if ($hoardValues['hoardTerminalYearRangeStart'] > $initialSliderValues['hoardTerminalYearRangeStart']) {
$rangeCondition = ' h.' . 'terminalYear1' . ' >= :' . $key;
$rangeCondition .= ' OR ';
$rangeCondition .= ' h.' . 'terminalYear2' . ' >= :' . $key;
$doctrineQueryBuilder->andWhere($rangeCondition);
$queryParameters[$key] = $value;
} else if ($hoardValues['hoardTerminalYearRangeEnd'] < $initialSliderValues['hoardTerminalYearRangeEnd']) {
$rangeCondition = ' h.' . 'terminalYear1' . ' <= :' . $endKey;
$rangeCondition .= ' OR ';
$rangeCondition .= ' h.' . 'terminalYear2' . ' <= :' . $endKey;
$doctrineQueryBuilder->andWhere($rangeCondition);
$queryParameters[$endKey] = $endValue;
}
}
} else {
if ($hoardValues['hoardTerminalYearRangeStart'] == $initialSliderValues['hoardTerminalYearRangeStart']) {
# Do nothing
} else {
$doctrineQueryBuilder->andWhere('h.' . 'terminalYear1' . ' = :' . $key);
$queryParameters[$key] = $value;
}
}
} else if ($field == "openingYearRangeStart") {
if (isset($hoardValues['hoardOpeningYearRangeEnd'])) {
if (($hoardValues['hoardOpeningYearRangeStart'] == $initialSliderValues['hoardOpeningYearRangeStart'])
and ($hoardValues['hoardOpeningYearRangeEnd'] == $initialSliderValues['hoardOpeningYearRangeEnd'])) {
# Do nothing
} else {
$endKey = "hoardOpeningYearRangeEnd";
$endValue = $hoardValues['hoardOpeningYearRangeEnd'];
if (($hoardValues['hoardOpeningYearRangeStart'] > $initialSliderValues['hoardOpeningYearRangeStart'])
and
($hoardValues['hoardOpeningYearRangeEnd'] < $initialSliderValues['hoardOpeningYearRangeEnd'])) {
$rangeCondition = ' (h.' . 'openingYear1' . ' >= :' . $key;
$rangeCondition .= ' AND h.' . 'openingYear1' . ' <= :' . $endKey;
$rangeCondition .= ' )';
$rangeCondition .= ' OR ';
$rangeCondition .= ' (h.' . 'openingYear2' . ' >= :' . $key;
$rangeCondition .= ' AND h.' . 'openingYear2' . ' <= :' . $endKey;
$rangeCondition .= ' )';
$doctrineQueryBuilder->andWhere($rangeCondition);
$queryParameters[$key] = $value;
$queryParameters[$endKey] = $endValue;
} else if ($hoardValues['hoardOpeningYearRangeStart'] > $initialSliderValues['hoardOpeningYearRangeStart']) {
$rangeCondition = ' h.' . 'openingYear1' . ' >= :' . $key;
$rangeCondition .= ' OR ';
$rangeCondition .= ' h.' . 'openingYear2' . ' >= :' . $key;
$doctrineQueryBuilder->andWhere($rangeCondition);
$queryParameters[$key] = $value;
} else if ($hoardValues['hoardOpeningYearRangeEnd'] < $initialSliderValues['hoardOpeningYearRangeEnd']) {
$rangeCondition = ' h.' . 'openingYear1' . ' <= :' . $endKey;
$rangeCondition .= ' OR ';
$rangeCondition .= ' h.' . 'openingYear2' . ' <= :' . $endKey;
$doctrineQueryBuilder->andWhere($rangeCondition);
$queryParameters[$endKey] = $endValue;
}
}
} else {
if ($hoardValues['hoardOpeningYearRangeStart'] == $initialSliderValues['hoardOpeningYearRangeStart']) {
# Do nothing
} else {
$doctrineQueryBuilder->andWhere('h.' . 'openingYear1' . ' = :' . $key);
$queryParameters[$key] = $value;
}
}
} else if ($field == "archaeologyContextDateRangeStart") {
if ($hoardValues['hoardArchaeologyContextDateRangeEnd']) {
if (($hoardValues['hoardArchaeologyContextDateRangeStart'] == $initialSliderValues['hoardArchaeologyContextDateRangeStart'])
and ($hoardValues['hoardArchaeologyContextDateRangeEnd'] == $initialSliderValues['hoardArchaeologyContextDateRangeEnd'])) {
# Do nothing
} else {
$endKey = "hoardArchaeologyContextDateRangeEnd";
$endValue = $hoardValues['hoardArchaeologyContextDateRangeEnd'];
if ($hoardValues['hoardArchaeologyContextDateRangeStart'] > $initialSliderValues['hoardArchaeologyContextDateRangeStart']) {
$rangeCondition = ' (h.' . 'archaeologyContextDate1' . ' >= :' . $key;
$rangeCondition .= ' AND h.' . 'archaeologyContextDate1' . ' <= :' . $endKey;
$rangeCondition .= ' )';
$rangeCondition .= ' OR ';
$rangeCondition .= ' (h.' . 'archaeologyContextDate2' . ' >= :' . $key;
$rangeCondition .= ' AND h.' . 'archaeologyContextDate2' . ' <= :' . $endKey;
$rangeCondition .= ' )';
$doctrineQueryBuilder->andWhere($rangeCondition);
$queryParameters[$key] = $value;
$queryParameters[$endKey] = $endValue;
} else {
# just search on end date
$rangeCondition = ' h.' . 'archaeologyContextDate1' . ' <= :' . $endKey;
$rangeCondition .= ' OR ';
$rangeCondition .= ' h.' . 'archaeologyContextDate2' . ' <= :' . $endKey;
$doctrineQueryBuilder->andWhere($rangeCondition);
$queryParameters[$endKey] = $endValue;
}
}
} else {
if ($hoardValues['hoardArchaeologyContextDateRangeStart'] == $initialSliderValues['hoardArchaeologyContextDateRangeStart']) {
# Do nothing
} else {
$doctrineQueryBuilder->andWhere('h.' . 'archaeologyContextDate1' . ' = :' . $key);
$queryParameters[$key] = $value;
}
}
} else if ($field == "coinCountMin") {
$endKey = "hoardCoinCountMax";
$endValue = $hoardValues['hoardCoinCountMax'];
if (($hoardValues['hoardCoinCountMin'] == $initialSliderValues['hoardCoinCountMin'])
and ($hoardValues['hoardCoinCountMax'] == $initialSliderValues['hoardCoinCountMax'])) {
# Do nothing
} else {
$doctrineQueryBuilder->join('h.coinCount', 'coinCt');
$doctrineQueryBuilder->andWhere('coinCt.coinCount >= :' . $key);
$queryParameters[$key] = $value;
if ($hoardValues['hoardCoinCountMax'] < $initialSliderValues['hoardCoinCountMax']) {
$doctrineQueryBuilder->andWhere('coinCt.coinCount <= :' . $endKey);
$queryParameters[$endKey] = $endValue;
}
}
} else if ((in_array($field, array("discoveryYearRangeEnd", "terminalYearRangeEnd", "openingYearRangeEnd", "archaeologyContextDateRangeEnd", "coinCountMax")))) {
# skip
} else if ($field == "hoardValidatedByUser" && $this->getUser()) {
$doctrineQueryBuilder->andWhere('h.validatedByUser = :' . $key);
$queryParameters[$key] = intval($value);
} else if ($field == "hoardValidatedByAdmin" && $this->userIsAdmin()) {
$doctrineQueryBuilder->andWhere('h.validatedByAdmin = :' . $key);
$queryParameters[$key] = intval($value);
} else if ($field == "hoardCoinDataValidatedByUser" && $this->getUser()) {
$doctrineQueryBuilder->andWhere('h.coinDataValidatedByUser = :' . $key);
$queryParameters[$key] = intval($value);
} else if ($field == "hoardCoinDataValidatedByAdmin" && $this->userIsAdmin()) {
$doctrineQueryBuilder->andWhere('h.coinDataValidatedByAdmin = :' . $key);
$queryParameters[$key] = intval($value);
} else if ($field == "objectComment") {
$doctrineQueryBuilder->join('h.objects', 'objects')
->andWhere('objects.comment LIKE :' . $key);
$queryParameters[$key] = '%'.$value.'%';
} else if ($field == "objectType") {
$doctrineQueryBuilder->join('h.objects', 'objects')
->andWhere('objects.object LIKE :'.$key);
$queryParameters[$key] = $value.'%';
} else if ($field == "hasContainer") {
$doctrineQueryBuilder->andWhere('h.containers IS NOT EMPTY');
} else if ($field == "hasObject") {
$doctrineQueryBuilder->andWhere('h.objects IS NOT EMPTY');
} else if ($field == "hasImage") {
$doctrineQueryBuilder->andWhere('h.hoardImages IS NOT EMPTY');
} else if ($field == "hideWhat") {
$doctrineQueryBuilder->andWhere('h.' . 'hideWhat' . ' = :' . $key);
$queryParameters[$key] = $value;
} else if ($field == "hideFrom") {
$doctrineQueryBuilder->andWhere('h.' . 'hideFrom' . ' = :' . $key);
$queryParameters[$key] = $value;
} else if ($field == "hasObjectWithImage") {
$doctrineQueryBuilder->join('h.objects', 'o')
->andWhere('o.objectImages IS NOT EMPTY');
} else if ($field == "containerString") {
$doctrineQueryBuilder->join('h.containers', 'cont')
->andWhere('cont.container LIKE :' . $key);
$queryParameters[$key] = '%'.$value.'%';
} else if ($field == "containerComment") {
$doctrineQueryBuilder->join('h.containers', 'cont')
->andWhere('cont.comment LIKE :' . $key);
$queryParameters[$key] = '%'.$value.'%';
} else if ($field == "containerHasImage") {
$doctrineQueryBuilder->join('h.containers', 'cont')
->andWhere('cont.containerImages IS NOT EMPTY');
}
else {
if ($field == "containerMaterials") {
$object = $field;
// $doctrineQueryBuilder->join('c.' . 'denominations', 'denomination_materials');
// $doctrineQueryBuilder->join('denomination_materials.material', 'materials');
$doctrineQueryBuilder->join('h.' . 'containers', 'container_materials');
$doctrineQueryBuilder->join('container_materials.material', 'containerMaterials');
$field = "id";
} else if ($field == "containerForms") {
$object = $field;
$doctrineQueryBuilder->join('h.' . 'containers', 'container_form');
$doctrineQueryBuilder->join('container_form.containerForm', 'containerForms');
$field = "id";
} else if ($field == "objectMaterials") {
$object = $field;
$doctrineQueryBuilder->join('h.' . 'objects', 'object_materials');
$doctrineQueryBuilder->join('object_materials.material', 'objectMaterials');
$field = "id";
} else if ($field == "reference") {
if (!$isHoardRefJoined) {
$doctrineQueryBuilder->join('h.' . 'hoardReferences', 'hoard_references');
$isHoardRefJoined = true;
}
$doctrineQueryBuilder->join('hoard_references.reference', 'hoardref');
$object = 'hoardref';
$field = "id";
} else if ($field == "reference_string") {
if (!$isHoardRefJoined) {
$doctrineQueryBuilder->join('h.' . 'hoardReferences', 'hoard_references');
$isHoardRefJoined = true;
}
$object = 'hoard_references';
$field = "reference_str";
}
if (is_array($value)) {
if(!isset($object)) {
$object = 'h';
}
$fieldQuery = "( ";
foreach ($value as $index => $val) {
if ($index > 0) {
$fieldQuery .= " OR ";
}
$fieldQuery .= $object . '.' . $field . ' = :' . $key . "_" . $index;
$queryParameters[$key . "_" . $index] = $val;
}
$fieldQuery .= " )";
$doctrineQueryBuilder->andWhere($fieldQuery);
} else {
if ($field == "reference_str") {
$doctrineQueryBuilder->andWhere($object . '.' . $field . ' LIKE :' . $key);
$queryParameters[$key] = '%'.$value.'%';
// this would allow users to use their own wildcards
// $val = str_replace("*", "%", $value);
// $val = str_replace("?", "_", $val);
// $queryParameters[$key] = $val;
} else {
$doctrineQueryBuilder->andWhere('h.' . $field . ' = :' . $key);
$queryParameters[$key] = $value;
}
}
}
}
$activeTab = 3; // Set tab to Results tab
}
//ignore coin year range if set to initial values
if(isset($coinValues['coinYearRangeStart']) && $coinValues['coinYearRangeStart'] == $initialSliderValues['coinYearRangeStart']) {
unset($coinValues['coinYearRangeStart']);
}
if(isset($coinValues['coinYearRangeEnd']) && $coinValues['coinYearRangeEnd'] == $initialSliderValues['coinYearRangeEnd']) {
unset($coinValues['coinYearRangeEnd']);
}
if (!empty($coinValues)) {
$isCoinRefJoined = false;
foreach ($coinValues as $key => $value) {
$field = lcfirst(substr($key, strlen('coin')));
$object = "c";
$subTables = array("persons", "reigns", "denominations", "mints", "aspects");
if (in_array($field, $subTables)) {
$object = $field;
$doctrineQueryBuilder->join('c.' . $field, $object);
$field = "id";
} else if ($field == "yearRangeStart") {
if(isset($coinValues['coinYearRangeEnd'])) {
if (($coinValues['coinYearRangeStart'] == $initialSliderValues['coinYearRangeStart'])
and ($coinValues['coinYearRangeEnd'] == $initialSliderValues['coinYearRangeEnd'])) {
#do nothing
} else {
$endKey = "coinYearRangeEnd";
$endValue = $coinValues['coinYearRangeEnd'];
if($coinValues['coinYearRangeStart'] > $initialSliderValues['coinYearRangeStart']) {
$rangeCondition = ' (c.' . 'startingDate' . ' >= :' . $key;
$rangeCondition .= ' AND c.' . 'startingDate' . ' <= :' . $endKey;
$rangeCondition .= ' )';
$rangeCondition .= ' OR ';
$rangeCondition .= ' (c.' . 'endingDate' . ' >= :' . $key;
$rangeCondition .= ' AND c.' . 'endingDate' . ' <= :' . $endKey;
$rangeCondition .= ' )';
$doctrineQueryBuilder->andWhere($rangeCondition);
$queryParameters[$key] = $value;
$queryParameters[$endKey] = $endValue;
} else {
# just search on end date
$rangeCondition = ' c.' . 'startingDate' . ' <= :' . $endKey;
$rangeCondition .= ' OR ';
$rangeCondition .= ' c.' . 'endingDate' . ' <= :' . $endKey;
$doctrineQueryBuilder->andWhere($rangeCondition);
$queryParameters[$endKey] = $endValue;
}
}
} else {
if ($coinValues['coinYearRangeStart'] == $initialSliderValues['coinYearRangeStart']) {
# Do nothing
} else {
$doctrineQueryBuilder->andWhere('c.' . 'startingDate' . ' = :' . $key);
$queryParameters[$key] = $value;
}
}
} else if ($field == "materials") {
$object = $field;
$doctrineQueryBuilder->join('c.' . 'denominations', 'denomination_materials');
$doctrineQueryBuilder->join('denomination_materials.material', 'materials');
$field = "id";
} else if ($field == "reference") {
$object = 'coinRef';
if (!$isCoinRefJoined) {
$doctrineQueryBuilder->join('c.' . 'coinReferences', $object);
$isCoinRefJoined = true;
}
$field = "reference";
} else if ($field == "referenceString") {
$object = 'coinRef';
if (!$isCoinRefJoined) {
$doctrineQueryBuilder->join('c.' . 'coinReferences', $object);
$isCoinRefJoined = true;
}
$field = "reference_str";
}
// materials is a special case as users only have the option to search for:
// "23" => "Gold", "22,31" => "Silver", "7,49,53" => "Bronze"
// material ids have to be converted vrom comma separated values to an array
if ($key == "coinMaterials") {
$value = explode(",", $value);
}
if (is_array($value)) {
$fieldQuery = "( ";
foreach ($value as $index => $val) {
if ($index > 0) {
$fieldQuery .= " OR ";
}
$fieldQuery .= $object . '.' . $field . ' = :' . $key . "_" . $index;
$queryParameters[$key . "_" . $index] = $val;
}
$fieldQuery .= " )";
$doctrineQueryBuilder->andWhere($fieldQuery);
} else {
if ($field == "hasImage") {
$doctrineQueryBuilder->join('c.' . 'coinImages', 'coin_images');
$doctrineQueryBuilder->andWhere('coin_images.deleted IS NULL');
//$queryParameters[$key] = $value;
} else {
if($field == 'yearRangeStart' || $field == 'yearRangeEnd') {
//this has already been handled
} elseif ($field == "reference_str") {
$doctrineQueryBuilder->andWhere($object . '.' . $field . ' LIKE :' . $key);
$val = str_replace("*", "%", $value);
$val = str_replace("?", "_", $val);
$queryParameters[$key] = $val;
} else {
// do a straight equality condition
$doctrineQueryBuilder->andWhere($object . '.' . $field . ' = :' . $key);
$queryParameters[$key] = $value;
}
}
}
}
}
}
// get different hoards based on query
/**
* Retrieves coordinates of the hoards from database based on query
*
* @Route("/ajax_hoard_locations", name="ajax_hoard_locations", methods={"GET"})
*/
public function ajaxGetHoardLocationQuery(Request $request) {
$search_type = $request->query->get('search_type');
$isCoinMintSearch = false;
$isAuthenticated = false;
if ($this->getUser()) {
$isAuthenticated = true;
}
$searchHasCoinFields = false;
$initialSliderValues = array();
$initialSliderValues['hoardDiscoveryYearRangeStart'] = $this->getMinDiscoveryDate();
$initialSliderValues['hoardDiscoveryYearRangeEnd'] = $this->getMaxDiscoveryDate();
$initialSliderValues['hoardTerminalYearRangeStart'] = $this->getMinTerminalDate();
$initialSliderValues['hoardTerminalYearRangeEnd'] = $this->getMaxTerminalDate();
$initialSliderValues['hoardOpeningYearRangeStart'] = $this->getMinOpeningDate();
$initialSliderValues['hoardOpeningYearRangeEnd'] = $this->getMaxOpeningDate();
$initialSliderValues['hoardArchaeologyContextDateRangeStart'] = $this->getMinArchaeologyContextDate();
$initialSliderValues['hoardArchaeologyContextDateRangeEnd'] = $this->getMaxArchaeologyContextDate();
$coinminmax = $this->getMinMaxCoinDate();
$initialSliderValues['coinYearRangeStart'] = $coinminmax['min1'];
$initialSliderValues['coinYearRangeEnd'] = $coinminmax['max1'];
$initialSliderValues['hoardCoinCountMin'] = 0;
$initialSliderValues['hoardCoinCountMax'] = 100000;
$em = $this->getDoctrine()->getManager();
if (isset($request->query->get('ox_hs')['rules']) && strlen($request->query->get('ox_hs')['rules'])) {
// check if coin fields are included in the search set $searchHasCoinFields
$rulesStr = $request->query->get('ox_hs')['rules'];
if ( strpos($rulesStr, '"field":"coin') || strpos($rulesStr, '"field":"c.') ) {
$searchHasCoinFields = true;
}
$rules = json_decode($rulesStr, true);
$doctrineQueryBuilder = $this->buildQuery($rules, $search_type, $request->request->get('format'));
$doctrineQueryBuilder->addSelect('h.id, h.findSpotLatitude, h.findSpotLongitude, h.findSpotName');
if ($search_type == 'search-coins') {
$doctrineQueryBuilder->addSelect('c.quantity');
if (strpos($rulesStr, '"field":"coinMints.id"')) {
$isCoinMintSearch = true;
// if coin mint was searched and searching for coins
// add mint locations to the response
$doctrineQueryBuilder
->addSelect('coinMints.id AS mintId, coinMints.mint, coinMints.latitude AS mintLatitude, coinMints.longitude AS mintLongitude');
}
}
}
else {
foreach ($request->query->get('ox_hs') as $key => $value) {
// check if coin fields are included in the search set $searchHasCoinFields
if (substr( $key, 0, 8 ) === "coinYear") {
if ($value != $initialSliderValues[$key]) {
$searchHasCoinFields = true;
}
}
elseif (substr( $key, 0, 4 ) === "coin") {
if ($value && $value != "") {
$searchHasCoinFields = true;
}
}
}
$doctrineQueryBuilder = $em->createQueryBuilder();
if ($search_type == 'search-coins') {
$doctrineQueryBuilder
->from('OxHoardBundle:Coin', 'c')
->leftJoin('c.hoard', 'h')
->addSelect('c.id, c.quantity');
}
else {
$doctrineQueryBuilder->select('h')
->from('OxHoardBundle:Hoard', 'h')
->leftJoin('h.coins', 'c');
}
$doctrineQueryBuilder->addSelect('h.id, h.findSpotLatitude, h.findSpotLongitude, h.findSpotName, h.validatedByUser')
->distinct();
$em->getFilters()->enable('softdeleteable');
$currentYear = date("Y");
$activeTab = 1;
$hoardValues = array();
$coinValues = array();
$queryParameters = array();
if (!empty($request->query->get('ox_hs'))) {
$this->constructSearchQuery($request, $doctrineQueryBuilder, $activeTab,
$hoardValues, $coinValues, $queryParameters, $initialSliderValues);
}
foreach ($queryParameters as $key => $value) {
$doctrineQueryBuilder->setParameter($key, $value);
}
// if coin mint was searched and searching for coins
if ($search_type == 'search-coins' && strpos($doctrineQueryBuilder->getDql(), "mints.id = :coinMints")) {
$isCoinMintSearch = true;
// add mint locations to the response
$doctrineQueryBuilder
->addSelect('mints.id AS mintId, mints.mint, mints.latitude AS mintLatitude, mints.longitude AS mintLongitude');
}
}
if (!$isAuthenticated) {
// public can only see hoards which are validated by the user,
// and which are either not hidden, or don't have everything hidden
$doctrineQueryBuilder
->andWhere('(h.validatedByUser = true) AND (h.hideFrom = 3 OR h.hideWhat < 3 OR h.hideWhat IS NULL)')
->andWhere('(h.hideLocation IS NULL OR h.hideLocation != 1)');
// if coin fields are included in the search
if ($searchHasCoinFields) {
// public can only see hoards with coins which are validated by the user,
// and which are either not hidden, or don't have anything hidden
$doctrineQueryBuilder->andWhere('(h.coinDataValidatedByUser = true) AND (h.hideFrom = 3 OR h.hideWhat IS NULL)');
}
}
$doctrineQueryBuilderAllRows = clone $doctrineQueryBuilder;
$boundary = isset($request->query->get('ox_hs')["boundary"]) ?
$request->query->get('ox_hs')["boundary"] :
null;
$noCoOrds = [];
$hasBoundary = true;
if (!$boundary || is_null($boundary)) {
$hasBoundary = false;
$doctrineQueryBuilderNoCoOrds = clone $doctrineQueryBuilderAllRows;
$doctrineQueryBuilderNoCoOrds
->andWhere('h.findSpotLongitude IS NULL OR h.findSpotLatitude IS NULL');
$doctrineQueryNoCoOrds = $doctrineQueryBuilderNoCoOrds->getQuery();
$noCoOrds = $doctrineQueryNoCoOrds->getArrayResult();
// Add countries to "No CoOrd" results, if present.
foreach ($noCoOrds as &$noCoOrds_hoard) {
if ($noCoOrds_hoard['id']) {
$hoardEntity = $em->getRepository('OxHoardBundle:Hoard')->find($noCoOrds_hoard['id']);
$countries = $hoardEntity->getCountries();
foreach ($countries as $country) {
if (isset($noCoOrds_hoard['country'])) {
$noCoOrds_hoard['country'] .= ", " . $country->getCountry();
}
else {
$noCoOrds_hoard['country'] = ", " . $country->getCountry();
}
}
}
}
}
$doctrineQueryBuilder
->andWhere('h.findSpotLatitude IS NOT NULL')
->andWhere('h.findSpotLongitude IS NOT NULL');
// Add handling of boundaries set for maps.
$boundary = isset($request->query->get('ox_hs')["boundary"]) ?
$request->query->get('ox_hs')["boundary"] :
null;
if ($boundary) {
$doctrineQueryBuilder->andWhere('ST_Contains(ST_GEOMFROMTEXT(\'Polygon((' . $boundary . '))\'), Point(h.findSpotLatitude, h.findSpotLongitude)) = true');
}
$doctrineQuery = $doctrineQueryBuilder->getQuery();
$doctrineQueryAllRows = $doctrineQueryBuilderAllRows->getQuery();
$searchedHoards = $doctrineQuery -> getArrayResult();
//
$minTerminalYear = $initialSliderValues['hoardTerminalYearRangeStart'];
$maxTerminalYear = $initialSliderValues['hoardTerminalYearRangeEnd'];
$termYears = [];
foreach ($searchedHoards as $hoard) {
if (isset($hoard[0]["terminalYear1"])) {
$termYears[] = $hoard[0]["terminalYear1"];
}
}
sort($termYears);
$minTerminalYear = isset($termYears[0]) ?
$termYears[0] :
$minTerminalYear;
$maxTerminalYear = isset($termYears[count($termYears) - 1]) ?
$termYears[count($termYears) - 1] :
$maxTerminalYear;
$allSearchedHoards = $doctrineQueryAllRows->getArrayResult();
if ($search_type == "search-coins") {
$totalPoints = array_reduce($allSearchedHoards, function ($carry, $item) {
if ($item['id'] && $item['findSpotName']) {
$carry += $item['quantity'];
}
return $carry;
});
}
else {
$totalPoints = count($allSearchedHoards);
}
return new JsonResponse(array(
'data' => $searchedHoards,
'terminalYears' => [
'min' => $minTerminalYear,
'max' => $maxTerminalYear,
],
'searchType' => $search_type,
'isAuthenticated' => $isAuthenticated,
'totalPoints' => $totalPoints,
'noCoOrds' => $noCoOrds,
'boundary' => $hasBoundary,
'isCoinMintSearch' => $isCoinMintSearch,
));
}
/**
* Get all coins to use in charts
*
* @param Request $request
* @Route("/coins_chart_ajax", name="coins_chart_get", methods={"GET"})
*/
public function restGetCoinsChart(Request $request, PaginatorInterface $paginator)
{
// call the indexAction with the given request string
$coins = $this->indexAction($request, $paginator, true);
$allCoins = array();
foreach ($coins as $coin) {
$quantity = $coin->getQuantity();
$startingDate = $coin->getStartingDate();
$endingDate = $coin->getEndingDate();
$reigns = $coin->getReigns();
foreach($reigns as $reign) {
if ($startingDate || $endingDate ||
($reign->getId() != 2191 && $reign->getId() != 242)) { // exclude reigns: Uncertain, Republic
array_push($allCoins, array(
'quantity' => $quantity / count($reigns),
'startingDate' => $startingDate,
'endingDate' => $endingDate,
"reignStartDate" => $reign->getStartDate(),
"reignEndDate" => $reign->getEndDate()
));
}
}
}
return new JsonResponse($allCoins);
}
}