├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── changelog.md
├── composer.json
├── phpunit.php
├── phpunit.xml.dist
├── src
└── PhpcrAdapter.php
└── tests
└── PhpcrAdapterTest.php
/.gitignore:
--------------------------------------------------------------------------------
1 | /composer.lock
2 | /vendor/
3 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 |
3 | php:
4 | - 5.4
5 | - 5.5
6 | - 5.6
7 |
8 | cache:
9 | directories:
10 | - $HOME/.composer/cache
11 |
12 | install:
13 | - travis_retry composer install --no-interaction --prefer-dist
14 |
15 | script:
16 | - bash -c 'if [ "$TRAVIS_PHP_VERSION" == "hhvm" ]; then bin/phpunit; fi;'
17 | - bash -c 'if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then bin/phpunit --coverage-text --coverage-clover coverage.xml; fi;'
18 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2015 David Buchmann
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is furnished
8 | to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Flysystem Adapter for the PHP Content Repository PHPCR
2 |
3 | [](https://travis-ci.org/thephpleague/flysystem-phpcr)
4 | [](LICENSE)
5 | [](https://packagist.org/packages/league/flysystem-phpcr)
6 | [](https://packagist.org/packages/league/flysystem-phpcr)
7 |
8 | ## Documentation
9 |
10 | See https://flysystem.thephpleague.com/docs/adapter/phpcr/
11 |
--------------------------------------------------------------------------------
/changelog.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## 1.1.0 - 2018-06-04
4 |
5 | ### Added
6 |
7 | * File timestamp can be set to any time through the configuration
8 |
9 | ### Fixed
10 |
11 | * Return encoding in metadata after file creation
12 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "league/flysystem-phpcr",
3 | "description": "Flysystem adapter for the PHP content repository",
4 | "keywords": [
5 | "filesystem", "phpcr", "flysystem"
6 | ],
7 | "authors": [
8 | {
9 | "name": "David Buchmann",
10 | "email": "david.buchmann@liip.ch"
11 | }
12 | ],
13 | "require": {
14 | "league/flysystem": "~1.0",
15 | "phpcr/phpcr-implementation": "~2.1.0"
16 | },
17 | "require-dev": {
18 | "phpunit/phpunit": "~4.0",
19 | "jackalope/jackalope-doctrine-dbal": "~1.0"
20 | },
21 | "autoload": {
22 | "psr-4": {
23 | "League\\Flysystem\\Phpcr\\": "src/"
24 | }
25 | },
26 | "license": "MIT",
27 | "config": {
28 | "bin-dir": "bin"
29 | },
30 | "extra": {
31 | "branch-alias": {
32 | "dev-master": "1.1-dev"
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/phpunit.php:
--------------------------------------------------------------------------------
1 |
13 |
14 |
15 |
16 | tests/
17 |
18 |
19 |
20 |
21 |
22 | src
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/src/PhpcrAdapter.php:
--------------------------------------------------------------------------------
1 |
20 | */
21 | class PhpcrAdapter extends AbstractAdapter
22 | {
23 | use NotSupportingVisibilityTrait;
24 |
25 | /**
26 | * @var SessionInterface
27 | */
28 | private $session;
29 |
30 | /**
31 | * Constructor.
32 | *
33 | * @param SessionInterface $session
34 | * @param string $root
35 | */
36 | public function __construct(SessionInterface $session, $root)
37 | {
38 | $this->session = $session;
39 | if (!$session->nodeExists($root)) {
40 | $parent = NodeHelper::createPath($this->session, PathHelper::getParentPath($root));
41 | $parent->addNode(PathHelper::getNodeName($root), 'nt:folder');
42 | } else {
43 | $rootNode = $this->session->getNode($root);
44 | if (!$rootNode->isNodeType('nt:folder')) {
45 | throw new \LogicException(sprintf(
46 | 'The root node at %s must be of type nt:folder, found %s',
47 | $root ,
48 | $rootNode->getPrimaryNodeType()->getName())
49 | );
50 | }
51 | }
52 | $this->setPathPrefix($root);
53 | }
54 |
55 | /**
56 | * Set the path prefix.
57 | *
58 | * @param string $prefix
59 | *
60 | * @return self
61 | */
62 | public function setPathPrefix($prefix)
63 | {
64 | parent::setPathPrefix($prefix);
65 | if (null === $this->pathPrefix) {
66 | $this->pathPrefix = $this->pathSeparator;
67 | }
68 | }
69 |
70 | /**
71 | * Prefix a path.
72 | *
73 | * @param string $path
74 | *
75 | * @return string prefixed path
76 | */
77 | public function applyPathPrefix($path)
78 | {
79 | $path = ltrim($path, '/');
80 | if (strlen($path) === 0) {
81 | return rtrim($this->getPathPrefix(), '/');
82 | }
83 |
84 | return $this->getPathPrefix() . $path;
85 | }
86 |
87 | /**
88 | * Ensure the directory exists and try to create it if it does not exist.
89 | *
90 | * @param string $path path relative to the $root.
91 | * @param boolean $create Whether to create the folder if not existing.
92 | *
93 | * @return NodeInterface The node at $root/$path.
94 | */
95 | private function getFolderNode($path, $create = false)
96 | {
97 | $location = $this->applyPathPrefix($path);
98 | if (!$create && !$this->session->nodeExists($location)) {
99 | // trigger the phpcr exception rather than trying to create parent nodes.
100 | return $this->session->getNode($location);
101 | }
102 |
103 | $folders = array();
104 | while (!$this->session->nodeExists($location)) {
105 | $folders[] = PathHelper::getNodeName($location);
106 | $location = PathHelper::getParentPath($location);
107 | }
108 |
109 | $node = $this->session->getNode($location);
110 | while (null !== $folder = array_pop($folders)) {
111 | $node = $node->addNode($folder, 'nt:folder');
112 | }
113 | if (!$node->isNodeType('nt:folder')) {
114 | throw new \LogicException($path.' is not a folder but '.$node->getPrimaryNodeType()->getName());
115 | }
116 |
117 | if ($create) {
118 | $this->session->save();
119 | }
120 |
121 | return $node;
122 | }
123 |
124 | /**
125 | * @param string $path path relative to the $root.
126 | * @param bool $create whether to create the file if it does not exist yet.
127 | *
128 | * @return NodeInterface The node at $root/$path
129 | */
130 | private function getFileNode($path, $create = false)
131 | {
132 | $fileName = PathHelper::getNodeName('/'.$path);
133 | $folderPath = PathHelper::getParentPath('/'.$path);
134 | $folder = $this->getFolderNode($folderPath, $create);
135 |
136 | if ($folder->hasNode($fileName) || !$create) {
137 | return $folder->getNode($fileName);
138 | }
139 |
140 | $file = $folder->addNode($fileName, 'nt:file');
141 | $file->addNode('jcr:content', 'nt:resource');
142 |
143 | return $file;
144 | }
145 |
146 | /**
147 | * {@inheritdoc}
148 | */
149 | public function has($path)
150 | {
151 | $location = $this->applyPathPrefix($path);
152 |
153 | return $this->session->nodeExists($location);
154 | }
155 |
156 | /**
157 | * @param NodeInterface $file
158 | * @param string $path path relative to the $root.
159 | * @param string|resource $contents
160 | * @param Config $config
161 | *
162 | * @return array Metadata for return value.
163 | */
164 | private function writeMeta(NodeInterface $file, $path, $contents, Config $config)
165 | {
166 | $content = $file->getNode('jcr:content');
167 | if (!$mimetype = $config->get('mimetype')) {
168 | if (is_string($contents)) {
169 | $mimetype = Util::guessMimeType($path, $contents);
170 | } else {
171 | $mimetype = null;
172 | }
173 | }
174 | $content->setProperty('jcr:mimeType', $mimetype);
175 |
176 | $type = 'file';
177 | $result = compact('mimetype', 'type', 'path');
178 |
179 | if ($encoding = $config->get('encoding')) {
180 | $result['encoding'] = $encoding;
181 | $content->setProperty('jcr:encoding', $encoding);
182 | }
183 | if($timestamp = $config->get('timestamp')) {
184 | $result['timestamp'] = $timestamp;
185 | $content->setProperty('jcr:lastModified', $timestamp);
186 | }
187 |
188 | return $result;
189 | }
190 |
191 | /**
192 | * {@inheritdoc}
193 | */
194 | public function write($path, $contents, Config $config)
195 | {
196 | $file = $this->getFileNode($path, true);
197 | $content = $file->getNode('jcr:content');
198 | $content->setProperty('jcr:data', $contents, PropertyType::BINARY);
199 |
200 | $result = $this->writeMeta($file, $path, $contents, $config);
201 | $result['size'] = $content->getProperty('jcr:data')->getLength();
202 | $result['contents'] = $contents;
203 |
204 | $this->session->save();
205 |
206 | return $result;
207 | }
208 |
209 | /**
210 | * {@inheritdoc}
211 | */
212 | public function writeStream($path, $resource, Config $config)
213 | {
214 | $file = $this->getFileNode($path, true);
215 | $content = $file->getNode('jcr:content');
216 |
217 | $content->setProperty('jcr:data', $resource);
218 |
219 | $this->session->save();
220 |
221 | return $this->writeMeta($file, $path, $resource, $config);
222 | }
223 |
224 | /**
225 | * {@inheritdoc}
226 | */
227 | public function readStream($path)
228 | {
229 | try {
230 | $file = $this->getFileNode($path);
231 | } catch (PathNotFoundException $e) {
232 | return false;
233 | }
234 | $content = $file->getNode('jcr:content');
235 | $result = $this->getFileInfo($file);
236 | $result['stream'] = $content->getPropertyValue('jcr:data', PropertyType::BINARY);
237 |
238 | return $result;
239 | }
240 |
241 | /**
242 | * {@inheritdoc}
243 | */
244 | public function updateStream($path, $resource, Config $config)
245 | {
246 | return $this->writeStream($path, $resource, $config);
247 | }
248 |
249 | /**
250 | * {@inheritdoc}
251 | */
252 | public function update($path, $contents, Config $config)
253 | {
254 | return $this->write($path, $contents, $config);
255 | }
256 |
257 | /**
258 | * {@inheritdoc}
259 | */
260 | public function read($path)
261 | {
262 | try {
263 | $file = $this->getFileNode($path);
264 | } catch (PathNotFoundException $e) {
265 | return false;
266 | }
267 | $content = $file->getNode('jcr:content');
268 | $result = $this->getFileInfo($file);
269 | $result['contents'] = $content->getPropertyValue('jcr:data', PropertyType::STRING);
270 |
271 | return $result;
272 | }
273 |
274 | /**
275 | * {@inheritdoc}
276 | */
277 | public function rename($path, $newpath)
278 | {
279 | $location = $this->applyPathPrefix($path);
280 | if (!$this->session->nodeExists($location)) {
281 | return false;
282 | }
283 | $destination = $this->applyPathPrefix($newpath);
284 | $parentFolder = $this->applyPathPrefix(PathHelper::getParentPath($newpath));
285 | $this->getFolderNode($parentFolder, true);
286 |
287 | $this->session->move($location, $destination);
288 | $this->session->save();
289 |
290 | return true;
291 | }
292 |
293 | /**
294 | * {@inheritdoc}
295 | */
296 | public function copy($path, $newpath)
297 | {
298 | $location = $this->applyPathPrefix($path);
299 | if (!$this->session->nodeExists($location)) {
300 | return false;
301 | }
302 | $destination = $this->applyPathPrefix($newpath);
303 | $parentFolder = $this->applyPathPrefix(PathHelper::getParentPath($newpath));
304 | $this->getFolderNode($parentFolder, true);
305 |
306 | $this->session->save();
307 | $this->session->getWorkspace()->copy($location, $destination);
308 |
309 | return true;
310 | }
311 |
312 | /**
313 | * {@inheritdoc}
314 | */
315 | public function delete($path)
316 | {
317 | try {
318 | $node = $this->getFileNode($path);
319 | } catch (PathNotFoundException $e) {
320 | return false;
321 | }
322 | $node->remove();
323 | $this->session->save();
324 |
325 | return true;
326 | }
327 |
328 | /**
329 | * {@inheritdoc}
330 | */
331 | public function listContents($directory = '', $recursive = false)
332 | {
333 | try {
334 | $folder = $this->getFolderNode($directory);
335 | } catch (PathNotFoundException $e) {
336 | return array();
337 | }
338 |
339 | $result = [];
340 | $files = [];
341 | foreach ($folder->getNodes() as $node) {
342 | $files[] = $node;
343 | }
344 | while ($file = array_shift($files)) {
345 | $result[] = $this->getFileInfo($file);
346 | if ($recursive && $file->isNodeType('nt:folder')) {
347 | foreach ($file->getNodes() as $node) {
348 | $files[] = $node;
349 | }
350 | }
351 | }
352 |
353 | return $result;
354 | }
355 |
356 | /**
357 | * {@inheritdoc}
358 | */
359 | public function getMetadata($path)
360 | {
361 | try {
362 | $file = $this->getFileNode($path);
363 | } catch (PathNotFoundException $e) {
364 | return false;
365 | }
366 |
367 | return $this->getFileInfo($file);
368 | }
369 |
370 | /**
371 | * {@inheritdoc}
372 | */
373 | public function getSize($path)
374 | {
375 | return $this->getMetadata($path);
376 | }
377 |
378 | /**
379 | * {@inheritdoc}
380 | */
381 | public function getMimetype($path)
382 | {
383 | return $this->getMetadata($path);
384 | }
385 |
386 | /**
387 | * {@inheritdoc}
388 | */
389 | public function getTimestamp($path)
390 | {
391 | return $this->getMetadata($path);
392 | }
393 |
394 | private function getFileInfo(NodeInterface $file)
395 | {
396 | $type = $file->isNodeType('nt:folder') ? 'folder' : 'file';
397 |
398 | $result = array(
399 | 'type' => $type,
400 | 'path' => $this->removePathPrefix($file->getPath()),
401 | );
402 |
403 | if ('file' === $type) {
404 | $content = $file->getNode('jcr:content');
405 | $result['size'] = $content->getProperty('jcr:data')->getLength();
406 | $result['timestamp'] = $content->getPropertyValue('jcr:lastModified', PropertyType::LONG);
407 | if ($content->hasProperty('jcr:mimeType')) {
408 | $result['mimetype'] = $content->getPropertyValue('jcr:mimeType');
409 | }
410 | if ($content->hasProperty('jcr:encoding')) {
411 | $result['encoding'] = $content->getPropertyValue('jcr:encoding');
412 | }
413 | }
414 |
415 | return $result;
416 | }
417 |
418 | /**
419 | * {@inheritdoc}
420 | */
421 | public function createDir($dirname, Config $config)
422 | {
423 | $this->getFolderNode($dirname, true);
424 |
425 | return ['path' => $dirname, 'type' => 'dir'];
426 | }
427 |
428 | /**
429 | * {@inheritdoc}
430 | */
431 | public function deleteDir($dirname)
432 | {
433 | try {
434 | $this->getFolderNode($dirname)->remove();
435 | } catch (PathNotFoundException $e) {
436 | return false;
437 | } catch (\LogicException $e) {
438 | return false;
439 | }
440 | $this->session->save();
441 |
442 | return true;
443 | }
444 | }
445 |
--------------------------------------------------------------------------------
/tests/PhpcrAdapterTest.php:
--------------------------------------------------------------------------------
1 | 'pdo_sqlite',
39 | 'path' => sys_get_temp_dir().DIRECTORY_SEPARATOR.'flysystem-test.db',
40 | ));
41 | $options = array('disable_fks' => static::$connection->getDatabasePlatform() instanceof \Doctrine\DBAL\Platforms\SqlitePlatform);
42 | $repositorySchema = new \Jackalope\Transport\DoctrineDBAL\RepositorySchema($options, static::$connection);
43 | $repositorySchema->reset();
44 | }
45 |
46 | public function setUp()
47 | {
48 | $this->root = '/flysystem_tests';
49 |
50 | $factory = new RepositoryFactoryDoctrineDBAL();
51 | $repository = $factory->getRepository(array(
52 | 'jackalope.doctrine_dbal_connection' => static::$connection,
53 | ));
54 | $this->session = $repository->login(new SimpleCredentials('test', 'test'));
55 | if ($this->session->nodeExists($this->root)) {
56 | $this->session->removeItem($this->root);
57 | }
58 | $this->adapter = new PhpcrAdapter($this->session, $this->root);
59 | }
60 |
61 | /**
62 | * @expectedException \LogicException
63 | */
64 | public function testConstructor()
65 | {
66 | $this->session->getRootNode()->addNode('/flysystem_tests_broken', 'nt:unstructured');
67 | new PhpcrAdapter($this->session, '/flysystem_tests_broken');
68 | }
69 |
70 | public function testHasWithDir()
71 | {
72 | $this->adapter->createDir('0', new Config());
73 | $this->assertTrue($this->adapter->has('0'));
74 | $this->adapter->deleteDir('0');
75 | }
76 |
77 | public function testHasWithFile()
78 | {
79 | $this->adapter->write('file.txt', 'content', new Config());
80 | $this->assertTrue($this->adapter->has('file.txt'));
81 | $this->adapter->delete('file.txt');
82 | }
83 |
84 | public function testReadNotFound()
85 | {
86 | $this->assertFalse($this->adapter->read('file.txt'));
87 | }
88 |
89 | public function testReadFolderNotFound()
90 | {
91 | $this->assertFalse($this->adapter->read('folder/file.txt'));
92 | }
93 |
94 | public function testReadStream()
95 | {
96 | $this->adapter->write('file.txt', 'contents', new Config());
97 | $result = $this->adapter->readStream('file.txt');
98 | $this->assertInternalType('array', $result);
99 | $this->assertArrayHasKey('stream', $result);
100 | $this->assertInternalType('resource', $result['stream']);
101 | fclose($result['stream']);
102 | $this->adapter->delete('file.txt');
103 | }
104 |
105 | public function testReadStreamNotFound()
106 | {
107 | $this->assertFalse($this->adapter->readStream('file.txt'));
108 | }
109 |
110 | public function testUpdate()
111 | {
112 | $this->adapter->update('file.txt', 'content', new Config());
113 | $this->assertTrue($this->adapter->has('file.txt'));
114 | $this->adapter->delete('file.txt');
115 | }
116 |
117 | public function testWriteStream()
118 | {
119 | $temp = tmpfile();
120 | fwrite($temp, 'dummy');
121 | rewind($temp);
122 | $this->adapter->writeStream('dir/file.txt', $temp, new Config(['visibility' => 'public']));
123 | //fclose($temp);
124 | $this->assertTrue($this->adapter->has('dir/file.txt'));
125 | $result = $this->adapter->read('dir/file.txt');
126 | $this->assertEquals('dummy', $result['contents']);
127 | $this->adapter->deleteDir('dir');
128 | }
129 |
130 | public function testUpdateStream()
131 | {
132 | $this->adapter->write('file.txt', 'initial', new Config());
133 | $temp = tmpfile();
134 | fwrite($temp, 'dummy');
135 | $this->adapter->updateStream('file.txt', $temp, new Config());
136 | // fclose($temp);
137 | $this->assertTrue($this->adapter->has('file.txt'));
138 | $this->adapter->delete('file.txt');
139 | }
140 |
141 | public function testCreateZeroDir()
142 | {
143 | $this->adapter->createDir('0', new Config());
144 | $this->assertTrue($this->session->nodeExists($this->root.'/0'));
145 | $this->adapter->deleteDir('0');
146 | }
147 |
148 | public function testRename()
149 | {
150 | $this->adapter->write('file.ext', 'content', new Config(['visibility' => 'public']));
151 | $this->assertTrue($this->adapter->rename('file.ext', 'new.ext'));
152 | $this->assertTrue($this->adapter->has('new.ext'));
153 | $this->assertFalse($this->adapter->has('file.ext'));
154 | $this->adapter->delete('file.ext');
155 | $this->adapter->delete('new.ext');
156 | }
157 |
158 | public function testRenameNotExists()
159 | {
160 | $this->assertFalse($this->adapter->rename('file.ext', 'new.ext'));
161 | }
162 |
163 | public function testCopy()
164 | {
165 | $this->adapter->write('file.ext', 'content', new Config(['visibility' => 'public']));
166 | $this->assertTrue($this->adapter->copy('file.ext', 'new.ext'));
167 | $this->assertTrue($this->adapter->has('new.ext'));
168 | $this->assertTrue($this->adapter->has('file.ext'));
169 | $this->adapter->delete('file.ext');
170 | $this->adapter->delete('new.ext');
171 | }
172 |
173 | public function testCopyNotExists()
174 | {
175 | $this->assertFalse($this->adapter->copy('file.ext', 'new.ext'));
176 | }
177 |
178 | public function testListContents()
179 | {
180 | $this->adapter->write('dirname/file.txt', 'contents', new Config());
181 | $this->adapter->write('dirname/subfolder/file.txt', 'contents', new Config());
182 | $contents = $this->adapter->listContents('dirname', false);
183 | $this->assertCount(2, $contents);
184 | $this->assertArrayHasKey('type', $contents[0]);
185 | $this->assertEquals('file', $contents[0]['type']);
186 | $this->assertArrayHasKey('type', $contents[1]);
187 | $this->assertEquals('folder', $contents[1]['type']);
188 | }
189 |
190 | public function testListContentsRecursive()
191 | {
192 | $this->adapter->write('dirname/file.txt', 'contents', new Config());
193 | $this->adapter->write('dirname/subfolder/file.txt', 'contents', new Config());
194 | $contents = $this->adapter->listContents('dirname', true);
195 | $this->assertCount(3, $contents);
196 | $this->assertArrayHasKey('type', $contents[0]);
197 | $this->assertEquals('file', $contents[0]['type']);
198 | $this->assertArrayHasKey('type', $contents[1]);
199 | $this->assertEquals('folder', $contents[1]['type']);
200 | $this->assertArrayHasKey('type', $contents[2]);
201 | $this->assertEquals('file', $contents[2]['type']);
202 | $this->assertEquals('dirname/subfolder/file.txt', $contents[2]['path']);
203 | }
204 |
205 | public function testListingNonexistingDirectory()
206 | {
207 | $result = $this->adapter->listContents('nonexisting/directory');
208 | $this->assertEquals([], $result);
209 | }
210 |
211 | public function testGetMetadataFolder()
212 | {
213 | $this->adapter->createDir('test', new Config());
214 | $result = $this->adapter->getMetadata('test');
215 | $this->assertInternalType('array', $result);
216 | $this->assertArrayHasKey('type', $result);
217 | $this->assertEquals('folder', $result['type']);
218 | }
219 |
220 | public function testGetMetadataNotExisting()
221 | {
222 | $this->assertFalse($this->adapter->getMetadata('dummy.txt'));
223 | }
224 |
225 | public function testGetSize()
226 | {
227 | $this->adapter->write('dummy.txt', '1234', new Config());
228 | $result = $this->adapter->getSize('dummy.txt');
229 | $this->assertInternalType('array', $result);
230 | $this->assertArrayHasKey('size', $result);
231 | $this->assertEquals(4, $result['size']);
232 | }
233 |
234 | public function testGetTimestamp()
235 | {
236 | $this->adapter->write('dummy.txt', '1234', new Config());
237 | $result = $this->adapter->getTimestamp('dummy.txt');
238 | $this->assertInternalType('array', $result);
239 | $this->assertArrayHasKey('timestamp', $result);
240 | $this->assertInternalType('int', $result['timestamp']);
241 | }
242 |
243 | public function testGetMimetype()
244 | {
245 | $this->adapter->write('text.txt', 'contents', new Config());
246 | $result = $this->adapter->getMimetype('text.txt');
247 | $this->assertInternalType('array', $result);
248 | $this->assertArrayHasKey('mimetype', $result);
249 | $this->assertEquals('text/plain', $result['mimetype']);
250 | }
251 |
252 | public function testGetEncoding()
253 | {
254 | $this->adapter->write('text.txt', 'contents', new Config(array('encoding' => 'utf-8')));
255 | $result = $this->adapter->getMimetype('text.txt');
256 | $this->assertInternalType('array', $result);
257 | $this->assertArrayHasKey('encoding', $result);
258 | $this->assertEquals('utf-8', $result['encoding']);
259 | }
260 |
261 | public function testDeleteDir()
262 | {
263 | $this->adapter->write('nested/dir/path.txt', 'contents', new Config());
264 | $this->assertTrue($this->session->nodeExists($this->root.'/nested/dir/path.txt'));
265 | $this->assertTrue($this->adapter->deleteDir('nested'));
266 | $this->assertFalse($this->adapter->has('nested/dir/path.txt'));
267 | $this->assertFalse($this->session->nodeExists($this->root.'/nested'));
268 | }
269 |
270 | public function testDeleteDirNotFound()
271 | {
272 | $this->assertFalse($this->adapter->deleteDir('nested'));
273 | }
274 |
275 | public function testDeleteDirIsFile()
276 | {
277 | $this->adapter->write('dir/path.txt', 'contents', new Config());
278 | $this->assertTrue($this->session->nodeExists($this->root.'/dir/path.txt'));
279 | $this->assertFalse($this->adapter->deleteDir('dir/path.txt'));
280 | }
281 |
282 | /**
283 | * @expectedException \LogicException
284 | */
285 | public function testVisibilityPublic()
286 | {
287 | $this->adapter->write('path.txt', 'contents', new Config());
288 | $this->adapter->setVisibility('path.txt', 'public');
289 | }
290 |
291 | /**
292 | * @expectedException \LogicException
293 | */
294 | public function testVisibilityPrivate()
295 | {
296 | $this->adapter->write('path.txt', 'contents', new Config());
297 | $this->adapter->setVisibility('path.txt', 'private');
298 | }
299 |
300 | public function testApplyPathPrefix()
301 | {
302 | $this->adapter->setPathPrefix('');
303 | $this->assertEquals('', $this->adapter->applyPathPrefix(''));
304 | }
305 |
306 | public function testApplyPathPrefixAbsolute()
307 | {
308 | $this->adapter->setPathPrefix($this->root . '/');
309 | $this->assertEquals($this->root, $this->adapter->applyPathPrefix('/'));
310 | }
311 |
312 | public function testWriteWithSpecificTimestampInConfig()
313 | {
314 | $timestamp = strtotime('today midnight');
315 | $this->adapter->write('dummy.txt', '1234', new Config(['timestamp' => $timestamp]));
316 | $result = $this->adapter->getTimestamp('dummy.txt');
317 | $this->assertInternalType('array', $result);
318 | $this->assertArrayHasKey('timestamp', $result);
319 | $this->assertInternalType('int', $result['timestamp']);
320 | $this->assertEquals($timestamp, $result['timestamp']);
321 | }
322 | }
323 |
--------------------------------------------------------------------------------