Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 55
0.00% covered (danger)
0.00%
0 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
TestPreviewer
0.00% covered (danger)
0.00%
0 / 55
0.00% covered (danger)
0.00%
0 / 8
272
0.00% covered (danger)
0.00%
0 / 1
 init
0.00% covered (danger)
0.00%
0 / 29
0.00% covered (danger)
0.00%
0 / 1
42
 configuration
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
12
 setNoCacheHeaders
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 getTestPreviewerConfigurationService
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getTestPreviewerService
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getTestPreviewerPresetsMapService
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 mapXmlExceptionMessage
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
6
 getPermissionChecker
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
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 (original work) Open Assessment Technologies SA ;
19 */
20
21declare(strict_types=1);
22
23namespace oat\taoQtiTestPreviewer\controller;
24
25use common_exception_UserReadableException;
26use InvalidArgumentException;
27use oat\tao\model\accessControl\PermissionChecker;
28use oat\tao\model\http\HttpJsonResponseTrait;
29use oat\tao\model\resources\ResourceAccessDeniedException;
30use oat\taoQtiTestPreviewer\models\test\TestPreviewConfig;
31use oat\taoQtiTestPreviewer\models\test\service\TestPreviewer as TestPreviewerService;
32use oat\taoQtiTestPreviewer\models\test\TestPreviewRequest;
33use oat\taoQtiTestPreviewer\models\TestCategoryPresetMap;
34use oat\taoQtiTestPreviewer\models\testConfiguration\service\TestPreviewerConfigurationService;
35use qtism\data\storage\xml\XmlStorageException;
36use tao_actions_ServiceModule;
37use Throwable;
38
39class TestPreviewer extends tao_actions_ServiceModule
40{
41    use HttpJsonResponseTrait;
42
43    public function init()
44    {
45        try {
46            $requestParams = $this->getPsrRequest()->getQueryParams();
47            $testUri = $requestParams['testUri'] ?? null;
48
49            if (empty($testUri)) {
50                throw  new InvalidArgumentException('Required `testUri` param is missing ');
51            }
52
53            if (!$this->getPermissionChecker()->hasReadAccess($testUri)) {
54                throw new ResourceAccessDeniedException($testUri);
55            }
56
57            $testPreviewRequest = new TestPreviewRequest(
58                $testUri,
59                new TestPreviewConfig([TestPreviewConfig::CHECK_INFORMATIONAL => true])
60            );
61            $response = $this->getTestPreviewerService()->createPreview($testPreviewRequest);
62
63            $this->setNoCacheHeaders();
64
65            $this->setSuccessJsonResponse(
66                [
67                    'success' => true,
68                    'testData' => [],
69                    'testContext' => [],
70                    'testMap' => $response->getMap()->getMap(),
71                    'presetMap' => $this->getTestPreviewerPresetsMapService()->getMap()
72                ]
73            );
74        } catch (XmlStorageException $xmlStorageException) {
75            $message = $this->mapXmlExceptionMessage($xmlStorageException);
76            $this->setErrorJsonResponse($message);
77        } catch (Throwable $exception) {
78            $message = $exception instanceof common_exception_UserReadableException
79                ? $exception->getUserMessage()
80                : $exception->getMessage();
81
82            $this->setErrorJsonResponse($message);
83        }
84    }
85
86    public function configuration(): void
87    {
88        try {
89            $this->setNoCacheHeaders();
90
91            $this->setSuccessJsonResponse(
92                $this->getTestPreviewerConfigurationService()->getConfiguration()
93            );
94        } catch (Throwable $exception) {
95            $message = $exception instanceof common_exception_UserReadableException
96                ? $exception->getUserMessage()
97                : $exception->getMessage();
98
99            $this->setErrorJsonResponse($message);
100        }
101    }
102
103    private function setNoCacheHeaders(): void
104    {
105        $this->getResponseFormatter()
106            ->addHeader('Cache-Control', 'no-cache, no-store, must-revalidate')
107            ->addHeader('Pragma', 'no-cache')
108            ->addHeader('Expires', '0');
109    }
110
111    private function getTestPreviewerConfigurationService(): TestPreviewerConfigurationService
112    {
113        return $this->getServiceLocator()->get(TestPreviewerConfigurationService::class);
114    }
115
116    private function getTestPreviewerService(): TestPreviewerService
117    {
118        return $this->getServiceLocator()->get(TestPreviewerService::class);
119    }
120
121    private function getTestPreviewerPresetsMapService(): TestCategoryPresetMap
122    {
123        return $this->getPsrContainer()->get(TestCategoryPresetMap::class);
124    }
125
126    private function mapXmlExceptionMessage(XmlStorageException $exception): string
127    {
128        if (
129            stristr(
130                $exception->getMessage(),
131                'An error occurred while unreferencing item reference with identifier'
132            ) !== false
133        ) {
134            return __(
135                'It seems that some items have been deleted. ' .
136                'Please remove the items with empty labels from the test and save before trying again.'
137            );
138        }
139        return $exception->getMessage();
140    }
141
142    private function getPermissionChecker(): PermissionChecker
143    {
144        return $this->getPsrContainer()->get(PermissionChecker::class);
145    }
146}