/src/Gaufrette/Adapter/AmazonS3.php

https://github.com/qpleple/Gaufrette · PHP · 214 lines · 121 code · 33 blank · 60 comment · 17 complexity · 21f450e75cc0ed852845d3ae8679600f MD5 · raw file

  1. <?php
  2. namespace Gaufrette\Adapter;
  3. use Gaufrette\Adapter;
  4. use Zend\Service\Amazon\S3\S3;
  5. /**
  6. * Amazon S3 adapter
  7. *
  8. * @package Gaufrette
  9. * @author Antoine Hérault <antoine.herault@gmail.com>
  10. */
  11. class AmazonS3 implements Adapter
  12. {
  13. protected $service;
  14. protected $bucket;
  15. protected $ensureBucket = false;
  16. protected $create;
  17. public function __construct(S3 $service, $bucket, $create = false)
  18. {
  19. $this->service = $service;
  20. $this->bucket = $bucket;
  21. $this->create = $create;
  22. }
  23. /**
  24. * {@inheritDoc}
  25. */
  26. public function read($key)
  27. {
  28. $this->ensureBucketExists();
  29. return $this->service->getObject($this->computePath($key));
  30. }
  31. /**
  32. * {@inheritDoc}
  33. */
  34. public function rename($key, $new)
  35. {
  36. $this->write($new, $this->read($key));
  37. $this->delete($key);
  38. }
  39. /**
  40. * {@inheritDoc}
  41. */
  42. public function write($key, $content)
  43. {
  44. $this->ensureBucketExists();
  45. if (!$this->service->putObject($this->computePath($key), $content)) {
  46. throw new \RuntimeException(sprintf('Could not write the \'%s\' file.', $key));
  47. }
  48. return $this->getStringNumBytes($content);
  49. }
  50. /**
  51. * {@inheritDoc}
  52. */
  53. public function exists($key)
  54. {
  55. $this->ensureBucketExists();
  56. return $this->service->isObjectAvailable($this->computePath($key));
  57. }
  58. /**
  59. * {@inheritDoc}
  60. */
  61. public function mtime($key)
  62. {
  63. $this->ensureBucketExists();
  64. $info = $this->service->getInfo($this->computePath($key));
  65. return $info['mtime'];
  66. }
  67. /**
  68. * {@inheritDoc}
  69. */
  70. public function checksum($key)
  71. {
  72. $this->ensureBucketExists();
  73. $info = $this->service->getInfo($this->computePath($key));
  74. return trim($info['etag'], '"');
  75. }
  76. /**
  77. * {@inheritDoc}
  78. */
  79. public function keys()
  80. {
  81. $this->ensureBucketExists();
  82. return $this->service->getObjectsByBucket($this->bucket);
  83. }
  84. /**
  85. * {@inheritDoc}
  86. */
  87. public function delete($key)
  88. {
  89. $this->ensureBucketExists();
  90. if (!$this->removeObject($this->computePath($key))) {
  91. throw new \RuntimeException(sprintf('Could not delete the \'%s\' file.', $key));
  92. }
  93. }
  94. /**
  95. * Ensures the specified bucket exists. If the bucket does not exists
  96. * and the create parameter is set to true, it will try to create the
  97. * bucket
  98. *
  99. * @param string $bucket The name of the bucket
  100. * @param boolean $create Whether to create the bucket
  101. *
  102. * @throws RuntimeException if the bucket does not exists or could not be
  103. * created
  104. */
  105. protected function ensureBucketExists()
  106. {
  107. if (!$this->ensureBucket) {
  108. $available = $this->service->isBucketAvailable($this->bucket);
  109. if (!$available && $this->create) {
  110. $created = $this->service->createBucket($this->bucket);
  111. if (!$created) {
  112. throw new \RuntimeException(sprintf('Could not create the \'%s\' bucket.', $this->bucket));
  113. }
  114. } else if (!$available) {
  115. throw new \RuntimeException(sprintf('The bucket \'%s\' was not found. Please create it on Amazon AWS.', $this->bucket));
  116. }
  117. $this->ensureBucket = true;
  118. }
  119. }
  120. /**
  121. * Computes the path for the specified key taking the bucket in account
  122. *
  123. * @param string $key The key for which to compute the path
  124. *
  125. * @return string
  126. */
  127. public function computePath($key)
  128. {
  129. return $this->bucket . '/' . $key;
  130. }
  131. /**
  132. * Computes the key for the specified path
  133. *
  134. * @param string $path for which to compute the key
  135. */
  136. public function computeKey($path)
  137. {
  138. if (0 !== strpos($path, $this->bucket . '/')) {
  139. throw new \InvalidArgumentException(sprintf('The specified path \'%s\' is out of the bucket \'%s\'.', $path, $this->bucket));
  140. }
  141. return ltrim(substr($path, strlen($this->bucket)), '/');
  142. }
  143. /**
  144. * Returns the number of bytes of the given string
  145. *
  146. * @param string $string
  147. *
  148. * @return integer
  149. */
  150. protected function getStringNumBytes($string)
  151. {
  152. $d = 0;
  153. $strlen_var = strlen($string);
  154. for ($c = 0; $c < $strlen_var; ++$c) {
  155. $ord_var_c = ord($string{$d});
  156. switch (true) {
  157. case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
  158. $d++;
  159. break;
  160. case (($ord_var_c & 0xE0) == 0xC0):
  161. $d+=2;
  162. break;
  163. case (($ord_var_c & 0xF0) == 0xE0):
  164. $d+=3;
  165. break;
  166. case (($ord_var_c & 0xF8) == 0xF0):
  167. $d+=4;
  168. break;
  169. case (($ord_var_c & 0xFC) == 0xF8):
  170. $d+=5;
  171. break;
  172. case (($ord_var_c & 0xFE) == 0xFC):
  173. $d+=6;
  174. break;
  175. default:
  176. $d++;
  177. }
  178. }
  179. return $d;
  180. }
  181. }