PageRenderTime 43ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

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

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