Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
69.23% covered (warning)
69.23%
27 / 39
71.43% covered (warning)
71.43%
5 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
SharedStimulusFactory
69.23% covered (warning)
69.23%
27 / 39
71.43% covered (warning)
71.43%
5 / 7
19.71
0.00% covered (danger)
0.00%
0 / 1
 createShardedStimulusFromSourceFiles
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
1
 getRelatedCssFilePath
50.00% covered (danger)
50.00%
9 / 18
0.00% covered (danger)
0.00%
0 / 1
6.00
 isFileExtension
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
12
 getStoreService
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getMediaService
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getUserLanguageService
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 buildParentClassUri
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
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) 2022 (original work) Open Assessment Technologies SA;
19 */
20
21declare(strict_types=1);
22
23namespace oat\taoQtiItem\model\qti\asset\factory;
24
25use core_kernel_classes_Class;
26use Laminas\ServiceManager\ServiceLocatorAwareTrait;
27use oat\oatbox\service\ConfigurableService;
28use oat\oatbox\user\UserLanguageService;
29use oat\tao\model\GenerisServiceTrait;
30use oat\taoMediaManager\model\MediaService;
31use oat\taoMediaManager\model\sharedStimulus\service\StoreService;
32use oat\taoQtiItem\model\Export\AbstractQTIItemExporter;
33use oat\taoQtiItem\model\qti\ImportService;
34use RecursiveDirectoryIterator;
35use RecursiveIteratorIterator;
36use SplFileInfo;
37
38class SharedStimulusFactory extends ConfigurableService
39{
40    use ServiceLocatorAwareTrait;
41    use GenerisServiceTrait;
42
43    private const MEDIA_ROOT_CLASS = 'http://www.tao.lu/Ontologies/TAOMedia.rdf#Media';
44
45    public function createShardedStimulusFromSourceFiles(
46        string $newXmlFile,
47        string $relativePath,
48        string $absolutePath,
49        array $targetClassPath
50    ): string {
51        $assetWithCss = $this->getStoreService()->store(
52            $newXmlFile,
53            basename($relativePath),
54            $this->getRelatedCssFilePath($absolutePath)
55        );
56
57        return $this->getMediaService()->createSharedStimulusInstance(
58            $assetWithCss . DIRECTORY_SEPARATOR . basename($relativePath),
59            $this->buildParentClassUri($targetClassPath),
60            $this->getUserLanguageService()->getAuthoringLanguage()
61        );
62    }
63
64    private function getRelatedCssFilePath(string $absolutePath): array
65    {
66        $cssSubDirectory = implode(
67            DIRECTORY_SEPARATOR,
68            [
69                dirname($absolutePath),
70                AbstractQTIItemExporter::CSS_DIRECTORY_NAME
71            ]
72        );
73
74        if (!is_dir($cssSubDirectory)) {
75            return [];
76        }
77
78        $iterator = new RecursiveIteratorIterator(
79            new RecursiveDirectoryIterator($cssSubDirectory),
80            RecursiveIteratorIterator::LEAVES_ONLY
81        );
82
83        $cssFiles = [];
84
85        /** @var $file SplFileInfo */
86        foreach ($iterator as $file) {
87            if ($this->isFileExtension($file, 'css')) {
88                $cssFiles[] = $file->getRealPath();
89            }
90        }
91
92        return $cssFiles;
93    }
94
95    public function isFileExtension(SplFileInfo $file, string $extension): bool
96    {
97        if ($file->isFile()) {
98            return preg_match('/^[\w]/', $file->getFilename()) === 1 && $file->getExtension() === $extension;
99        }
100
101        return false;
102    }
103
104    private function getStoreService(): StoreService
105    {
106        return $this->getServiceLocator()->get(StoreService::class);
107    }
108
109    private function getMediaService(): MediaService
110    {
111        return $this->getServiceLocator()->get(MediaService::class);
112    }
113
114    private function getUserLanguageService(): UserLanguageService
115    {
116        return $this->getServiceLocator()->get(UserLanguageService::SERVICE_ID);
117    }
118
119    private function buildParentClassUri(array $labelPath): string
120    {
121        $mediaClass = $this->getClass(self::MEDIA_ROOT_CLASS);
122
123        // Creating same classes in the media root
124        foreach ($labelPath as $classLabel) {
125            $mediaClass = $mediaClass->retrieveSubClassByLabel($classLabel)
126                ?: $mediaClass->createSubClass($classLabel);
127        }
128
129        return $mediaClass->getUri();
130    }
131}