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