Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 100
0.00% covered (danger)
0.00%
0 / 12
CRAP
0.00% covered (danger)
0.00%
0 / 1
DeliveryFactory
0.00% covered (danger)
0.00%
0 / 100
0.00% covered (danger)
0.00%
0 / 12
1260
0.00% covered (danger)
0.00%
0 / 1
 create
0.00% covered (danger)
0.00%
0 / 47
0.00% covered (danger)
0.00%
0 / 1
110
 setInitialProperties
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
30
 getInitialPropertiesFromRequest
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
30
 getInitialPropertiesFromArray
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
20
 createDeliveryResource
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
12
 createNamespacedDeliveryResource
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
6
 getNamespace
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 createNamespacedDeliveryId
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 createDeliverDeleteRequest
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getEventManager
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getDeliveryDeleteService
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getDeliveryNamespaceRegistry
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) 2017 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
19 *
20 */
21
22namespace oat\taoDeliveryRdf\model;
23
24use common_report_Report as Report;
25use core_kernel_classes_ResourceFactory as ResourceFactory;
26use oat\generis\model\data\event\ResourceCreated;
27use oat\generis\model\OntologyAwareTrait;
28use oat\generis\model\OntologyRdf;
29use oat\generis\model\OntologyRdfs;
30use oat\oatbox\service\ConfigurableService;
31use core_kernel_classes_Resource as KernelResource;
32use core_kernel_classes_Class as KernelClass;
33use oat\tao\helpers\form\ValidationRuleRegistry;
34use oat\oatbox\event\EventManager;
35use oat\taoDelivery\model\container\delivery\AbstractContainer;
36use oat\taoDeliveryRdf\model\Delete\DeliveryDeleteRequest;
37use oat\taoDeliveryRdf\model\Delete\DeliveryDeleteService;
38use oat\taoDeliveryRdf\model\Delivery\Business\Contract\DeliveryNamespaceRegistryInterface;
39use oat\taoDeliveryRdf\model\Delivery\Business\Domain\DeliveryNamespace;
40use oat\taoDeliveryRdf\model\event\DeliveryCreatedEvent;
41use oat\taoDelivery\model\container\delivery\ContainerProvider;
42use RuntimeException;
43
44/**
45 * Services to manage Deliveries
46 *
47 * @access public
48 * @author Antoine Robin, <antoine@taotesting.com>
49 * @package taoDelivery
50 */
51class DeliveryFactory extends ConfigurableService
52{
53    use OntologyAwareTrait;
54
55    public const SERVICE_ID = 'taoDeliveryRdf/DeliveryFactory';
56
57    public const OPTION_PROPERTIES = 'properties';
58
59    /**
60     * 'initialProperties' => array(
61     *      'uri_of_property'
62     * )
63     */
64    public const OPTION_INITIAL_PROPERTIES = 'initialProperties';
65
66    /**
67     * initialPropertiesMap' => array(
68     *      'name_of_rest_parameter' => array(
69     *          'uri' => 'uri_of_property',
70     *          'values' => array(
71     *              'true' => 'http://www.tao.lu/Ontologies/TAODelivery.rdf#ComplyEnabled'
72     *              )
73     *          )
74     *      )
75     */
76    public const OPTION_INITIAL_PROPERTIES_MAP = 'initialPropertiesMap';
77    public const OPTION_INITIAL_PROPERTIES_MAP_VALUES = 'values';
78    public const OPTION_INITIAL_PROPERTIES_MAP_URI = 'uri';
79
80    public const PROPERTY_DELIVERY_COMPILE_TASK = 'http://www.tao.lu/Ontologies/TAODelivery.rdf#DeliveryCompileTask';
81
82    private $deliveryResource;
83
84    public function create(
85        KernelClass $deliveryClass,
86        KernelResource $test,
87        string $label = '',
88        KernelResource $deliveryResource = null,
89        array $additionalParameters = []
90    ): Report {
91
92        \common_Logger::i('Creating ' . $label . ' with ' . $test->getLabel() . ' under ' . $deliveryClass->getLabel());
93
94        // checking on properties
95        foreach ($this->getOption(self::OPTION_PROPERTIES) as $deliveryProperty => $testProperty) {
96            $testPropretyInstance = new \core_kernel_classes_Property($testProperty);
97            $validationValue = (string) $testPropretyInstance->getOnePropertyValue(
98                new \core_kernel_classes_Property(ValidationRuleRegistry::PROPERTY_VALIDATION_RULE)
99            );
100
101            $propertyValues = $test->getPropertyValues($testPropretyInstance);
102
103            if ($validationValue === 'notEmpty' && empty($propertyValues)) {
104                $report = Report::createFailure(
105                    __('Test publishing failed because "%s" is empty.', $testPropretyInstance->getLabel())
106                );
107
108                return $report;
109            }
110        }
111
112        if (!$deliveryResource instanceof KernelResource) {
113            $deliveryResource = $this->getNamespace() && $additionalParameters
114                ? $this->createNamespacedDeliveryResource(
115                    $deliveryClass,
116                    $additionalParameters
117                )
118                : ResourceFactory::create($deliveryClass);
119        }
120
121        $this->deliveryResource = $deliveryResource;
122
123        $storage = new TrackedStorage();
124        $this->propagate($storage);
125        $compiler = $this
126            ->getServiceLocator()
127            ->get(\taoTests_models_classes_TestsService::class)
128            ->getCompiler($test, $storage);
129
130        $report = $compiler->compile();
131        if ($report->getType() == Report::TYPE_SUCCESS) {
132            $serviceCall = $report->getData();
133
134            $properties = [
135                OntologyRdfs::RDFS_LABEL => $label,
136                DeliveryAssemblyService::PROPERTY_DELIVERY_DIRECTORY => $storage->getSpawnedDirectoryIds(),
137                DeliveryAssemblyService::PROPERTY_ORIGIN => $test,
138            ];
139
140            foreach ($this->getOption(self::OPTION_PROPERTIES) as $deliveryProperty => $testProperty) {
141                $properties[$deliveryProperty] = $test->getPropertyValues(
142                    new \core_kernel_classes_Property($testProperty)
143                );
144            }
145
146            $container = null;
147            if ($compiler instanceof ContainerProvider) {
148                $container = $compiler->getContainer();
149            }
150            $compilationInstance = $this->createDeliveryResource($deliveryClass, $serviceCall, $container, $properties);
151
152            $eventManager = $this->getServiceManager()->get(EventManager::SERVICE_ID);
153            $eventManager->trigger(new DeliveryCreatedEvent($compilationInstance));
154
155            $report->setData($compilationInstance);
156        }
157
158        return $report;
159    }
160
161    /**
162     * @param $values
163     * @param KernelResource $delivery
164     *
165     * @return KernelResource
166     */
167    public function setInitialProperties($values, KernelResource $delivery)
168    {
169        $initialProperties = $this->getOption(self::OPTION_INITIAL_PROPERTIES);
170
171        foreach ($values as $uri => $value) {
172            if (in_array($uri, $initialProperties) && $value) {
173                $property = $this->getProperty($uri);
174                $value = is_array($value) ? current($value) : $value;
175                $delivery->setPropertyValue($property, $value);
176            }
177        }
178        return $delivery;
179    }
180
181    /**
182     * @param \Request $request
183     *
184     * @return array
185     */
186    public function getInitialPropertiesFromRequest(\Request $request)
187    {
188        $initialPropertiesMap = $this->getOption(self::OPTION_INITIAL_PROPERTIES_MAP);
189        $requestParameters = $request->getParameters();
190        $initialProperties = [];
191        foreach ($requestParameters as $parameter => $value) {
192            if (isset($initialPropertiesMap[$parameter]) && $value) {
193                $config = $initialPropertiesMap[$parameter];
194                $values = $config[self::OPTION_INITIAL_PROPERTIES_MAP_VALUES];
195                if (isset($values[$value])) {
196                    $initialProperties[$config[self::OPTION_INITIAL_PROPERTIES_MAP_URI]] = $values[$value];
197                }
198            }
199        }
200        return $initialProperties;
201    }
202
203    /**
204     * @param array $properties
205     *
206     * @return array
207     */
208    public function getInitialPropertiesFromArray($properties)
209    {
210        $initialProperties = $this->getOption(self::OPTION_INITIAL_PROPERTIES);
211        $initialPropertiesResponse = [];
212        foreach ($properties as $uri => $value) {
213            if (in_array($uri, $initialProperties) && $value) {
214                $initialPropertiesResponse[$uri] = $value;
215            }
216        }
217        return $initialPropertiesResponse;
218    }
219
220    protected function createDeliveryResource(
221        KernelClass $deliveryClass,
222        \tao_models_classes_service_ServiceCall $serviceCall,
223        AbstractContainer $container = null,
224        array $properties = []
225    ): KernelResource {
226        $properties[DeliveryAssemblyService::PROPERTY_DELIVERY_TIME]    = time();
227        $properties[DeliveryAssemblyService::PROPERTY_DELIVERY_RUNTIME] = json_encode($serviceCall);
228        if (!is_null($container)) {
229            $properties[ContainerRuntime::PROPERTY_CONTAINER] = json_encode($container);
230        }
231
232        if ($this->deliveryResource instanceof KernelResource) {
233            $compilationInstance = $this->deliveryResource;
234            $compilationInstance->setPropertiesValues($properties);
235        } else {
236            $compilationInstance = $deliveryClass->createInstanceWithProperties($properties);
237        }
238
239        return $compilationInstance;
240    }
241
242    private function createNamespacedDeliveryResource(
243        KernelClass $deliveryClass,
244        array $additionalParameters
245    ): KernelResource {
246        $deliveryId = trim($additionalParameters[DeliveryAssemblyService::PROPERTY_ASSESSMENT_PROJECT_ID] ?? '');
247
248        if ('' === $deliveryId) {
249            throw new RuntimeException(
250                sprintf('%s must not be empty', DeliveryAssemblyService::PROPERTY_ASSESSMENT_PROJECT_ID)
251            );
252        }
253
254        $this->getDeliveryDeleteService()
255            ->execute(
256                $this->createDeliverDeleteRequest($deliveryId)
257            );
258
259        $delivery = $deliveryClass->getResource($this->createNamespacedDeliveryId($deliveryId));
260
261        $delivery->setPropertiesValues([OntologyRdf::RDF_TYPE => $deliveryClass]);
262
263        $this->getEventManager()->trigger(new ResourceCreated($delivery));
264
265        return $delivery;
266    }
267
268    private function getNamespace(): ?DeliveryNamespace
269    {
270        return $this->getDeliveryNamespaceRegistry()->get();
271    }
272
273    private function createNamespacedDeliveryId(string $deliveryId): string
274    {
275        return "{$this->getNamespace()}#$deliveryId";
276    }
277
278    private function createDeliverDeleteRequest(string $deliveryId): DeliveryDeleteRequest
279    {
280        return (new DeliveryDeleteRequest($this->createNamespacedDeliveryId($deliveryId)))
281            ->setIsRecursive();
282    }
283
284    private function getEventManager(): EventManager
285    {
286        return $this->getServiceLocator()->get(EventManager::class);
287    }
288
289    private function getDeliveryDeleteService(): DeliveryDeleteService
290    {
291        return $this->getServiceLocator()->get(DeliveryDeleteService::class);
292    }
293
294    private function getDeliveryNamespaceRegistry(): DeliveryNamespaceRegistryInterface
295    {
296        return $this->getServiceLocator()->get(DeliveryNamespaceRegistryInterface::class);
297    }
298}