You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

267 lines
6.0 KiB

  1. <?php
  2. /**
  3. * Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
  4. * This file is licensed under the Affero General Public License version 3 or
  5. * later.
  6. * See the COPYING-README file.
  7. */
  8. namespace OC\Files\Cache\Wrapper;
  9. /**
  10. * Jail to a subdirectory of the wrapped cache
  11. */
  12. class CacheJail extends CacheWrapper {
  13. /**
  14. * @var string
  15. */
  16. protected $root;
  17. /**
  18. * @param \OC\Files\Cache\Cache $cache
  19. * @param string $root
  20. */
  21. public function __construct($cache, $root) {
  22. parent::__construct($cache);
  23. $this->root = $root;
  24. }
  25. protected function getSourcePath($path) {
  26. if ($path === '') {
  27. return $this->root;
  28. } else {
  29. return $this->root . '/' . ltrim($path, '/');
  30. }
  31. }
  32. /**
  33. * @param string $path
  34. * @return null|string the jailed path or null if the path is outside the jail
  35. */
  36. protected function getJailedPath($path) {
  37. $rootLength = strlen($this->root) + 1;
  38. if ($path === $this->root) {
  39. return '';
  40. } else if (substr($path, 0, $rootLength) === $this->root . '/') {
  41. return substr($path, $rootLength);
  42. } else {
  43. return null;
  44. }
  45. }
  46. /**
  47. * @param array $entry
  48. * @return array
  49. */
  50. protected function formatCacheEntry($entry) {
  51. if (isset($entry['path'])) {
  52. $entry['path'] = $this->getJailedPath($entry['path']);
  53. }
  54. return $entry;
  55. }
  56. protected function filterCacheEntry($entry) {
  57. $rootLength = strlen($this->root) + 1;
  58. return ($entry['path'] === $this->root) or (substr($entry['path'], 0, $rootLength) === $this->root . '/');
  59. }
  60. /**
  61. * get the stored metadata of a file or folder
  62. *
  63. * @param string /int $file
  64. * @return array|false
  65. */
  66. public function get($file) {
  67. if (is_string($file) or $file == '') {
  68. $file = $this->getSourcePath($file);
  69. }
  70. return parent::get($file);
  71. }
  72. /**
  73. * store meta data for a file or folder
  74. *
  75. * @param string $file
  76. * @param array $data
  77. *
  78. * @return int file id
  79. */
  80. public function put($file, array $data) {
  81. return $this->cache->put($this->getSourcePath($file), $data);
  82. }
  83. /**
  84. * update the metadata in the cache
  85. *
  86. * @param int $id
  87. * @param array $data
  88. */
  89. public function update($id, array $data) {
  90. $this->cache->update($this->getSourcePath($id), $data);
  91. }
  92. /**
  93. * get the file id for a file
  94. *
  95. * @param string $file
  96. * @return int
  97. */
  98. public function getId($file) {
  99. return $this->cache->getId($this->getSourcePath($file));
  100. }
  101. /**
  102. * get the id of the parent folder of a file
  103. *
  104. * @param string $file
  105. * @return int
  106. */
  107. public function getParentId($file) {
  108. if ($file === '') {
  109. return -1;
  110. } else {
  111. return $this->cache->getParentId($this->getSourcePath($file));
  112. }
  113. }
  114. /**
  115. * check if a file is available in the cache
  116. *
  117. * @param string $file
  118. * @return bool
  119. */
  120. public function inCache($file) {
  121. return $this->cache->inCache($this->getSourcePath($file));
  122. }
  123. /**
  124. * remove a file or folder from the cache
  125. *
  126. * @param string $file
  127. */
  128. public function remove($file) {
  129. $this->cache->remove($this->getSourcePath($file));
  130. }
  131. /**
  132. * Move a file or folder in the cache
  133. *
  134. * @param string $source
  135. * @param string $target
  136. */
  137. public function move($source, $target) {
  138. $this->cache->move($this->getSourcePath($source), $this->getSourcePath($target));
  139. }
  140. /**
  141. * remove all entries for files that are stored on the storage from the cache
  142. */
  143. public function clear() {
  144. $this->cache->remove($this->root);
  145. }
  146. /**
  147. * @param string $file
  148. *
  149. * @return int Cache::NOT_FOUND, Cache::PARTIAL, Cache::SHALLOW or Cache::COMPLETE
  150. */
  151. public function getStatus($file) {
  152. return $this->cache->getStatus($this->getSourcePath($file));
  153. }
  154. private function formatSearchResults($results) {
  155. $results = array_filter($results, array($this, 'filterCacheEntry'));
  156. $results = array_values($results);
  157. return array_map(array($this, 'formatCacheEntry'), $results);
  158. }
  159. /**
  160. * search for files matching $pattern
  161. *
  162. * @param string $pattern
  163. * @return array an array of file data
  164. */
  165. public function search($pattern) {
  166. $results = $this->cache->search($pattern);
  167. return $this->formatSearchResults($results);
  168. }
  169. /**
  170. * search for files by mimetype
  171. *
  172. * @param string $mimetype
  173. * @return array
  174. */
  175. public function searchByMime($mimetype) {
  176. $results = $this->cache->searchByMime($mimetype);
  177. return $this->formatSearchResults($results);
  178. }
  179. /**
  180. * search for files by mimetype
  181. *
  182. * @param string|int $tag name or tag id
  183. * @param string $userId owner of the tags
  184. * @return array
  185. */
  186. public function searchByTag($tag, $userId) {
  187. $results = $this->cache->searchByTag($tag, $userId);
  188. return $this->formatSearchResults($results);
  189. }
  190. /**
  191. * update the folder size and the size of all parent folders
  192. *
  193. * @param string|boolean $path
  194. * @param array $data (optional) meta data of the folder
  195. */
  196. public function correctFolderSize($path, $data = null) {
  197. $this->cache->correctFolderSize($this->getSourcePath($path), $data);
  198. }
  199. /**
  200. * get the size of a folder and set it in the cache
  201. *
  202. * @param string $path
  203. * @param array $entry (optional) meta data of the folder
  204. * @return int
  205. */
  206. public function calculateFolderSize($path, $entry = null) {
  207. return $this->cache->calculateFolderSize($this->getSourcePath($path), $entry);
  208. }
  209. /**
  210. * get all file ids on the files on the storage
  211. *
  212. * @return int[]
  213. */
  214. public function getAll() {
  215. // not supported
  216. return array();
  217. }
  218. /**
  219. * find a folder in the cache which has not been fully scanned
  220. *
  221. * If multiply incomplete folders are in the cache, the one with the highest id will be returned,
  222. * use the one with the highest id gives the best result with the background scanner, since that is most
  223. * likely the folder where we stopped scanning previously
  224. *
  225. * @return string|bool the path of the folder or false when no folder matched
  226. */
  227. public function getIncomplete() {
  228. // not supported
  229. return false;
  230. }
  231. /**
  232. * get the path of a file on this storage by it's id
  233. *
  234. * @param int $id
  235. * @return string|null
  236. */
  237. public function getPathById($id) {
  238. $path = $this->cache->getPathById($id);
  239. return $this->getJailedPath($path);
  240. }
  241. }