Skip to content

Commit b76d7d2

Browse files
author
Moh. Sulton Hasanuddin
committed
add support for Google Cloud Storage
1 parent ba7e2b5 commit b76d7d2

File tree

6 files changed

+174
-11
lines changed

6 files changed

+174
-11
lines changed

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
"php": ">=5.4",
1414
"symfony/http-foundation": "~2.3|~3.0",
1515
"imagine/imagine": "~0.6.2",
16-
"doctrine/inflector": "~1"
16+
"doctrine/inflector": "~1",
17+
"superbalist/flysystem-google-storage": "^3.0|^4.0|^5.0"
1718
},
1819
"require-dev": {
1920
"mockery/mockery": "0.8.0",

src/Attachment.php

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -532,15 +532,10 @@ public function jsonSerialize()
532532
*/
533533
protected function flushWrites()
534534
{
535-
foreach ($this->queuedForWrite as $style) {
536-
if ($style->dimensions && $this->uploadedFile->isImage()) {
537-
$file = $this->resizer->resize($this->uploadedFile, $style);
538-
} else {
539-
$file = $this->uploadedFile->getRealPath();
540-
}
541-
542-
$filePath = $this->path($style->name);
543-
$this->move($file, $filePath);
535+
if ($this->uploadedFile->isImage()) {
536+
$this->queueImages();
537+
} else {
538+
$this->queueFile();
544539
}
545540

546541
$this->queuedForWrite = [];
@@ -555,6 +550,27 @@ protected function flushDeletes()
555550
$this->queuedForDeletion = [];
556551
}
557552

553+
protected function queueImages()
554+
{
555+
foreach ($this->queuedForWrite as $style) {
556+
if ($style->dimensions) {
557+
$file = $this->resizer->resize($this->uploadedFile, $style);
558+
} else {
559+
$file = $this->uploadedFile->getRealPath();
560+
}
561+
562+
$filePath = $this->path($style->name);
563+
$this->move($file, $filePath);
564+
}
565+
}
566+
567+
protected function queueFile()
568+
{
569+
$file = $this->uploadedFile->getRealPath();
570+
$filePath = $this->path($this->config->default_style);
571+
$this->move($file, $filePath);
572+
}
573+
558574
/**
559575
* Fill the queuedForWrite que with all of this attachment's styles.
560576
*/

src/Factories/Storage.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Codesleeve\Stapler\Attachment as AttachedFile;
66
use Codesleeve\Stapler\Storage\Filesystem;
7+
use Codesleeve\Stapler\Storage\GCS;
78
use Codesleeve\Stapler\Storage\S3;
89
use Codesleeve\Stapler\Stapler;
910

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

33+
case 'gcs':
34+
$gcsFilesystem = Stapler::getGCSClientInstance($attachment);
35+
36+
return new GCS($attachment, $gcsFilesystem);
37+
break;
38+
3239
default:
3340
return new Filesystem($attachment);
3441
break;

src/Stapler.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
use Codesleeve\Stapler\Interfaces\Attachment as AttachmentInterface;
66
use Codesleeve\Stapler\Interfaces\Config as ConfigInterface;
77
use Codesleeve\Stapler\File\Image\Resizer;
8+
use League\Flysystem\Filesystem as LeagueFilesystem;
9+
use Superbalist\Flysystem\GoogleStorage\GoogleStorageAdapter;
10+
use Google\Cloud\Storage\StorageClient;
811
use Aws\S3\S3Client;
912

1013
/**
@@ -187,6 +190,26 @@ public static function getS3ClientInstance(AttachmentInterface $attachedFile)
187190
return static::$s3Clients[$key];
188191
}
189192

193+
/**
194+
* Return an Filesystem object for Google Cloud Storage.
195+
*
196+
* @param AttachmentInterface $attachedFile
197+
*
198+
* @return \League\Flysystem\Filesystem
199+
*/
200+
public static function getGCSClientInstance(AttachmentInterface $attachedFile)
201+
{
202+
$storageClient = new StorageClient([
203+
'projectId' => $attachedFile->google_cloud_project_id,
204+
'keyFilePath' => $attachedFile->google_cloud_key_file,
205+
]);
206+
207+
$bucket = $storageClient->bucket($attachedFile->google_cloud_storage_bucket);
208+
$adapter = new GoogleStorageAdapter($storageClient, $bucket);
209+
$filesystem = new LeagueFilesystem($adapter);
210+
return $filesystem;
211+
}
212+
190213
/**
191214
* Return a configuration object instance.
192215
* If no instance is currently set, we'll return an instance

src/Storage/GCS.php

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?php
2+
3+
namespace Codesleeve\Stapler\Storage;
4+
5+
use Codesleeve\Stapler\Interfaces\Storage as StorageInterface;
6+
use Codesleeve\Stapler\Attachment;
7+
use League\Flysystem\Filesystem;
8+
9+
class GCS implements StorageInterface
10+
{
11+
/**
12+
* The current attachedFile object being processed.
13+
*
14+
* @var \Codesleeve\Stapler\Attachment
15+
*/
16+
public $attachedFile;
17+
18+
/**
19+
* The AWS S3Client instance.
20+
*
21+
* @var Filesystem
22+
*/
23+
protected $filesystem;
24+
25+
/**
26+
* Constructor method.
27+
*
28+
* @param Attachment $attachedFile
29+
* @param Filesystem $filesystem
30+
*/
31+
public function __construct(Attachment $attachedFile, Filesystem $filesystem)
32+
{
33+
$this->attachedFile = $attachedFile;
34+
$this->filesystem = $filesystem;
35+
}
36+
37+
/**
38+
* Return the url for a file upload.
39+
*
40+
* @param string $styleName
41+
*
42+
* @return string
43+
*/
44+
public function url($styleName)
45+
{
46+
return $this->filesystem->getAdapter()->getUrl($this->path($styleName));
47+
}
48+
49+
/**
50+
* Return the key the uploaded file object is stored under within a bucket.
51+
*
52+
* @param string $styleName
53+
*
54+
* @return string
55+
*/
56+
public function path($styleName)
57+
{
58+
return $this->attachedFile->getInterpolator()->interpolate($this->attachedFile->path, $this->attachedFile, $styleName);
59+
}
60+
61+
/**
62+
* Remove an attached file.
63+
*
64+
* @param array $filePaths
65+
*/
66+
public function remove(array $filePaths)
67+
{
68+
if ($filePaths) {
69+
$this->filesystem->delete($filePaths);
70+
}
71+
}
72+
73+
/**
74+
* Move an uploaded file to it's intended destination.
75+
*
76+
* @param string $file
77+
* @param string $filePath
78+
*/
79+
public function move($file, $filePath)
80+
{
81+
$this->filesystem->put($filePath, fopen($file, 'r+'));
82+
}
83+
}

src/Validator.php

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,17 @@ class Validator implements ValidatorInterface
1414
*/
1515
public function validateOptions(array $options)
1616
{
17-
$options['storage'] == 'filesystem' ? $this->validateFilesystemOptions($options) : $this->validateS3Options($options);
17+
switch ($options['storage']) {
18+
case 's3':
19+
$this->validateS3Options($options);
20+
break;
21+
case 'gcs':
22+
$this->validateGCSOptions($options);
23+
break;
24+
case 'filesystem':
25+
default:
26+
$this->validateFilesystemOptions($options);
27+
}
1828
}
1929

2030
/**
@@ -54,4 +64,27 @@ protected function validateS3Options(array $options)
5464
throw new Exceptions\InvalidUrlOptionException('Invalid Path: a key is required for s3 storage.', 1);
5565
}
5666
}
67+
68+
/**
69+
* Validate the attachment options for an attachment type when the storage
70+
* driver is set to 'gcs'.
71+
*
72+
* @throws InvalidUrlOptionException
73+
*
74+
* @param array $options
75+
*/
76+
protected function validateGCSOptions(array $options)
77+
{
78+
if (!$options['google_cloud_project_id']) {
79+
throw new InvalidUrlOptionException('Invalid Path: a google project id is required for gcs storage.', 1);
80+
}
81+
82+
if (!$options['google_cloud_key_file']) {
83+
throw new InvalidUrlOptionException('Invalid Path: a google key file is required for gcs storage.', 1);
84+
}
85+
86+
if (!$options['google_cloud_storage_bucket']) {
87+
throw new InvalidUrlOptionException('Invalid Path: a bucket is required for gcs storage.', 1);
88+
}
89+
}
5790
}

0 commit comments

Comments
 (0)