Skip to content

Commit

Permalink
add support for Google Cloud Storage
Browse files Browse the repository at this point in the history
  • Loading branch information
shcode committed Aug 3, 2017
1 parent ba7e2b5 commit 3e80569
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 11 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"php": ">=5.4",
"symfony/http-foundation": "~2.3|~3.0",
"imagine/imagine": "~0.6.2",
"doctrine/inflector": "~1"
"doctrine/inflector": "~1",
"superbalist/flysystem-google-storage": "^3.0|^4.0|^5.0"
},
"require-dev": {
"mockery/mockery": "0.8.0",
Expand Down
34 changes: 25 additions & 9 deletions src/Attachment.php
Original file line number Diff line number Diff line change
Expand Up @@ -532,15 +532,10 @@ public function jsonSerialize()
*/
protected function flushWrites()
{
foreach ($this->queuedForWrite as $style) {
if ($style->dimensions && $this->uploadedFile->isImage()) {
$file = $this->resizer->resize($this->uploadedFile, $style);
} else {
$file = $this->uploadedFile->getRealPath();
}

$filePath = $this->path($style->name);
$this->move($file, $filePath);
if ($this->uploadedFile->isImage()) {
$this->queueImages();
} else {
$this->queueFile();
}

$this->queuedForWrite = [];
Expand All @@ -555,6 +550,27 @@ protected function flushDeletes()
$this->queuedForDeletion = [];
}

protected function queueImages()
{
foreach ($this->queuedForWrite as $style) {
if ($style->dimensions) {
$file = $this->resizer->resize($this->uploadedFile, $style);
} else {
$file = $this->uploadedFile->getRealPath();
}

$filePath = $this->path($style->name);
$this->move($file, $filePath);
}
}

protected function queueFile()
{
$file = $this->uploadedFile->getRealPath();
$filePath = $this->path($this->config->default_style);
$this->move($file, $filePath);
}

/**
* Fill the queuedForWrite que with all of this attachment's styles.
*/
Expand Down
7 changes: 7 additions & 0 deletions src/Factories/Storage.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Codesleeve\Stapler\Attachment as AttachedFile;
use Codesleeve\Stapler\Storage\Filesystem;
use Codesleeve\Stapler\Storage\GCS;
use Codesleeve\Stapler\Storage\S3;
use Codesleeve\Stapler\Stapler;

Expand All @@ -29,6 +30,12 @@ public static function create(AttachedFile $attachment)
return new S3($attachment, $s3Client);
break;

case 'gcs':
$gcsFilesystem = Stapler::getGCSClientInstance($attachment);

return new GCS($attachment, $gcsFilesystem);
break;

default:
return new Filesystem($attachment);
break;
Expand Down
23 changes: 23 additions & 0 deletions src/Stapler.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
use Codesleeve\Stapler\Interfaces\Attachment as AttachmentInterface;
use Codesleeve\Stapler\Interfaces\Config as ConfigInterface;
use Codesleeve\Stapler\File\Image\Resizer;
use League\Flysystem\Filesystem as LeagueFilesystem;
use Superbalist\Flysystem\GoogleStorage\GoogleStorageAdapter;
use Google\Cloud\Storage\StorageClient;
use Aws\S3\S3Client;

/**
Expand Down Expand Up @@ -187,6 +190,26 @@ public static function getS3ClientInstance(AttachmentInterface $attachedFile)
return static::$s3Clients[$key];
}

/**
* Return an Filesystem object for Google Cloud Storage.
*
* @param AttachmentInterface $attachedFile
*
* @return \League\Flysystem\Filesystem
*/
public static function getGCSClientInstance(AttachmentInterface $attachedFile)
{
$storageClient = new StorageClient([
'projectId' => $attachedFile->google_cloud_project_id,
'keyFilePath' => $attachedFile->google_cloud_key_file,
]);

$bucket = $storageClient->bucket($attachedFile->google_cloud_storage_bucket);
$adapter = new GoogleStorageAdapter($storageClient, $bucket);
$filesystem = new LeagueFilesystem($adapter);
return $filesystem;
}

/**
* Return a configuration object instance.
* If no instance is currently set, we'll return an instance
Expand Down
83 changes: 83 additions & 0 deletions src/Storage/GCS.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php

namespace Codesleeve\Stapler\Storage;

use Codesleeve\Stapler\Interfaces\Storage as StorageInterface;
use Codesleeve\Stapler\Attachment;
use League\Flysystem\Filesystem;

class GCS implements StorageInterface
{
/**
* The current attachedFile object being processed.
*
* @var \Codesleeve\Stapler\Attachment
*/
public $attachedFile;

/**
* The AWS S3Client instance.
*
* @var Filesystem
*/
protected $filesystem;

/**
* Constructor method.
*
* @param Attachment $attachedFile
* @param Filesystem $filesystem
*/
public function __construct(Attachment $attachedFile, Filesystem $filesystem)
{
$this->attachedFile = $attachedFile;
$this->filesystem = $filesystem;
}

/**
* Return the url for a file upload.
*
* @param string $styleName
*
* @return string
*/
public function url($styleName)
{
return $this->filesystem->getAdapter()->getUrl($this->path($styleName));
}

/**
* Return the key the uploaded file object is stored under within a bucket.
*
* @param string $styleName
*
* @return string
*/
public function path($styleName)
{
return $this->attachedFile->getInterpolator()->interpolate($this->attachedFile->path, $this->attachedFile, $styleName);
}

/**
* Remove an attached file.
*
* @param array $filePaths
*/
public function remove(array $filePaths)
{
if ($filePaths) {
$this->filesystem->delete($filePaths);
}
}

/**
* Move an uploaded file to it's intended destination.
*
* @param string $file
* @param string $filePath
*/
public function move($file, $filePath)
{
$this->filesystem->put($filePath, fopen($file, 'r+'));
}
}
35 changes: 34 additions & 1 deletion src/Validator.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,17 @@ class Validator implements ValidatorInterface
*/
public function validateOptions(array $options)
{
$options['storage'] == 'filesystem' ? $this->validateFilesystemOptions($options) : $this->validateS3Options($options);
switch ($options['storage']) {
case 's3':
$this->validateS3Options($options);
break;
case 'gcs':
$this->validateGCSOptions($options);
break;
case 'filesystem':
default:
$this->validateFilesystemOptions($options);
}
}

/**
Expand Down Expand Up @@ -54,4 +64,27 @@ protected function validateS3Options(array $options)
throw new Exceptions\InvalidUrlOptionException('Invalid Path: a key is required for s3 storage.', 1);
}
}

/**
* Validate the attachment options for an attachment type when the storage
* driver is set to 'gcs'.
*
* @throws InvalidUrlOptionException
*
* @param array $options
*/
protected function validateGCSOptions(array $options)
{
if (!$options['google_cloud_project_id']) {
throw new InvalidUrlOptionException('Invalid Path: a google project id is required for gcs storage.', 1);
}

if (!$options['google_cloud_key_file']) {
throw new InvalidUrlOptionException('Invalid Path: a google key file is required for gcs storage.', 1);
}

if (!$options['google_cloud_storage_bucket']) {
throw new InvalidUrlOptionException('Invalid Path: a bucket is required for gcs storage.', 1);
}
}
}

0 comments on commit 3e80569

Please sign in to comment.