Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
88.33% covered (warning)
88.33%
53 / 60
75.00% covered (warning)
75.00%
3 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
AssetContentCopier
88.33% covered (warning)
88.33%
53 / 60
75.00% covered (warning)
75.00%
3 / 4
10.16
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 copy
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
2
 cloneAsset
79.41% covered (warning)
79.41%
27 / 34
0.00% covered (danger)
0.00%
0 / 1
4.14
 getResourceLanguageCode
100.00% covered (success)
100.00%
9 / 9
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-2024 (original work) Open Assessment Technologies SA.
19 */
20
21declare(strict_types=1);
22
23namespace oat\taoMediaManager\model\classes\Copier;
24
25use common_Exception;
26use core_kernel_classes_Resource;
27use oat\tao\model\resources\Contract\InstanceContentCopierInterface;
28use oat\taoMediaManager\model\fileManagement\FileManagement;
29use oat\taoMediaManager\model\MediaService;
30use oat\taoMediaManager\model\MediaSource;
31use oat\taoMediaManager\model\sharedStimulus\factory\CommandFactory;
32use oat\taoMediaManager\model\sharedStimulus\service\CopyService;
33use oat\taoMediaManager\model\sharedStimulus\specification\SharedStimulusResourceSpecification;
34use oat\taoMediaManager\model\TaoMediaOntology;
35
36class AssetContentCopier implements InstanceContentCopierInterface
37{
38    /** @var SharedStimulusResourceSpecification */
39    private $sharedStimulusSpecification;
40
41    /** @var CommandFactory */
42    private $commandFactory;
43
44    /** @var CopyService */
45    private $sharedStimulusCopyService;
46
47    /** @var MediaSource|null */
48    private $mediaSource;
49
50    /** @var string */
51    private $defaultLanguage;
52
53    private MediaService $mediaService;
54    private FileManagement $fileManagement;
55
56    public function __construct(
57        SharedStimulusResourceSpecification $sharedStimulusResourceSpecification,
58        CommandFactory $commandFactory,
59        CopyService $sharedStimulusCopyService,
60        MediaService $mediaService,
61        FileManagement $fileManagement,
62        string $defaultLanguage,
63        MediaSource $mediaSource = null
64    ) {
65        $this->sharedStimulusSpecification = $sharedStimulusResourceSpecification;
66        $this->commandFactory = $commandFactory;
67        $this->sharedStimulusCopyService = $sharedStimulusCopyService;
68        $this->mediaService = $mediaService;
69        $this->fileManagement = $fileManagement;
70        $this->defaultLanguage = $defaultLanguage;
71        $this->mediaSource = $mediaSource;
72    }
73
74    /**
75     * @throws common_Exception
76     */
77    public function copy(
78        core_kernel_classes_Resource $instance,
79        core_kernel_classes_Resource $destinationInstance
80    ): void {
81        if ($this->sharedStimulusSpecification->isSatisfiedBy($instance)) {
82            $this->sharedStimulusCopyService->copy(
83                $this->commandFactory->makeCopyCommand(
84                    $instance->getUri(),
85                    $destinationInstance->getUri(),
86                    $this->getResourceLanguageCode($instance)
87                )
88            );
89
90            return;
91        }
92
93        $this->cloneAsset($instance, $destinationInstance);
94    }
95
96    /**
97     * @throws common_Exception
98     */
99    private function cloneAsset(core_kernel_classes_Resource $fromAsset, core_kernel_classes_Resource $toAsset): void
100    {
101        $mediaSource = $this->mediaSource ?? new MediaSource([]);
102        $fileInfo = $mediaSource->getFileInfo($fromAsset->getUri());
103        $stream = $this->fileManagement->getFileStream($fileInfo['link']);
104        $tmpMediaPath = tempnam(sys_get_temp_dir(), 'taoMediaManager_') . '_' . $fileInfo['name'];
105        $logPrefix = sprintf(
106            '[link=%s,fromLabel=%s,fromUri=%s,toLabel=%s,toUri=%s]',
107            $fileInfo['link'],
108            $fromAsset->getLabel(),
109            $fromAsset->getUri(),
110            $toAsset->getLabel(),
111            $toAsset->getUri()
112        );
113
114        if (!file_put_contents($tmpMediaPath, $stream->getContents())) {
115            throw new common_Exception(
116                sprintf(
117                    '%s Failed saving asset to a temporary file "%s" while copying it',
118                    $logPrefix,
119                    $tmpMediaPath,
120                )
121            );
122        }
123
124        $toAsset->setPropertiesValues(
125            [
126                TaoMediaOntology::PROPERTY_LINK => '',
127            ]
128        );
129
130        if (!$this->mediaService->editMediaInstance($tmpMediaPath, $toAsset->getUri())) {
131            throw new common_Exception(
132                sprintf(
133                    '%s Failed saving asset into filesystem while copying it',
134                    $logPrefix,
135                )
136            );
137        }
138
139        if (is_readable($tmpMediaPath)) {
140            unlink($tmpMediaPath);
141        }
142    }
143
144    private function getResourceLanguageCode(
145        core_kernel_classes_Resource $instance
146    ): string {
147        $lang = $instance->getPropertyValues(
148            $instance->getProperty(TaoMediaOntology::PROPERTY_LANGUAGE)
149        );
150
151        if (empty($lang)) {
152            return $this->defaultLanguage;
153        }
154
155        $langCode = trim(current($lang));
156
157        return empty($langCode)
158            ? $this->defaultLanguage
159            : $langCode;
160    }
161}