vendor/league/flysystem/src/MountManager.php line 391

Open in your IDE?
  1. <?php
  2. namespace League\Flysystem;
  3. use InvalidArgumentException;
  4. use League\Flysystem\Plugin\PluggableTrait;
  5. use League\Flysystem\Plugin\PluginNotFoundException;
  6. /**
  7.  * Class MountManager.
  8.  *
  9.  * Proxies methods to Filesystem (@see __call):
  10.  *
  11.  * @method AdapterInterface getAdapter($prefix)
  12.  * @method Config getConfig($prefix)
  13.  * @method array listFiles($directory = '', $recursive = false)
  14.  * @method array listPaths($directory = '', $recursive = false)
  15.  * @method array getWithMetadata($path, array $metadata)
  16.  * @method Filesystem flushCache()
  17.  * @method void assertPresent($path)
  18.  * @method void assertAbsent($path)
  19.  * @method Filesystem addPlugin(PluginInterface $plugin)
  20.  */
  21. class MountManager implements FilesystemInterface
  22. {
  23.     use PluggableTrait;
  24.     /**
  25.      * @var FilesystemInterface[]
  26.      */
  27.     protected $filesystems = [];
  28.     /**
  29.      * Constructor.
  30.      *
  31.      * @param FilesystemInterface[] $filesystems [:prefix => Filesystem,]
  32.      *
  33.      * @throws InvalidArgumentException
  34.      */
  35.     public function __construct(array $filesystems = [])
  36.     {
  37.         $this->mountFilesystems($filesystems);
  38.     }
  39.     /**
  40.      * Mount filesystems.
  41.      *
  42.      * @param FilesystemInterface[] $filesystems [:prefix => Filesystem,]
  43.      *
  44.      * @throws InvalidArgumentException
  45.      *
  46.      * @return $this
  47.      */
  48.     public function mountFilesystems(array $filesystems)
  49.     {
  50.         foreach ($filesystems as $prefix => $filesystem) {
  51.             $this->mountFilesystem($prefix$filesystem);
  52.         }
  53.         return $this;
  54.     }
  55.     /**
  56.      * Mount filesystems.
  57.      *
  58.      * @param string              $prefix
  59.      * @param FilesystemInterface $filesystem
  60.      *
  61.      * @throws InvalidArgumentException
  62.      *
  63.      * @return $this
  64.      */
  65.     public function mountFilesystem($prefixFilesystemInterface $filesystem)
  66.     {
  67.         if ( ! is_string($prefix)) {
  68.             throw new InvalidArgumentException(__METHOD__ ' expects argument #1 to be a string.');
  69.         }
  70.         $this->filesystems[$prefix] = $filesystem;
  71.         return $this;
  72.     }
  73.     /**
  74.      * Get the filesystem with the corresponding prefix.
  75.      *
  76.      * @param string $prefix
  77.      *
  78.      * @throws FilesystemNotFoundException
  79.      *
  80.      * @return FilesystemInterface
  81.      */
  82.     public function getFilesystem($prefix)
  83.     {
  84.         if ( ! isset($this->filesystems[$prefix])) {
  85.             throw new FilesystemNotFoundException('No filesystem mounted with prefix ' $prefix);
  86.         }
  87.         return $this->filesystems[$prefix];
  88.     }
  89.     /**
  90.      * Retrieve the prefix from an arguments array.
  91.      *
  92.      * @param array $arguments
  93.      *
  94.      * @throws InvalidArgumentException
  95.      *
  96.      * @return array [:prefix, :arguments]
  97.      */
  98.     public function filterPrefix(array $arguments)
  99.     {
  100.         if (empty($arguments)) {
  101.             throw new InvalidArgumentException('At least one argument needed');
  102.         }
  103.         $path array_shift($arguments);
  104.         if ( ! is_string($path)) {
  105.             throw new InvalidArgumentException('First argument should be a string');
  106.         }
  107.         list($prefix$path) = $this->getPrefixAndPath($path);
  108.         array_unshift($arguments$path);
  109.         return [$prefix$arguments];
  110.     }
  111.     /**
  112.      * @param string $directory
  113.      * @param bool   $recursive
  114.      *
  115.      * @throws InvalidArgumentException
  116.      * @throws FilesystemNotFoundException
  117.      *
  118.      * @return array
  119.      */
  120.     public function listContents($directory ''$recursive false)
  121.     {
  122.         list($prefix$directory) = $this->getPrefixAndPath($directory);
  123.         $filesystem $this->getFilesystem($prefix);
  124.         $result $filesystem->listContents($directory$recursive);
  125.         foreach ($result as &$file) {
  126.             $file['filesystem'] = $prefix;
  127.         }
  128.         return $result;
  129.     }
  130.     /**
  131.      * Call forwarder.
  132.      *
  133.      * @param string $method
  134.      * @param array  $arguments
  135.      *
  136.      * @throws InvalidArgumentException
  137.      * @throws FilesystemNotFoundException
  138.      *
  139.      * @return mixed
  140.      */
  141.     public function __call($method$arguments)
  142.     {
  143.         list($prefix$arguments) = $this->filterPrefix($arguments);
  144.         return $this->invokePluginOnFilesystem($method$arguments$prefix);
  145.     }
  146.     /**
  147.      * @param string $from
  148.      * @param string $to
  149.      * @param array  $config
  150.      *
  151.      * @throws InvalidArgumentException
  152.      * @throws FilesystemNotFoundException
  153.      * @throws FileExistsException
  154.      *
  155.      * @return bool
  156.      */
  157.     public function copy($from$to, array $config = [])
  158.     {
  159.         list($prefixFrom$from) = $this->getPrefixAndPath($from);
  160.         $buffer $this->getFilesystem($prefixFrom)->readStream($from);
  161.         if ($buffer === false) {
  162.             return false;
  163.         }
  164.         list($prefixTo$to) = $this->getPrefixAndPath($to);
  165.         $result $this->getFilesystem($prefixTo)->writeStream($to$buffer$config);
  166.         if (is_resource($buffer)) {
  167.             fclose($buffer);
  168.         }
  169.         return $result;
  170.     }
  171.     /**
  172.      * List with plugin adapter.
  173.      *
  174.      * @param array  $keys
  175.      * @param string $directory
  176.      * @param bool   $recursive
  177.      *
  178.      * @throws InvalidArgumentException
  179.      * @throws FilesystemNotFoundException
  180.      *
  181.      * @return array
  182.      */
  183.     public function listWith(array $keys = [], $directory ''$recursive false)
  184.     {
  185.         list($prefix$directory) = $this->getPrefixAndPath($directory);
  186.         $arguments = [$keys$directory$recursive];
  187.         return $this->invokePluginOnFilesystem('listWith'$arguments$prefix);
  188.     }
  189.     /**
  190.      * Move a file.
  191.      *
  192.      * @param string $from
  193.      * @param string $to
  194.      * @param array  $config
  195.      *
  196.      * @throws InvalidArgumentException
  197.      * @throws FilesystemNotFoundException
  198.      *
  199.      * @return bool
  200.      */
  201.     public function move($from$to, array $config = [])
  202.     {
  203.         list($prefixFrom$pathFrom) = $this->getPrefixAndPath($from);
  204.         list($prefixTo$pathTo) = $this->getPrefixAndPath($to);
  205.         if ($prefixFrom === $prefixTo) {
  206.             $filesystem $this->getFilesystem($prefixFrom);
  207.             $renamed $filesystem->rename($pathFrom$pathTo);
  208.             if ($renamed && isset($config['visibility'])) {
  209.                 return $filesystem->setVisibility($pathTo$config['visibility']);
  210.             }
  211.             return $renamed;
  212.         }
  213.         $copied $this->copy($from$to$config);
  214.         if ($copied) {
  215.             return $this->delete($from);
  216.         }
  217.         return false;
  218.     }
  219.     /**
  220.      * Invoke a plugin on a filesystem mounted on a given prefix.
  221.      *
  222.      * @param string $method
  223.      * @param array  $arguments
  224.      * @param string $prefix
  225.      *
  226.      * @throws FilesystemNotFoundException
  227.      *
  228.      * @return mixed
  229.      */
  230.     public function invokePluginOnFilesystem($method$arguments$prefix)
  231.     {
  232.         $filesystem $this->getFilesystem($prefix);
  233.         try {
  234.             return $this->invokePlugin($method$arguments$filesystem);
  235.         } catch (PluginNotFoundException $e) {
  236.             // Let it pass, it's ok, don't panic.
  237.         }
  238.         $callback = [$filesystem$method];
  239.         return call_user_func_array($callback$arguments);
  240.     }
  241.     /**
  242.      * @param string $path
  243.      *
  244.      * @throws InvalidArgumentException
  245.      *
  246.      * @return string[] [:prefix, :path]
  247.      */
  248.     protected function getPrefixAndPath($path)
  249.     {
  250.         if (strpos($path'://') < 1) {
  251.             throw new InvalidArgumentException('No prefix detected in path: ' $path);
  252.         }
  253.         return explode('://'$path2);
  254.     }
  255.     /**
  256.      * Check whether a file exists.
  257.      *
  258.      * @param string $path
  259.      *
  260.      * @return bool
  261.      */
  262.     public function has($path)
  263.     {
  264.         list($prefix$path) = $this->getPrefixAndPath($path);
  265.         return $this->getFilesystem($prefix)->has($path);
  266.     }
  267.     /**
  268.      * Read a file.
  269.      *
  270.      * @param string $path The path to the file.
  271.      *
  272.      * @throws FileNotFoundException
  273.      *
  274.      * @return string|false The file contents or false on failure.
  275.      */
  276.     public function read($path)
  277.     {
  278.         list($prefix$path) = $this->getPrefixAndPath($path);
  279.         return $this->getFilesystem($prefix)->read($path);
  280.     }
  281.     /**
  282.      * Retrieves a read-stream for a path.
  283.      *
  284.      * @param string $path The path to the file.
  285.      *
  286.      * @throws FileNotFoundException
  287.      *
  288.      * @return resource|false The path resource or false on failure.
  289.      */
  290.     public function readStream($path)
  291.     {
  292.         list($prefix$path) = $this->getPrefixAndPath($path);
  293.         return $this->getFilesystem($prefix)->readStream($path);
  294.     }
  295.     /**
  296.      * Get a file's metadata.
  297.      *
  298.      * @param string $path The path to the file.
  299.      *
  300.      * @throws FileNotFoundException
  301.      *
  302.      * @return array|false The file metadata or false on failure.
  303.      */
  304.     public function getMetadata($path)
  305.     {
  306.         list($prefix$path) = $this->getPrefixAndPath($path);
  307.         return $this->getFilesystem($prefix)->getMetadata($path);
  308.     }
  309.     /**
  310.      * Get a file's size.
  311.      *
  312.      * @param string $path The path to the file.
  313.      *
  314.      * @throws FileNotFoundException
  315.      *
  316.      * @return int|false The file size or false on failure.
  317.      */
  318.     public function getSize($path)
  319.     {
  320.         list($prefix$path) = $this->getPrefixAndPath($path);
  321.         return $this->getFilesystem($prefix)->getSize($path);
  322.     }
  323.     /**
  324.      * Get a file's mime-type.
  325.      *
  326.      * @param string $path The path to the file.
  327.      *
  328.      * @throws FileNotFoundException
  329.      *
  330.      * @return string|false The file mime-type or false on failure.
  331.      */
  332.     public function getMimetype($path)
  333.     {
  334.         list($prefix$path) = $this->getPrefixAndPath($path);
  335.         return $this->getFilesystem($prefix)->getMimetype($path);
  336.     }
  337.     /**
  338.      * Get a file's timestamp.
  339.      *
  340.      * @param string $path The path to the file.
  341.      *
  342.      * @throws FileNotFoundException
  343.      *
  344.      * @return string|false The timestamp or false on failure.
  345.      */
  346.     public function getTimestamp($path)
  347.     {
  348.         list($prefix$path) = $this->getPrefixAndPath($path);
  349.         return $this->getFilesystem($prefix)->getTimestamp($path);
  350.     }
  351.     /**
  352.      * Get a file's visibility.
  353.      *
  354.      * @param string $path The path to the file.
  355.      *
  356.      * @throws FileNotFoundException
  357.      *
  358.      * @return string|false The visibility (public|private) or false on failure.
  359.      */
  360.     public function getVisibility($path)
  361.     {
  362.         list($prefix$path) = $this->getPrefixAndPath($path);
  363.         return $this->getFilesystem($prefix)->getVisibility($path);
  364.     }
  365.     /**
  366.      * Write a new file.
  367.      *
  368.      * @param string $path     The path of the new file.
  369.      * @param string $contents The file contents.
  370.      * @param array  $config   An optional configuration array.
  371.      *
  372.      * @throws FileExistsException
  373.      *
  374.      * @return bool True on success, false on failure.
  375.      */
  376.     public function write($path$contents, array $config = [])
  377.     {
  378.         list($prefix$path) = $this->getPrefixAndPath($path);
  379.         return $this->getFilesystem($prefix)->write($path$contents$config);
  380.     }
  381.     /**
  382.      * Write a new file using a stream.
  383.      *
  384.      * @param string   $path     The path of the new file.
  385.      * @param resource $resource The file handle.
  386.      * @param array    $config   An optional configuration array.
  387.      *
  388.      * @throws InvalidArgumentException If $resource is not a file handle.
  389.      * @throws FileExistsException
  390.      *
  391.      * @return bool True on success, false on failure.
  392.      */
  393.     public function writeStream($path$resource, array $config = [])
  394.     {
  395.         list($prefix$path) = $this->getPrefixAndPath($path);
  396.         return $this->getFilesystem($prefix)->writeStream($path$resource$config);
  397.     }
  398.     /**
  399.      * Update an existing file.
  400.      *
  401.      * @param string $path     The path of the existing file.
  402.      * @param string $contents The file contents.
  403.      * @param array  $config   An optional configuration array.
  404.      *
  405.      * @throws FileNotFoundException
  406.      *
  407.      * @return bool True on success, false on failure.
  408.      */
  409.     public function update($path$contents, array $config = [])
  410.     {
  411.         list($prefix$path) = $this->getPrefixAndPath($path);
  412.         return $this->getFilesystem($prefix)->update($path$contents$config);
  413.     }
  414.     /**
  415.      * Update an existing file using a stream.
  416.      *
  417.      * @param string   $path     The path of the existing file.
  418.      * @param resource $resource The file handle.
  419.      * @param array    $config   An optional configuration array.
  420.      *
  421.      * @throws InvalidArgumentException If $resource is not a file handle.
  422.      * @throws FileNotFoundException
  423.      *
  424.      * @return bool True on success, false on failure.
  425.      */
  426.     public function updateStream($path$resource, array $config = [])
  427.     {
  428.         list($prefix$path) = $this->getPrefixAndPath($path);
  429.         return $this->getFilesystem($prefix)->updateStream($path$resource$config);
  430.     }
  431.     /**
  432.      * Rename a file.
  433.      *
  434.      * @param string $path    Path to the existing file.
  435.      * @param string $newpath The new path of the file.
  436.      *
  437.      * @throws FileExistsException   Thrown if $newpath exists.
  438.      * @throws FileNotFoundException Thrown if $path does not exist.
  439.      *
  440.      * @return bool True on success, false on failure.
  441.      */
  442.     public function rename($path$newpath)
  443.     {
  444.         list($prefix$path) = $this->getPrefixAndPath($path);
  445.         return $this->getFilesystem($prefix)->rename($path$newpath);
  446.     }
  447.     /**
  448.      * Delete a file.
  449.      *
  450.      * @param string $path
  451.      *
  452.      * @throws FileNotFoundException
  453.      *
  454.      * @return bool True on success, false on failure.
  455.      */
  456.     public function delete($path)
  457.     {
  458.         list($prefix$path) = $this->getPrefixAndPath($path);
  459.         return $this->getFilesystem($prefix)->delete($path);
  460.     }
  461.     /**
  462.      * Delete a directory.
  463.      *
  464.      * @param string $dirname
  465.      *
  466.      * @throws RootViolationException Thrown if $dirname is empty.
  467.      *
  468.      * @return bool True on success, false on failure.
  469.      */
  470.     public function deleteDir($dirname)
  471.     {
  472.         list($prefix$dirname) = $this->getPrefixAndPath($dirname);
  473.         return $this->getFilesystem($prefix)->deleteDir($dirname);
  474.     }
  475.     /**
  476.      * Create a directory.
  477.      *
  478.      * @param string $dirname The name of the new directory.
  479.      * @param array  $config  An optional configuration array.
  480.      *
  481.      * @return bool True on success, false on failure.
  482.      */
  483.     public function createDir($dirname, array $config = [])
  484.     {
  485.         list($prefix$dirname) = $this->getPrefixAndPath($dirname);
  486.         return $this->getFilesystem($prefix)->createDir($dirname);
  487.     }
  488.     /**
  489.      * Set the visibility for a file.
  490.      *
  491.      * @param string $path       The path to the file.
  492.      * @param string $visibility One of 'public' or 'private'.
  493.      *
  494.      * @throws FileNotFoundException
  495.      *
  496.      * @return bool True on success, false on failure.
  497.      */
  498.     public function setVisibility($path$visibility)
  499.     {
  500.         list($prefix$path) = $this->getPrefixAndPath($path);
  501.         return $this->getFilesystem($prefix)->setVisibility($path$visibility);
  502.     }
  503.     /**
  504.      * Create a file or update if exists.
  505.      *
  506.      * @param string $path     The path to the file.
  507.      * @param string $contents The file contents.
  508.      * @param array  $config   An optional configuration array.
  509.      *
  510.      * @return bool True on success, false on failure.
  511.      */
  512.     public function put($path$contents, array $config = [])
  513.     {
  514.         list($prefix$path) = $this->getPrefixAndPath($path);
  515.         return $this->getFilesystem($prefix)->put($path$contents$config);
  516.     }
  517.     /**
  518.      * Create a file or update if exists.
  519.      *
  520.      * @param string   $path     The path to the file.
  521.      * @param resource $resource The file handle.
  522.      * @param array    $config   An optional configuration array.
  523.      *
  524.      * @throws InvalidArgumentException Thrown if $resource is not a resource.
  525.      *
  526.      * @return bool True on success, false on failure.
  527.      */
  528.     public function putStream($path$resource, array $config = [])
  529.     {
  530.         list($prefix$path) = $this->getPrefixAndPath($path);
  531.         return $this->getFilesystem($prefix)->putStream($path$resource$config);
  532.     }
  533.     /**
  534.      * Read and delete a file.
  535.      *
  536.      * @param string $path The path to the file.
  537.      *
  538.      * @throws FileNotFoundException
  539.      *
  540.      * @return string|false The file contents, or false on failure.
  541.      */
  542.     public function readAndDelete($path)
  543.     {
  544.         list($prefix$path) = $this->getPrefixAndPath($path);
  545.         return $this->getFilesystem($prefix)->readAndDelete($path);
  546.     }
  547.     /**
  548.      * Get a file/directory handler.
  549.      *
  550.      * @deprecated
  551.      *
  552.      * @param string  $path    The path to the file.
  553.      * @param Handler $handler An optional existing handler to populate.
  554.      *
  555.      * @return Handler Either a file or directory handler.
  556.      */
  557.     public function get($pathHandler $handler null)
  558.     {
  559.         list($prefix$path) = $this->getPrefixAndPath($path);
  560.         return $this->getFilesystem($prefix)->get($path);
  561.     }
  562. }