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

Locator_Controller::LocationSearch()   C

Complexity

Conditions 7
Paths 5

Size

Total Lines 36
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 7
Bugs 0 Features 0
Metric Value
c 7
b 0
f 0
dl 0
loc 36
ccs 0
cts 0
cp 0
rs 6.7272
cc 7
eloc 22
nc 5
nop 0
crap 56
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
    public function getCMSFields()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
24 1
    {
25 1
        $fields = parent::getCMSFields();
26 1
27
        // Settings
28
        $fields->addFieldsToTab('Root.Settings', array(
29 1
            HeaderField::create('DisplayOptions', 'Display Options', 3),
30 1
            OptionsetField::create('Unit', 'Unit of measure', array('m' => 'Miles', 'km' => 'Kilometers')),
31
            CheckboxField::create('AutoGeocode', 'Auto Geocode - Automatically filter map results based on user location')
32
                ->setDescription('Note: if any locations are set as featured, the auto geocode is automatically disabled.'),
33 1
            CheckboxField::create('ModalWindow', 'Modal Window - Show Map results in a modal window'),
34 1
        ));
35 1
36 1
        // Filter categories
37 1
        $config = GridFieldConfig_RelationEditor::create();
38 1
        if (class_exists('GridFieldAddExistingSearchButton')) {
39 1
            $config->removeComponentsByType('GridFieldAddExistingAutocompleter');
40
            $config->addComponent(new GridFieldAddExistingSearchButton());
41 1
        }
42
        $categories = $this->Categories();
43 1
        $categoriesField = GridField::create('Categories', 'Categories', $categories, $config)
44
            ->setDescription('only show locations from the selected category');
45
46 3
            // Filter
47
            $fields->addFieldsToTab('Root.Filter', array(
48 3
                HeaderField::create('CategoryOptionsHeader', 'Location Filtering', 3),
49
                $categoriesField,
50 3
            ));
51 3
52 3
        $this->extend('updateCMSFields', $fields);
53 3
54
        return $fields;
55
    }
56 1
57
    public static function getLocations($filter = array(), $exclude = array(), $filterAny = array())
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
58 1
    {
59
        $filter['ShowInLocator'] = true;
60
        $exclude['Lat'] = 0;
61 1
62
        $Locations = Location::get()->exclude($exclude)->filter($filter)->filterAny($filterAny);
63 1
64
        return $Locations;
65
    }
66
67
    public function getAreLocations()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
68
    {
69
        return self::getLocations();
70
    }
71
72
    public function getAllCategories()
73
    {
74
        return LocationCategory::get();
75
    }
76
77
    public static function getPageCategories($id = null)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
78
    {
79
        if ($id) {
80
            if ($locator = self::get()->byID($id)) {
81
                return $locator->Categories();
82
            }
83
84
            return false;
85
        }
86
87
        return false;
88
    }
89
}
90
91
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...
92
{
93
    // allowed actions
94
    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...
95
        'xml',
96
        'LocationSearch',
97
    );
98
99
    // Set Requirements based on input from CMS
100
    public function init()
101
    {
102
        parent::init();
103
104
        $themeDir = SSViewer::get_theme_folder();
105
106
        Requirements::javascript('framework/thirdparty/jquery/jquery.js');
107
        if (Locator::getLocations()) {
108
            Requirements::javascript('http://maps.google.com/maps/api/js?sensor=false');
109
            Requirements::javascript('locator/thirdparty/handlebars/handlebars-v1.3.0.js');
110
            Requirements::javascript('locator/thirdparty/jquery-store-locator/js/jquery.storelocator.js');
111
        }
112
113
        Requirements::css('locator/css/map.css');
114
115
        $featured = (Locator::getLocations(array('Featured' => 1))->count() > 0) ?
116
            'featuredLocations: true' :
117
            'featuredLocations: false';
118
119
        // map config based on user input in Settings tab
120
        // AutoGeocode or Full Map
121
        $load = ($this->data()->AutoGeocode) ?
122
            'autoGeocode: true, fullMapStart: false,' :
123
            'autoGeocode: false, fullMapStart: true, storeLimit: 1000, maxDistance: true,';
124
125
        $base = Director::baseFolder();
126
        $themePath = $base.'/'.$themeDir;
127
128
        $listTemplatePath = (file_exists($themePath.'/templates/location-list-description.html')) ?
129
            $themeDir.'/templates/location-list-description.html' :
130
            'locator/templates/location-list-description.html';
131
        $infowindowTemplatePath = (file_exists($themePath.'/templates/infowindow-description.html')) ?
132
            $themeDir.'/templates/infowindow-description.html' :
133
            'locator/templates/infowindow-description.html';
134
135
        // in page or modal
136
        $modal = ($this->data()->ModalWindow) ? 'modalWindow: true' : 'modalWindow: false';
137
138
        $kilometer = ($this->data()->Unit == 'km') ? 'lengthUnit: "km"' : 'lengthUnit: "m"';
139
140
        $link = $this->Link().'xml.xml';
141
142
        // init map
143
        if (Locator::getLocations()) {
144
            Requirements::customScript("
145
                $(function($) {
146
                    $('#map-container').storeLocator({
147
                        ".$load."
148
                        dataLocation: '".$link."',
149
                        listTemplatePath: '".$listTemplatePath."',
150
                        infowindowTemplatePath: '".$infowindowTemplatePath."',
151
                        originMarker: true,
152
                        ".$modal.',
153
                        '.$featured.",
154
                        slideMap: false,
155
                        zoomLevel: 0,
156
                        distanceAlert: 120,
157
                        noForm: true,
158
                        formID: 'Form_LocationSearch',
159
                        inputID: 'Form_LocationSearch_address',
160
                        categoryID: 'Form_LocationSearch_category',
161
                        distanceAlert: -1,
162
                        ".$kilometer.'
163
                    });
164
                });
165
            ');
166
        }
167
    }
168 1
169
    public function index(SS_HTTPRequest $request)
170 1
    {
171 1
172 1
    }
173 1
174
    /**
175 1
     * @param array $searchCriteria
176 1
     * @return mixed
177 1
     */
178 1
    public function Items($searchCriteria = array())
179
    {
180 1
        $request = ($this->request) ? $this->request : $this->parentController->getRequest();
181
        if(empty($searchCriteria)) $searchCriteria = $request->requestVars();
182 1
183
        //if category filters are selected on Locator
184 1
        $filterAny = array();
185
        if ($this->Categories()->exists() && !isset($searchCriteria['CategoryID'])) {
186
            $categories = $this->Categories();
187
            foreach ($categories as $category) {
188
                $filterAny['CategoryID'] = $category->ID;
189
            }
190
            $searchCriteria['filterAny'] = $filterAny;
191
        }
192 1
193
        // if address field has value, check against all address fields
194 1
195 1
196 1
        $context = (method_exists('Location', 'getCustomSearchContext')) ? singleton('Location')->getCustomSearchContext() : singleton('Location')->getDefaultSearchContext();
197
        $records = $context->getResults($searchCriteria);
198 1
199
        return $records;
200
    }
201 1
202
    /**
203
     * Find all locations for map.
204
     *
205
     * Will return a XML feed of all locations marked "show in locator".
206
     *
207
     * @return XML file
208
     *
209
     * @todo rename/refactor to allow for json/xml
210
     * @todo allow $filter to run off of getVars key/val pair
211
     */
212
    public function xml()
213
    {
214
        return $this->customise(array(
215
            'Locations' => $this->Items(),
216
        ))->renderWith('LocationXML');
217
    }
218
219
    /**
220
     * LocationSearch form.
221
     *
222
     * Search form for locations, updates map and results list via AJAX
223
     *
224
     * @return Form
225
     */
226
    public function LocationSearch()
227
    {
228
        $fields = FieldList::create(
229
            $address = TextField::create('location', '')
230
                ->setAttribute('placeholder', 'address or zip code')
231
        );
232
233
        $locatorCategories = Locator::getPageCategories($this->ID);
234
235
        if (LocationCategory::get()->Count() > 0 && $locatorCategories && $locatorCategories->Count() != 1) {
236
237
            $ct = $locatorCategories->Count();
238
239
            if ($ct > 0 && $ct != 1) {
240
                $categories = $locatorCategories;
241
            } else {
242
                $categories = LocationCategory::get();
243
            }
244
245
            if ($categories->count() > 0) {
246
                $fields->push(
247
                    DropdownField::create(
248
                        'CategoryID',
249
                        '',
250
                        $categories->map()
251
                    )->setEmptyString('Select Category'));
252
            }
253
        }
254
255
        $actions = FieldList::create(
256
            FormAction::create('doSearch', 'Search')
257
        );
258
259
        return Form::create($this, 'LocationSearch', $fields, $actions)
260
            ->setFormMethod('get');
261
    }
262
263
    // Results filtered by query
264
    function doSearch($data, $form, $request)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
265
    {
266
        if (isset($data['location'])) {
267
            $location = $data['location'];
268
            $data['Address'] = $location;
269
            $data['Suburb'] = $location;
270
            $data['State'] = $location;
271
            $data['Postcode'] = $location;
272
            $data['Country'] = $location;
273
        }
274
        return $this->render(array(
275
            'Items' => $this->Items($data),
276
            'AdvSearchForm' => $form
277
        ));
278
    }
279
}
280