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

Inherited from BO\Zmsdldb\File\Location

24    protected function parseData(mixed $data)
25    {
26        $itemList = new Collection();
27        foreach ($data['data'] as $item) {
28            $location = new Entity($item);
29            if ($location->isLocale($this->locale)) {
30                $itemList[$item['id']] = $location;
31            }
32        }
33        return $itemList;
34    }
89    public function fetchListByOffice(mixed $office): mixed
90    {
91        return $this->access()->fromAuthority()
92        ->readListByOfficePath($office)
93        ->removeEmptyAuthorities()
94        ->sortByName();
95    }

Inherited from BO\Zmsdldb\File\Base

49    public function __construct(mixed $dataFile, string $locale = "de")
50    {
51        $this->dataFile = $dataFile;
52        $this->locale = $locale;
53    }
55    public function readDataFile(): mixed
56    {
57        if (empty($this->data)) {
58            $jsonFile = $this->dataFile;
59            if (!is_readable($jsonFile)) {
60                throw new Exception("Cannot read $jsonFile");
61            }
62            $json = file_get_contents($jsonFile);
63            if ($json === false) {
64                throw new Exception("Cannot read $jsonFile");
65            }
66            $data = json_decode($json, true);
67            if (!$data) {
68                throw new Exception("Could not decide $jsonFile");
69            }
70            $this->data = $data;
71        }
72        return $this->data;
73    }
76    public function getDataAsArray(): mixed
77    {
78        try {
79            $data = $this->readDataFile();
80
81            return $data['data'];
82        } catch (\Exception $e) {
83            throw $e;
84        }
85    }
88    public function getHash(): mixed
89    {
90        try {
91            $data = $this->readDataFile();
92
93            return $data['hash'];
94        } catch (\Exception $e) {
95            throw $e;
96        }
97    }
100    public function getData(): mixed
101    {
102        try {
103            $data = $this->readDataFile();
104
105            return $data;
106        } catch (\Exception $e) {
107            throw $e;
108        }
109    }
114    public function loadData()
115    {
116        try {
117            $data = $this->readDataFile();
118            $this->itemList = $this->parseData($data);
119        } catch (\Exception $e) {
120            throw $e;
121        }
122    }
127    public function getItemList()
128    {
129        if (null === $this->itemList) {
130            $this->loadData();
131        }
132        return $this->itemList;
133    }
135    protected function setItemList(\BO\Zmsdldb\Collection\Base $list): static
136    {
137        /** @var TCollection $list */
138        $this->itemList = $list;
139        return $this;
140    }
158    public function setAccessInstance(\BO\Zmsdldb\AbstractAccess $accessInstance): void
159    {
160        $this->accessInstance = $accessInstance;
161    }
163    public function access(): \BO\Zmsdldb\AbstractAccess
164    {
165        if (!$this->accessInstance instanceof \BO\Zmsdldb\AbstractAccess) {
166            throw new Exception('Access instance is not initialized');
167        }
168        return $this->accessInstance;
169    }