Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
82.14% covered (warning)
82.14%
69 / 84
60.00% covered (warning)
60.00%
3 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
ResultSetResponseNormalizer
82.14% covered (warning)
82.14%
69 / 84
60.00% covered (warning)
60.00%
3 / 5
17.46
0.00% covered (danger)
0.00%
0 / 1
 normalize
80.95% covered (warning)
80.95%
34 / 42
0.00% covered (danger)
0.00%
0 / 1
7.34
 normalizeSafeClass
75.86% covered (warning)
75.86%
22 / 29
0.00% covered (danger)
0.00%
0 / 1
4.23
 createResponse
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
3
 getPermissionHelper
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getResultAccessChecker
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
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) 2020-2022 (original work) Open Assessment Technologies SA;
19 */
20
21declare(strict_types=1);
22
23namespace oat\tao\model\search;
24
25use oat\generis\model\data\permission\PermissionHelper;
26use oat\generis\model\data\permission\PermissionInterface;
27use oat\generis\model\OntologyAwareTrait;
28use oat\oatbox\service\ConfigurableService;
29
30class ResultSetResponseNormalizer extends ConfigurableService
31{
32    use OntologyAwareTrait;
33
34    /**
35     * @inheritDoc
36     */
37    public function normalize(SearchQuery $searchQuery, ResultSet $resultSet, string $structure): array
38    {
39        $resultsRaw = $resultSet->getArrayCopy();
40        $resultAmount = count($resultsRaw);
41        $resourcePermissions = [];
42        $responseData = [];
43        $resultAccessChecker = $this->getResultAccessChecker();
44
45        if ($resultAmount > 0) {
46            $accessibleResultsMap = array_flip(
47                $this->getPermissionHelper()
48                    ->filterByPermission(
49                        array_column($resultsRaw, 'id'),
50                        PermissionInterface::RIGHT_READ
51                    )
52            );
53
54            foreach ($resultsRaw as $content) {
55                $resourceId = $content['id'];
56
57                if (!is_array($content)) {
58                    $this->logError(
59                        sprintf(
60                            'Search content issue detected: expected array, but %s given',
61                            json_encode($content)
62                        )
63                    );
64                    continue;
65                }
66
67                $isAccessible = isset($accessibleResultsMap[$resourceId]);
68
69                if (!$isAccessible) {
70                    $hasReadAccess = false;
71                }
72
73                if ($isAccessible) {
74                    $hasReadAccess = $resultAccessChecker->hasReadAccess($content);
75                }
76
77                if ($hasReadAccess === false) {
78                    $content = [
79                        'label' => __('Access Denied'),
80                        'id' => $resourceId,
81                    ];
82                }
83
84                $resourcePermissions[$resourceId] = !$hasReadAccess;
85
86                $responseData[] = $content;
87            }
88        }
89
90        return $this->createResponse(
91            $responseData,
92            $resourcePermissions,
93            $searchQuery,
94            $resultSet,
95            $resultAmount
96        );
97    }
98
99    /**
100     * @inheritDoc
101     */
102    public function normalizeSafeClass(SearchQuery $searchQuery, ResultSet $resultSet, string $structure): array
103    {
104        $resultsRaw = $resultSet->getArrayCopy();
105        $resultAmount = count($resultsRaw);
106        $resourcePermissions = [];
107        $responseData = [];
108
109        if ($resultAmount > 0) {
110            $accessibleResultsMap = array_flip(
111                $this->getPermissionHelper()->filterByPermission(
112                    array_column($resultsRaw, 'id'),
113                    PermissionInterface::RIGHT_READ
114                )
115            );
116
117            foreach ($resultsRaw as $content) {
118                if (!is_array($content)) {
119                    $this->logError(
120                        sprintf(
121                            'Search content issue detected: expected array, but %s given',
122                            json_encode($content)
123                        )
124                    );
125                    continue;
126                }
127
128                $resourcePermissions[$content['id']] = !isset($accessibleResultsMap[$content['id']]);
129                $responseData[] = $content;
130            }
131        }
132
133        return $this->createResponse(
134            $responseData,
135            $resourcePermissions,
136            $searchQuery,
137            $resultSet,
138            $resultAmount
139        );
140    }
141
142    private function createResponse(
143        array $responseData,
144        array $resourcePermissions,
145        SearchQuery $searchQuery,
146        ResultSet $resultSet,
147        int $resultAmount
148    ): array {
149        return [
150            'data' => $responseData,
151            'readonly' => $resourcePermissions,
152            'success' => true,
153            'page' => empty($responseData) ? 0 : $searchQuery->getPage(),
154            'total' => empty($searchQuery->getRows())
155                ? 1
156                : ceil($resultSet->getTotalCount() / $searchQuery->getRows()),
157            'totalCount' => $resultSet->getTotalCount(),
158            'records' => $resultAmount,
159        ];
160    }
161
162    private function getPermissionHelper(): PermissionHelper
163    {
164        return $this->getServiceLocator()->get(PermissionHelper::class);
165    }
166
167    private function getResultAccessChecker(): ResultAccessChecker
168    {
169        return $this->getServiceLocator()->get(ResultAccessChecker::class);
170    }
171}