Source of file LocatorController.php
Size: 10,422 Bytes - Last Modified: 2021-12-24T06:46:21+00:00
/var/www/docs.ssmods.com/process/src/src/pages/LocatorController.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367 | <?php namespace Dynamic\Locator; use Dynamic\SilverStripeGeocoder\DistanceDataExtension; use Dynamic\SilverStripeGeocoder\GoogleGeocoder; use muskie9\DataToArrayList\ORM\DataToArrayListHelper; use SilverStripe\Control\Controller; use SilverStripe\Control\HTTPRequest; use SilverStripe\Core\Config\Config; use SilverStripe\ORM\ArrayList; use SilverStripe\ORM\DataList; use SilverStripe\View\ArrayData; use SilverStripe\View\Requirements; /** * Class LocatorController * * @mixin Locator */ class LocatorController extends \PageController { /** * @var array */ private static $allowed_actions = [ 'xml', 'json', ]; /** * @var array */ private static $base_filter = []; /** * @var array */ private static $base_exclude = [ 'Lat' => 0, 'Lng' => 0, ]; /** * @var array */ private static $base_filter_any = []; /** * @var bool */ private static $bootstrapify = true; /** * ID of map container * * @var string */ private static $map_container = 'map'; /** * class of location list container * * @var string */ private static $list_container = 'loc-list'; /** * GET variable which, if isset, will trigger storeLocator init and return XML * * @var string */ private static $query_trigger = 'action_doFilterLocations'; /** * @var DataList|ArrayList */ protected $locations; /** * Set Requirements based on input from CMS */ public function init() { parent::init(); // prevent init of map if no query $request = Controller::curr()->getRequest(); if (!$this->getTrigger($request)) { return; } $locations = $this->getLocations(); // prevent init of map if there are no locations if (!$locations) { return; } // google maps api key $key = Config::inst()->get(GoogleGeocoder::class, 'map_api_key'); Requirements::javascript('https://maps.google.com/maps/api/js?key=' . $key); $mapSettings = [ 'fullMapStart' => true, 'maxDistance' => true, 'storeLimit' => -1, 'originMarker' => true, 'slideMap' => false, 'distanceAlert' => -1, 'featuredLocations' => false, 'defaultLat' => 0, 'defaultLng' => 0, 'mapSettings' => [ 'zoom' => 12, 'mapTypeId' => 'google.maps.MapTypeId.ROADMAP', 'disableDoubleClickZoom' => true, 'scrollwheel' => false, 'navigationControl' => false, 'draggable' => false ], ]; $mapSettings['listTemplatePath'] = $this->getListTemplate(); $mapSettings['infowindowTemplatePath'] = $this->getInfoWindowTemplate(); $mapSettings['lengthUnit'] = $this->data()->Unit == 'km' ? 'km' : 'm'; $mapSettings['mapID'] = Config::inst()->get(LocatorController::class, 'map_container'); $mapSettings['locationList'] = Config::inst()->get(LocatorController::class, 'list_container'); if ($locations->filter('Featured', true)->count() > 0) { $mapSettings['featuredLocations'] = true; } // map config based on user input in Settings tab $limit = Config::inst()->get(LocatorController::class, 'limit'); if (0 < $limit) { $mapSettings['storeLimit'] = $limit; } if ($coords = $this->getAddressSearchCoords()) { $mapSettings['defaultLat'] = $coords->getField("Lat"); $mapSettings['defaultLat'] = $coords->getField("Lng"); } // pass GET variables to xml action $vars = $this->request->getVars(); unset($vars['url']); $url = ''; if (count($vars)) { $url .= '?' . http_build_query($vars); } $mapSettings['dataLocation'] = Controller::join_links($this->Link(), 'xml.xml', $url); if ($stylePath = $this->getMapStyleJSONPath()) { if ($style = file_get_contents($stylePath)) { $mapSettings['mapSettings']['styles'] = json_decode($style); } } if ($imagePath = $this->getMarkerIcon()) { $mapSettings['markerImg'] = $imagePath; } $this->extend('modifyMapSettings', $mapSettings); $encoded = json_encode($mapSettings, JSON_UNESCAPED_SLASHES); // mapTypeId is a javascript object $encoded = preg_replace('/("mapTypeId"\s*:\s*)"(.+?)"/i', '$1$2', $encoded); $this->extend('modifyMapSettingsEncoded', $encoded); // init map Requirements::customScript(" $(function(){ $('#map-container').storeLocator({$encoded}); }); ", 'jquery-locator'); } /** * @param HTTPRequest $request * * @return bool */ public function getTrigger(HTTPRequest $request = null) { if ($request === null) { $request = $this->getRequest(); } $trigger = $request->getVar(Config::inst()->get(LocatorController::class, 'query_trigger')); return isset($trigger); } /** * @return ArrayList|DataList */ public function getLocations() { if (!$this->locations) { $this->setLocations($this->request); } return $this->locations; } /** * @param HTTPRequest|null $request * * @return $this */ public function setLocations(HTTPRequest $request = null) { if ($request === null) { $request = $this->request; } $filter = $this->config()->get('base_filter'); $categoryVar = $this->data()->config()->get('category_var'); if ($request->getVar($categoryVar)) { $filter['Categories.ID'] = $request->getVar($categoryVar); } else { if ($this->getPageCategories()->exists()) { foreach ($this->getPageCategories() as $category) { $filter['Categories.ID'][] = $category->ID; } } } $this->extend('updateLocatorFilter', $filter, $request); $filterAny = $this->config()->get('base_filter_any'); $this->extend('updateLocatorFilterAny', $filterAny, $request); $exclude = $this->config()->get('base_exclude'); $this->extend('updateLocatorExclude', $exclude, $request); $class = $this->data()->ClassName; $locations = $class::get_locations($filter, $filterAny, $exclude); $locations = DataToArrayListHelper::to_array_list($locations); //allow for adjusting list post possible distance calculation $this->extend('updateLocationList', $locations); if ($locations->canSortBy('Distance')) { $locations = $locations->sort('Distance'); } if ($this->getShowRadius()) { $radiusVar = $this->data()->config()->get('radius_var'); if ($radius = (int)$request->getVar($radiusVar)) { $locations = $locations->filterByCallback(function ($location) use (&$radius) { return $location->Distance <= $radius; }); } } //allow for returning list to be set as $this->extend('updateListType', $locations); $limit = $this->getLimit(); if ($limit > 0) { $locations = $locations->limit($limit); } $this->locations = $locations; return $this; } /** * @return ArrayData|boolean */ public function getAddressSearchCoords() { $addressVar = Config::inst()->get(DistanceDataExtension::class, 'address_var'); if (!$this->request->getVar($addressVar)) { return false; } if (class_exists(GoogleGeocoder::class)) { $geocoder = new GoogleGeocoder($this->request->getVar($addressVar)); $response = $geocoder->getResult(); $lat = $response->getLatitude(); $lng = $response->getLongitude(); return new ArrayData([ "Lat" => $lat, "Lng" => $lng, ]); } } /** * @param HTTPRequest $request * * @return \SilverStripe\View\ViewableData_Customised */ public function index(HTTPRequest $request) { if ($this->getTrigger($request)) { $locations = $this->getLocations(); } else { $locations = ArrayList::create(); } return $this->customise(array( 'Locations' => $locations, )); } /** * Renders locations in xml format * * @return \SilverStripe\ORM\FieldType\DBHTMLText */ public function xml() { $this->getResponse()->addHeader("Content-Type", "application/xml"); $data = new ArrayData(array( "Locations" => $this->getLocations(), "AddressCoords" => $this->getAddressSearchCoords(), )); return $data->renderWith('Dynamic/Locator/Data/XML'); } /** * Renders locations in json format * * @return \SilverStripe\ORM\FieldType\DBHTMLText */ public function json() { $this->getResponse()->addHeader("Content-Type", "application/json"); $data = new ArrayData(array( "Locations" => $this->getLocations(), "AddressCoords" => $this->getAddressSearchCoords(), )); return $data->renderWith('Dynamic/Locator/Data/JSON'); } /** * LocationSearch form. * * Search form for locations, updates map and results list via AJAX * * @return \SilverStripe\Forms\Form */ public function LocationSearch() { $form = LocatorForm::create($this, 'LocationSearch'); if (class_exists(BootstrapForm::class) && $this->config()->get('bootstrapify')) { $form->Fields()->bootstrapify(); $form->Actions()->bootstrapify(); } return $form ->setFormMethod('GET') ->setFormAction($this->Link()) ->disableSecurityToken() ->loadDataFrom($this->request->getVars()); } } |