Overview

Namespaces

  • NGS
    • Client
      • Exception
    • Converter
    • Patterns
  • PHP

Classes

  • BigDecimal
  • BigInt
  • ByteStream
  • LocalDate
  • Location
  • Money
  • Name
  • Point
  • S3
  • Timestamp
  • Utils
  • UUID
  • Overview
  • Namespace
  • Class
  • Tree
  1: <?php
  2: namespace NGS;
  3: 
  4: use AmazonS3;
  5: use InvalidArgumentException;
  6: use LogicException;
  7: use NGS\Converter\PrimitiveConverter;
  8: use NGS\S3;
  9: use NGS\Utils;
 10: use NGS\UUID;
 11: use S3StreamWrapper;
 12: 
 13: class S3
 14: {
 15:     const HOST = 's3.amazonaws.com';
 16: 
 17:     /** @var AmazonS3 singleton AmazonS3 instance */
 18:     private static $client;
 19: 
 20:     private static $defaultBucket;
 21: 
 22:     private $bucket;
 23:     private $key;
 24:     private $name;
 25:     private $length;
 26:     private $mimeType;
 27:     private $metadata;
 28: 
 29:     /**
 30:      * Constructs new instance from array, stream, another NGS\S3 instance
 31:      * @param S3|array|resource $source
 32:      * @param string $bucket
 33:      */
 34:     public function __construct($source=null, $bucket=null)
 35:     {
 36:         if(is_array($source)) {
 37:             self::fromArray($source);
 38:         }
 39:         elseif($source !== null) {
 40:             if ($bucket !== null) {
 41:                 $this->bucket = PrimitiveConverter::toString($bucket);
 42:             }
 43:             if ($source instanceof S3) {
 44:                 $this->fromArray($source->toArray());
 45:             }
 46:             elseif (is_string($source)) {
 47:                 $this->upload($source);
 48:             }
 49:             elseif (is_resource($source) && get_resource_type($source)==='stream') {
 50:                 $this->upload($source);
 51:             }
 52:             else {
 53:                 throw new InvalidArgumentException('Cannot construct NGS\S3 from invalid type "'.Utils::getType($source).'"');
 54:             }
 55:         }
 56:     }
 57: 
 58:     private function fromArray(array $values)
 59:     {
 60:         if (isset($values['Bucket']))
 61:             $this->bucket   = PrimitiveConverter::toString($values['Bucket']);
 62:         if (isset($values['Key']))
 63:             $this->key      = PrimitiveConverter::toString($values['Key']);
 64:         if (isset($values['Length']))
 65:             $this->length   = PrimitiveConverter::toInteger($values['Length']);
 66:         if (isset($values['Name']))
 67:             $this->setName($values['Name']);
 68:         if (isset($values['MimeType']))
 69:             $this->setMimeType($values['MimeType']);
 70:         if (isset($values['Metadata']))
 71:             $this->setMetadata($values['Metadata']);
 72:     }
 73: 
 74:     public function setName($name)
 75:     {
 76:         $this->name = PrimitiveConverter::toString($name);
 77:     }
 78: 
 79:     public function setMetadata(array $metadata)
 80:     {
 81:         $this->metadata = PrimitiveConverter::toMap($metadata);
 82:     }
 83: 
 84:     public function setMimeType($mimeType)
 85:     {
 86:         $this->mimeType = PrimitiveConverter::toString($mimeType);
 87:     }
 88: 
 89:     public function getBucket()
 90:     {
 91:         return $this->bucket;
 92:     }
 93: 
 94:     public function getKey()
 95:     {
 96:         return $this->key;
 97:     }
 98: 
 99:     public function getMetadata()
100:     {
101:         return $this->metadata;
102:     }
103: 
104:     public function getMimeType()
105:     {
106:         return $this->mimeType;
107:     }
108: 
109:     public function getName()
110:     {
111:         return $this->name;
112:     }
113: 
114:     public function getURI()
115:     {
116:         return $this->bucket+':'+$this->key;
117:     }
118: 
119:     public function __get($property)
120:     {
121:         switch ($property) {
122:             case 'bucket':
123:                 return $this->getBucket();
124:             case 'key':
125:                 return $this->getKey();
126:             case 'metaData':
127:                 return $this->getMetadata();
128:             case 'mimeType':
129:                 return $this->getMimeType();
130:             case 'name':
131:                 return $this->getName();
132:             case 'URI':
133:                 return $this->getURI();
134:             default:
135:                 throw new InvalidArgumentException('Cannot access unexisting property "'.$property.'"');
136:         }
137:     }
138: 
139:     public function getUrl()
140:     {
141:         return 'http://'.self::HOST.'/'.$this->bucket.'/'.$this->key;
142:     }
143: 
144:     public function __toString()
145:     {
146:         return $this->getUrl();
147:     }
148: 
149:     public function toArray()
150:     {
151:         return array(
152:             'Bucket'   => $this->bucket,
153:             'Key'      => $this->key,
154:             'Length'   => $this->length,
155:             'Name'     => $this->name,
156:             'MimeType' => $this->mimeType,
157:             'Metadata' => $this->metadata,
158:         );
159:     }
160: 
161:     /**
162:      * Set singleton AmazonS3 instance
163:      * @param AmazonS3 $client
164:      */
165:     public static function setClient(AmazonS3 $client)
166:     {
167:         self::$client = $client;
168:     }
169: 
170:     /**
171:      * Get singleton AmazonS3 instance
172:      * @return AmazonS3
173:      */
174:     public static function getClient()
175:     {
176:         return self::$client;
177:     }
178: 
179:     public static function getDefaultBucket()
180:     {
181:         return self::$defaultBucket;
182:     }
183: 
184:     public static function setDefaultBucket($bucket)
185:     {
186:         if(!is_string($bucket)) {
187:             throw new InvalidArgumentException('Cannot set default bucket, bucket name must be a string, invalid type was '.Utils::getType($bucket));
188:         }
189:         self::$defaultBucket = $bucket;
190:     }
191: 
192:     public static function load($bucket, $key)
193:     {
194:         $response = self::loadContent($bucket, $key);
195:         if($response->isOK()) {
196:             return $response->body;
197:         }
198:         else {
199:             throw new InvalidArgumentException('Could not load "'.$this->bucket.'/'.$this->key.'"');
200:         }
201:     }
202: 
203:     public function getStream()
204:     {
205:         self::registerS3StreamWrapper();
206:         return fopen('s3://'.$this->bucket.'/'.$this->key, 'r');
207:     }
208: 
209:     private function _upload(array $options)
210:     {
211:         if($this->bucket === null) {
212:             if(self::getDefaultBucket() === null)
213:                 throw new LogicException('Cannot upload content to S3, no bucket was provided, and no default bucket is set.');
214:             $this->bucket = self::getDefaultBucket();
215:         }
216:         $this->key = self::generateKey();
217: 
218:         if ($this->metadata !== null) {
219:             $options['meta'] = $this->metadata;
220:         }
221:         if ($this->mimeType !== null) {
222:             $options['contentType'] = $this->mimeType;
223:         }
224:         if ($this->length !== null) {
225:             $options['length'] = $this->length;
226:         }
227: 
228:         $response = self::getClient()->create_object($this->bucket, $this->key, $options);
229:         return $this->checkResponse($response, 'uploading file');
230:     }
231: 
232:     public function upload($file)
233:     {
234:         if (!is_resource($file) && !is_string($file)) {
235:             throw new InvalidArgumentException('Cannot upload file to S3, provided type must be stream or existing filepath, invalid type was "'.Utils::getType($file).'"');
236:         }
237:         elseif (is_resource($file) && get_resource_type($file)!=='stream') {
238:             throw new InvalidArgumentException('Cannot upload file to S3, provided file was stream but invalid type "'.  get_resource_type($file).'"');
239:         }
240:         elseif (is_string($file) && !is_file($file)) {
241:             throw new InvalidArgumentException('Cannot upload file to S3, no file found at provided path "'.$file.'"');
242:         }
243: 
244:         if(is_string($file)) {
245:             $file = fopen($file, 'r');
246:         }
247:         $stat = fstat($file);
248:         if(isset($stat['size'])) {
249:             $this->length = $stat['size'];
250:         }
251:         return $this->_upload(array('fileUpload' => $file));
252:     }
253: 
254:     public function uploadString($content)
255:     {
256:         if(!is_string($content)) {
257:             throw new InvalidArgumentException('Cannot upload string content to S3, type must be string, invalid type was "'.Utils::getType($file).'"');
258:         }
259:         $this->length = strlen($content);
260:         return $this->_upload(array('upload' => $content));
261:     }
262: 
263:     public function delete()
264:     {
265:         if(!isset($this->bucket)) {
266:             throw new \InvalidArgumentException('Cannot delete S3 object with no bucket set');
267:         }
268:         if(!isset($this->key)) {
269:             throw new \InvalidArgumentException('Cannot delete S3 object with no key set');
270:         }
271:         $response = self::getClient()->delete_object($this->bucket, $this->key);
272: 
273:         if(!$response->isOK()) {
274:             throw new InvalidArgumentException('Could not delete object '.$this->getURI().'');
275:         }
276:         return true;
277:     }
278: 
279:     private function checkResponse($response, $action)
280:     {
281:         if($response===null)
282:             throw new LogicException('Response was null');
283:         if($response->isOK())
284:             return $this;
285:         throw new LogicException(
286:             'Error while performing action ."'.$action.'. '
287:             .'Response status was: '.$response->status.'. '
288:             .'Response body: '.$response->body);
289:     }
290: 
291:     private static function registerS3StreamWrapper()
292:     {
293:         static $wrapperIsRegistered = false;
294:         if($wrapperIsRegistered)
295:             return ;
296:         $wrapperIsRegistered = true;
297:         if(!S3StreamWrapper::register(self::getClient(), 's3'))
298:             throw new LogicException('Failed to register S3StreamWrapper');
299:         return ;
300:     }
301: 
302:     private static function loadContent($bucket, $key)
303:     {
304:         return self::getClient()->get_object($bucket, $key);
305:     }
306: 
307:     private static function generateKey()
308:     {
309:         return (string)UUID::v4();
310:     }
311: 
312: };
313: 
API documentation generated by ApiGen 2.8.0