Completed
Push — master ( 2fc117...7cb9e8 )
by Nicolaas
02:21
created

StockistSearchPage_Controller::showsearches()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 21
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 21
rs 9.0534
c 0
b 0
f 0
cc 4
eloc 11
nc 3
nop 0
1
<?php
2
3
class StockistSearchPage extends Page
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
4
{
5
6
    /**
7
     * @inherited
8
     */
9
    private static $icon = 'mysite/images/treeicons/StockistSearchPage';
0 ignored issues
show
Unused Code introduced by
The property $icon 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...
10
11
    /**
12
     * @inherited
13
     */
14
    private static $db = array(
0 ignored issues
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...
15
        "DefaultZoom" => "Int"
16
    );
17
18
    /**
19
     * @inherited
20
     */
21
    private static $default_child = 'StockistCountryPage';
0 ignored issues
show
Unused Code introduced by
The property $default_child 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
     * @inherited
25
     */
26
    private static $allowed_children = array('StockistCountryPage');
0 ignored issues
show
Unused Code introduced by
The property $allowed_children 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...
27
28
    /**
29
     * @inherited
30
     */
31
    private static $defaults = array('DefaultZoom' => 0);
0 ignored issues
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...
32
33
    /**
34
     * @inherited
35
     */
36
    private static $can_be_root = true;
0 ignored issues
show
Unused Code introduced by
The property $can_be_root 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...
37
38
    /**
39
     * @inherited
40
     */
41
    private static $description = 'Stockist Search Page - Main page for Stockists';
0 ignored issues
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...
42
43
    /**
44
     * Standard SS variable.
45
     */
46
    private static $singular_name = "Stockist Search Page";
0 ignored issues
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...
47
    public function i18n_singular_name()
48
    {
49
        return "Stockist Search Page";
50
    }
51
52
    /**
53
     * Standard SS variable.
54
     */
55
    private static $plural_name = "Stockist Search Pages";
0 ignored issues
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...
56
    public function i18n_plural_name()
57
    {
58
        return "Stockist Search Pages";
59
    }
60
61
    /**
62
     * @inherited
63
     */
64
   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...
65
   {
66
       $fields = parent::getCMSFields();
67
       $fields->removeByName("Map");
68
       $fields->addFieldToTab(
69
            "Root.SearchHistory", new LiteralField("SearchHistoryLink", "<a href=\"".$this->Link("showsearches")."\">What did people search for?</a>")
70
        );
71
       $fields->addFieldToTab('Root.Map', $defaultZoomField = new NumericField('DefaultZoom'));
72
       $defaultZoomField->setRightTitle('Set between 1 and 20.  One is the whole world and twenty is highest zoom level for map. Leave at zero for auto-zoom.');
73
       return $fields;
74
   }
75
76
    /**
77
     *
78
     * can only create one
79
     */
80
    public function canCreate($member = null)
81
    {
82
        return StockistSearchPage::get()
83
            ->filter(array("ClassName" => "StockistSearchPage"))
84
            ->count() ? false : true;
85
    }
86
87
88
    /**
89
     * returns a list of continents
90
     * @return DataList
91
     */
92
    public function AllContintents()
93
    {
94
        if ($root = $this->StockistSearchPage()) {
95
            return StockistCountryPage::get()->filter(array("ParentID" => $root->ID))->sort(array("Title" => "ASC"));
96
        }
97
    }
98
99
    /**
100
     * this is only provided on a country level
101
     * @return DataList | Null
0 ignored issues
show
Documentation introduced by
Should the return type not be DataList|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
102
     */
103
    public function AllPhysicalStockists()
104
    {
105
        return null;
106
    }
107
108
    /**
109
     * this is only provided on a country level
110
     * @return DataList | Null
0 ignored issues
show
Documentation introduced by
Should the return type not be DataList|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
111
     */
112
    public function AllOnlineStockists()
113
    {
114
        return null;
115
    }
116
117
    /**
118
     * @return Boolean
119
     */
120
    public function HasPhysicalStockistsANDOnlineStockists()
121
    {
122
        $a = $this->AllPhysicalStockists();
123
        $b = $this->AllOnlineStockists();
124
        if ($a && $b) {
125
            if ($a->count() && $b->count()) {
126
                return true;
127
            }
128
        }
129
        return false;
130
    }
131
}
132
133
class StockistSearchPage_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...
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
134
{
135
136
    /**
137
     * @inherited
138
     */
139
    private static $allowed_actions = array(
0 ignored issues
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...
140
        "showsearches" => "ADMIN",
141
        "updatemap" => "ADMIN",
142
        "showtype" => true,
143
        "showcountries" => true,
144
        "listofstockists" => true,
145
        "listofstockistscsv" => true,
146
        'addresssearch' => true,
147
        'addresssearchmap' => true,
148
        'SearchByAddressForm' => true,
149
    );
150
151
    public function init()
152
    {
153
        parent::init();
154
        $this->myCurrentCountryCode = EcommerceCountry::get_country();
155
        $this->HasGeoInfo = true;
156
    }
157
158
    public function index()
159
    {
160
        $this->addMap(
161
            $action = "showpointbyid",
162
            $title = $this->Title.' - '.$this->MyStockistCountryTitle(),
163
            $lng = 0,
164
            $lat = 0,
165
            implode(',', $this->locationsForCurrentCountry()->column("ID"))
166
        );
167
        return array();
168
    }
169
170
    public function MyAddAddressFinderForm()
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...
171
    {
172
        return $this->AddressFinderForm(array("StockistPage"));
173
    }
174
175
    /**
176
     * returns all the locations (GoogleMapLocationsObject) relevant
177
     * to the current user's country for display on the map.
178
     * We get the country from:
179
     * ```php
180
     *     $countryCode = EcommerceCountry::get_country();
181
     * ```
182
     *
183
     * @return DataList of GoogleMapLocationsObject
184
     */
185
    protected function locationsForCurrentCountry()
186
    {
187
        $objects = null;
0 ignored issues
show
Unused Code introduced by
$objects 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...
188
        if ($this->myCurrentCountryCode) {
189
            $objects = GoogleMapLocationsObject::get()->filter(array("CountryNameCode" => $this->myCurrentCountryCode));
190
            if ($objects->count()) {
191
                return $objects;
192
            }
193
        }
194
        $stockistCountryPage = StockistCountryPage::get()
195
            ->filter(array('CountryCode' => $this->myCurrentCountryCode))
196
            ->first();
197
        if(! $stockistCountryPage) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
198
            //use the AdditionalCountries to work out other options ...
199
        }
200
        if($stockistCountryPage) {
201
            $list = $stockistCountryPage->AllChildLocations();
202
            if($list->count()) {
203
                return $list;
204
            }
205
        }
206
207
        //final backup
208
        return GoogleMapLocationsObject::get();
209
    }
210
211
    public function AlphaList()
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...
212
    {
213
        if ($objects = $this->locationsForCurrentCountry()) {
214
            $parents = $objects->column('ParentID');
215
            if (count($parents)) {
216
                $pages = StockistPage::get()->filter(
217
                    array(
218
                        "ID" => $parents
219
                    )
220
                );
221
                if ($pages->count() < 25) {
222
                    return $pages;
223
                }
224
            }
225
        }
226
    }
227
228
    /**
229
     * @return DataList
230
     */
231
    public function Countries()
232
    {
233
        $objects = StockistCountryPage::get()->filter(array("ParentID" => $this->ID))->sort(array("Title" => "ASC"));
234
        if ($objects->count() == 0) {
235
            return StockistCountryPage::get()->filter(array("ID" => $this->ID));
236
        }
237
        return $objects;
238
    }
239
240
    /**
241
     * for template
242
     * @return Boolean
243
     */
244
    public function IsSearchPage()
245
    {
246
        return true;
247
    }
248
249
    public function IsStockistPage()
250
    {
251
        return true;
252
    }
253
254
    public function showsearches()
255
    {
256
        if (Permission::check('ADMIN')) {
257
            $sql = "
258
                SELECT SearchedFor
259
                FROM \"GoogleMapSearchRecord\"
260
                ORDER BY Created DESC
261
                LIMIT 10000
262
            ";
263
            $rows = DB::query($sql);
264
            if ($rows) {
265
                $this->Content .= "<h2>previous searches</h2><ul>";
266
                foreach ($rows as $row) {
267
                    $this->Content .= "<li>".$row["SearchedFor"]."</li>";
268
                }
269
                $this->Content .= "</ul>";
270
            }
271
            return array();
272
        }
273
        Security::permissionFailure($this, "You need to be logged in as administrator to see this map");
274
    }
275
276
    /**
277
     *
278
     * @param HTTPRequest
279
     */
280
    public function showtype($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...
281
    {
282
        $type = $request->param("ID");
283
        return $this->redirect($this->Link()."#".$this->Link("showtype/$type/"));
284
    }
285
286
    /**
287
     * we use this specfically so that we can change the country for
288
     * a page.
289
     * @return String
290
     */
291
    public function MyStockistCountryTitle()
292
    {
293
        if ($this->myCurrentCountryCode) {
294
            return EcommerceCountry::find_title($this->myCurrentCountryCode);
295
        } else {
296
            return $this->MyCountryTitle();
297
        }
298
    }
299
300
301
    ####################################
302
    # CSV
303
    ####################################
304
305
    /**
306
     *
307
     * download CSV action
308
     */
309
    public function listofstockistscsv()
310
    {
311
        $html = $this->createListOfStockists();
312
        $html = mb_convert_encoding($html, 'HTML-ENTITIES', "UTF-8");
313
314
        /*** a new dom object ***/
315
        $dom = new domDocument;
316
317
        /*** load the html into the object ***/
318
        $dom->loadHTML($html);
319
320
        /*** discard white space ***/
321
        $dom->preserveWhiteSpace = false;
322
323
        /*** the table by its tag name ***/
324
        $htmlTable = $dom->getElementsByTagName('table');
325
        $htmlRows = $htmlTable->item(0)->getElementsByTagName('tr');
326
        $rowArray = array();
327
        foreach ($htmlRows as $htmlRow) {
328
            $headerCells = array();
329
            $htmlHeaders = $htmlRow->getElementsByTagName('th');
330
            foreach ($htmlHeaders as $htmlHeader) {
331
                $headerCells [] = $htmlHeader->nodeValue;
332
            }
333
            $htmlCells = $htmlRow->getElementsByTagName('td');
334
            $rowCells = array();
335
            foreach ($htmlCells as $htmlCell) {
336
                $rowCells [] = $htmlCell->nodeValue;
337
            }
338
            $rowArray[] = '"'.implode('", "', array_merge($headerCells, $rowCells)).'"';
339
        }
340
        $csv = implode("\r\n", $rowArray);
341
        $filename_prefix = 'stockists';
342
        $filename = $filename_prefix."_".date("Y-m-d_H-i", time());
343
344
        //Generate the CSV file header
345
        header("Content-type: application/vnd.ms-excel");
346
        header("Content-Encoding: UTF-8");
347
        header("Content-type: text/csv; charset=UTF-8");
348
        header("Content-disposition: csv" . date("Y-m-d") . ".csv");
349
        header("Content-disposition: filename=".$filename.".csv");
350
        echo "\xEF\xBB\xBF"; // UTF-8 BOM
351
        //Print the contents of out to the generated file.
352
        print $csv;
353
    }
354
355
356
    /**
357
     *
358
     * create HTML row for table of stockists
359
     */
360
    private function getChildrenAsHTMLRows($parent)
361
    {
362
        $childGroups = DataObject::get("SiteTree", "ParentID = ".$parent->ID);
363
        $html = "";
364
        if ($childGroups) {
365
            foreach ($childGroups as $childGroup) {
366
                $html .= $this->getChildrenAsHTMLRows($childGroup);
367
            }
368
        }
369
        $childStockists = DataObject::get("StockistPage", "ParentID = ".$parent->ID);
370
        if ($childStockists) {
371
            foreach ($childStockists as $stockist) {
372
                $stockistParent = $stockist;
373
                $parentNames = array();
374
                $stockistParent = DataObject::get_by_id("SiteTree", $stockistParent->ParentID);
375
                while ($stockistParent && ($stockistParent->ParentID)) {
376
                    $parentNames[] = $stockistParent->Title;
377
                    $stockistParent = DataObject::get_by_id("SiteTree", $stockistParent->ParentID);
378
                }
379
                $html .= "<tr>";
380
                $html .= "<td>".Convert::raw2xml(implode(", ", ($parentNames)))."</td>";
381
                $html .= "<td>".Convert::raw2xml($stockist->Type)."</td>";
382
                $html .= "<td>".Convert::raw2xml($stockist->Title)."</td>";
383
                $html .= "<td>".Convert::raw2xml($stockist->City)."</td>";
384
                $html .= "<td>".Convert::raw2xml($stockist->WebAddress)."</td>";
385
                $html .= "<td>".Convert::raw2xml($stockist->Email)."</td>";
386
                $html .= "<td>".Convert::raw2xml($stockist->Phone)."</td>";
387
                $html .= "</tr>";
388
            }
389
        }
390
        return $html;
391
    }
392
393
394
395
    /**
396
     *
397
     * view list of stockists on blank screen with download link
398
     */
399
    public function listofstockists()
400
    {
401
        $html = "<h4><a href=\"".$this->Link("listofstockistscsv")."\">download csv file for Excel</a></h4>";
402
        $html .= $this->createListOfStockists();
403
        return $html;
404
    }
405
406
407
    private function createListOfStockists()
408
    {
409
        $html = "
410
        <table border=\"1\">
411
            <tr>
412
                <th>Region / Type</th>
413
                <th>Type</th>
414
                <th>Name</th>
415
                <th>City</th>
416
                <th>WebAddress</th>
417
                <th>Email</th>
418
                <th>Phone</th>
419
            </tr>";
420
        $html .= $this->getChildrenAsHTMLRows($this->Parent());
421
        $html .=   "</table>";
422
        return $html;
423
    }
424
425
426
    public function updatemap()
427
    {
428
        $pages = StockistPage::get()
429
            ->filter(array("HasGeoInfo" => 0));
430
        if ($pages && $pages->count()) {
431
            foreach ($pages as $page) {
432
                $page->write();
433
                $page->publish('Stage', 'Live');
434
            }
435
        }
436
        die("locations updated");
0 ignored issues
show
Coding Style Compatibility introduced by
The method updatemap() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
437
    }
438
}
439