These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /** |
||
4 | * Class Locator |
||
5 | * |
||
6 | * @property bool $AutoGeocode |
||
7 | * @property bool $ModalWindow |
||
8 | * @property string $Unit |
||
9 | * @method Categories|ManyManyList $Categories |
||
10 | */ |
||
11 | class Locator extends Page |
||
12 | { |
||
13 | |||
14 | /** |
||
15 | * @var array |
||
16 | */ |
||
17 | private static $db = array( |
||
18 | 'AutoGeocode' => 'Boolean', |
||
19 | 1 | 'ModalWindow' => 'Boolean', |
|
20 | 'Unit' => 'Enum("m,km","m")', |
||
21 | 1 | ); |
|
22 | |||
23 | /** |
||
24 | 1 | * @var array |
|
25 | 1 | */ |
|
26 | 1 | private static $many_many = array( |
|
27 | 'Categories' => 'LocationCategory', |
||
28 | ); |
||
29 | 1 | ||
30 | 1 | /** |
|
31 | * @var array |
||
32 | */ |
||
33 | 1 | private static $defaults = array( |
|
34 | 1 | 'AutoGeocode' => true, |
|
35 | 1 | ); |
|
36 | 1 | ||
37 | 1 | /** |
|
38 | 1 | * @var string |
|
39 | 1 | */ |
|
40 | private static $singular_name = 'Locator'; |
||
41 | 1 | /** |
|
42 | * @var string |
||
43 | 1 | */ |
|
44 | private static $plural_name = 'Locators'; |
||
45 | /** |
||
46 | 3 | * @var string |
|
47 | */ |
||
48 | 3 | private static $description = 'Find locations on a map'; |
|
49 | |||
50 | 3 | /** |
|
51 | 3 | * @return FieldList |
|
52 | 3 | */ |
|
53 | 3 | public function getCMSFields() |
|
54 | { |
||
55 | $fields = parent::getCMSFields(); |
||
56 | 1 | ||
57 | // Settings |
||
58 | 1 | $fields->addFieldsToTab('Root.Settings', array( |
|
59 | HeaderField::create('DisplayOptions', 'Display Options', 3), |
||
60 | OptionsetField::create('Unit', 'Unit of measure', array('m' => 'Miles', 'km' => 'Kilometers')), |
||
61 | 1 | CheckboxField::create('AutoGeocode', 'Auto Geocode - Automatically filter map results based on user location') |
|
62 | ->setDescription('Note: if any locations are set as featured, the auto geocode is automatically disabled.'), |
||
63 | 1 | CheckboxField::create('ModalWindow', 'Modal Window - Show Map results in a modal window'), |
|
64 | )); |
||
65 | |||
66 | // Filter categories |
||
67 | $config = GridFieldConfig_RelationEditor::create(); |
||
68 | if (class_exists('GridFieldAddExistingSearchButton')) { |
||
69 | $config->removeComponentsByType('GridFieldAddExistingAutocompleter'); |
||
70 | $config->addComponent(new GridFieldAddExistingSearchButton()); |
||
71 | } |
||
72 | $categories = $this->Categories(); |
||
73 | $categoriesField = GridField::create('Categories', 'Categories', $categories, $config) |
||
74 | ->setDescription('only show locations from the selected category'); |
||
75 | |||
76 | // Filter |
||
77 | $fields->addFieldsToTab('Root.Filter', array( |
||
78 | HeaderField::create('CategoryOptionsHeader', 'Location Filtering', 3), |
||
79 | $categoriesField, |
||
80 | )); |
||
81 | |||
82 | $this->extend('updateCMSFields', $fields); |
||
83 | |||
84 | return $fields; |
||
85 | } |
||
86 | |||
87 | /** |
||
88 | * @param array $filter |
||
89 | * @param array $filterAny |
||
90 | * @param array $exclude |
||
91 | * @param null $filterByCallback |
||
92 | * @return ArrayList |
||
93 | */ |
||
94 | public static function locations( |
||
95 | $filter = array(), |
||
96 | $filterAny = array(), |
||
97 | $exclude = array(), |
||
98 | $filterByCallback = null |
||
99 | ) |
||
100 | { |
||
101 | $locationsList = ArrayList::create(); |
||
102 | |||
103 | // filter by ShowInLocator |
||
104 | $filter['ShowInLocator'] = 1; |
||
105 | |||
106 | $locations = Location::get()->filter($filter); |
||
107 | |||
108 | if (!empty($filterAny)) { |
||
109 | $locations = $locations->filterAny($filterAny); |
||
110 | } |
||
111 | if (!empty($exclude)) { |
||
112 | $locations = $locations->exclude($exclude); |
||
113 | } |
||
114 | |||
115 | if ($filterByCallback !== null && is_callable($filterByCallback)) { |
||
116 | $locations = $locations->filterByCallback($filterByCallback); |
||
117 | } |
||
118 | |||
119 | if ($locations->exists()) { |
||
120 | $locationsList->merge($locations); |
||
121 | } |
||
122 | |||
123 | return $locationsList; |
||
124 | } |
||
125 | |||
126 | /** |
||
127 | * @return DataList |
||
128 | */ |
||
129 | public static function getAllCategories() |
||
130 | { |
||
131 | return LocationCategory::get(); |
||
132 | } |
||
133 | |||
134 | /** |
||
135 | * @param null $id |
||
136 | * @return bool |
||
137 | */ |
||
138 | public static function getPageCategories($id = null) |
||
139 | { |
||
140 | if ($id) { |
||
141 | if ($locator = self::get()->byID($id)) { |
||
142 | return $locator->Categories(); |
||
143 | } |
||
144 | |||
145 | return false; |
||
146 | } |
||
147 | |||
148 | return false; |
||
149 | } |
||
150 | |||
151 | |||
152 | } |
||
153 | |||
154 | /** |
||
155 | * Class Locator_Controller |
||
156 | */ |
||
157 | class Locator_Controller extends Page_Controller |
||
158 | { |
||
159 | /** |
||
160 | * @var array |
||
161 | */ |
||
162 | private static $allowed_actions = array( |
||
163 | 'xml', |
||
164 | ); |
||
165 | |||
166 | /** |
||
167 | * Set Requirements based on input from CMS |
||
168 | 1 | */ |
|
169 | public function init() |
||
170 | 1 | { |
|
171 | 1 | parent::init(); |
|
172 | 1 | ||
173 | 1 | $themeDir = SSViewer::get_theme_folder(); |
|
174 | |||
175 | 1 | // google maps api key |
|
176 | 1 | $key = Config::inst()->get('GoogleGeocoding', 'google_api_key'); |
|
177 | 1 | ||
178 | 1 | $locations = $this->Items($this->request); |
|
179 | |||
180 | 1 | Requirements::javascript('framework/thirdparty/jquery/jquery.js'); |
|
181 | if ($locations) { |
||
182 | 1 | Requirements::javascript('http://maps.google.com/maps/api/js?key=' . $key); |
|
183 | Requirements::javascript('locator/thirdparty/handlebars/handlebars-v1.3.0.js'); |
||
184 | 1 | Requirements::javascript('locator/thirdparty/jquery-store-locator/js/jquery.storelocator.js'); |
|
185 | } |
||
186 | |||
187 | Requirements::css('locator/css/map.css'); |
||
188 | |||
189 | $featuredInList = ($locations->filter('Featured', true)->count() > 0); |
||
190 | |||
191 | $featured = $featuredInList |
||
192 | 1 | ? 'featuredLocations: true' |
|
193 | : 'featuredLocations: false'; |
||
194 | 1 | ||
195 | 1 | // map config based on user input in Settings tab |
|
196 | 1 | // AutoGeocode or Full Map |
|
197 | if ($this->data()->AutoGeocode) { |
||
198 | 1 | $load = $featuredInList |
|
199 | ? 'autoGeocode: false, fullMapStart: true, storeLimit: 1000, maxDistance: true,' |
||
200 | : 'autoGeocode: true, fullMapStart: false,'; |
||
201 | 1 | } else { |
|
202 | $load = 'autoGeocode: false, fullMapStart: true, storeLimit: 1000, maxDistance: true,'; |
||
203 | } |
||
204 | |||
205 | /*$load = ($this->data()->AutoGeocode) ? |
||
0 ignored issues
–
show
|
|||
206 | 'autoGeocode: true, fullMapStart: false,' : |
||
207 | 'autoGeocode: false, fullMapStart: true, storeLimit: 1000, maxDistance: true,';*/ |
||
208 | |||
209 | $base = Director::baseFolder(); |
||
210 | $themePath = $base . '/' . $themeDir; |
||
211 | |||
212 | $listTemplatePath = (file_exists($themePath . '/templates/location-list-description.html')) ? |
||
213 | $themeDir . '/templates/location-list-description.html' : |
||
214 | 'locator/templates/location-list-description.html'; |
||
215 | $infowindowTemplatePath = (file_exists($themePath . '/templates/infowindow-description.html')) ? |
||
216 | $themeDir . '/templates/infowindow-description.html' : |
||
217 | 'locator/templates/infowindow-description.html'; |
||
218 | |||
219 | // in page or modal |
||
220 | $modal = ($this->data()->ModalWindow) ? 'modalWindow: true' : 'modalWindow: false'; |
||
221 | |||
222 | $kilometer = ($this->data()->Unit == 'km') ? 'lengthUnit: "km"' : 'lengthUnit: "m"'; |
||
223 | |||
224 | // pass GET variables to xml action |
||
225 | $vars = $this->request->getVars(); |
||
226 | unset($vars['url']); |
||
227 | unset($vars['action_index']); |
||
228 | $url = ''; |
||
229 | if (count($vars)) { |
||
230 | $url .= '?' . http_build_query($vars); |
||
231 | } |
||
232 | $link = $this->Link() . 'xml.xml' . $url; |
||
233 | |||
234 | // init map |
||
235 | if ($locations) { |
||
236 | Requirements::customScript(" |
||
237 | $(function($) { |
||
238 | $('#map-container').storeLocator({ |
||
239 | " . $load . " |
||
240 | dataLocation: '" . $link . "', |
||
241 | listTemplatePath: '" . $listTemplatePath . "', |
||
242 | infowindowTemplatePath: '" . $infowindowTemplatePath . "', |
||
243 | originMarker: true, |
||
244 | " . $modal . ', |
||
245 | ' . $featured . ", |
||
246 | slideMap: false, |
||
247 | zoomLevel: 0, |
||
248 | noForm: true, |
||
249 | formID: 'Form_LocationSearch', |
||
250 | inputID: 'Form_LocationSearch_Address', |
||
251 | categoryID: 'Form_LocationSearch_category', |
||
252 | distanceAlert: -1, |
||
253 | " . $kilometer . ' |
||
254 | }); |
||
255 | }); |
||
256 | '); |
||
257 | } |
||
258 | } |
||
259 | |||
260 | /** |
||
261 | * @param SS_HTTPRequest $request |
||
262 | * |
||
263 | * @return ViewableData_Customised |
||
264 | */ |
||
265 | public function index(SS_HTTPRequest $request) |
||
266 | { |
||
267 | $locations = $this->Items($request); |
||
268 | |||
269 | return $this->customise(array( |
||
270 | 'Locations' => $locations, |
||
271 | )); |
||
272 | } |
||
273 | |||
274 | /** |
||
275 | * Return a XML feed of all locations marked "show in locator" |
||
276 | * |
||
277 | * @param SS_HTTPRequest $request |
||
278 | * @return HTMLText |
||
279 | */ |
||
280 | public function xml(SS_HTTPRequest $request) |
||
281 | { |
||
282 | $locations = $this->Items($request); |
||
283 | |||
284 | return $this->customise(array( |
||
285 | 'Locations' => $locations, |
||
286 | ))->renderWith('LocationXML'); |
||
287 | } |
||
288 | |||
289 | /** |
||
290 | * @param SS_HTTPRequest $request |
||
291 | * |
||
292 | * @return ArrayList |
||
293 | */ |
||
294 | public function Items(SS_HTTPRequest $request) |
||
295 | { |
||
296 | $request = ($request) ? $request : $this->request; |
||
297 | |||
298 | $filter = array(); |
||
299 | $filterAny = array(); |
||
300 | $exclude = ['Lat' => 0.00000, 'Lng' => 0.00000]; |
||
301 | |||
302 | // only show locations marked as ShowInLocator |
||
303 | $filter['ShowInLocator'] = 1; |
||
304 | |||
305 | // search across all address related fields |
||
306 | $address = ($request->getVar('Address')) ? $request->getVar('Address') : false; |
||
307 | if ($address && $this->data()->AutoGeocode == 0) { |
||
308 | $filterAny['Address:PartialMatch'] = $address; |
||
309 | $filterAny['Suburb:PartialMatch'] = $address; |
||
310 | $filterAny['State:PartialMatch'] = $address; |
||
311 | $filterAny['Postcode:PartialMatch'] = $address; |
||
312 | $filterAny['Country:PartialMatch'] = $address; |
||
313 | } else { |
||
314 | unset($filter['Address']); |
||
315 | } |
||
316 | |||
317 | // search for category from form, else categories from Locator |
||
318 | $category = ($request->getVar('CategoryID')) ? $request->getVar('CategoryID') : false; |
||
319 | if ($category) { |
||
320 | $filter['CategoryID:ExactMatch'] = $category; |
||
321 | } elseif ($this->Categories()->exists()) { |
||
322 | $categories = $this->Categories(); |
||
323 | $categoryArray = array(); |
||
324 | foreach ($categories as $category) { |
||
325 | array_push($categoryArray, $category->ID); |
||
326 | } |
||
327 | $filter['CategoryID'] = $categoryArray; |
||
328 | } |
||
329 | |||
330 | $locations = Locator::locations($filter, $filterAny, $exclude); |
||
331 | |||
332 | return $locations; |
||
333 | } |
||
334 | |||
335 | /** |
||
336 | * LocationSearch form. |
||
337 | * |
||
338 | * Search form for locations, updates map and results list via AJAX |
||
339 | * |
||
340 | * @return Form |
||
341 | */ |
||
342 | public function LocationSearch() |
||
343 | { |
||
344 | $fields = FieldList::create( |
||
345 | $address = TextField::create('Address', '') |
||
346 | ->setAttribute('placeholder', 'address or zip code') |
||
347 | ); |
||
348 | |||
349 | $filterCategories = Locator::getPageCategories($this->ID); |
||
350 | $allCategories = Locator::getAllCategories(); |
||
351 | |||
352 | if ($allCategories->Count() > 0) { |
||
353 | $categories = ArrayList::create(); |
||
354 | if ($filterCategories->Count() > 0) { |
||
355 | if ($filterCategories->Count() != 1) { |
||
356 | $categories = $filterCategories; |
||
357 | } |
||
358 | } else { |
||
359 | $categories = $allCategories; |
||
360 | } |
||
361 | |||
362 | if ($categories->count() > 0) { |
||
363 | $fields->push( |
||
364 | DropdownField::create( |
||
365 | 'CategoryID', |
||
366 | '', |
||
367 | $categories->map() |
||
368 | )->setEmptyString('All Categories')); |
||
369 | } |
||
370 | } |
||
371 | |||
372 | $actions = FieldList::create( |
||
373 | FormAction::create('index', 'Search') |
||
374 | ); |
||
375 | |||
376 | if (class_exists('BootstrapForm')) { |
||
377 | $form = BootstrapForm::create($this, 'LocationSearch', $fields, $actions); |
||
378 | } else { |
||
379 | $form = Form::create($this, 'LocationSearch', $fields, $actions); |
||
380 | } |
||
381 | |||
382 | return $form |
||
383 | ->setFormMethod('GET') |
||
384 | ->setFormAction($this->Link()) |
||
385 | ->disableSecurityToken() |
||
386 | ->loadDataFrom($this->request->getVars()); |
||
387 | } |
||
388 | |||
389 | } |
||
390 |
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.