/bitrix/modules/main/install/image_uploader/ImageUploaderPHP/UploadCache.class.php

https://gitlab.com/Rad1calDreamer/honey · PHP · 204 lines · 159 code · 28 blank · 17 comment · 28 complexity · 16878b02a7ceaf3c78baf6c31dd86ba4 MD5 · raw file

  1. <?php
  2. class UploadCache {
  3. private $_cacheRoot;
  4. /**
  5. * UploadCache constructor
  6. * @param UploadSession $uploadSession
  7. */
  8. function __construct($cacheRoot) {
  9. if (!empty($cacheRoot)) {
  10. $cacheRoot = rtrim($cacheRoot, '/\\');
  11. }
  12. if (empty($cacheRoot)) {
  13. throw new Exception('Cache root directory can not be null.');
  14. }
  15. $this->_cacheRoot = $cacheRoot;
  16. }
  17. /**
  18. * Get default root upload cache directory.
  19. */
  20. public function getCacheRoot() {
  21. return $this->_cacheRoot;
  22. }
  23. public static function moveFile($source, $destination) {
  24. $result = @rename($source, $destination);
  25. if (!$result) {
  26. // copy-remove otherwise
  27. $result = copy($source, $destination);
  28. unlink($source);
  29. }
  30. return $result;
  31. }
  32. public function getLastFullScanTimestamp() {
  33. $file = $this->getCacheRoot().DIRECTORY_SEPARATOR.'timestamp';
  34. $timestamp = 0;
  35. if (is_file($file)) {
  36. $timestamp = file_get_contents($file);
  37. $timestamp = @intval($timestamp, 10);
  38. }
  39. return $timestamp;
  40. }
  41. public function setLastFullScanTimestamp($value = NULL) {
  42. $file = $this->getCacheRoot().DIRECTORY_SEPARATOR.'timestamp';
  43. if ($value === NULL) {
  44. $value = time();
  45. }
  46. file_put_contents($file, $value);
  47. }
  48. /**
  49. * Check if package exists in the cache
  50. * @param $package
  51. */
  52. public function isPackageCached($uploadSessionId, $packageIndex) {
  53. return file_exists($this->getPackageCacheDirectory($uploadSessionId, $packageIndex));
  54. }
  55. public function loadSavedFields($uploadSessionId, $packageIndex) {
  56. $filePath = $this->getPackageCacheDirectory($uploadSessionId, $packageIndex) . DIRECTORY_SEPARATOR . 'post';
  57. return unserialize(file_get_contents($filePath));
  58. }
  59. public function loadSavedFiles($uploadSessionId, $packageIndex) {
  60. $path = $this->getPackageCacheDirectory($uploadSessionId, $packageIndex) . DIRECTORY_SEPARATOR;
  61. $items = scandir($path);
  62. $rg = '#^File\\d+_\\d+$#';
  63. $files = array();
  64. foreach ($items as $file) {
  65. if (preg_match($rg, $file)) {
  66. $files[$file] = array(
  67. 'cached' => true,
  68. 'tmp_name' => $path . $file,
  69. 'type' => 'application/octet-stream',
  70. 'error' => UPLOAD_ERR_OK,
  71. 'size' => filesize($path . $file)
  72. );
  73. }
  74. }
  75. return $files;
  76. }
  77. /**
  78. * Save package fields and files into upload temp cache
  79. * @param Package $package
  80. */
  81. public function saveRequestData($uploadSessionId, $packageIndex, $fields, $files) {
  82. $path = $this->getPackageCacheDirectory($uploadSessionId, $packageIndex);
  83. if (!file_exists($path)) {
  84. mkdir($path, 0777, true);
  85. }
  86. $this->saveFields($path, $fields);
  87. $this->saveFiles($path, $files, $fields);
  88. $this->setWriteTimestamp($uploadSessionId);
  89. }
  90. private function saveFields($path, $fields) {
  91. $filePath = $path . DIRECTORY_SEPARATOR . 'post';
  92. if (file_exists($filePath)) {
  93. $data = file_get_contents($filePath);
  94. $data = unserialize($data);
  95. }
  96. if (isset($data)) {
  97. $fields = array_merge($data, $fields);
  98. }
  99. file_put_contents($path . DIRECTORY_SEPARATOR . 'post', serialize($fields));
  100. }
  101. private function saveFiles($path, $files, $fields) {
  102. foreach ($files as $key => $file) {
  103. $filePath = $path . DIRECTORY_SEPARATOR . $key;
  104. if (isset($file['in_request']) && $file['in_request'] === true) {
  105. $data = $fields[$key];
  106. $fdst = fopen($filePath, 'a');
  107. fwrite($fdst, $data);
  108. fclose($fdst);
  109. } else {
  110. if (is_uploaded_file($file['tmp_name']) && !file_exists($filePath)) {
  111. move_uploaded_file($file['tmp_name'], $filePath);
  112. } else {
  113. $this->appendToFile($file['tmp_name'], $filePath);
  114. }
  115. }
  116. }
  117. }
  118. private function appendToFile($source, $destination) {
  119. $buff = 4096;
  120. $fsrc = fopen($source, 'r');
  121. $fdst = fopen($destination, 'a');
  122. while (($data = fread($fsrc, $buff)) !== '') {
  123. fwrite($fdst, $data);
  124. }
  125. fclose($fsrc);
  126. fclose($fdst);
  127. }
  128. public function getSessionCacheDirectory($uploadSessionId) {
  129. return $this->getCacheRoot() . DIRECTORY_SEPARATOR . $uploadSessionId;
  130. }
  131. public function getPackageCacheDirectory($uploadSessionId, $packageIndex) {
  132. return $this->getSessionCacheDirectory($uploadSessionId) . DIRECTORY_SEPARATOR . $packageIndex;
  133. }
  134. private function setWriteTimestamp($uploadSessionId, $time = NULL) {
  135. if ($time === NULL) {
  136. $time = time();
  137. }
  138. file_put_contents($this->getSessionCacheDirectory($uploadSessionId).DIRECTORY_SEPARATOR.'timestamp', $time);
  139. }
  140. public function getWriteTimestamp($uploadSessionId) {
  141. $timestampFile = $this->getSessionCacheDirectory($uploadSessionId).DIRECTORY_SEPARATOR.'timestamp';
  142. $timestamp = -1;
  143. if (is_file($timestampFile)) {
  144. $timestamp = file_get_contents($timestampFile);
  145. $timestamp = @intval($timestamp, 10);
  146. }
  147. if ($timestamp <= 0) {
  148. // If no timestamp file then set current time
  149. $timestamp = time();
  150. $this->setWriteTimestamp($uploadSessionId, $timestamp);
  151. }
  152. return $timestamp;
  153. }
  154. public function cleanUploadSessionCache($uploadSessionId) {
  155. $dir = $this->getSessionCacheDirectory($uploadSessionId);
  156. if (!empty($dir) && file_exists($dir)) {
  157. UploadCache::rmdir_recursive($dir);
  158. }
  159. }
  160. private static function rmdir_recursive($dir) {
  161. if (is_dir($dir)) {
  162. $objects = scandir($dir);
  163. foreach ($objects as $object) {
  164. if ($object != '.' && $object != '..') {
  165. if (is_dir($dir.DIRECTORY_SEPARATOR.$object)) {
  166. UploadCache::rmdir_recursive($dir.DIRECTORY_SEPARATOR.$object);
  167. } else {
  168. unlink($dir.DIRECTORY_SEPARATOR.$object);
  169. }
  170. }
  171. }
  172. reset($objects);
  173. rmdir($dir);
  174. }
  175. }
  176. }