Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
69.23% |
36 / 52 |
|
54.55% |
6 / 11 |
CRAP | |
0.00% |
0 / 1 |
LtiNavigationService | |
69.23% |
36 / 52 |
|
54.55% |
6 / 11 |
36.10 | |
0.00% |
0 / 1 |
getReturnUrl | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
generateReturnUrl | |
26.67% |
4 / 15 |
|
0.00% |
0 / 1 |
6.55 | |||
buildConsumerReturnUrl | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
2 | |||
getConsumerReturnParams | |
83.33% |
5 / 6 |
|
0.00% |
0 / 1 |
2.02 | |||
shouldShowThankYou | |
81.82% |
9 / 11 |
|
0.00% |
0 / 1 |
6.22 | |||
buildThankYouUrl | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
buildConsumerReturnUrlQuery | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
getLtiReturnUrlQueryParams | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
getDeliveryReturnQueryParams | |
83.33% |
5 / 6 |
|
0.00% |
0 / 1 |
2.02 | |||
getReturnUrlIdParams | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getUrlHelper | |
100.00% |
1 / 1 |
|
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) 2018-2023 (original work) Open Assessment Technologies SA. |
19 | * |
20 | */ |
21 | |
22 | declare(strict_types=1); |
23 | |
24 | namespace oat\ltiDeliveryProvider\model\navigation; |
25 | |
26 | use oat\ltiDeliveryProvider\model\navigation\Command\GenerateReturnUrlCommand; |
27 | use oat\oatbox\service\ConfigurableService; |
28 | use oat\oatbox\service\exception\InvalidService; |
29 | use oat\oatbox\service\exception\InvalidServiceManagerException; |
30 | use oat\tao\helpers\UrlHelper; |
31 | use oat\taoLti\models\classes\LtiException; |
32 | use oat\taoLti\models\classes\LtiLaunchData; |
33 | use oat\ltiDeliveryProvider\controller\DeliveryTool; |
34 | use oat\taoLti\models\classes\LtiMessages\LtiMessage; |
35 | use oat\taoDelivery\model\execution\DeliveryExecutionInterface; |
36 | |
37 | class LtiNavigationService extends ConfigurableService |
38 | { |
39 | public const SERVICE_ID = 'ltiDeliveryProvider/LtiNavigation'; |
40 | |
41 | public const OPTION_DELIVERY_RETURN_STATUS = 'delivery_return_status'; |
42 | public const OPTION_MESSAGE_FACTORY = 'message'; |
43 | public const OPTION_RETURN_URL_IDENTIFIER = 'returnUrlId'; |
44 | |
45 | /** |
46 | * Whenever or not the thank you screen should be shown by default |
47 | */ |
48 | public const OPTION_THANK_YOU_SCREEN = 'thankyouScreen'; |
49 | |
50 | /** |
51 | * @deprecated Please use "generateReturnUrl" |
52 | */ |
53 | public function getReturnUrl(LtiLaunchData $launchData, DeliveryExecutionInterface $deliveryExecution): string |
54 | { |
55 | return $this->generateReturnUrl(new GenerateReturnUrlCommand($launchData, $deliveryExecution)); |
56 | } |
57 | |
58 | public function generateReturnUrl(GenerateReturnUrlCommand $command): string |
59 | { |
60 | if ($command->isCustomFeedback()) { |
61 | return $this->getUrlHelper()->buildUrl( |
62 | 'feedback', |
63 | 'DeliveryRunner', |
64 | 'ltiDeliveryProvider', |
65 | array_merge( |
66 | [ |
67 | 'deliveryExecution' => $command->getDeliveryExecution()->getIdentifier(), |
68 | ], |
69 | $command->getQueryStringData() |
70 | ) |
71 | ); |
72 | } |
73 | |
74 | return $this->shouldShowThankYou($command->getLaunchData()) |
75 | ? $this->buildThankYouUrl() |
76 | : $this->buildConsumerReturnUrl($command->getLaunchData(), $command->getDeliveryExecution()); |
77 | } |
78 | |
79 | /** |
80 | * @param LtiLaunchData $launchData |
81 | * @param DeliveryExecutionInterface $deliveryExecution |
82 | * @return string |
83 | * @throws \common_exception_NotFound |
84 | * @throws InvalidService |
85 | * @throws InvalidServiceManagerException |
86 | * @throws LtiException |
87 | */ |
88 | protected function buildConsumerReturnUrl( |
89 | LtiLaunchData $launchData, |
90 | DeliveryExecutionInterface $deliveryExecution |
91 | ): string { |
92 | $urlParts = parse_url($launchData->getReturnUrl()); |
93 | $port = empty($urlParts['port']) ? '' : (':' . $urlParts['port']); |
94 | $path = $urlParts['path'] ?? ''; |
95 | $queryString = $this->buildConsumerReturnUrlQuery($deliveryExecution, $urlParts); |
96 | |
97 | return $urlParts['scheme'] . '://' . $urlParts['host'] . $port . $path . '?' . $queryString; |
98 | } |
99 | |
100 | /** |
101 | * @param DeliveryExecutionInterface $deliveryExecution |
102 | * @return array |
103 | * @throws \common_exception_NotFound |
104 | * @throws InvalidService |
105 | * @throws InvalidServiceManagerException |
106 | */ |
107 | protected function getConsumerReturnParams(DeliveryExecutionInterface $deliveryExecution): array |
108 | { |
109 | $ltiReturnQueryParams = $this->getLtiReturnUrlQueryParams($deliveryExecution); |
110 | $deliveryReturnQueryParams = $this->getDeliveryReturnQueryParams($deliveryExecution); |
111 | $returnUrlIdParams = []; |
112 | if ($this->getOption(self::OPTION_RETURN_URL_IDENTIFIER)) { |
113 | $returnUrlIdParams = $this->getReturnUrlIdParams(); |
114 | } |
115 | return array_merge($ltiReturnQueryParams, $deliveryReturnQueryParams, $returnUrlIdParams); |
116 | } |
117 | |
118 | /** |
119 | * Whenever or not to show the thank you screen |
120 | * @param LtiLaunchData $launchData |
121 | * @return bool |
122 | */ |
123 | protected function shouldShowThankYou(LtiLaunchData $launchData): bool |
124 | { |
125 | if (!$launchData->hasReturnUrl()) { |
126 | return true; |
127 | } |
128 | |
129 | if ($launchData->hasVariable(DeliveryTool::PARAM_SKIP_THANKYOU)) { |
130 | switch ($launchData->getVariable(DeliveryTool::PARAM_SKIP_THANKYOU)) { |
131 | case 'true': |
132 | return false; |
133 | case 'false': |
134 | return true; |
135 | default: |
136 | $this->logWarning('Unexpected value for \'' . DeliveryTool::PARAM_SKIP_THANKYOU . '\': ' |
137 | . $launchData->getVariable(DeliveryTool::PARAM_SKIP_THANKYOU)); |
138 | } |
139 | } |
140 | return $this->getOption(self::OPTION_THANK_YOU_SCREEN); |
141 | } |
142 | |
143 | /** |
144 | * @return string |
145 | */ |
146 | protected function buildThankYouUrl(): string |
147 | { |
148 | return $this->getUrlHelper()->buildUrl('thankYou', 'DeliveryRunner', 'ltiDeliveryProvider'); |
149 | } |
150 | |
151 | /** |
152 | * @param DeliveryExecutionInterface $deliveryExecution |
153 | * @param array $urlParts |
154 | * @return array |
155 | * @throws \common_exception_NotFound |
156 | */ |
157 | private function buildConsumerReturnUrlQuery(DeliveryExecutionInterface $deliveryExecution, array $urlParts): string |
158 | { |
159 | $urlParts['query'] = $urlParts['query'] ?? ''; |
160 | parse_str($urlParts['query'], $params); |
161 | |
162 | return http_build_query(array_merge($params, $this->getConsumerReturnParams($deliveryExecution))); |
163 | } |
164 | |
165 | /** |
166 | * @param DeliveryExecutionInterface $deliveryExecution |
167 | * @return array |
168 | * @throws InvalidService |
169 | * @throws InvalidServiceManagerException |
170 | */ |
171 | private function getLtiReturnUrlQueryParams(DeliveryExecutionInterface $deliveryExecution): array |
172 | { |
173 | $ltiMessage = $this->getSubService(self::OPTION_MESSAGE_FACTORY)->getLtiMessage($deliveryExecution); |
174 | |
175 | return ($ltiMessage instanceof LtiMessage) ? $ltiMessage->getUrlParams() : []; |
176 | } |
177 | |
178 | /** |
179 | * @param DeliveryExecutionInterface $deliveryExecution |
180 | * @param $params |
181 | * @return mixed |
182 | * @throws \common_exception_NotFound |
183 | */ |
184 | private function getDeliveryReturnQueryParams(DeliveryExecutionInterface $deliveryExecution): array |
185 | { |
186 | $params = [ |
187 | 'deliveryExecution' => $deliveryExecution->getIdentifier() |
188 | ]; |
189 | |
190 | if ($this->getOption(self::OPTION_DELIVERY_RETURN_STATUS)) { |
191 | $params['deliveryExecutionStatus'] = $deliveryExecution->getState()->getLabel(); |
192 | } |
193 | |
194 | return $params; |
195 | } |
196 | |
197 | /** |
198 | * @return array |
199 | * @throws \Exception |
200 | */ |
201 | private function getReturnUrlIdParams(): array |
202 | { |
203 | return ['returnUrlId' => \helpers_Random::generateString(10)]; |
204 | } |
205 | |
206 | private function getUrlHelper(): UrlHelper |
207 | { |
208 | return $this->getServiceLocator()->get(UrlHelper::class); |
209 | } |
210 | } |