PageRenderTime 25ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/3.0/modules/aws_s3/helpers/aws_s3.php

https://github.com/wrlee/gallery3-contrib
PHP | 330 lines | 267 code | 61 blank | 2 comment | 45 complexity | 5ed2ab7a61364138a52da1ae6e774ebc MD5 | raw file
  1. <?php defined("SYSPATH") or die("No direct script access.");
  2. class aws_s3_Core {
  3. const UPLOAD_FULLSIZE = 1;
  4. const UPLOAD_RESIZE = 2;
  5. const UPLOAD_THUMB = 4;
  6. private static $_s3;
  7. static function get_s3() {
  8. if (!self::$_s3) {
  9. require_once(MODPATH . "aws_s3/lib/s3.php");
  10. S3::setAuth(module::get_var("aws_s3", "access_key"), module::get_var("aws_s3", "secret_key"));
  11. S3::$useSSL = module::get_var("aws_s3", "use_ssl", false);
  12. }
  13. return self::$_s3;
  14. }
  15. static function getHash($string) {
  16. return base64_encode(extension_loaded('hash') ?
  17. hash_hmac('sha1', $string, module::get_var("aws_s3", "secret_key"), true) : pack('H*', sha1(
  18. (str_pad(module::get_var("aws_s3", "secret_key"), 64, chr(0x00)) ^ (str_repeat(chr(0x5c), 64))) .
  19. pack('H*', sha1((str_pad(module::get_var("aws_s3", "secret_key"), 64, chr(0x00)) ^
  20. (str_repeat(chr(0x36), 64))) . $string)))));
  21. }
  22. static function generate_url($resource, $authenticated = false, $updated = null) {
  23. $find = array("{guid}", "{bucket}", "{resource}");
  24. $replace = array(module::get_var("aws_s3", "g3id"), module::get_var("aws_s3", "bucket_name"), $resource);
  25. $url = str_replace($find, $replace, module::get_var("aws_s3", "url_str"));
  26. if ($authenticated) {
  27. preg_match("%https?://([a-zA-Z0-9\.-]*)/(.*)$%", $url, $matches);
  28. $host = module::get_var("aws_s3" , "bucket_name");
  29. $resource = $matches[2];
  30. $url .= "?AWSAccessKeyId=" . module::get_var("aws_s3", "access_key") .
  31. "&Expires=" . (time() + module::get_var("aws_s3", "sig_exp")) .
  32. "&Signature=" . urlencode(self::getHash("GET\n\n\n" . (time() + module::get_var("aws_s3", "sig_exp")) . "\n/" . $host . "/" . $resource));
  33. self::get_s3();
  34. S3::getAuthenticatedURL(module::get_var("aws_s3", "bucket_name"), $resource, module::get_var("aws_s3", "sig_exp"));
  35. }
  36. else
  37. $url .= "?m=" . ($updated ? $updated : time());
  38. return $url;
  39. }
  40. static function get_resource_url($resource) {
  41. $url = self::generate_url($resource);
  42. preg_match("%https?://[\w\.\-]*/(.*)\?%", $url, $matches);
  43. if (count($matches) > 0)
  44. return $matches[1];
  45. return false;
  46. }
  47. static function log($item) {
  48. if (is_string($item) || is_numeric($item)) {}
  49. else
  50. $item = print_r($item, true);
  51. $fh = fopen(VARPATH . "modules/aws_s3/log/aws_s3-" . date("Y-m-d") . ".log", "a");
  52. fwrite($fh, date("Y-m-d H:i:s") . ": " . $item . "\n");
  53. fclose($fh);
  54. }
  55. static function get_upload_flags() {
  56. $flags = 0;
  57. if (module::get_var("aws_s3", "upload_thumbs") == 1)
  58. $flags += self::UPLOAD_THUMB;
  59. if (module::get_var("aws_s3", "upload_resizes") == 1)
  60. $flags += self::UPLOAD_RESIZE;
  61. if (module::get_var("aws_s3", "upload_fullsizes") == 1)
  62. $flags += self::UPLOAD_FULLSIZE;
  63. return $flags;
  64. }
  65. static function upload_item($item, $flags = 7) {
  66. self::get_s3();
  67. $filename = urldecode($item->relative_path());
  68. $itype = "I";
  69. if ($item->is_album()) {
  70. $filename .= "/.album.jpg";
  71. $itype = "A";
  72. }
  73. if (!$item->s3_fullsize_uploaded && $flags & aws_s3::UPLOAD_FULLSIZE && !$item->is_album()) {
  74. aws_s3::log("[" . $itype . ":" . $item->id . "] Uploading fullsize object");
  75. $success_fs = S3::putObjectFile(VARPATH . "albums/" . $filename,
  76. module::get_var("aws_s3", "bucket_name"),
  77. self::get_resource_url("fs/" . $filename),
  78. ($item->view_1 ? S3::ACL_PUBLIC_READ : S3::ACL_PRIVATE));
  79. $item->s3_fullsize_uploaded = $success_fs;
  80. }
  81. else
  82. $success_fs = true;
  83. if (!$item->s3_resize_uploaded && $flags & aws_s3::UPLOAD_RESIZE && !$item->is_album()) {
  84. aws_s3::log("[" . $itype . ":" . $item->id . "] Uploading resize object");
  85. $success_rs = S3::putObjectFile(VARPATH . "resizes/" . $filename,
  86. module::get_var("aws_s3", "bucket_name"),
  87. self::get_resource_url("rs/" . $filename),
  88. ($item->view_1 ? S3::ACL_PUBLIC_READ : S3::ACL_PRIVATE));
  89. $item->s3_resize_uploaded = $success_rs;
  90. }
  91. else
  92. $success_rs = true;
  93. if (!$item->s3_thumb_uploaded && $flags & aws_s3::UPLOAD_THUMB) {
  94. aws_s3::log("[" . $itype . ":" . $item->id . "] Uploading thumbnail object");
  95. $success_th = S3::putObjectFile(VARPATH . "thumbs/" . $filename,
  96. module::get_var("aws_s3", "bucket_name"),
  97. self::get_resource_url("th/" . $filename),
  98. ($item->view_1 ? S3::ACL_PUBLIC_READ : S3::ACL_PRIVATE));
  99. $item->s3_thumb_uploaded = $success_th;
  100. }
  101. else
  102. $success_th = true;
  103. $item->s3_item_hash = md5($item->relative_path());
  104. $item->save();
  105. $success = $success_fs && $success_th && $success_rs;
  106. aws_s3::log("item upload success: " . $success);
  107. return $success;
  108. }
  109. static function move_item($old_item, $new_item) {
  110. self::get_s3();
  111. $old_filename = urldecode($old_item->relative_path());
  112. $new_filename = urldecode($new_item->relative_path());
  113. aws_s3::log("old filename: " . self::get_resource_url("fs/" . $old_filename) . ", " .
  114. "new filename: " . self::get_resource_url("fs/" . $new_filename));
  115. //aws_s3::log($old_item->get_aws_s3_meta());
  116. if ($old_item->s3_fullsize_uploaded) {
  117. aws_s3::log("Copying fullsize " . $old_filename . " to " . $new_filename);
  118. S3::copyObject(module::get_var("aws_s3", "bucket_name"), self::get_resource_url("fs/" . $old_filename),
  119. module::get_var("aws_s3", "bucket_name"), self::get_resource_url("fs/" . $new_filename),
  120. ($new_item->view_1 ? S3::ACL_PUBLIC_READ : S3::ACL_PRIVATE));
  121. S3::deleteObject(module::get_var("aws_s3", "bucket_name"), self::get_resource_url("fs/" . $old_filename));
  122. }
  123. else
  124. aws_s3::upload_item($new_item, aws_s3::UPLOAD_FULLSIZE);
  125. if ($old_item->s3_resize_uploaded) {
  126. aws_s3::log("Copying resized " . $old_filename . " to " . $new_filename);
  127. S3::copyObject(module::get_var("aws_s3", "bucket_name"), self::get_resource_url("rs/" . $old_filename),
  128. module::get_var("aws_s3", "bucket_name"), self::get_resource_url("rs/" . $new_filename),
  129. ($new_item->view_1 ? S3::ACL_PUBLIC_READ : S3::ACL_PRIVATE));
  130. S3::deleteObject(module::get_var("aws_s3", "bucket_name"), self::get_resource_url("rs/" . $old_filename));
  131. }
  132. else
  133. aws_s3::upload_item($new_item, aws_s3::UPLOAD_RESIZE);
  134. if ($old_item->s3_thumb_uploaded) {
  135. aws_s3::log("Copying thumbnail " . $old_filename . " to " . $new_filename);
  136. S3::copyObject(module::get_var("aws_s3", "bucket_name"), self::get_resource_url("th/" . $old_filename),
  137. module::get_var("aws_s3", "bucket_name"), self::get_resource_url("th/" . $new_filename),
  138. ($new_item->view_1 ? S3::ACL_PUBLIC_READ : S3::ACL_PRIVATE));
  139. S3::deleteObject(module::get_var("aws_s3", "bucket_name"), self::get_resource_url("th/" . $old_filename));
  140. }
  141. else
  142. aws_s3::upload_item($new_item, aws_s3::UPLOAD_THUMB);
  143. }
  144. static function remove_item($item) {
  145. self::get_s3();
  146. $filename = urldecode($item->relative_path());
  147. $itype = "I";
  148. if ($item->is_album()) {
  149. $filename .= "/.album.jpg";
  150. $itype = "A";
  151. }
  152. if ($item->s3_fullsize_uploaded && !$item->is_album()) {
  153. aws_s3::log("[" . $itype . ":" . $item->id . "] Deleting fullsize object");
  154. $success_fs = S3::deleteObject(module::get_var("aws_s3", "bucket_name"),
  155. self::get_resource_url("fs/" . $filename));
  156. $item->s3_fullsize_uploaded = !$success_fs;
  157. }
  158. else
  159. $success_fs = true;
  160. if ($item->s3_resize_uploaded && !$item->is_album()) {
  161. aws_s3::log("[" . $itype . ":" . $item->id . "] Deleting resize object");
  162. $success_rs = S3::deleteObject(module::get_var("aws_s3", "bucket_name"),
  163. self::get_resource_url("rs/" . $filename));
  164. $item->s3_resize_uploaded = !$success_rs;
  165. }
  166. else
  167. $success_rs = true;
  168. if ($item->s3_thumb_uploaded) {
  169. aws_s3::log("[" . $itype . ":" . $item->id . "] Deleting thumbnail object");
  170. $success_th = S3::deleteObject(module::get_var("aws_s3", "bucket_name"),
  171. self::get_resource_url("th/" . $filename));
  172. $item->s3_thumb_uploaded = !$success_th;
  173. }
  174. else
  175. $success_th = true;
  176. $item->save_s3_meta();
  177. $success = $success_fs && $success_th && $success_rs;
  178. aws_s3::log("S3 delete success: " . $success);
  179. return $success;
  180. }
  181. static function getAuthenticatedURL($bucket, $uri) {
  182. self::get_s3();
  183. return S3::getAuthenticatedURL($bucket, $uri, 60);
  184. }
  185. static function validate_number($field) {
  186. if (preg_match("/\D/", $field->value))
  187. $field->add_error("not_numeric", 1);
  188. }
  189. static function validate_bucket($field) {
  190. if (preg_match("/[^a-zA-Z0-9\-\.]/", $field->value))
  191. $field->add_error("invalid", 1);
  192. }
  193. // @TODO: Write validation function (check with S3)
  194. static function validate_access_details($access_key, $secret_key, $bucket_name) {
  195. require_once(MODPATH . "aws_s3/lib/s3.php");
  196. S3::setAuth($access_key, $secret_key);
  197. S3::$useSSL = false;
  198. $success_test = S3::putObjectString((string)time(), $bucket_name, ".s3_test");
  199. if ($success_test)
  200. S3::deleteObject($bucket_name, ".s3_test");
  201. return $success_test;
  202. }
  203. static function base64_filename(Item_Model $item) {
  204. $file_path = explode("/", $item->relative_path());
  205. return base64_encode(end($file_path));
  206. }
  207. static function can_schedule() {
  208. if (!module::is_active("scheduler")) {
  209. return false;
  210. }
  211. return true;
  212. }
  213. static function schedule_task($task) {
  214. $schedule = ORM::factory("schedule");
  215. $schedule->add_task($task);
  216. }
  217. static function schedule_full_sync2() {
  218. $task_def =
  219. Task_Definition::factory()
  220. ->callback("aws_s3_task::sync")
  221. ->name("Amazon S3 bucket synchronisation")
  222. ->severity(log::SUCCESS);
  223. $task = task::create($task_def, array());
  224. self::schedule_task($task);
  225. }
  226. static function schedule_full_sync($this_task) {
  227. if (!self::can_schedule())
  228. throw new Exception("Unable to initialize schedule");
  229. try {
  230. self::schedule_full_sync2();
  231. $this_task->status = "Scheduled re-sync task";
  232. $this_task->done = true;
  233. $this_task->state = "success";
  234. $this_task->percent_complete = 100;
  235. }
  236. catch (Exception $err) {
  237. $task->done = true;
  238. $thisSynchronise_task->state = "error";
  239. $this_task->status = $err->getMessage();
  240. $this_task->log((string)$err);
  241. }
  242. $this_task->save();
  243. if (!module::get_var("aws_s3", "synced", false)) {
  244. site_status::warning(
  245. "Your site has been scheduled for full Amazon S3 re-synchronisation. This message will clear when this has been completed.",
  246. "aws_s3_not_synced"
  247. );
  248. }
  249. return true;
  250. }
  251. static function schedule_item_sync($item) {
  252. if (!self::can_schedule())
  253. throw new Exception("Unable to initialize schedule");
  254. $item_id = null;
  255. if (is_object($item) && $item instanceof Item_Model)
  256. $item_id = $item->id;
  257. else if (is_numeric($item))
  258. $item_id = $item;
  259. else
  260. throw new Exception("Un-intelligible item reference passed.");
  261. $task_def =
  262. Task_Definition::factory()
  263. ->callback("aws_s3_task::upload_item")
  264. ->name("Amazon S3 item upload (ID: " . $item_id . ")")
  265. ->severity(log::SUCCESS);
  266. $task = task::create($task_def, array("item_id" => $item_id));
  267. self::schedule_task($task);
  268. }
  269. }