PageRenderTime 29ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/league/flysystem/src/Adapter/Local.php

https://gitlab.com/Pasantias/pasantiasASLG
PHP | 506 lines | 319 code | 73 blank | 114 comment | 21 complexity | 8c7e349e32993d14e057c45a0610088c MD5 | raw file
  1. <?php
  2. namespace League\Flysystem\Adapter;
  3. use DirectoryIterator;
  4. use FilesystemIterator;
  5. use finfo as Finfo;
  6. use League\Flysystem\AdapterInterface;
  7. use League\Flysystem\Config;
  8. use League\Flysystem\Exception;
  9. use League\Flysystem\NotSupportedException;
  10. use League\Flysystem\UnreadableFileException;
  11. use League\Flysystem\Util;
  12. use RecursiveDirectoryIterator;
  13. use RecursiveIteratorIterator;
  14. use SplFileInfo;
  15. class Local extends AbstractAdapter
  16. {
  17. /**
  18. * @var int
  19. */
  20. const SKIP_LINKS = 0001;
  21. /**
  22. * @var int
  23. */
  24. const DISALLOW_LINKS = 0002;
  25. /**
  26. * @var array
  27. */
  28. protected static $permissions = [
  29. 'file' => [
  30. 'public' => 0744,
  31. 'private' => 0700,
  32. ],
  33. 'dir' => [
  34. 'public' => 0755,
  35. 'private' => 0700,
  36. ]
  37. ];
  38. /**
  39. * @var string
  40. */
  41. protected $pathSeparator = DIRECTORY_SEPARATOR;
  42. /**
  43. * @var array
  44. */
  45. protected $permissionMap;
  46. /**
  47. * @var int
  48. */
  49. protected $writeFlags;
  50. /**
  51. * @var int
  52. */
  53. private $linkHandling;
  54. /**
  55. * Constructor.
  56. *
  57. * @param string $root
  58. * @param int $writeFlags
  59. * @param int $linkHandling
  60. * @param array $permissions
  61. */
  62. public function __construct($root, $writeFlags = LOCK_EX, $linkHandling = self::DISALLOW_LINKS, array $permissions = [])
  63. {
  64. // permissionMap needs to be set before ensureDirectory() is called.
  65. $this->permissionMap = array_replace_recursive(static::$permissions, $permissions);
  66. $realRoot = $this->ensureDirectory($root);
  67. if ( ! is_dir($realRoot) || ! is_readable($realRoot)) {
  68. throw new \LogicException('The root path ' . $root . ' is not readable.');
  69. }
  70. $this->setPathPrefix($realRoot);
  71. $this->writeFlags = $writeFlags;
  72. $this->linkHandling = $linkHandling;
  73. }
  74. /**
  75. * Ensure the root directory exists.
  76. *
  77. * @param string $root root directory path
  78. *
  79. * @return string real path to root
  80. *
  81. * @throws Exception in case the root directory can not be created
  82. */
  83. protected function ensureDirectory($root)
  84. {
  85. if ( ! is_dir($root)) {
  86. $umask = umask(0);
  87. if ( ! mkdir($root, $this->permissionMap['dir']['public'], true)) {
  88. throw new Exception(sprintf('Impossible to create the root directory "%s".', $root));
  89. }
  90. umask($umask);
  91. }
  92. return realpath($root);
  93. }
  94. /**
  95. * @inheritdoc
  96. */
  97. public function has($path)
  98. {
  99. $location = $this->applyPathPrefix($path);
  100. return file_exists($location);
  101. }
  102. /**
  103. * @inheritdoc
  104. */
  105. public function write($path, $contents, Config $config)
  106. {
  107. $location = $this->applyPathPrefix($path);
  108. $this->ensureDirectory(dirname($location));
  109. if (($size = file_put_contents($location, $contents, $this->writeFlags)) === false) {
  110. return false;
  111. }
  112. $type = 'file';
  113. $result = compact('contents', 'type', 'size', 'path');
  114. if ($visibility = $config->get('visibility')) {
  115. $result['visibility'] = $visibility;
  116. $this->setVisibility($path, $visibility);
  117. }
  118. return $result;
  119. }
  120. /**
  121. * @inheritdoc
  122. */
  123. public function writeStream($path, $resource, Config $config)
  124. {
  125. $location = $this->applyPathPrefix($path);
  126. $this->ensureDirectory(dirname($location));
  127. $stream = fopen($location, 'w+');
  128. if ( ! $stream) {
  129. return false;
  130. }
  131. stream_copy_to_stream($resource, $stream);
  132. if ( ! fclose($stream)) {
  133. return false;
  134. }
  135. if ($visibility = $config->get('visibility')) {
  136. $this->setVisibility($path, $visibility);
  137. }
  138. return compact('path', 'visibility');
  139. }
  140. /**
  141. * @inheritdoc
  142. */
  143. public function readStream($path)
  144. {
  145. $location = $this->applyPathPrefix($path);
  146. $stream = fopen($location, 'r');
  147. return compact('stream', 'path');
  148. }
  149. /**
  150. * @inheritdoc
  151. */
  152. public function updateStream($path, $resource, Config $config)
  153. {
  154. return $this->writeStream($path, $resource, $config);
  155. }
  156. /**
  157. * @inheritdoc
  158. */
  159. public function update($path, $contents, Config $config)
  160. {
  161. $location = $this->applyPathPrefix($path);
  162. $mimetype = Util::guessMimeType($path, $contents);
  163. $size = file_put_contents($location, $contents, $this->writeFlags);
  164. if ($size === false) {
  165. return false;
  166. }
  167. return compact('path', 'size', 'contents', 'mimetype');
  168. }
  169. /**
  170. * @inheritdoc
  171. */
  172. public function read($path)
  173. {
  174. $location = $this->applyPathPrefix($path);
  175. $contents = file_get_contents($location);
  176. if ($contents === false) {
  177. return false;
  178. }
  179. return compact('contents', 'path');
  180. }
  181. /**
  182. * @inheritdoc
  183. */
  184. public function rename($path, $newpath)
  185. {
  186. $location = $this->applyPathPrefix($path);
  187. $destination = $this->applyPathPrefix($newpath);
  188. $parentDirectory = $this->applyPathPrefix(Util::dirname($newpath));
  189. $this->ensureDirectory($parentDirectory);
  190. return rename($location, $destination);
  191. }
  192. /**
  193. * @inheritdoc
  194. */
  195. public function copy($path, $newpath)
  196. {
  197. $location = $this->applyPathPrefix($path);
  198. $destination = $this->applyPathPrefix($newpath);
  199. $this->ensureDirectory(dirname($destination));
  200. return copy($location, $destination);
  201. }
  202. /**
  203. * @inheritdoc
  204. */
  205. public function delete($path)
  206. {
  207. $location = $this->applyPathPrefix($path);
  208. return unlink($location);
  209. }
  210. /**
  211. * @inheritdoc
  212. */
  213. public function listContents($directory = '', $recursive = false)
  214. {
  215. $result = [];
  216. $location = $this->applyPathPrefix($directory) . $this->pathSeparator;
  217. if ( ! is_dir($location)) {
  218. return [];
  219. }
  220. $iterator = $recursive ? $this->getRecursiveDirectoryIterator($location) : $this->getDirectoryIterator($location);
  221. foreach ($iterator as $file) {
  222. $path = $this->getFilePath($file);
  223. if (preg_match('#(^|/|\\\\)\.{1,2}$#', $path)) {
  224. continue;
  225. }
  226. $result[] = $this->normalizeFileInfo($file);
  227. }
  228. return array_filter($result);
  229. }
  230. /**
  231. * @inheritdoc
  232. */
  233. public function getMetadata($path)
  234. {
  235. $location = $this->applyPathPrefix($path);
  236. $info = new SplFileInfo($location);
  237. return $this->normalizeFileInfo($info);
  238. }
  239. /**
  240. * @inheritdoc
  241. */
  242. public function getSize($path)
  243. {
  244. return $this->getMetadata($path);
  245. }
  246. /**
  247. * @inheritdoc
  248. */
  249. public function getMimetype($path)
  250. {
  251. $location = $this->applyPathPrefix($path);
  252. $finfo = new Finfo(FILEINFO_MIME_TYPE);
  253. return ['mimetype' => $finfo->file($location)];
  254. }
  255. /**
  256. * @inheritdoc
  257. */
  258. public function getTimestamp($path)
  259. {
  260. return $this->getMetadata($path);
  261. }
  262. /**
  263. * @inheritdoc
  264. */
  265. public function getVisibility($path)
  266. {
  267. $location = $this->applyPathPrefix($path);
  268. clearstatcache(false, $location);
  269. $permissions = octdec(substr(sprintf('%o', fileperms($location)), -4));
  270. $visibility = $permissions & 0044 ? AdapterInterface::VISIBILITY_PUBLIC : AdapterInterface::VISIBILITY_PRIVATE;
  271. return compact('visibility');
  272. }
  273. /**
  274. * @inheritdoc
  275. */
  276. public function setVisibility($path, $visibility)
  277. {
  278. $location = $this->applyPathPrefix($path);
  279. $type = is_dir($location) ? 'dir' : 'file';
  280. $success = chmod($location, $this->permissionMap[$type][$visibility]);
  281. if ($success === false) {
  282. return false;
  283. }
  284. return compact('visibility');
  285. }
  286. /**
  287. * @inheritdoc
  288. */
  289. public function createDir($dirname, Config $config)
  290. {
  291. $location = $this->applyPathPrefix($dirname);
  292. $umask = umask(0);
  293. $visibility = $config->get('visibility', 'public');
  294. if ( ! is_dir($location) && ! mkdir($location, $this->permissionMap['dir'][$visibility], true)) {
  295. $return = false;
  296. } else {
  297. $return = ['path' => $dirname, 'type' => 'dir'];
  298. }
  299. umask($umask);
  300. return $return;
  301. }
  302. /**
  303. * @inheritdoc
  304. */
  305. public function deleteDir($dirname)
  306. {
  307. $location = $this->applyPathPrefix($dirname);
  308. if ( ! is_dir($location)) {
  309. return false;
  310. }
  311. $contents = $this->getRecursiveDirectoryIterator($location, RecursiveIteratorIterator::CHILD_FIRST);
  312. /** @var SplFileInfo $file */
  313. foreach ($contents as $file) {
  314. $this->guardAgainstUnreadableFileInfo($file);
  315. $this->deleteFileInfoObject($file);
  316. }
  317. return rmdir($location);
  318. }
  319. /**
  320. * @param SplFileInfo $file
  321. */
  322. protected function deleteFileInfoObject(SplFileInfo $file)
  323. {
  324. switch ($file->getType()) {
  325. case 'dir':
  326. rmdir($file->getRealPath());
  327. break;
  328. case 'link':
  329. unlink($file->getPathname());
  330. break;
  331. default:
  332. unlink($file->getRealPath());
  333. }
  334. }
  335. /**
  336. * Normalize the file info.
  337. *
  338. * @param SplFileInfo $file
  339. *
  340. * @return array
  341. */
  342. protected function normalizeFileInfo(SplFileInfo $file)
  343. {
  344. if ( ! $file->isLink()) {
  345. return $this->mapFileInfo($file);
  346. }
  347. if ($this->linkHandling & self::DISALLOW_LINKS) {
  348. throw NotSupportedException::forLink($file);
  349. }
  350. }
  351. /**
  352. * Get the normalized path from a SplFileInfo object.
  353. *
  354. * @param SplFileInfo $file
  355. *
  356. * @return string
  357. */
  358. protected function getFilePath(SplFileInfo $file)
  359. {
  360. $location = $file->getPathname();
  361. $path = $this->removePathPrefix($location);
  362. return trim(str_replace('\\', '/', $path), '/');
  363. }
  364. /**
  365. * @param string $path
  366. * @param int $mode
  367. *
  368. * @return RecursiveIteratorIterator
  369. */
  370. protected function getRecursiveDirectoryIterator($path, $mode = RecursiveIteratorIterator::SELF_FIRST)
  371. {
  372. return new RecursiveIteratorIterator(
  373. new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS),
  374. $mode
  375. );
  376. }
  377. /**
  378. * @param string $path
  379. *
  380. * @return DirectoryIterator
  381. */
  382. protected function getDirectoryIterator($path)
  383. {
  384. $iterator = new DirectoryIterator($path);
  385. return $iterator;
  386. }
  387. /**
  388. * @param SplFileInfo $file
  389. *
  390. * @return array
  391. */
  392. protected function mapFileInfo(SplFileInfo $file)
  393. {
  394. $normalized = [
  395. 'type' => $file->getType(),
  396. 'path' => $this->getFilePath($file),
  397. ];
  398. $normalized['timestamp'] = $file->getMTime();
  399. if ($normalized['type'] === 'file') {
  400. $normalized['size'] = $file->getSize();
  401. }
  402. return $normalized;
  403. }
  404. /**
  405. * @inheritdoc
  406. */
  407. public function applyPathPrefix($path)
  408. {
  409. $prefixedPath = parent::applyPathPrefix($path);
  410. return str_replace('/', DIRECTORY_SEPARATOR, $prefixedPath);
  411. }
  412. /**
  413. * @param SplFileInfo $file
  414. *
  415. * @throws UnreadableFileException
  416. */
  417. protected function guardAgainstUnreadableFileInfo(SplFileInfo $file)
  418. {
  419. if ( ! $file->isReadable()) {
  420. throw UnreadableFileException::forFileInfo($file);
  421. }
  422. }
  423. }