Completed
Pull Request — master (#88)
by Jason
02:30
created

Locator_Controller::init()   F

Complexity

Conditions 10
Paths 512

Size

Total Lines 79
Code Lines 42

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 22.5

Importance

Changes 25
Bugs 1 Features 3
Metric Value
c 25
b 1
f 3
dl 0
loc 79
ccs 18
cts 36
cp 0.5
rs 3.8504
cc 10
eloc 42
nc 512
nop 0
crap 22.5

How to fix   Long Method    Complexity   

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
class Locator extends Page
4
{
5
    private static $db = array(
1 ignored issue
show
Unused Code introduced by
The property $db is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
6
        'AutoGeocode' => 'Boolean',
7
        'ModalWindow' => 'Boolean',
8
        'Unit' => 'Enum("m,km","m")',
9
    );
10
11
    private static $many_many = array(
1 ignored issue
show
Unused Code introduced by
The property $many_many is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
12
        'Categories' => 'LocationCategory',
13
    );
14
15
    private static $defaults = array(
1 ignored issue
show
Unused Code introduced by
The property $defaults is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
16
        'AutoGeocode' => true,
17
    );
18
19 1
    private static $singular_name = 'Locator';
1 ignored issue
show
Unused Code introduced by
The property $singular_name is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
20
    private static $plural_name = 'Locators';
1 ignored issue
show
Unused Code introduced by
The property $plural_name is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
21 1
    private static $description = 'Find locations on a map';
1 ignored issue
show
Unused Code introduced by
The property $description is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
22
23
    /**
24 1
     * @return FieldList
25 1
     */
26 1
    public function getCMSFields()
27
    {
28
        $fields = parent::getCMSFields();
29 1
30 1
        // Settings
31
        $fields->addFieldsToTab('Root.Settings', array(
32
            HeaderField::create('DisplayOptions', 'Display Options', 3),
33 1
            OptionsetField::create('Unit', 'Unit of measure', array('m' => 'Miles', 'km' => 'Kilometers')),
34 1
            CheckboxField::create('AutoGeocode', 'Auto Geocode - Automatically filter map results based on user location')
35 1
                ->setDescription('Note: if any locations are set as featured, the auto geocode is automatically disabled.'),
36 1
            CheckboxField::create('ModalWindow', 'Modal Window - Show Map results in a modal window'),
37 1
        ));
38 1
39 1
        // Filter categories
40
        $config = GridFieldConfig_RelationEditor::create();
41 1
        if (class_exists('GridFieldAddExistingSearchButton')) {
42
            $config->removeComponentsByType('GridFieldAddExistingAutocompleter');
43 1
            $config->addComponent(new GridFieldAddExistingSearchButton());
44
        }
45
        $categories = $this->Categories();
46 3
        $categoriesField = GridField::create('Categories', 'Categories', $categories, $config)
47
            ->setDescription('only show locations from the selected category');
48 3
49
            // Filter
50 3
            $fields->addFieldsToTab('Root.Filter', array(
51 3
                HeaderField::create('CategoryOptionsHeader', 'Location Filtering', 3),
52 3
                $categoriesField,
53 3
            ));
54
55
        $this->extend('updateCMSFields', $fields);
56 1
57
        return $fields;
58 1
    }
59
60
    /**
61 1
     * @param array $filter
62
     * @param array $filterAny
63 1
     * @param array $exclude
64
     * @param null $filterByCallback
65
     * @return ArrayList
66
     */
67
    public static function locations(
68
        $filter = array(),
69
        $filterAny = array(),
70
        $exclude = array(),
71
        $filterByCallback = null
72
    ) {
73
        $locationsList = ArrayList::create();
74
75
        // filter by ShowInLocator
76
        $filter['ShowInLocator'] = 1;
77
78
        $locations = Location::get()->filter($filter);
79
80
        if (!empty($filterAny)) {
81
            $locations = $locations->filterAny($filterAny);
82
        }
83
        if (!empty($exclude)) {
84
            $locations = $locations->exclude($exclude);
85
        }
86
87
        if ($filterByCallback !== null && is_callable($filterByCallback)) {
88
            $locations = $locations->filterByCallback($filterByCallback);
89
        }
90
91
        if ($locations->exists()) {
92
            $locationsList->merge($locations);
93
        }
94
95
        return $locationsList;
96
    }
97
98
    /**
99
     * @return DataList
100
     */
101
    public static function getAllCategories()
102
    {
103
        return LocationCategory::get();
104
    }
105
106
    /**
107
     * @param null $id
108
     * @return bool
109
     */
110
    public static function getPageCategories($id = null)
111
    {
112
        if ($id) {
113
            if ($locator = self::get()->byID($id)) {
114
                return $locator->Categories();
115
            }
116
117
            return false;
118
        }
119
120
        return false;
121
    }
122
123
124
}
125
126
class Locator_Controller extends Page_Controller
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
127
{
128
    // allowed actions
129
    private static $allowed_actions = array(
1 ignored issue
show
Unused Code introduced by
The property $allowed_actions is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
130
        'xml',
131
    );
132
133
    // Set Requirements based on input from CMS
134
    public function init()
135
    {
136
        parent::init();
137
138
        $themeDir = SSViewer::get_theme_folder();
139
140
        // google maps api key
141
        $key = Config::inst()->get('GoogleGeocoding', 'google_api_key');
142
143
        $locations = $this->Items($this->request);
144
145
        Requirements::javascript('framework/thirdparty/jquery/jquery.js');
146
        if ($locations) {
147
            Requirements::javascript('http://maps.google.com/maps/api/js?key='.$key);
148
            Requirements::javascript('locator/thirdparty/handlebars/handlebars-v1.3.0.js');
149
            Requirements::javascript('locator/thirdparty/jquery-store-locator/js/jquery.storelocator.js');
150
        }
151
152
        Requirements::css('locator/css/map.css');
153
154
        $featured = ($locations->filter(array('Featured' => 1))->count() > 0) ?
155
            'featuredLocations: true' :
156
            'featuredLocations: false';
157
158
        // map config based on user input in Settings tab
159
        // AutoGeocode or Full Map
160
        $load = ($this->data()->AutoGeocode) ?
161
            'autoGeocode: true, fullMapStart: false,' :
162
            'autoGeocode: false, fullMapStart: true, storeLimit: 1000, maxDistance: true,';
163
164
        $base = Director::baseFolder();
165
        $themePath = $base.'/'.$themeDir;
166
167
        $listTemplatePath = (file_exists($themePath.'/templates/location-list-description.html')) ?
168 1
            $themeDir.'/templates/location-list-description.html' :
169
            'locator/templates/location-list-description.html';
170 1
        $infowindowTemplatePath = (file_exists($themePath.'/templates/infowindow-description.html')) ?
171 1
            $themeDir.'/templates/infowindow-description.html' :
172 1
            'locator/templates/infowindow-description.html';
173 1
174
        // in page or modal
175 1
        $modal = ($this->data()->ModalWindow) ? 'modalWindow: true' : 'modalWindow: false';
176 1
177 1
        $kilometer = ($this->data()->Unit == 'km') ? 'lengthUnit: "km"' : 'lengthUnit: "m"';
178 1
179
        // pass GET variables to xml action
180 1
        $vars = $this->request->getVars();
181
        unset($vars['url']);
182 1
        $url = '';
183
        if (count($vars)) {
184 1
            $url .= '?'.http_build_query($vars);
185
        }
186
        $link = $this->Link().'xml.xml'.$url;
187
188
        // init map
189
        if ($locations) {
190
            Requirements::customScript("
191
                $(function($) {
192 1
                    $('#map-container').storeLocator({
193
                        ".$load."
194 1
                        dataLocation: '".$link."',
195 1
                        listTemplatePath: '".$listTemplatePath."',
196 1
                        infowindowTemplatePath: '".$infowindowTemplatePath."',
197
                        originMarker: true,
198 1
                        ".$modal.',
199
                        '.$featured.",
200
                        slideMap: false,
201 1
                        zoomLevel: 0,
202
                        noForm: true,
203
                        formID: 'Form_LocationSearch',
204
                        inputID: 'Form_LocationSearch_Address',
205
                        categoryID: 'Form_LocationSearch_CategoryID',
206
                        distanceAlert: -1,
207
                        ".$kilometer.'
208
                    });
209
                });
210
            ');
211
        }
212
    }
213
214
    /**
215
     * @param SS_HTTPRequest $request
216
     *
217
     * @return ViewableData_Customised
218
     */
219
    public function index(SS_HTTPRequest $request)
220
    {
221
        $locations = $this->Items($request);
222
223
        return $this->customise(array(
224
            'Locations' => $locations,
225
        ));
226
    }
227
228
    /**
229
     * Return a XML feed of all locations marked "show in locator"
230
     *
231
     * @param SS_HTTPRequest $request
232
     * @return HTMLText
233
     */
234
    public function xml(SS_HTTPRequest $request)
235
    {
236
        $locations = $this->Items($request);
237
238
        return $this->customise(array(
239
            'Locations' => $locations,
240
        ))->renderWith('LocationXML');
241
    }
242
243
    /**
244
     * @param array $searchCriteria
245
     *
246
     * @return mixed
247
     */
248
    public function Items($searchCriteria = array())
249
    {
250
        $request = ($this->request) ? $this->request : $this->parentController->getRequest();
251
        if (empty($searchCriteria)) {
252
            $searchCriteria = $request->requestVars();
0 ignored issues
show
Unused Code introduced by
$searchCriteria is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
253
        }
254
255
        $filter = array();
256
        $filterAny = array();
257
        $exclude = array();
258
259
        // only show locations marked as ShowInLocator
260
        $filter['ShowInLocator'] = 1;
261
262
        // search across all address related fields
263
        $address = ($request->getVar('Address')) ? $request->getVar('Address') : false;
264
        if ($address) {
265
            $filterAny['Address:PartialMatch'] = $address;
266
            $filterAny['Suburb:PartialMatch'] = $address;
267
            $filterAny['State:PartialMatch'] = $address;
268
            $filterAny['Postcode:PartialMatch'] = $address;
269
            $filterAny['Country:PartialMatch'] = $address;
270
        }
271
272
        $category = ($request->getVar('CategoryID')) ? $request->getVar('CategoryID') : false;
273
        if ($category) {
274
            $filter['CategoryID'] = $category;
275
        }
276
277
        $locations = Locator::locations($filter, $filterAny, $exclude);
278
279
        return $locations;
280
    }
281
282
    /**
283
     * LocationSearch form.
284
     *
285
     * Search form for locations, updates map and results list via AJAX
286
     *
287
     * @return Form
288
     */
289
    public function LocationSearch()
290
    {
291
        $fields = FieldList::create(
292
            $address = TextField::create('Address', '')
293
                ->setAttribute('placeholder', 'address or zip code')
294
        );
295
296
        $filterCategories = Locator::getPageCategories($this->ID);
297
        $allCategories = Locator::getAllCategories();
298
299
        if ($allCategories->Count() > 0) {
300
            $categories = ArrayList::create();
301
            if ($filterCategories->Count() > 0) {
0 ignored issues
show
Bug introduced by
The method Count cannot be called on $filterCategories (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
302
                if ($filterCategories->Count() != 1) {
0 ignored issues
show
Bug introduced by
The method Count cannot be called on $filterCategories (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
303
                    $categories = $filterCategories;
304
                }
305
            } else {
306
                $categories = $allCategories;
307
            }
308
309
            if ($categories->count() > 0) {
310
                $fields->push(
311
                    DropdownField::create(
312
                        'CategoryID',
313
                        '',
314
                        $categories->map()
315
                    )->setEmptyString('All Categories'));
316
            }
317
        }
318
319
        $actions = FieldList::create(
320
            FormAction::create('index', 'Search')
321
        );
322
323
        if (class_exists('BootstrapForm')) {
324
            $form = BootstrapForm::create($this, 'LocationSearch', $fields, $actions);
325
        } else {
326
            $form = Form::create($this, 'LocationSearch', $fields, $actions);
327
        }
328
329
        return $form
330
            ->setFormMethod('GET')
331
            ->setFormAction($this->Link())
332
            ->disableSecurityToken()
333
            ->loadDataFrom($this->request->getVars())
334
        ;
335
    }
336
}
337