Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 54 |
|
0.00% |
0 / 9 |
CRAP | |
0.00% |
0 / 1 |
tao_models_classes_service_FileStorage | |
0.00% |
0 / 54 |
|
0.00% |
0 / 9 |
462 | |
0.00% |
0 / 1 |
singleton | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getFsId | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
6 | |||
getAccessProvider | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
6 | |||
spawnDirectory | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
getDirectoryById | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
6 | |||
deleteDirectoryById | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
2 | |||
import | |
0.00% |
0 / 16 |
|
0.00% |
0 / 1 |
56 | |||
id2path | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
12 | |||
getStreamHash | |
0.00% |
0 / 3 |
|
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) 2013 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT); |
19 | * |
20 | * |
21 | */ |
22 | |
23 | use oat\tao\model\websource\WebsourceManager; |
24 | use oat\oatbox\service\ConfigurableService; |
25 | use oat\oatbox\service\ServiceManager; |
26 | use oat\tao\model\websource\Websource; |
27 | use oat\oatbox\filesystem\FileSystemService; |
28 | use oat\tao\model\service\ServiceFileStorage; |
29 | |
30 | /** |
31 | * Represents the file storage used in services |
32 | * |
33 | * @access public |
34 | * @author Joel Bout, <joel@taotesting.com> |
35 | * @package tao |
36 | |
37 | */ |
38 | class tao_models_classes_service_FileStorage extends ConfigurableService implements ServiceFileStorage |
39 | { |
40 | public const OPTION_PUBLIC_FS = 'public'; |
41 | public const OPTION_PRIVATE_FS = 'private'; |
42 | public const OPTION_ACCESS_PROVIDER = 'provider'; |
43 | |
44 | /** |
45 | * @return tao_models_classes_service_FileStorage |
46 | */ |
47 | public static function singleton() |
48 | { |
49 | return ServiceManager::getServiceManager()->get(self::SERVICE_ID); |
50 | } |
51 | |
52 | private $accessProvider; |
53 | |
54 | /** |
55 | * @return string |
56 | */ |
57 | protected function getFsId($public) |
58 | { |
59 | return $public ? $this->getOption(self::OPTION_PUBLIC_FS) : $this->getOption(self::OPTION_PRIVATE_FS); |
60 | } |
61 | |
62 | /** |
63 | * @return Websource |
64 | * @throws \oat\tao\model\websource\WebsourceNotFound |
65 | */ |
66 | protected function getAccessProvider() |
67 | { |
68 | if (is_null($this->accessProvider)) { |
69 | $this->accessProvider = $this->getServiceLocator() |
70 | ->get(WebsourceManager::class) |
71 | ->getWebsource($this->getOption(self::OPTION_ACCESS_PROVIDER)); |
72 | } |
73 | return $this->accessProvider; |
74 | } |
75 | |
76 | /** |
77 | * @param boolean $public |
78 | * @return tao_models_classes_service_StorageDirectory |
79 | */ |
80 | public function spawnDirectory($public = false) |
81 | { |
82 | $id = common_Utils::getNewUri() . ($public ? '+' : '-'); |
83 | $directory = $this->getDirectoryById($id); |
84 | return $directory; |
85 | } |
86 | |
87 | /** |
88 | * @param string $id |
89 | * @return tao_models_classes_service_StorageDirectory |
90 | */ |
91 | public function getDirectoryById($id) |
92 | { |
93 | $public = $id[strlen($id) - 1] == '+'; |
94 | $path = $this->id2path($id); |
95 | $dir = new tao_models_classes_service_StorageDirectory( |
96 | $id, |
97 | $this->getFsId($public), |
98 | $path, |
99 | $public ? $this->getAccessProvider() : null |
100 | ); |
101 | $dir->setServiceLocator($this->getServiceLocator()); |
102 | return $dir; |
103 | } |
104 | |
105 | /** |
106 | * Delete directory represented by the $id |
107 | * |
108 | * @param $id |
109 | * @return mixed |
110 | */ |
111 | public function deleteDirectoryById($id) |
112 | { |
113 | $public = $id[strlen($id) - 1] == '+'; |
114 | $path = $this->id2path($id); |
115 | return $this |
116 | ->getServiceLocator() |
117 | ->get(FileSystemService::SERVICE_ID) |
118 | ->getFileSystem($this->getFsId($public)) |
119 | ->deleteDirectory($path); |
120 | } |
121 | |
122 | /** |
123 | * @param string $id |
124 | * @param string $directoryPath |
125 | * @throws common_Exception |
126 | */ |
127 | public function import($id, $directoryPath) |
128 | { |
129 | $directory = $this->getDirectoryById($id); |
130 | if (is_dir($directoryPath) && is_readable($directoryPath)) { |
131 | foreach ( |
132 | $iterator = new \RecursiveIteratorIterator( |
133 | new \RecursiveDirectoryIterator($directoryPath, \RecursiveDirectoryIterator::SKIP_DOTS), |
134 | \RecursiveIteratorIterator::SELF_FIRST |
135 | ) as $item |
136 | ) { |
137 | if (!$item->isDir()) { |
138 | $file = $directory->getFile($iterator->getSubPathName()); |
139 | $fh = fopen($item, 'rb'); |
140 | |
141 | if ($file->exists()) { |
142 | if (0 !== strcmp($this->getStreamHash($fh), $this->getStreamHash($file->readStream()))) { |
143 | fclose($fh); |
144 | throw new common_Exception('Different file content'); |
145 | } |
146 | } else { |
147 | $file->put($fh); |
148 | fclose($fh); |
149 | } |
150 | } |
151 | } |
152 | } else { |
153 | common_Logger::w('Missing directory ' . $directoryPath); |
154 | } |
155 | } |
156 | |
157 | private function id2path($id) |
158 | { |
159 | |
160 | $encoded = md5($id); |
161 | $returnValue = ""; |
162 | $len = strlen($encoded); |
163 | for ($i = 0; $i < $len; $i++) { |
164 | if ($i < 3) { |
165 | $returnValue .= $encoded[$i] . DIRECTORY_SEPARATOR; |
166 | } else { |
167 | $returnValue .= $encoded[$i]; |
168 | } |
169 | } |
170 | |
171 | return $returnValue . DIRECTORY_SEPARATOR; |
172 | } |
173 | |
174 | /** |
175 | * Calculates hash for given stream |
176 | * @param $stream |
177 | * @param string $hash |
178 | * @return string |
179 | */ |
180 | private function getStreamHash($stream, $hash = 'md5') |
181 | { |
182 | $hc = hash_init($hash); |
183 | hash_update_stream($hc, $stream); |
184 | return hash_final($hc); |
185 | } |
186 | } |