Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 56
0.00% covered (danger)
0.00%
0 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
ListResourceLookup
0.00% covered (danger)
0.00%
0 / 56
0.00% covered (danger)
0.00%
0 / 8
306
0.00% covered (danger)
0.00%
0 / 1
 getResources
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 searchByString
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
6
 searchByProperties
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
2
 format
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
12
 getResourceData
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
20
 getClasses
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 getSignatureGenerator
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getParentClassUri
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2
3/**
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; under version 2
7 * of the License (non-upgradable).
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17 *
18 * Copyright (c) 2017 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
19 *
20 */
21
22namespace oat\tao\model\resources;
23
24use core_kernel_classes_Resource;
25use oat\generis\model\OntologyRdf;
26use oat\generis\model\OntologyAwareTrait;
27use oat\generis\model\OntologyRdfs;
28use oat\oatbox\service\ConfigurableService;
29use oat\tao\model\search\ResultSet;
30use oat\tao\model\search\Search;
31use oat\oatbox\service\ServiceManager;
32use oat\tao\model\security\SignatureGenerator;
33
34/**
35 * Look up resources and format them as a flat list
36 *
37 * @author Bertrand Chevrier <bertrand@taotesting.com>
38 */
39class ListResourceLookup extends ConfigurableService implements ResourceLookup
40{
41    use OntologyAwareTrait;
42
43    public const SERVICE_ID = 'tao/ListResourceLookup';
44
45    /**
46     * Retrieve Resources for the given parameters as a list
47     *
48     * @param \core_kernel_classes_Class $rootClass       the resources class
49     * @param array                      $propertyFilters propUri/propValue to search resources
50     * @param string[]                   $selectedUris    the resources to open
51     * @param int                        $offset          for paging
52     * @param int                        $limit           for paging
53     * @return array the resources
54     */
55    public function getResources(
56        \core_kernel_classes_Class $rootClass,
57        array $selectedUris = [],
58        array $propertyFilters = [],
59        $offset = 0,
60        $limit = 30
61    ) {
62        // Searching by label parameter will utilize fulltext search
63        if (count($propertyFilters) == 1 && isset($propertyFilters[OntologyRdfs::RDFS_LABEL])) {
64            $searchString = current($propertyFilters);
65            return $this->searchByString($searchString, $rootClass, $offset, $limit);
66        } else {
67            return $this->searchByProperties($propertyFilters, $rootClass, $offset, $limit);
68        }
69    }
70
71    /**
72     * Search using an advanced search string
73     * @param string $searchString
74     * @param \core_kernel_classes_Class $rootClass
75     * @param int $offset
76     * @param int $limit
77     * @return array
78     */
79    private function searchByString($searchString, $rootClass, $offset, $limit)
80    {
81        /** @var Search $searchService */
82        $searchService = $this->getServiceLocator()->get(Search::SERVICE_ID);
83        /** @var ResultSet $result */
84        $result = $searchService->query($searchString, $rootClass, $offset, $limit);
85        $count = $result->getTotalCount();
86
87        $ids = [];
88        foreach ($result as $item) {
89            $ids[] = $item['id'] ?? $item;
90        }
91
92        return $this->format($ids, $count, $offset, $limit);
93    }
94
95    /**
96     * Search using properties
97     * @param string $searchString
98     * @param \core_kernel_classes_Class $rootClass
99     * @param int $offset
100     * @param int $limit
101     * @return array
102     */
103    private function searchByProperties($propertyFilters, $rootClass, $offset, $limit)
104    {
105        // for searching by properties will be used RDF search
106        $options = [
107            'recursive' => true,
108            'like'      => true,
109            'limit'     => $limit,
110            'offset'    => $offset
111        ];
112        $count = $rootClass->countInstances($propertyFilters, $options);
113        $resources = $rootClass->searchInstances($propertyFilters, $options);
114        return $this->format($resources, $count, $offset, $limit);
115    }
116
117    /**
118     * Format the results according to the needs of ListLookup
119     * @param array $result
120     * @param int $count
121     * @param int $offset
122     * @param int $limit
123     * @return array
124     */
125    private function format($result, $count, $offset, $limit)
126    {
127        $nodes = [];
128        foreach ($result as $item) {
129            $resource = $this->getResource($item);
130            $data = $this->getResourceData($resource);
131            if ($data) {
132                $nodes[] = $data;
133            }
134        }
135        return [
136            'total'  => $count,
137            'offset' => $offset,
138            'limit'  => $limit,
139            'nodes'  => $nodes
140        ];
141    }
142
143    /**
144     * Preparing resource to be used in the ListLookup
145     * @param $resource
146     * @return array|bool
147     */
148    private function getResourceData($resource)
149    {
150        $data = false;
151        if (!is_null($resource) && $resource->exists()) {
152            $resourceTypes = array_keys($resource->getTypes());
153            $data = [
154                'uri'        => $resource->getUri(),
155                'classUri'   => $resourceTypes[0],
156                'label'      => $resource->getLabel(),
157                'type'       => 'instance',
158                'signature'  => $this->getSignatureGenerator()->generate($resource->getUri()),
159            ];
160            $parentClassUri = $this->getParentClassUri($resource);
161            if ($parentClassUri !== null) {
162                $data['classSignature'] = $this->getSignatureGenerator()->generate($parentClassUri);
163            }
164        }
165        return $data;
166    }
167
168    public function getClasses(
169        \core_kernel_classes_Class $rootClass,
170        array $selectedUris = [],
171        array $propertyFilters = [],
172        $offset = 0,
173        $limit = 30
174    ) {
175        return [];
176    }
177
178    private function getSignatureGenerator(): SignatureGenerator
179    {
180        return $this->getServiceManager()->get(SignatureGenerator::class);
181    }
182
183    private function getParentClassUri(core_kernel_classes_Resource $resource): ?string
184    {
185        $parentClassUri = $resource->getOnePropertyValue($resource->getProperty(OntologyRdf::RDF_TYPE));
186        return $parentClassUri !== null
187            ? $parentClassUri->getUri()
188            : null;
189    }
190}