123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402 |
- <?php
-
- namespace Illuminate\Filesystem;
-
- use Closure;
- use Aws\S3\S3Client;
- use OpenCloud\Rackspace;
- use Illuminate\Support\Arr;
- use InvalidArgumentException;
- use League\Flysystem\AdapterInterface;
- use League\Flysystem\Sftp\SftpAdapter;
- use League\Flysystem\FilesystemInterface;
- use League\Flysystem\Cached\CachedAdapter;
- use League\Flysystem\Filesystem as Flysystem;
- use League\Flysystem\Adapter\Ftp as FtpAdapter;
- use League\Flysystem\Rackspace\RackspaceAdapter;
- use League\Flysystem\Adapter\Local as LocalAdapter;
- use League\Flysystem\AwsS3v3\AwsS3Adapter as S3Adapter;
- use League\Flysystem\Cached\Storage\Memory as MemoryStore;
- use Illuminate\Contracts\Filesystem\Factory as FactoryContract;
-
- /**
- * @mixin \Illuminate\Contracts\Filesystem\Filesystem
- */
- class FilesystemManager implements FactoryContract
- {
- /**
- * The application instance.
- *
- * @var \Illuminate\Contracts\Foundation\Application
- */
- protected $app;
-
- /**
- * The array of resolved filesystem drivers.
- *
- * @var array
- */
- protected $disks = [];
-
- /**
- * The registered custom driver creators.
- *
- * @var array
- */
- protected $customCreators = [];
-
- /**
- * Create a new filesystem manager instance.
- *
- * @param \Illuminate\Contracts\Foundation\Application $app
- * @return void
- */
- public function __construct($app)
- {
- $this->app = $app;
- }
-
- /**
- * Get a filesystem instance.
- *
- * @param string $name
- * @return \Illuminate\Contracts\Filesystem\Filesystem
- */
- public function drive($name = null)
- {
- return $this->disk($name);
- }
-
- /**
- * Get a filesystem instance.
- *
- * @param string $name
- * @return \Illuminate\Contracts\Filesystem\Filesystem
- */
- public function disk($name = null)
- {
- $name = $name ?: $this->getDefaultDriver();
-
- return $this->disks[$name] = $this->get($name);
- }
-
- /**
- * Get a default cloud filesystem instance.
- *
- * @return \Illuminate\Contracts\Filesystem\Filesystem
- */
- public function cloud()
- {
- $name = $this->getDefaultCloudDriver();
-
- return $this->disks[$name] = $this->get($name);
- }
-
- /**
- * Attempt to get the disk from the local cache.
- *
- * @param string $name
- * @return \Illuminate\Contracts\Filesystem\Filesystem
- */
- protected function get($name)
- {
- return $this->disks[$name] ?? $this->resolve($name);
- }
-
- /**
- * Resolve the given disk.
- *
- * @param string $name
- * @return \Illuminate\Contracts\Filesystem\Filesystem
- *
- * @throws \InvalidArgumentException
- */
- protected function resolve($name)
- {
- $config = $this->getConfig($name);
-
- if (isset($this->customCreators[$config['driver']])) {
- return $this->callCustomCreator($config);
- }
-
- $driverMethod = 'create'.ucfirst($config['driver']).'Driver';
-
- if (method_exists($this, $driverMethod)) {
- return $this->{$driverMethod}($config);
- } else {
- throw new InvalidArgumentException("Driver [{$config['driver']}] is not supported.");
- }
- }
-
- /**
- * Call a custom driver creator.
- *
- * @param array $config
- * @return \Illuminate\Contracts\Filesystem\Filesystem
- */
- protected function callCustomCreator(array $config)
- {
- $driver = $this->customCreators[$config['driver']]($this->app, $config);
-
- if ($driver instanceof FilesystemInterface) {
- return $this->adapt($driver);
- }
-
- return $driver;
- }
-
- /**
- * Create an instance of the local driver.
- *
- * @param array $config
- * @return \Illuminate\Contracts\Filesystem\Filesystem
- */
- public function createLocalDriver(array $config)
- {
- $permissions = $config['permissions'] ?? [];
-
- $links = ($config['links'] ?? null) === 'skip'
- ? LocalAdapter::SKIP_LINKS
- : LocalAdapter::DISALLOW_LINKS;
-
- return $this->adapt($this->createFlysystem(new LocalAdapter(
- $config['root'], LOCK_EX, $links, $permissions
- ), $config));
- }
-
- /**
- * Create an instance of the ftp driver.
- *
- * @param array $config
- * @return \Illuminate\Contracts\Filesystem\Filesystem
- */
- public function createFtpDriver(array $config)
- {
- return $this->adapt($this->createFlysystem(
- new FtpAdapter($config), $config
- ));
- }
-
- /**
- * Create an instance of the sftp driver.
- *
- * @param array $config
- * @return \Illuminate\Contracts\Filesystem\Filesystem
- */
- public function createSftpDriver(array $config)
- {
- return $this->adapt($this->createFlysystem(
- new SftpAdapter($config), $config
- ));
- }
-
- /**
- * Create an instance of the Amazon S3 driver.
- *
- * @param array $config
- * @return \Illuminate\Contracts\Filesystem\Cloud
- */
- public function createS3Driver(array $config)
- {
- $s3Config = $this->formatS3Config($config);
-
- $root = $s3Config['root'] ?? null;
-
- $options = $config['options'] ?? [];
-
- return $this->adapt($this->createFlysystem(
- new S3Adapter(new S3Client($s3Config), $s3Config['bucket'], $root, $options), $config
- ));
- }
-
- /**
- * Format the given S3 configuration with the default options.
- *
- * @param array $config
- * @return array
- */
- protected function formatS3Config(array $config)
- {
- $config += ['version' => 'latest'];
-
- if ($config['key'] && $config['secret']) {
- $config['credentials'] = Arr::only($config, ['key', 'secret']);
- }
-
- return $config;
- }
-
- /**
- * Create an instance of the Rackspace driver.
- *
- * @param array $config
- * @return \Illuminate\Contracts\Filesystem\Cloud
- */
- public function createRackspaceDriver(array $config)
- {
- $client = new Rackspace($config['endpoint'], [
- 'username' => $config['username'], 'apiKey' => $config['key'],
- ]);
-
- $root = $config['root'] ?? null;
-
- return $this->adapt($this->createFlysystem(
- new RackspaceAdapter($this->getRackspaceContainer($client, $config), $root), $config
- ));
- }
-
- /**
- * Get the Rackspace Cloud Files container.
- *
- * @param \OpenCloud\Rackspace $client
- * @param array $config
- * @return \OpenCloud\ObjectStore\Resource\Container
- */
- protected function getRackspaceContainer(Rackspace $client, array $config)
- {
- $urlType = $config['url_type'] ?? null;
-
- $store = $client->objectStoreService('cloudFiles', $config['region'], $urlType);
-
- return $store->getContainer($config['container']);
- }
-
- /**
- * Create a Flysystem instance with the given adapter.
- *
- * @param \League\Flysystem\AdapterInterface $adapter
- * @param array $config
- * @return \League\Flysystem\FilesystemInterface
- */
- protected function createFlysystem(AdapterInterface $adapter, array $config)
- {
- $cache = Arr::pull($config, 'cache');
-
- $config = Arr::only($config, ['visibility', 'disable_asserts', 'url']);
-
- if ($cache) {
- $adapter = new CachedAdapter($adapter, $this->createCacheStore($cache));
- }
-
- return new Flysystem($adapter, count($config) > 0 ? $config : null);
- }
-
- /**
- * Create a cache store instance.
- *
- * @param mixed $config
- * @return \League\Flysystem\Cached\CacheInterface
- *
- * @throws \InvalidArgumentException
- */
- protected function createCacheStore($config)
- {
- if ($config === true) {
- return new MemoryStore;
- }
-
- return new Cache(
- $this->app['cache']->store($config['store']),
- $config['prefix'] ?? 'flysystem',
- $config['expire'] ?? null
- );
- }
-
- /**
- * Adapt the filesystem implementation.
- *
- * @param \League\Flysystem\FilesystemInterface $filesystem
- * @return \Illuminate\Contracts\Filesystem\Filesystem
- */
- protected function adapt(FilesystemInterface $filesystem)
- {
- return new FilesystemAdapter($filesystem);
- }
-
- /**
- * Set the given disk instance.
- *
- * @param string $name
- * @param mixed $disk
- * @return $this
- */
- public function set($name, $disk)
- {
- $this->disks[$name] = $disk;
-
- return $this;
- }
-
- /**
- * Get the filesystem connection configuration.
- *
- * @param string $name
- * @return array
- */
- protected function getConfig($name)
- {
- return $this->app['config']["filesystems.disks.{$name}"];
- }
-
- /**
- * Get the default driver name.
- *
- * @return string
- */
- public function getDefaultDriver()
- {
- return $this->app['config']['filesystems.default'];
- }
-
- /**
- * Get the default cloud driver name.
- *
- * @return string
- */
- public function getDefaultCloudDriver()
- {
- return $this->app['config']['filesystems.cloud'];
- }
-
- /**
- * Unset the given disk instances.
- *
- * @param array|string $disk
- * @return $this
- */
- public function forgetDisk($disk)
- {
- foreach ((array) $disk as $diskName) {
- unset($this->disks[$diskName]);
- }
-
- return $this;
- }
-
- /**
- * Register a custom driver creator Closure.
- *
- * @param string $driver
- * @param \Closure $callback
- * @return $this
- */
- public function extend($driver, Closure $callback)
- {
- $this->customCreators[$driver] = $callback;
-
- return $this;
- }
-
- /**
- * Dynamically call the default driver instance.
- *
- * @param string $method
- * @param array $parameters
- * @return mixed
- */
- public function __call($method, $parameters)
- {
- return $this->disk()->$method(...$parameters);
- }
- }
|