Passed
Push — enhancement/more-config-option... ( e4871a...997483 )
by Matthew
03:47 queued 42s
created

LocatorController::setLocations()   B

Complexity

Conditions 9
Paths 72

Size

Total Lines 59
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 32
c 3
b 0
f 0
dl 0
loc 59
rs 8.0555
cc 9
nc 72
nop 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Dynamic\Locator;
4
5
use Dynamic\SilverStripeGeocoder\DistanceDataExtension;
6
use Dynamic\SilverStripeGeocoder\GoogleGeocoder;
7
use muskie9\DataToArrayList\ORM\DataToArrayListHelper;
8
use SilverStripe\Control\Controller;
9
use SilverStripe\Control\HTTPRequest;
10
use SilverStripe\Core\Config\Config;
11
use SilverStripe\ORM\ArrayList;
12
use SilverStripe\ORM\DataList;
13
use SilverStripe\View\ArrayData;
14
use SilverStripe\View\Requirements;
15
16
/**
17
 * Class LocatorController
18
 *
19
 * @mixin Locator
20
 */
21
class LocatorController extends \PageController
22
{
23
    /**
24
     * @var array
25
     */
26
    private static $allowed_actions = [
0 ignored issues
show
introduced by
The private property $allowed_actions is not used, and could be removed.
Loading history...
27
        'xml',
28
        'json',
29
    ];
30
31
    /**
32
     * @var array
33
     */
34
    private static $base_filter = [];
0 ignored issues
show
introduced by
The private property $base_filter is not used, and could be removed.
Loading history...
35
36
    /**
37
     * @var array
38
     */
39
    private static $base_exclude = [
0 ignored issues
show
introduced by
The private property $base_exclude is not used, and could be removed.
Loading history...
40
        'Lat' => 0,
41
        'Lng' => 0,
42
    ];
43
44
    /**
45
     * @var array
46
     */
47
    private static $base_filter_any = [];
0 ignored issues
show
introduced by
The private property $base_filter_any is not used, and could be removed.
Loading history...
48
49
    /**
50
     * @var bool
51
     */
52
    private static $bootstrapify = true;
0 ignored issues
show
introduced by
The private property $bootstrapify is not used, and could be removed.
Loading history...
53
54
    /**
55
     * ID of map container
56
     *
57
     * @var string
58
     */
59
    private static $map_container = 'map';
0 ignored issues
show
introduced by
The private property $map_container is not used, and could be removed.
Loading history...
60
61
    /**
62
     * class of location list container
63
     *
64
     * @var string
65
     */
66
    private static $list_container = 'loc-list';
0 ignored issues
show
introduced by
The private property $list_container is not used, and could be removed.
Loading history...
67
68
    /**
69
     * The zoom level of the map
70
     * @var int
71
     */
72
    private static $zoom = 12;
0 ignored issues
show
introduced by
The private property $zoom is not used, and could be removed.
Loading history...
73
74
    /**
75
     * The minimum zoom level the map can have
76
     * @var int
77
     */
78
    private static $min_zoom = 6;
0 ignored issues
show
introduced by
The private property $min_zoom is not used, and could be removed.
Loading history...
79
80
    /**
81
     * The maximum zoom level the map can have
82
     * @var int
83
     */
84
    private static $max_zoom = 18;
0 ignored issues
show
introduced by
The private property $max_zoom is not used, and could be removed.
Loading history...
85
86
    /**
87
     * If double clicking the map should not zoom
88
     * @var bool
89
     */
90
    private static $disable_double_click_zoom = true;
0 ignored issues
show
introduced by
The private property $disable_double_click_zoom is not used, and could be removed.
Loading history...
91
92
    /**
93
     * If the map should disable zoom by scrollwheel
94
     * @var bool
95
     */
96
    private static $scrollwheel = false;
0 ignored issues
show
introduced by
The private property $scrollwheel is not used, and could be removed.
Loading history...
97
98
    /**
99
     * If the map should show naviagtion controls
100
     * @var bool
101
     */
102
    private static $navigation_control = false;
0 ignored issues
show
introduced by
The private property $navigation_control is not used, and could be removed.
Loading history...
103
104
    /**
105
     * @var bool
106
     */
107
    private static $draggable = false;
0 ignored issues
show
introduced by
The private property $draggable is not used, and could be removed.
Loading history...
108
109
    /**
110
     * @var DataList|ArrayList
111
     */
112
    protected $locations;
113
114
    /**
115
     * Set Requirements based on input from CMS
116
     */
117
    public function init()
118
    {
119
        parent::init();
120
121
        // prevent init of map if no query
122
        $request = Controller::curr()->getRequest();
123
        if (!$this->getTrigger($request)) {
124
            return;
125
        }
126
127
        $locations = $this->getLocations();
128
129
        // prevent init of map if there are no locations
130
        if (!$locations) {
131
            return;
132
        }
133
134
        // google maps api key
135
        $key = Config::inst()->get(GoogleGeocoder::class, 'map_api_key');
136
        Requirements::javascript('https://maps.google.com/maps/api/js?key=' . $key);
137
138
        $mapSettings = [
139
            'fullMapStart' => true,
140
            'maxDistance' => true,
141
            'storeLimit' => -1,
142
            'originMarker' => true,
143
            'slideMap' => false,
144
            'distanceAlert' => -1,
145
            'featuredLocations' => false,
146
            'defaultLat' => 0,
147
            'defaultLng' => 0,
148
            'mapSettings' => [
149
                'zoom' => Config::inst()->get(LocatorController::class, 'zoom'),
150
                'minZoom' => Config::inst()->get(LocatorController::class, 'min_zoom'),
151
                'maxZoom' => Config::inst()->get(LocatorController::class, 'max_zoom'),
152
                'mapTypeId' => 'google.maps.MapTypeId.ROADMAP',
153
                'disableDoubleClickZoom' => Config::inst()->get(LocatorController::class, 'disable_double_click_zoom'),
154
                'scrollwheel' => Config::inst()->get(LocatorController::class, 'scrollwheel'),
155
                'navigationControl' => Config::inst()->get(LocatorController::class, 'navigation_control'),
156
                'draggable' => Config::inst()->get(LocatorController::class, 'draggable'),
157
            ],
158
        ];
159
160
        $mapSettings['listTemplatePath'] = $this->getListTemplate();
0 ignored issues
show
Bug introduced by
The method getListTemplate() does not exist on Dynamic\Locator\LocatorController. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

160
        /** @scrutinizer ignore-call */ 
161
        $mapSettings['listTemplatePath'] = $this->getListTemplate();
Loading history...
161
        $mapSettings['infowindowTemplatePath'] = $this->getInfoWindowTemplate();
0 ignored issues
show
Bug introduced by
The method getInfoWindowTemplate() does not exist on Dynamic\Locator\LocatorController. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

161
        /** @scrutinizer ignore-call */ 
162
        $mapSettings['infowindowTemplatePath'] = $this->getInfoWindowTemplate();
Loading history...
162
        $mapSettings['lengthUnit'] = $this->data()->Unit == 'km' ? 'km' : 'm';
163
        $mapSettings['mapID'] = Config::inst()->get(LocatorController::class, 'map_container');
164
        $mapSettings['locationList'] = Config::inst()->get(LocatorController::class, 'list_container');
165
166
        if ($locations->filter('Featured', true)->count() > 0) {
167
            $mapSettings['featuredLocations'] = true;
168
        }
169
170
        // map config based on user input in Settings tab
171
        $limit = Config::inst()->get(LocatorController::class, 'limit');
172
        if (0 < $limit) {
173
            $mapSettings['storeLimit'] = $limit;
174
        }
175
176
        if ($coords = $this->getAddressSearchCoords()) {
177
            $mapSettings['defaultLat'] = $coords->getField("Lat");
178
            $mapSettings['defaultLat'] = $coords->getField("Lng");
179
        }
180
181
        // pass GET variables to xml action
182
        $vars = $this->request->getVars();
183
        unset($vars['url']);
184
        $url = '';
185
        if (count($vars)) {
186
            $url .= '?' . http_build_query($vars);
187
        }
188
        $mapSettings['dataLocation'] = Controller::join_links($this->Link(), 'xml.xml', $url);
189
190
        if ($stylePath = $this->getMapStyleJSONPath()) {
0 ignored issues
show
Bug introduced by
The method getMapStyleJSONPath() does not exist on Dynamic\Locator\LocatorController. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

190
        if ($stylePath = $this->/** @scrutinizer ignore-call */ getMapStyleJSONPath()) {
Loading history...
191
            if ($style = file_get_contents($stylePath)) {
192
                $mapSettings['mapSettings']['styles'] = json_decode($style);
193
            }
194
        }
195
196
        if ($imagePath = $this->getMarkerIcon()) {
0 ignored issues
show
Bug introduced by
The method getMarkerIcon() does not exist on Dynamic\Locator\LocatorController. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

196
        if ($imagePath = $this->/** @scrutinizer ignore-call */ getMarkerIcon()) {
Loading history...
197
            $mapSettings['markerImg'] = $imagePath;
198
        }
199
200
        $this->extend('modifyMapSettings', $mapSettings);
201
202
        $encoded = json_encode($mapSettings, JSON_UNESCAPED_SLASHES);
203
        // mapTypeId is a javascript object
204
        $encoded = preg_replace('/("mapTypeId"\s*:\s*)"(.+?)"/i', '$1$2', $encoded);
205
206
        $this->extend('modifyMapSettingsEncoded', $encoded);
207
        // init map
208
        Requirements::customScript("
209
                $(function(){
210
                    $('#map-container').storeLocator({$encoded});
211
                });
212
            ", 'jquery-locator');
213
    }
214
215
    /**
216
     * @param HTTPRequest $request
217
     *
218
     * @return bool
219
     */
220
    public function getTrigger(HTTPRequest $request = null)
221
    {
222
        if ($request === null) {
223
            $request = $this->getRequest();
0 ignored issues
show
Unused Code introduced by
The assignment to $request is dead and can be removed.
Loading history...
224
        }
225
        return !empty($this->getRequest()->getVars()) || $this->data()->ResultsOnLoad;
226
    }
227
228
    /**
229
     * @return ArrayList|DataList
230
     */
231
    public function getLocations()
232
    {
233
        if (!$this->locations) {
234
            $this->setLocations($this->request);
235
        }
236
237
        return $this->locations;
238
    }
239
240
    /**
241
     * @param HTTPRequest|null $request
242
     *
243
     * @return $this
244
     */
245
    public function setLocations(HTTPRequest $request = null)
246
    {
247
248
        if ($request === null) {
249
            $request = $this->request;
250
        }
251
        $filter = $this->config()->get('base_filter');
252
253
        $categoryVar = $this->data()->config()->get('category_var');
254
        if ($request->getVar($categoryVar)) {
255
            $filter['Categories.ID'] = $request->getVar($categoryVar);
256
        } else {
257
            if ($this->getPageCategories()->exists()) {
0 ignored issues
show
Bug introduced by
The method getPageCategories() does not exist on Dynamic\Locator\LocatorController. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

257
            if ($this->/** @scrutinizer ignore-call */ getPageCategories()->exists()) {
Loading history...
258
                foreach ($this->getPageCategories() as $category) {
259
                    $filter['Categories.ID'][] = $category->ID;
260
                }
261
            }
262
        }
263
264
        $this->extend('updateLocatorFilter', $filter, $request);
265
266
        $filterAny = $this->config()->get('base_filter_any');
267
        $this->extend('updateLocatorFilterAny', $filterAny, $request);
268
269
        $exclude = $this->config()->get('base_exclude');
270
        $this->extend('updateLocatorExclude', $exclude, $request);
271
272
        $class = $this->data()->ClassName;
273
        $locations = $class::get_locations($filter, $filterAny, $exclude);
274
        $locations = DataToArrayListHelper::to_array_list($locations);
275
276
        //allow for adjusting list post possible distance calculation
277
        $this->extend('updateLocationList', $locations);
278
279
        if ($locations->canSortBy('Distance')) {
280
            $locations = $locations->sort('Distance');
281
        }
282
283
        if ($this->getShowRadius()) {
0 ignored issues
show
Bug introduced by
The method getShowRadius() does not exist on Dynamic\Locator\LocatorController. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

283
        if ($this->/** @scrutinizer ignore-call */ getShowRadius()) {
Loading history...
284
            $radiusVar = $this->data()->config()->get('radius_var');
285
286
            if ($radius = (int)$request->getVar($radiusVar)) {
287
                $locations = $locations->filterByCallback(function ($location) use (&$radius) {
288
                    return $location->Distance <= $radius;
289
                });
290
            }
291
        }
292
293
        //allow for returning list to be set as
294
        $this->extend('updateListType', $locations);
295
296
        $limit = $this->getLimit();
0 ignored issues
show
Bug introduced by
The method getLimit() does not exist on Dynamic\Locator\LocatorController. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

296
        /** @scrutinizer ignore-call */ 
297
        $limit = $this->getLimit();
Loading history...
297
        if ($limit > 0) {
298
            $locations = $locations->limit($limit);
299
        }
300
301
        $this->locations = $locations;
302
303
        return $this;
304
    }
305
306
    /**
307
     * @return ArrayData|boolean
308
     */
309
    public function getAddressSearchCoords()
310
    {
311
        $addressVar = Config::inst()->get(DistanceDataExtension::class, 'address_var');
312
        if (!$this->request->getVar($addressVar)) {
313
            return false;
314
        }
315
        if (class_exists(GoogleGeocoder::class)) {
316
            $geocoder = new GoogleGeocoder($this->request->getVar($addressVar));
317
            $response = $geocoder->getResult();
318
            $lat = $response->getLatitude();
319
            $lng = $response->getLongitude();
320
321
            return new ArrayData([
322
                "Lat" => $lat,
323
                "Lng" => $lng,
324
            ]);
325
        }
326
    }
327
328
    /**
329
     * @param HTTPRequest $request
330
     *
331
     * @return \SilverStripe\View\ViewableData_Customised
332
     */
333
    public function index(HTTPRequest $request)
334
    {
335
        if ($this->getTrigger($request)) {
336
            $locations = $this->getLocations();
337
        } else {
338
            $locations = ArrayList::create();
339
        }
340
341
        return $this->customise(array(
342
            'Locations' => $locations,
343
        ));
344
    }
345
346
    /**
347
     * Renders locations in xml format
348
     *
349
     * @return \SilverStripe\ORM\FieldType\DBHTMLText
350
     */
351
    public function xml()
352
    {
353
        $this->getResponse()->addHeader("Content-Type", "application/xml");
354
        $data = new ArrayData(array(
355
            "Locations" => $this->getLocations(),
356
            "AddressCoords" => $this->getAddressSearchCoords(),
357
        ));
358
359
        return $data->renderWith('Dynamic/Locator/Data/XML');
360
    }
361
362
    /**
363
     * Renders locations in json format
364
     *
365
     * @return \SilverStripe\ORM\FieldType\DBHTMLText
366
     */
367
    public function json()
368
    {
369
        $this->getResponse()->addHeader("Content-Type", "application/json");
370
        $data = new ArrayData(array(
371
            "Locations" => $this->getLocations(),
372
            "AddressCoords" => $this->getAddressSearchCoords(),
373
        ));
374
375
        return $data->renderWith('Dynamic/Locator/Data/JSON');
376
    }
377
378
    /**
379
     * LocationSearch form.
380
     *
381
     * Search form for locations, updates map and results list via AJAX
382
     *
383
     * @return \SilverStripe\Forms\Form
384
     */
385
    public function LocationSearch()
386
    {
387
388
        $form = LocatorForm::create($this, 'LocationSearch');
389
        if (class_exists(BootstrapForm::class) && $this->config()->get('bootstrapify')) {
0 ignored issues
show
Bug introduced by
The type Dynamic\Locator\BootstrapForm was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
390
            $form->Fields()->bootstrapify();
391
            $form->Actions()->bootstrapify();
392
        }
393
394
        return $form
395
            ->setFormMethod('GET')
396
            ->setFormAction($this->Link())
397
            ->disableSecurityToken()
398
            ->loadDataFrom($this->request->getVars());
399
    }
400
}
401