Skip to content

Commit

Permalink
Added Copy function and improved the documentation.
Browse files Browse the repository at this point in the history
  • Loading branch information
jmartin82 committed Sep 13, 2016
1 parent 0b31297 commit 75d51e4
Show file tree
Hide file tree
Showing 13 changed files with 263 additions and 41 deletions.
45 changes: 34 additions & 11 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,34 @@ Storage is a filesystem abstraction which allows you to easily swap out a local
## TLDR;
```php

//faster way
(new StorageBuilder())->build()->put('/tmp/test.txt',"this is a test");

//more customized
$sb = new StorageBuilder();
$s = $sb->addAdapter('S3AWS')
->addAdapter(new DropBox())
->addAdapter('FileSystem')
//one adapter (save data to S3)
$s3Adapter = new \Cmp\Storage\Adapter\S3AWSAdapter();
$s->put('/tmp/test.txt',"this is a test");


//two adapters with a fallback strategy and decorated with a logger
$s3Adapter = new \Cmp\Storage\Adapter\S3AWSAdapter();
$fallBackAdapter = (new StorageBuilder())->addAdapter($s3Adapter)
->addAdapter($s3Adapter) //the order matters with FallBackChainStrategy
->addAdapter($fileSystemAdapter)
->setLogger(new Logger())
->build(new \Cmp\Storage\Strategy\FallBackChainStrategy());
$s->put('/tmp/test.txt',"this is a test");

//it saves data to S3 and if fails save the data to FS
$fallBackAdapter->put('/tmp/test.txt',"this is a test");


//one step more fs adapter bind to one folder and strategy to another folder
$vfs = new \Cmp\Storage\MountableVirtualStorage($fileSystemStorage); //bind to any path that non match with mountpoint folders
$localMountPoint = new \Cmp\Storage\MountPoint('/tmp', $fileSystemAdapter);
$publicMountPoint = new \Cmp\Storage\MountPoint('/var/www/app/public', $s3Adapter);
$vfs->registerMountPoint($localMountPoint);
$vfs->registerMountPoint($publicMountPoint);

/*
//move file from /tmp (FS) to /var/www/app/public (S3) and if fails try to move from /tmp (FS) to /var/www/app/public (FS)
*/
$vfs->move('/tmp/testfile.jpg','/var/www/app/public/avatar.jpg' );
```

## Installation
Expand Down Expand Up @@ -55,6 +70,7 @@ The adapter interface contains these methods:
* `get`
* `getStream`
* `rename`
* `copy`
* `delete`
* `put`
* `putStream`
Expand Down Expand Up @@ -84,8 +100,12 @@ After that you can register new mount points.
Example:

```php
$localMountPoint = new \Cmp\Storage\MountPoint('/tmp', $this->fileSystemStorage);
$publicMountPoint = new \Cmp\Storage\MountPoint('/var/www/app/public', $this->s3Adapter);
$s3Adapter = new \Cmp\Storage\Adapter\S3AWSAdapter();
$fileSystemAdapter = new \Cmp\Storage\Adapter\FileSystemAdapter();

$localMountPoint = new \Cmp\Storage\MountPoint('/tmp', $fileSystemAdapter);
$publicMountPoint = new \Cmp\Storage\MountPoint('/var/www/app/public', $s3Adapter);

$vfs = new \Cmp\Storage\MountableVirtualStorage($this->fileSystemStorage); //bind to /
$vfs->registerMountPoint($localMountPoint);
$vfs->registerMountPoint($publicMountPoint);
Expand Down Expand Up @@ -145,6 +165,9 @@ Retrieves a read-stream for a file.
### Rename
Rename a file.

### Copy
Copy a file.

### Delete
Delete a file or directory (even if is not empty).

Expand Down
16 changes: 16 additions & 0 deletions src/Cmp/Storage/Adapter/FileSystemAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,22 @@ public function rename($path, $newpath, $overwrite = false)
return rename($path, $newpath);
}

/**
* Copy a file.
*
* @param string $path Path to the existing file
* @param string $newpath The destination path of the copy
*
* @return bool
*/
public function copy($path, $newpath)
{
$path = $this->normalizePath($path);
$this->assertNotFileExists($path);

return copy($path, $newpath);
}

/**
* Delete a file or directory.
*
Expand Down
8 changes: 5 additions & 3 deletions src/Cmp/Storage/Adapter/S3AWSAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -243,12 +243,14 @@ public function putStream($path, $resource)
}

/**
* @param string $path
* @param string $newpath
* Copy a file.
*
* @param string $path Path to the existing file
* @param string $newpath The destination path of the copy
*
* @return bool
*/
private function copy($path, $newpath)
public function copy($path, $newpath)
{
$path = $this->trimPrefix($path);
$newpath = $this->trimPrefix($newpath);
Expand Down
67 changes: 45 additions & 22 deletions src/Cmp/Storage/MountableVirtualStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,17 @@ public function registerMountPoint(MountPoint $mountPoint)
}

/**
* @param $path
* @param VirtualPath $vp
*
* @return MountPoint
*
*/
public function getMountPointForPath($path)
public function getMountPointForPath(VirtualPath $vp)
{
$it = $this->mountPoints->getIterator();
$virtualPath = new VirtualPath($path);

foreach ($it as $mountPoint) {
if ($mountPoint->getVirtualPath()->isChild($virtualPath)) {
if ($mountPoint->getVirtualPath()->isChild($vp)) {
return $mountPoint;
}
}
Expand All @@ -61,54 +62,75 @@ public function getMountPointForPath($path)

public function exists($path)
{
return $this->getStorageForPath($path)->exists($path);
$vp = new VirtualPath($path);
return $this->getStorageForPath($vp)->exists($vp->getPath());
}

public function get($path)
{
return $this->getStorageForPath($path)->get($path);
$vp = new VirtualPath($path);
return $this->getStorageForPath($vp)->get($vp->getPath());
}

public function getStream($path)
{
return $this->getStorageForPath($path)->getStream($path);
$vp = new VirtualPath($path);
return $this->getStorageForPath($vp)->getStream($vp->getPath());
}

public function rename($path, $newpath, $overwrite = false)
{
$storageSrc = $this->getStorageForPath($path);
$storageDst = $this->getStorageForPath($newpath);
$svp = new VirtualPath($path);
$dvp = new VirtualPath($newpath);
$storageSrc = $this->getStorageForPath($svp);
$storageDst = $this->getStorageForPath($dvp);

if (!$overwrite && $storageDst->exists($dvp->getPath())) {
throw new FileExistsException($dvp->getPath());

if (!$storageSrc->exists($path)) {
return false;
}

if (!$overwrite && $storageDst->exists($newpath)) {
throw new FileExistsException($newpath);
return $this->copy($svp->getPath(), $dvp->getPath()) && $storageSrc->delete($svp->getPath());
}


public function copy($path, $newpath)
{
$svp = new VirtualPath($path);
$dvp = new VirtualPath($newpath);
$storageSrc = $this->getStorageForPath($svp);
$storageDst = $this->getStorageForPath($dvp);

if (!$storageSrc->exists($svp->getPath())) {
return false;
}

$stream = $storageSrc->getStream($path);
$stream = $storageSrc->getStream($svp->getPath());
if (!$stream) {
return false;
}
$storageDst->putStream($newpath, $stream);
$storageDst->putStream($dvp->getPath(), $stream);

return $storageDst->exists($newpath) && $storageSrc->delete($path);
return $storageDst->exists($dvp->getPath());
}


public function delete($path)
{
return $this->getStorageForPath($path)->delete($path);
$vp = new VirtualPath($path);
return $this->getStorageForPath($vp)->delete($vp->getPath());
}

public function put($path, $contents)
{
return $this->getStorageForPath($path)->put($path, $contents);
$vp = new VirtualPath($path);
return $this->getStorageForPath($vp)->put($vp->getPath(), $contents);
}

public function putStream($path, $resource)
{
return $this->getStorageForPath($path)->putStream($path, $resource);
$vp = new VirtualPath($path);
return $this->getStorageForPath($vp)->putStream($vp->getPath(), $resource);
}

/**
Expand All @@ -123,14 +145,15 @@ private function getDefaultMountPoint(VirtualStorageInterface $defaultVirtualSto
return $defaultMountPoint;
}


/**
* @param $path
* @param VirtualPath $vp
*
* @return VirtualStorageInterface
*/
private function getStorageForPath($path)
private function getStorageForPath(VirtualPath $vp)
{
$mountPoint = $this->getMountPointForPath($path);
$mountPoint = $this->getMountPointForPath($vp);

return $mountPoint->getStorage();
}
Expand Down
17 changes: 17 additions & 0 deletions src/Cmp/Storage/Strategy/CallAllStrategy.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,23 @@ public function rename($path, $newpath, $overwrite = false)
return $this->runAllAndLog($fn);
}

/**
* Copy a file.
*
* @param string $path Path to the existing file
* @param string $newpath The new path of the file
*
* @return bool
*/
public function copy($path, $newpath)
{
$fn = function ($adapter) use ($path, $newpath) {
return $adapter->copy($path, $newpath);
};

return $this->runAllAndLog($fn);
}

/**
* Delete a file.
*
Expand Down
19 changes: 19 additions & 0 deletions src/Cmp/Storage/Strategy/FallBackChainStrategy.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,25 @@ public function rename($path, $newpath, $overwrite = false)
return $this->runChainAndLog($fn);
}

/**
* Copy a file.
*
* @param string $path Path to the existing file
* @param string $newpath The new path of the file
*
* @return bool
*
* @throws FileExistsException Thrown if $newpath exists
*/
public function copy($path, $newpath)
{
$fn = function (AdapterInterface $adapter) use ($path, $newpath) {
return $adapter->copy($path, $newpath);
};

return $this->runChainAndLog($fn);
}

/**
* Delete a file.
*
Expand Down
11 changes: 11 additions & 0 deletions src/Cmp/Storage/VirtualStorageInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,17 @@ public function getStream($path);
*/
public function rename($path, $newpath, $overwrite = false);


/**
* Rename a file.
*
* @param string $path Path to the existing file
* @param string $newpath The destination path of the copy
*
* @return bool
*/
public function copy($path, $newpath);

/**
* Delete a file or directory.
*
Expand Down
14 changes: 14 additions & 0 deletions test/integration/Cmp/Storage/Adapter/FileSystemAdapterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,20 @@ public function testFileRename()
$this->assertFileExists($filenameNew);
}

public function testFileCopy()
{
$filenameOld = $this->getTempFileName();
$filenameNew = $this->getTempFileName();
$this->assertFileNotExists($filenameOld);
$this->assertFileNotExists($filenameNew);
$this->assertTrue($this->fileSystemStorage->put($filenameOld, 'testFileRename'));
$this->assertFileExists($filenameOld);
$this->assertTrue($this->fileSystemStorage->copy($filenameOld, $filenameNew));
$this->assertFileExists($filenameOld);
$this->assertFileExists($filenameNew);
}


public function testFileRenameWithOverWrite()
{
$filenameOld = $this->getTempFileName();
Expand Down
13 changes: 13 additions & 0 deletions test/integration/Cmp/Storage/Adapter/S3AwsAdapterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,19 @@ public function testFileRename()
$this->assertTrue($this->s3Adapter->exists($filenameNew));
}

public function testFileCopy()
{
$filenameOld = $this->getTempFileName();
$filenameNew = $this->getTempFileName();
$this->assertFalse($this->s3Adapter->exists($filenameOld));
$this->assertFalse($this->s3Adapter->exists($filenameNew));
$this->assertTrue($this->s3Adapter->put($filenameOld, 'testFileRename'));
$this->assertTrue($this->s3Adapter->exists($filenameOld));
$this->assertTrue($this->s3Adapter->copy($filenameOld, $filenameNew));
$this->assertTrue($this->s3Adapter->exists($filenameOld));
$this->assertTrue($this->s3Adapter->exists($filenameNew));
}

public function testFileRenameWithOverWrite()
{
$filenameOld = $this->getTempFileName();
Expand Down
17 changes: 17 additions & 0 deletions test/integration/Cmp/Storage/MountPointsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,23 @@ public function moveFilesBetweenEndpoints()
$this->assertTrue($this->vfs->exists($filenameNew));
}

public function copyFilesBetweenEndpoints()
{
$path = $this->getAvailablePath();
$filenameOld = $this->getTempFileNameInPath($path['tmp']);
$filenameNew = $this->getTempFileNameInPath($path['public']);

$this->assertFalse($this->vfs->exists($filenameOld));
$this->assertFalse($this->vfs->exists($filenameNew));

$this->assertTrue($this->vfs->put($filenameOld, 'testFileRename'));
$this->assertFalse($this->vfs->exists($filenameNew));

$this->assertTrue($this->vfs->copy($filenameOld, $filenameNew));
$this->assertTrue($this->vfs->exists($filenameOld));
$this->assertTrue($this->vfs->exists($filenameNew));
}


public function testFilePutWithStrategies()
{
Expand Down
Loading

0 comments on commit 75d51e4

Please sign in to comment.