Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 196
0.00% covered (danger)
0.00%
0 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
Location
0.00% covered (danger)
0.00%
0 / 196
0.00% covered (danger)
0.00%
0 / 8
1482
0.00% covered (danger)
0.00%
0 / 1
 fetchId
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
12
 fetchList
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 1
20
 fetchFromCsv
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
6
 searchAll
0.00% covered (danger)
0.00%
0 / 44
0.00% covered (danger)
0.00%
0 / 1
56
 readSearchResultList
0.00% covered (danger)
0.00%
0 / 45
0.00% covered (danger)
0.00%
0 / 1
56
 fetchGeoJsonLocations
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
12
 fetchGeoJson
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
72
 fetchLocationsForCompilation
0.00% covered (danger)
0.00%
0 / 25
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2
3/**
4 * @package ClientDldb
5 * @copyright BerlinOnline Stadtportal GmbH & Co. KG
6 **/
7
8namespace BO\Zmsdldb\Elastic;
9
10use BO\Zmsdldb\Entity\Location as Entity;
11use BO\Zmsdldb\Collection\Locations as Collection;
12use BO\Zmsdldb\File\Location as Base;
13
14/**
15 * @SuppressWarnings(Coupling)
16 */
17class Location extends Base
18{
19    /**
20     *
21     * @return Entity
22     */
23    public function fetchId($location_id)
24    {
25        if ($location_id) {
26            $query = Helper::boolFilteredQuery();
27            $query->getFilter()->addMust(Helper::idsFilter($this->locale . $location_id));
28            $result = $this->access()
29                ->getIndex()
30                ->getType('location')
31                ->search($query, 1);
32
33            if ($result->count() == 1) {
34                $locationList = $result->getResults();
35                return new Entity($locationList[0]->getData());
36            }
37        }
38        return false;
39    }
40
41    /**
42     *
43     * @return Collection
44     */
45    public function fetchList($service_csv = '')
46    {
47        $query = Helper::boolFilteredQuery();
48        $limit = 10000;
49        $query->getFilter()->addMust(Helper::localeFilter($this->locale));
50        if ($service_csv) {
51            foreach (explode(',', $service_csv) as $service_id) {
52                $filter = new \Elastica\Filter\Term(array(
53                    'services.service' => $service_id
54                ));
55                $query->getFilter()->addMust($filter);
56            }
57        }
58        $resultList = $this->access()
59            ->getIndex()
60            ->getType('location')
61            ->search($query, $limit);
62
63        $locationList = new Collection();
64        foreach ($resultList as $result) {
65            $location = new Entity($result->getData());
66            $locationList[$location['id']] = $location;
67        }
68        return $locationList;
69    }
70
71    /**
72     *
73     * @return Collection
74     */
75    public function fetchFromCsv($location_csv)
76    {
77        $query = Helper::boolFilteredQuery();
78        $filter = new \Elastica\Filter\Ids();
79        $ids = explode(',', $location_csv);
80        $ids = array_map(function ($value) {
81            return $this->locale . $value;
82        }, $ids);
83        $filter->setIds($ids);
84        $query->getFilter()->addMust($filter);
85        $resultList = $this->access()
86            ->getIndex()
87            ->getType('location')
88            ->search($query, 10000);
89        $locationList = new Collection();
90        foreach ($resultList as $result) {
91            $location = new Entity($result->getData());
92            $locationList[$location['id']] = $location;
93        }
94        return $locationList;
95    }
96
97    /**
98     *
99     * @return \BO\ClientDldb\Collection\Authorities
100     */
101    public function searchAll($querystring, $service_csv = '')
102    {
103        $query = Helper::boolFilteredQuery();
104        $mainquery = new \Elastica\Query();
105        $limit = 1000;
106        $searchquery = new \Elastica\Query\QueryString();
107        if ($querystring > 10000 && $querystring < 15000) {
108            // if it is a postal code, sort by distance and limit results
109            $coordinates = \BO\Zmsdldb\Plz\Coordinates::zip2LatLon($querystring);
110            if (false !== $coordinates) {
111                $searchquery->setQuery('*');
112                $mainquery->addSort([
113                    "_geo_distance" => [
114                        "geo" => [
115                            "lat" => $coordinates['lat'],
116                            "lon" => $coordinates['lon']
117                        ],
118                        "order" => "asc",
119                        "unit" => "km"
120                    ]
121                ]);
122                $limit = 5;
123            }
124        } elseif ('' === trim($querystring)) {
125            // if empty, find all and trust in the filter
126            $searchquery->setQuery('*');
127        } else {
128            $searchquery->setQuery($querystring);
129        }
130        $searchquery->setFields([
131            'name^9',
132            'authority.name^5',
133            'address.street',
134            'address.postal_code^9'
135        ]);
136        $query->getQuery()->addShould($searchquery);
137        $filter = null;
138        if ($service_csv) {
139            foreach (explode(',', $service_csv) as $service_id) {
140                $filter = new \Elastica\Filter\Term(array(
141                    'services.service' => $service_id
142                ));
143                $query->getFilter()->addMust($filter);
144            }
145        }
146        $mainquery->setQuery($query);
147        $resultList = $this->access()
148            ->getIndex()
149            ->getType('location')
150            ->search($mainquery, $limit);
151        return $this->access()
152            ->fromAuthority()
153            ->fromLocationResults($resultList);
154    }
155
156    /**
157     * search locations
158     * this function is similar to self::searchAll() but it might get different boosts in the future
159     *
160     * @return Collection
161     */
162    public function readSearchResultList($querystring, $service_csv = '')
163    {
164        $query = Helper::boolFilteredQuery();
165        $query->getFilter()->addMust(Helper::localeFilter($this->locale));
166        $mainquery = new \Elastica\Query();
167        $limit = 1000;
168        //$sort = true;
169        $searchquery = new \Elastica\Query\QueryString();
170        if ($querystring > 10000 && $querystring < 15000) {
171            // if it is a postal code, sort by distance and limit results
172            $coordinates = \BO\Zmsdldb\Plz\Coordinates::zip2LatLon($querystring);
173            if (false !== $coordinates) {
174                $searchquery->setQuery('*');
175                $mainquery->addSort([
176                    "_geo_distance" => [
177                        "geo" => [
178                            "lat" => $coordinates['lat'],
179                            "lon" => $coordinates['lon']
180                        ],
181                        "order" => "asc",
182                        "unit" => "km"
183                    ]
184                ]);
185                $limit = 5;
186                //$sort = false;
187            }
188        } elseif ('' === trim($querystring)) {
189            // if empty, find all and trust in the filter
190            $searchquery->setQuery('*');
191        } else {
192            $searchquery->setQuery($querystring);
193        }
194        $searchquery->setFields([
195            'name^9',
196            'authority.name^5',
197            'address.street',
198            'address.postal_code^9'
199        ]);
200        $query->getQuery()->addShould($searchquery);
201        $filter = null;
202        if ($service_csv) {
203            foreach (explode(',', $service_csv) as $service_id) {
204                $filter = new \Elastica\Filter\Term(array(
205                    'services.service' => $service_id
206                ));
207                $query->getFilter()->addMust($filter);
208            }
209        }
210        $mainquery->setQuery($query);
211        $resultList = $this->access()
212            ->getIndex()
213            ->getType('location')
214            ->search($mainquery, $limit);
215        return $this->access()
216            ->fromAuthority()
217            ->fromLocationResults($resultList);
218    }
219
220    protected function fetchGeoJsonLocations($category, $getAll)
221    {
222        $query = new \Elastica\Query();
223        $query->setSource(['id', 'name', 'address.*', 'geo.*', 'meta.*', 'category.*']);
224
225        $filter =  new \Elastica\Query\MatchAll();
226
227        if (!empty($category) && false === $getAll) {
228            $filter = new \Elastica\Query\BoolQuery();
229            $termFilter = new \Elastica\Query\Term(['category.identifier' => $category]);
230            $filter->addMust($termFilter);
231        }
232        $query->setQuery($filter);
233        $query->addSort(['office' => ['order' => 'asc']]);
234        $query->addSort(['name' => ['order' => 'asc']]);
235        $resultList = $this->access()
236            ->getIndex()
237            ->getType('location')
238            ->search($query, 1000)
239        ;
240        return $resultList;
241    }
242
243    /**
244     * @todo Refactoring required, functions in this class should return entities, not JSON data
245     */
246    public function fetchGeoJson($category = null, $getAll = false)
247    {
248        $resultList = $this->fetchGeoJsonLocations($category, $getAll);
249        $geoJson = [];
250        // TODO check refactoring: the following lines were ineffective cause the line $geoJson=[] happened afterwards
251        //if (!empty($category) && false === $getAll) {
252        //    $geoJson['category'] = $category;
253        //}
254        foreach ($resultList as $result) {
255            $location = new Entity($result->getData());
256            if (empty($location['category']['identifier'])) {
257                continue;
258            }
259            if (!isset($geoJson[$location['category']['identifier']])) {
260                $geoJson[$location['category']['identifier']] = [
261                    'name' => $location['category']['name'],
262                    'type' => 'cluster',
263                    'active' => (
264                        !empty($category)
265                        && $category == $location['category']['identifier'] ? true : (
266                            !empty($category) && $category != $location['category']['identifier'] ? false : true
267                        )
268                    ),
269                    'data' => ['type' => 'FeatureCollection', 'features' => []]
270                ];
271            }
272            $geoJson[$location['category']['identifier']]['data']['features'][] = $location->getGeoJson();
273        }
274
275        return $geoJson;
276    }
277
278    public function fetchLocationsForCompilation($authoritys = [], $locations = [])
279    {
280        $limit = 1000;
281
282        $localeFilter = new \Elastica\Query\Term(array(
283            'meta.locale' => $this->locale
284        ));
285
286        $boolquery = new \Elastica\Query\BoolQuery();
287        $boolquery->addMust($localeFilter);
288
289        if (!empty($authoritys)) {
290            $authorityFilter = new \Elastica\Query\Terms('authority.id', $authoritys);
291            $boolquery->addMust($authorityFilter);
292        }
293        if (!empty($locations)) {
294            $locationFilter = new \Elastica\Query\Terms('id', $locations);
295            $boolquery->addMust($locationFilter);
296        }
297
298        $query = \Elastica\Query::create($boolquery);
299        $query->addSort(['sort' => 'asc']);
300        #print_r(json_encode($query->toArray()));exit;
301        $resultList = $this
302            ->access()
303            ->getIndex()
304            ->getType('location')
305            ->search($query, $limit)
306        ;
307
308        $locationList = new Collection();
309        foreach ($resultList as $result) {
310            $location = new Entity($result->getData());
311            $locationList[$location['id']] = $location;
312        }
313        return $locationList;
314    }
315}