diff --git a/flysystem.info.yml b/flysystem.info.yml index 75c8ba413a12e04b34bf0b9f3a211a3f980d432e..bb7fe92bef35ea2393007a388b52e1c102dbe4c5 100644 --- a/flysystem.info.yml +++ b/flysystem.info.yml @@ -2,6 +2,4 @@ name: Flysystem type: module description: 'Provides access to various filesystem backends using Flysystem.' package: Flysystem -core_version_requirement: ^10.3 -dependencies: - - drupal:field +core_version_requirement: ^10 || ^11 diff --git a/flysystem.module b/flysystem.module index da02359972a65202d98979bb773960fa46a48db3..ad98ac703c6058fab9822bd55b4e7dabe372fa82 100644 --- a/flysystem.module +++ b/flysystem.module @@ -8,36 +8,42 @@ use Drupal\Core\Access\AccessResult; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Session\AccountInterface; -use Drupal\Core\StreamWrapper\StreamWrapperManager; use Drupal\file\FileInterface; /** - * Implements hook_file_download(). + * Implements hook_cron(). */ -function flysystem_file_download($uri) { - $schemes = []; - $config_storage = \Drupal::service('config.storage'); - $entity_config_names = $config_storage->listAll('flysystem.flysystem_adapter_config'); - $configured_entities = $config_storage->readMultiple($entity_config_names); - foreach ($configured_entities as $value) { - $schemes[] = $value['id']; - } - - $scheme = StreamWrapperManager::getScheme($uri); - - if (!$scheme || !in_array($scheme, $schemes, TRUE)) { - return; - } +// Function flysystem_cron() { +// Drupal::service('flysystem_factory')->ensure(); +// } - if (!file_exists($uri)) { - return; - } +/** + * Implements hook_rebuild(). + */ +// Function flysystem_rebuild() { +// Drupal::service('flysystem_factory')->ensure(); +// } - return [ - 'Content-Type' => \Drupal::service('file.mime_type.guesser.extension')->guessMimeType($uri), - 'Content-Length' => filesize($uri), - ]; -} +/** + * Implements hook_file_download(). + */ +// Function flysystem_file_download($uri) { +// $schemes = Drupal::service('flysystem_factory')->getSchemes(); +// $scheme = StreamWrapperManager::getScheme($uri); +// +// if (!$scheme || !in_array($scheme, $schemes, TRUE)) { +// return; +// } +// +// if (!file_exists($uri)) { +// return; +// } +// +// return [ +// 'Content-Type' => Drupal::service('file.mime_type.guesser.extension')->guessMimeType($uri), +// 'Content-Length' => filesize($uri), +// ]; +// } /** * Implements hook_entity_access(). @@ -45,7 +51,6 @@ function flysystem_file_download($uri) { * @see Drupal\file\FileAccessControlHandler */ function flysystem_entity_access(EntityInterface $entity, $operation, AccountInterface $account) { - $schemes = []; if (!$entity instanceof FileInterface) { return AccessResult::neutral(); } @@ -54,21 +59,17 @@ function flysystem_entity_access(EntityInterface $entity, $operation, AccountInt return AccessResult::neutral(); } - $config_storage = \Drupal::service('config.storage'); - $entity_config_names = $config_storage->listAll('flysystem.flysystem_adapter_config'); - $configured_entities = $config_storage->readMultiple($entity_config_names); - foreach ($configured_entities as $value) { - $schemes[] = $value['id']; - } - - $scheme = StreamWrapperManager::getScheme($entity->getFileUri()); - if (!$scheme || !in_array($scheme, $schemes, TRUE)) { - return AccessResult::neutral(); - } - - if ($operation === 'download') { - return AccessResult::allowed(); - } - - return AccessResult::allowedIfHasPermission($account, 'access content'); + // $schemes = Drupal::service('flysystem_factory')->getSchemes(); + // $scheme = StreamWrapperManager::getScheme($entity->getFileUri()); + // If (!$scheme || !in_array($scheme, $schemes, TRUE)) { + // return AccessResult::neutral(); + // } + // $settings = Settings::get('flysystem', []); + // If (empty($settings[$scheme]['config']['public'])) { + // return AccessResult::neutral(); + // } + // If ($operation === 'download') { + // return AccessResult::allowed(); + // } + // Return AccessResult::allowedIfHasPermission($account, 'access content'); } diff --git a/modules/flysystem_local/config/schema/flysystem_local.adapter.schema.yml b/modules/flysystem_local/config/schema/flysystem_local.adapter.schema.yml index cf48f4e0e864e1ba9eb93eaabfba70aa49403301..6d9aeccc4602b5e9136646c6d74500953c297f65 100644 --- a/modules/flysystem_local/config/schema/flysystem_local.adapter.schema.yml +++ b/modules/flysystem_local/config/schema/flysystem_local.adapter.schema.yml @@ -2,6 +2,9 @@ plugin.plugin_configuration.flysystem_adapter_config.flysystem_local: type: mapping label: 'Flysystem Local Filesystem settings' mapping: + schema: + type: 'string' + label: 'File management schema' root_directory: type: 'string' label: 'File Storage directory, relative to Drupal root' diff --git a/modules/flysystem_local/flysystem_local.info.yml b/modules/flysystem_local/flysystem_local.info.yml index 2451230e39158e17b72753f56b39b5732efd9df2..eb80635642b9f554c12d6109673d09ff015d1443 100644 --- a/modules/flysystem_local/flysystem_local.info.yml +++ b/modules/flysystem_local/flysystem_local.info.yml @@ -2,6 +2,4 @@ name: 'Flysystem Local Filesytem Adapter' type: module description: 'Flysystem Local Filesystem Adapter.' package: 'Flysystem' -core_version_requirement: ^10 -dependencies: - - flysystem:flysystem +core_version_requirement: ^10 || ^11 diff --git a/modules/flysystem_local/src/Plugin/FlysystemAdapter/LocalAdapter.php b/modules/flysystem_local/src/Plugin/FlysystemAdapter/LocalAdapter.php index d1ae70692cc10ad2f61d53ef930886471f13fcc0..a8d47a40e594ab1a506464b3aadd188315dad8aa 100644 --- a/modules/flysystem_local/src/Plugin/FlysystemAdapter/LocalAdapter.php +++ b/modules/flysystem_local/src/Plugin/FlysystemAdapter/LocalAdapter.php @@ -9,6 +9,7 @@ use Drupal\flysystem\FlysystemSubAdapterInterface; use Drupal\flysystem\Plugin\FlysystemAdapterPluginBase; use Drupal\flysystem\Plugin\FlysystemAdapterPluginTrait; use League\Flysystem\Local\LocalFilesystemAdapter; +use League\Flysystem\UnixVisibility\PortableVisibilityConverter; /** * Plugin implementation of the flysystem_adapter. @@ -55,7 +56,7 @@ final class LocalAdapter extends FlysystemAdapterPluginBase implements Flysystem /** * The League\Flysystem\FilesytemAdapter class for this adapter. */ - static protected string $flysystemAdapterClass = 'League\Flysystem\Local\LocalFilesystemAdapter'; + static protected string $flysystemAdapterClass = '\League\Flysystem\Local\LocalFilesystemAdapter'; /** * The fully qualified name of this class. @@ -74,6 +75,15 @@ final class LocalAdapter extends FlysystemAdapterPluginBase implements Flysystem */ public function buildSubConfigurationForm(array &$form, FormStateInterface $form_state, $flysystem_adapter_config) { $defaultPermissions = $this->getDefaultPermissions(); + $form['schema'] = [ + '#type' => 'textfield', + '#title' => $this->t('Schema'), + '#maxlength' => 255, + '#description' => $this->t('The schema used to identify files managed by this adapter.'), + // @todo determine how to retrieve saved values once form is saved. + '#default_value' => $flysystem_adapter_config->getSubAdapterConfigItem('schema'), + '#required' => TRUE, + ]; $form['root_directory'] = [ '#type' => 'textfield', '#title' => $this->t('File Storage Location'), @@ -137,7 +147,7 @@ final class LocalAdapter extends FlysystemAdapterPluginBase implements Flysystem $form['plugin_adapter_class'] = [ '#type' => 'hidden', '#title' => $this->t('Drupal Flysystem Plugin Adapter Class'), - '#default_value' => __CLASS__ . "Utility", + '#default_value' => __CLASS__, ]; return $form; @@ -149,15 +159,15 @@ final class LocalAdapter extends FlysystemAdapterPluginBase implements Flysystem * @return string * Fully qualified class name for \League\Flysystem\FilesystemAdapter */ - public static function getFlysystemAdapterClass() { + static public function getFlysystemAdapterClass() { return self::$flysystemAdapterClass; } /** * Returns a configured Flysystem FilesystemAdapter. */ - public static function configureFlysystemAdapter(array $configure_entity) { - + static public function configureFlysystemAdapter(array $configure_entity) { + } } diff --git a/modules/flysystem_local/src/Plugin/FlysystemAdapter/LocalAdapterUtility.php b/modules/flysystem_local/src/Plugin/FlysystemAdapter/LocalAdapterUtility.php deleted file mode 100644 index 51f22ff68714aba2a9424b324e92f1f23b101206..0000000000000000000000000000000000000000 --- a/modules/flysystem_local/src/Plugin/FlysystemAdapter/LocalAdapterUtility.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php - -declare(strict_types=1); - -namespace Drupal\flysystem_local\Plugin\FlysystemAdapter; - -use League\Flysystem\Local\LocalFilesystemAdapter; -use League\Flysystem\UnixVisibility\PortableVisibilityConverter; - -/** - * Local Adapter factory class. - */ -class LocalAdapterUtility { - - /** - * Configures the designated adapter. - * - * @param array $sub_adapter_config - * The sub adapter config item for this adapter config. - * - * @return array - * Array containing configured adapter and configuration options array. - */ - public static function create($sub_adapter_config) { - $options = []; - $visibilityArray = [ - 'file' => [ - 'public' => (int) $sub_adapter_config['permissions']['file']['public'], - 'private' => (int) $sub_adapter_config['permissions']['file']['private'], - ], - 'dir' => [ - 'public' => (int) $sub_adapter_config['permissions']['dir']['public'], - 'private' => (int) $sub_adapter_config['permissions']['dir']['private'], - ], - ]; - // Set to converter, or set to NULL if not supported. - // @see https://flysystem.thephpleague.com/docs/ for information on configuring adapters. - $visibility = PortableVisibilityConverter::fromArray($visibilityArray); - $link_handling = strlen($sub_adapter_config['link_handling']) == 0 ? LocalFilesystemAdapter::DISALLOW_LINKS : LocalFilesystemAdapter::SKIP_LINKS; - $adapter = new LocalFilesystemAdapter( - $sub_adapter_config['root_directory'], - $visibility, - (int) $sub_adapter_config['write_flags'], - $link_handling, - ); - $options['visibility'] = $visibility; - return ['adapter' => $adapter, 'options' => $options]; - } - -} diff --git a/src/Compiler/FlysystemRegisterStreamWrappers.php b/src/Compiler/FlysystemRegisterStreamWrappers.php new file mode 100644 index 0000000000000000000000000000000000000000..5513c127cd16585e3cea632c033c4c1f61557065 --- /dev/null +++ b/src/Compiler/FlysystemRegisterStreamWrappers.php @@ -0,0 +1,58 @@ +<?php + +namespace Drupal\flysystem\Compiler; + +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Drupal\flysystem\FlyStream\FlyStreamWrapper; +use League\Flysystem\Filesystem; + +/** + * Create streamwrapper service entries for the configured Flysystem Adapters. + * + * The core RegisterStreamWrapperPass() must be called after this pass to + * actually register the container entries created with this pass. + * + * @see Drupal\flysystem\FlysystemServiceProvider + */ +class FlysystemRegisterStreamWrappers implements CompilerPassInterface { + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container): void { + /** @var \Drupal\Core\Config\CachedStorage $config_storage */ + $config_storage = $container->get('config.storage'); + $entity_config_names = $config_storage->listAll('flysystem.flysystem_adapter_config'); + $configured_entities = $config_storage->readMultiple($entity_config_names); + + foreach ($configured_entities as $key) { + if (empty($key)) { + // This should never happen, however if it does skip this entry. + continue; + } + + if ($key['status'] !== TRUE) { + // Scheme is not enabled. + continue; + } + + $adapterConfig = + //... + + $service_definition = new Definition(FlyStreamWrapper::class); + $service_definition->setTags( + [ + 'stream_wrapper' => [ + [ + 'scheme' => $key['sub_adapter_config']['schema'], + ], + ], + ], + ); + $service_definition->setPublic(TRUE); + $container->setDefinition('stream_wrapper.' . $key['id'], $service_definition); + } + } + +} diff --git a/src/Decorator/FlysystemDrupalFileSystem.php b/src/Decorator/FlysystemDrupalFileSystem.php index 264d48adb3d8db370461269c089f9d06d5471b50..238c0b2a1c01880878a57a0420717ab3ba9e2a15 100644 --- a/src/Decorator/FlysystemDrupalFileSystem.php +++ b/src/Decorator/FlysystemDrupalFileSystem.php @@ -11,7 +11,7 @@ use Drupal\Core\File\FileSystem; use Drupal\Core\Site\Settings; use Drupal\Core\StreamWrapper\StreamWrapperManager; use Drupal\Core\StreamWrapper\StreamWrapperManagerInterface; -use Drupal\flysystem\FlyStream\FlyStreamWrapperInterface; +use League\Flysystem\FilesystemOperator; /** * Decorates \Drupal::service('file_system'). @@ -91,7 +91,7 @@ class FlysystemDrupalFileSystem extends FileSystem { if (!isset($mode)) { /** @var \Drupal\Core\StreamWrapper\StreamWrapperInterface $wrapper */ $wrapper = $this->streamWrapperManager->getViaUri($uri); - if ($wrapper instanceof FlyStreamWrapperInterface) { + if ($wrapper instanceof FilesystemOperator) { return $this->chmodFs($wrapper, $uri, $mode); } } @@ -104,7 +104,7 @@ class FlysystemDrupalFileSystem extends FileSystem { public function mkdir($uri, $mode = NULL, $recursive = FALSE, $context = NULL) { /** @var \Drupal\Core\StreamWrapper\StreamWrapperInterface $wrapper */ $wrapper = $this->streamWrapperManager->getViaUri($uri); - if ($wrapper instanceof FlyStreamWrapperInterface) { + if ($wrapper instanceof FilesystemOperator) { return $this->mkdirFs($wrapper, $uri, $mode, $recursive, $context); } return $this->decoratedService->mkdir($uri, $mode, $recursive, $context); @@ -118,7 +118,7 @@ class FlysystemDrupalFileSystem extends FileSystem { public function rmdir($uri, $context = NULL) { /** @var \Drupal\Core\StreamWrapper\StreamWrapperInterface $wrapper */ $wrapper = $this->streamWrapperManager->getViaUri($uri); - if ($wrapper instanceof FlyStreamWrapperInterface) { + if ($wrapper instanceof FilesystemOperator) { return $this->rmdirFs($wrapper, $uri, $context); } return $this->decoratedService->rmdir($uri, $context); @@ -130,7 +130,7 @@ class FlysystemDrupalFileSystem extends FileSystem { public function copy($source, $destination, $fileExists = FileExists::Rename) { /** @var \Drupal\Core\StreamWrapper\StreamWrapperInterface $wrapper */ $wrapper = $this->streamWrapperManager->getViaScheme(StreamWrapperManager::getScheme($source)); - if ($wrapper instanceof FlyStreamWrapperInterface) { + if ($wrapper instanceof FilesystemOperator) { return $this->copyFs($wrapper, $source, $destination, $fileExists); } return $this->decoratedService->copy($source, $destination, $fileExists); @@ -142,7 +142,7 @@ class FlysystemDrupalFileSystem extends FileSystem { public function delete($path) { /** @var \Drupal\Core\StreamWrapper\StreamWrapperManager $wrapper */ $wrapper = $this->streamWrapperManager->getViaUri($path); - if ($wrapper instanceof FlyStreamWrapperInterface) { + if ($wrapper instanceof FilesystemOperator) { return $this->deleteFs($wrapper, $path); } return $this->decoratedService->delete($path); @@ -157,7 +157,7 @@ class FlysystemDrupalFileSystem extends FileSystem { } /** @var \Drupal\Core\StreamWrapper\StreamWrapperInterface $wrapper */ $wrapper = $this->streamWrapperManager->getViaUri($path); - if ($wrapper instanceof FlyStreamWrapperInterface) { + if ($wrapper instanceof FilesystemOperator) { return $this->deleteRecursiveFs($wrapper, $path, $callback); } return $this->decoratedService->deleteRecursive($path, NULL); @@ -169,7 +169,7 @@ class FlysystemDrupalFileSystem extends FileSystem { public function move($source, $destination, $fileExists = FileExists::Rename) { /** @var \Drupal\Core\StreamWrapper\StreamWrapperInterface $wrapper */ $wrapper = $this->streamWrapperManager->getViaScheme(StreamWrapperManager::getScheme($source)); - if ($wrapper instanceof FlyStreamWrapperInterface) { + if ($wrapper instanceof FilesystemOperator) { return $this->moveFs($wrapper, $source, $destination, $fileExists); } return $this->decoratedService->move($source, $destination, $fileExists); @@ -191,7 +191,7 @@ class FlysystemDrupalFileSystem extends FileSystem { } /** @var \Drupal\Core\StreamWrapper\StreamWrapperInterface $wrapper */ $wrapper = $this->streamWrapperManager->getViaScheme(StreamWrapperManager::getScheme($destination)); - if ($wrapper instanceof FlyStreamWrapperInterface) { + if ($wrapper instanceof FilesystemOperator) { return $this->saveDataFs($wrapper, $temp_name, $destination, $fileExists); } return $this->decoratedService->move($temp_name, $destination, $fileExists); @@ -207,7 +207,7 @@ class FlysystemDrupalFileSystem extends FileSystem { } /** @var \Drupal\Core\StreamWrapper\StreamWrapperInterface $wrapper */ $wrapper = $this->streamWrapperManager->getViaScheme(StreamWrapperManager::getScheme($directory)); - if ($wrapper instanceof FlyStreamWrapperInterface) { + if ($wrapper instanceof FilesystemOperator) { return $this->prepareDirectoryFs($wrapper, $directory, $options); } return $this->decoratedService->prepareDirectory($directory, $options); @@ -240,7 +240,7 @@ class FlysystemDrupalFileSystem extends FileSystem { /** @var \Drupal\Core\StreamWrapper\StreamWrapperInterface $wrapper */ $wrapper = $this->streamWrapperManager->getViaScheme(StreamWrapperManager::getScheme($destination)); - if ($wrapper instanceof FlyStreamWrapperInterface) { + if ($wrapper instanceof FilesystemOperator) { return $this->createFilenameFs($wrapper, $separator, $destination, $basename, $directory); } return $this->decoratedService->createFilename($basename, $directory); @@ -256,7 +256,7 @@ class FlysystemDrupalFileSystem extends FileSystem { } /** @var \Drupal\Core\StreamWrapper\StreamWrapperInterface $wrapper */ $wrapper = $this->streamWrapperManager->getViaScheme(StreamWrapperManager::getScheme($destination)); - if ($wrapper instanceof FlyStreamWrapperInterface) { + if ($wrapper instanceof FilesystemOperator) { return $this->getDestinationFilenameFs($wrapper, $basename, $destination, $fileExists); } return $this->decoratedService->getDestinationFilename($destination, $fileExists); diff --git a/src/Decorator/FlysystemFileSystemTrait.php b/src/Decorator/FlysystemFileSystemTrait.php index 3d8d2d127d1dcb99d432dc374f1615e3be3b0392..87c7b003da0901ff3e86739c54d95e17dfc37023 100644 --- a/src/Decorator/FlysystemFileSystemTrait.php +++ b/src/Decorator/FlysystemFileSystemTrait.php @@ -20,7 +20,7 @@ trait FlysystemFileSystemTrait { /** * Converts Drupal's FileSystem::chmod() to FilesystemOperator methods. * - * @param \Drupal\flysystem\FlyStream\FlyStreamWrapperInterface $wrapper + * @param \League\Flysystem\FilesystemOperator $wrapper * Drupal StreamWrapper service. * @param string $uri * A string containing a URI file, or directory path. @@ -31,23 +31,21 @@ trait FlysystemFileSystemTrait { * TRUE for success, FALSE in the event of an error. */ protected function chmodFs($wrapper, $uri, $mode = NULL): bool { - \Drupal::logger('flysystem')->notice('Calling ' . __METHOD__ . ', uri: ' . $uri); try { $drupalMode = NULL; - if ($wrapper->filesystem->directoryExists($uri)) { + if ($wrapper->directoryExists($uri)) { // @todo May have to write a Flysystem VisibilityConverter for // Local file adapter that substitutes Drupal file and directory // permission settings for the default settings in Flysystem. $drupalMode = $this->settings->get('file_chmod_directory', static::CHMOD_DIRECTORY); } - elseif ($wrapper->filesystem->fileExists($uri)) { + elseif ($wrapper->fileExists($uri)) { $drupalMode = $this->settings->get('file_chmod_file', static::CHMOD_FILE); } - $wrapper->filesystem->setVisibility($uri, $drupalMode); + $wrapper->setVisibility($uri, $drupalMode); return TRUE; } catch (\Exception $e) { - \Drupal::logger('FlyStreamWrapper')->error('Exception: ' . $e->getMessage()); // @todo write exception handler for possible exceptions thrown // by FlysystemAdapter::setVisibility(); } @@ -57,7 +55,7 @@ trait FlysystemFileSystemTrait { /** * Converts Drupal's FileSystem::mkdir() to FilesystemOperator methods. * - * @param \Drupal\flysystem\FlyStream\FlyStreamWrapperInterface $wrapper + * @param \League\Flysystem\FilesystemOperator $wrapper * Drupal StreamWrapper service. * @param string $uri * A URI or pathname. @@ -76,21 +74,14 @@ trait FlysystemFileSystemTrait { * @todo finish writing, see inline todo comments. */ protected function mkdirFs($wrapper, $uri, $mode = NULL, $recursive = FALSE, $context = NULL): bool { - \Drupal::logger('flysystem')->notice('Calling ' . __METHOD__ . ', uri: ' . $uri); - if (!isset($mode)) { - $mode = $this->settings->get('file_chmod_directory', static::CHMOD_DIRECTORY); - } - try { // @todo figure out how to utilize directory permissions, see notes on // Flysystem VisibilityConverter. // @see \League\Flysystem\Filesystem::createDirectory() - $wrapper->filesystem->createDirectory($uri); + $wrapper->createDirectory($uri); return TRUE; } catch (\Exception $e) { - \Drupal::logger('FlyStreamWrapper')->error('Exception: ' . $e->getMessage()); - \Drupal::logger('FlyStreamWrapper')->error('Failed to create directory for ' . $uri); // @todo write exception handler to handle Flysystem Exception, and // return a proper return code, which is FALSE. } @@ -100,7 +91,7 @@ trait FlysystemFileSystemTrait { /** * Converts Drupal's FileSystem::rmdir() to FilesystemOperator methods. * - * @param \Drupal\flysystem\FlyStream\FlyStreamWrapperInterface $wrapper + * @param \League\Flysystem\FilesystemOperator $wrapper * Drupal StreamWrapper service. * @param string $uri * A URI or pathname. @@ -113,16 +104,14 @@ trait FlysystemFileSystemTrait { * @todo finish writing, see inline todo comments. */ protected function rmdirFs($wrapper, $uri, $context = NULL): bool { - \Drupal::logger('flysystem')->notice('Calling ' . __METHOD__ . ', uri: ' . $uri); try { // @todo figure out how to utilize directory permissions, see notes on // Flysystem VisibilityConverter. // @see \League\Flysystem\Filesystem::deleteDirectory() - $wrapper->filesystem->deleteDirectory($uri); + $wrapper->deleteDirectory($uri); return TRUE; } catch (\Exception $e) { - \Drupal::logger('FlyStreamWrapper')->error('Exception: ' . $e->getMessage()); // @todo write exception handler to handle Flysystem Exception, and // return a proper return code, which is FALSE. } @@ -132,7 +121,7 @@ trait FlysystemFileSystemTrait { /** * Converts Drupal's FileSystem::copy() to FilesystemOperator methods. * - * @param \Drupal\flysystem\FlyStream\FlyStreamWrapperInterface $wrapper + * @param \League\Flysystem\FilesystemOperator $wrapper * Drupal StreamWrapper service. * @param string $source * A string specifying the filepath or URI of the source file. @@ -148,16 +137,14 @@ trait FlysystemFileSystemTrait { * @todo Rewrite to leverage Flysystem (yes) */ protected function copyFs($wrapper, $source, $destination, $fileExists): string { - \Drupal::logger('flysystem')->notice('Calling ' . __METHOD__ . ', source: ' . $source . ', destination: ' . $destination); try { // @todo figure out how to utilize directory permissions, see notes on // Flysystem VisibilityConverter. // @see \League\Flysystem\Filesystem::copy(). - $wrapper->filesystem->copy($source, $destination); + $wrapper->copy($source, $destination); return $destination; } catch (\Exception $e) { - \Drupal::logger('FlyStreamWrapper')->error('Exception: ' . $e->getMessage()); // @todo write exception handler to handle Flysystem Exception, and // return a proper return code, which is FALSE. } @@ -167,7 +154,7 @@ trait FlysystemFileSystemTrait { /** * Converts Drupal's FileSystem::delete() to FilesystemOperator methods. * - * @param \Drupal\flysystem\FlyStream\FlyStreamWrapperInterface $wrapper + * @param \League\Flysystem\FilesystemOperator $wrapper * Drupal StreamWrapper service. * @param string $path * A string containing a file path or (streamwrapper) URI. @@ -178,16 +165,14 @@ trait FlysystemFileSystemTrait { * @todo finish writing, see inline todo comments. */ protected function deleteFs($wrapper, $path) { - \Drupal::logger('flysystem')->notice('Calling ' . __METHOD__ . ', path: ' . $path); - if ($wrapper->filesystem->directoryExists($path)) { + if ($wrapper->directoryExists($path)) { throw new NotRegularFileException("Cannot delete '$path' because it is a directory. Use deleteRecursive() instead."); } - if ($wrapper->filesystem->fileExists($path)) { + if ($wrapper->fileExists($path)) { try { - $wrapper->filesystem->delete($path); + $wrapper->delete($path); } catch (\Exception $e) { - \Drupal::logger('FlyStreamWrapper')->error('Exception: ' . $e->getMessage()); // @todo modify \Exception to use class from Flysystem, // and throw a proper exception. } @@ -199,7 +184,7 @@ trait FlysystemFileSystemTrait { /** * Drupal's FileSystem::deleteRecursive() to FilesystemOperator methods. * - * @param \Drupal\flysystem\FlyStream\FlyStreamWrapperInterface $wrapper + * @param \League\Flysystem\FilesystemOperator $wrapper * Drupal StreamWrapper service. * @param string $path * A string containing either an URI or a file or directory path. @@ -212,13 +197,12 @@ trait FlysystemFileSystemTrait { * TRUE if successful, FALSE if not. */ protected function deleteRecursiveFs($wrapper, $path, callable $callback = NULL): bool { - \Drupal::logger('flysystem')->notice('Calling ' . __METHOD__ . ', path: ' . $path); - if (!$wrapper->filesystem->fileExists($path)) { + if (!$wrapper->fileExists($path)) { return TRUE; } - if ($wrapper->filesystem->directoryExists($path)) { - $dir = $wrapper->filesystem->listContents($path); + if ($wrapper->directoryExists($path)) { + $dir = $wrapper->listContents($path); foreach ($dir as $entry) { $entry_path = $path . '/' . $entry->path(); $this->deleteRecursive($entry_path, $callback); @@ -231,7 +215,7 @@ trait FlysystemFileSystemTrait { /** * Converts Drupal's FileSystem::move() to FilesystemOperator methods. * - * @param \Drupal\flysystem\FlyStream\FlyStreamWrapperInterface $wrapper + * @param \League\Flysystem\FilesystemOperator $wrapper * Drupal StreamWrapper service. * @param string $source * A string specifying the filepath or URI of the source file. @@ -248,17 +232,15 @@ trait FlysystemFileSystemTrait { * @todo finish writing, see inline todo comments. */ protected function moveFs($wrapper, $source, $destination, $fileExists): string { - \Drupal::logger('flysystem')->notice('Calling ' . __METHOD__ . ', source: ' . $source . ', destination: ' . $destination); try { // @todo figure out how to utilize directory permissions, see notes on // Flysystem VisibilityConverter. // @see \League\Flysystem\Filesystem::move(). // What do we do with the $replace flag? - $wrapper->filesystem->move($source, $destination); + $wrapper->move($source, $destination); return $destination; } catch (\Exception $e) { - \Drupal::logger('FlyStreamWrapper')->error('Exception: ' . $e->getMessage()); // @todo write exception handler to handle Flysystem Exception, and // return a proper return code, which is FALSE. } @@ -268,7 +250,7 @@ trait FlysystemFileSystemTrait { /** * Converts Drupal's FileSystem::saveData() to FilesystemOperator methods. * - * @param \Drupal\flysystem\FlyStream\FlyStreamWrapperInterface $wrapper + * @param \League\Flysystem\FilesystemOperator $wrapper * Drupal StreamWrapper service. * @param string $temp_nam * A string containing the contents of the file, moved to a temporary @@ -285,18 +267,16 @@ trait FlysystemFileSystemTrait { * @todo finish writing, see inline todo comments. */ protected function saveDataFs($wrapper, $temp_nam, $destination, $fileExists) { - \Drupal::logger('flysystem')->notice('Calling ' . __METHOD__ . ', temp_nam: ' . $temp_nam . ', destination: ' . $destination); // Move the file to its final destination. try { // @todo figure out how to utilize directory permissions, see notes on // Flysystem VisibilityConverter. // @see \League\Flysystem\Filesystem::move(). // Do we need to use the $replace flag here in the FlysystemAdapter? - $wrapper->filesystem->move($temp_nam, $destination); + $wrapper->move($temp_nam, $destination); return $destination; } catch (\Exception $e) { - \Drupal::logger('FlyStreamWrapper')->error('Exception: ' . $e->getMessage()); // @todo write exception handler to handle Flysystem Exception, and // return a proper return code, which is FALSE. } @@ -304,9 +284,9 @@ trait FlysystemFileSystemTrait { } /** - * Drupal's FileSystem::prepareDirectory() to FilesystemOperator methods. + * Drupal's FileSystem::prepareDirecctory() to FilesystemOperator methods. * - * @param \Drupal\flysystem\FlyStream\FlyStreamWrapperInterface $wrapper + * @param \League\Flysystem\FilesystemOperator $wrapper * Drupal StreamWrapper service. * @param string $directory * A string reference containing the name of a directory path or URI. A @@ -324,11 +304,6 @@ trait FlysystemFileSystemTrait { * @see \League\Flysystem\FilesystemOperator::directoryExists() */ protected function prepareDirectoryFs($wrapper, &$directory, $options): bool { - \Drupal::logger('flysystem')->notice('Calling ' . __METHOD__ . ', directory: ' . $directory); - if (!$this->streamWrapperManager->isValidUri($directory)) { - // Only trim if we're not dealing with a stream. - $directory = rtrim($directory, '/\\'); - } // How do we use the flags, self::MODIFY_PERMISSIONS and // static::CREATE_DIRECTORY here? // @see Drupal\Core\File\FileSystemInterface::prepareDirectory(). @@ -339,35 +314,24 @@ trait FlysystemFileSystemTrait { if ($success) { return TRUE; } - // If the operation failed, check again if the directory was created - // by another process/server, only report a failure if not. In this case - // we still need to ensure the directory is writable. - if (!is_dir($directory)) { - return FALSE; - } } catch (\Exception $e) { - \Drupal::logger('FlyStreamWrapper')->error('Exception: ' . $e->getMessage()); // @todo write exception handler to handle Flysystem Exception, and // return a proper return code, which is FALSE. } // If the operation failed, check again if the directory was created // by another process/server, only report a failure if not. In this case // we still need to ensure the directory is writable. - if (!$wrapper->filesystem->directoryExists($directory)) { + if (!$wrapper->directoryExists($directory)) { return FALSE; } - $writable = is_writable($directory); - if (!$writable && ($options & static::MODIFY_PERMISSIONS)) { - return $this->chmod($directory); - } - return $writeable; + return $this->chmod($directory); } /** * Drupal's FileSystem::createFilename() to FilesystemOperator methods. * - * @param \Drupal\flysystem\FlyStream\FlyStreamWrapperInterface $wrapper + * @param \League\Flysystem\FilesystemOperator $wrapper * Drupal StreamWrapper service. * @param string $separator * The pathname separator. @@ -386,9 +350,8 @@ trait FlysystemFileSystemTrait { * @todo reevaluate against \Drupal\Core\File\FileSystem::createFilename(). */ protected function createFilenameFs($wrapper, $separator, $destination, $basename, $directory): string { - \Drupal::logger('flysystem')->notice('Calling ' . __METHOD__ . ', separator: ' . $separator . ', destination: ' . $destination . ', basename: ' . $basename . ', directory: ' . $directory); try { - $exists = $wrapper->filesystem->fileExists($destination); + $exists = $wrapper->fileExists($destination); if ($exists) { // Destination file already exists, generate an alternative. $pos = strrpos($basename, '.'); @@ -404,12 +367,11 @@ trait FlysystemFileSystemTrait { $counter = 0; do { $destination = $directory . $separator . $name . '_' . $counter++ . $ext; - } while ($wrapper->filesystem->fileExists($destination)); + } while ($wrapper->fileExists($destination)); } } catch (\Exception $e) { - \Drupal::logger('FlyStreamWrapper')->error('Exception: ' . $e->getMessage()); // @todo write exception handler to handle Flysystem Exception, and // return a proper return code, which is FALSE. } @@ -419,7 +381,7 @@ trait FlysystemFileSystemTrait { /** * FileSystem::getDestinationFilename() to FilesystemOperator methods. * - * @param \Drupal\flysystem\FlyStream\FlyStreamWrapperInterface $wrapper + * @param \League\Flysystem\FilesystemOperator $wrapper * Drupal StreamWrapper service. * @param string $basename * The base file name, calculated. @@ -435,9 +397,8 @@ trait FlysystemFileSystemTrait { * @todo finish writing, see inline todo comments. */ protected function getDestinationFilenameFs($wrapper, $basename, $destination, $fileExists): string|bool { - \Drupal::logger('flysystem')->notice('Calling ' . __METHOD__ . ', basename: ' . $basename . ', destination: ' . $destination); try { - if ($wrapper->filesystem->fileExists($destination)) { + if ($wrapper->fileExists($destination)) { switch ($fileExists) { case FileExists::Replace: // Do nothing here, we want to overwrite the existing file. @@ -458,7 +419,6 @@ trait FlysystemFileSystemTrait { } } catch (\Exception $e) { - \Drupal::logger('FlyStreamWrapper')->error('Exception: ' . $e->getMessage()); // @todo write exception handler to handle Flysystem Exception, and // return a proper return code, which is FALSE. } diff --git a/src/FlyStream/FlyStreamData.php b/src/FlyStream/FlyStreamData.php new file mode 100644 index 0000000000000000000000000000000000000000..4f3066352c5bdd4ab9ae85177303e11b7b950f39 --- /dev/null +++ b/src/FlyStream/FlyStreamData.php @@ -0,0 +1,147 @@ +<?php + +namespace Drupal\flysystem\FlyStream; + +/** + * FlyStream Stream Wrapper Configuration data. + */ +class FlyStreamData { + /** + * File directory path. + * + * @var string + */ + public $path; + + /** + * Wrapper schema. + * + * @var string + */ + public $protocol; + + /** + * File path. + * + * @var string + */ + public $file; + + /** + * Flysystem Filesystem instance. + * + * @var \League\Flysystem\FilesystemOperator + */ + public $filesystem; + + /** + * Configuration data. + * + * @var array<string, int|string|bool|null> + */ + public $config = []; + + /** + * Resource handle. + * + * @var resource|false + */ + public $handle = FALSE; + + /** + * Write only setting. + * + * @var bool + */ + public $writeOnly = FALSE; + + /** + * Always Append setting. + * + * @var bool + */ + public $alwaysAppend = FALSE; + + /** + * Work on Local Copy setting. + * + * @var bool + */ + public $workOnLocalCopy = FALSE; + + /** + * Write Buffer Size. + * + * @var int + */ + public $writeBufferSize = 0; + + /** + * Bytes written to stream. + * + * @var int + */ + public $bytesWritten = 0; + + /** + * Lock Key setting. + * + * @var \Symfony\Component\Lock\Key + */ + public $lockKey; + + /** + * Directory Listing contents. + * + * @var \Iterator<mixed,\League\Flysystem\StorageAttributes> + */ + public $dirListing; + + /** + * Configures settings based on path. + * + * @param string $path + * File path. + */ + public function setPath(string $path): void { + $this->path = $path; + $this->protocol = substr($path, 0, (int) strpos($path, '://')); + $this->file = self::getFile($path); + $this->filesystem = FlyStreamWrapper::$filesystems[$this->protocol]; + $this->config = FlyStreamWrapper::$config[$this->protocol]; + } + + /** + * Get the file path. + * + * @param string $path + * File path. + * + * @return string + * File path converted. + */ + public static function getFile(string $path): string { + return (string) substr($path, strpos($path, '://') + 3); + } + + /** + * Gets Ignore Visibility Errors settings. + * + * @return bool + * Boolean setting. + */ + public function ignoreVisibilityErrors(): bool { + return (bool) $this->config[FlyStreamWrapper::IGNORE_VISIBILITY_ERRORS]; + } + + /** + * Gets Emulate Directory Last Modified settings. + * + * @return bool + * Boolean setting. + */ + public function emulateDirectoryLastModified(): bool { + return (bool) $this->config[FlyStreamWrapper::EMULATE_DIRECTORY_LAST_MODIFIED]; + } + +} diff --git a/src/FlyStream/FlyStreamWrapper.php b/src/FlyStream/FlyStreamWrapper.php index 4f618a8b88cedf79318460d85636f1e239414136..1f2f942a503d9a470b74970a445b9b68543ab694 100644 --- a/src/FlyStream/FlyStreamWrapper.php +++ b/src/FlyStream/FlyStreamWrapper.php @@ -12,6 +12,20 @@ class FlyStreamWrapper extends FlyStreamWrapperBase implements FlyStreamWrapperI use StringTranslationTrait; + /** + * FlysystemOperator instances. + * + * @var array<\League\Flysystem\FilesystemOperator> + */ + public static $filesystems; + + /** + * Configuration settings. + * + * @var array + */ + public static $config; + /** * Instance URI (stream). * @@ -21,6 +35,13 @@ class FlyStreamWrapper extends FlyStreamWrapperBase implements FlyStreamWrapperI */ protected $uri; + /** + * Scheme identifier. + * + * @var string + */ + protected $scheme = ''; + /** * StreamWrapper type. * diff --git a/src/FlyStream/FlyStreamWrapperBase.php b/src/FlyStream/FlyStreamWrapperBase.php index d652465fe29d8be01823170082fabbfba5d216e0..66647f9f35eb98eb8c9370ce4702a22bfb549bb7 100644 --- a/src/FlyStream/FlyStreamWrapperBase.php +++ b/src/FlyStream/FlyStreamWrapperBase.php @@ -2,7 +2,6 @@ namespace Drupal\flysystem\FlyStream; -use Drupal\Core\Config\CachedStorage; use Drupal\Core\StreamWrapper\PhpStreamWrapperInterface; use Drupal\flysystem\FlyStream\Exception\CouldNotDeleteFileException; use Drupal\flysystem\FlyStream\Exception\CouldNotRemoveDirectoryException; @@ -20,7 +19,6 @@ use Drupal\flysystem\FlyStream\Exception\UnableToCreateDirectoryException; use Drupal\flysystem\FlyStream\Exception\UnableToReadException; use Drupal\flysystem\FlyStream\Exception\UnableToWriteException; use League\Flysystem\Config; -use League\Flysystem\Filesystem; use League\Flysystem\FilesystemException; use League\Flysystem\StorageAttributes; use League\Flysystem\UnableToRetrieveMetadata; @@ -39,17 +37,11 @@ class FlyStreamWrapperBase implements PhpStreamWrapperInterface, FlyStreamWrappe use ExceptionHandlerTrait; /** - * Config Storage service. + * Current StreamWrapper Filesystem configuration data. * - * @var \Drupal\Core\Config\CachedStorage - */ - protected $configStorage; - /** - * Configuration file name. - * - * @var string|null - */ - protected $configuration; + * @var \Drupal\flysystem\FlyStream\FlyStreamData + * */ + protected $current; /** * File permission mode. @@ -72,143 +64,19 @@ class FlyStreamWrapperBase implements PhpStreamWrapperInterface, FlyStreamWrappe */ public $context; - /** - * Directory Listing contents. - * - * @var \Iterator<mixed,\League\Flysystem\StorageAttributes> - */ - public $dirListing; - - /** - * File directory path. - * - * @var string - */ - public $path; - - /** - * Wrapper scheme. - * - * @var string - */ - protected $scheme; - - /** - * File path. - * - * @var string - */ - public $file; - - /** - * Flysystem Filesystem instance. - * - * @var \League\Flysystem\FilesystemOperator - */ - public $filesystem; - - /** - * Configuration data. - * - * @var array<string, int|string|bool|null> - */ - public $config = []; - - /** - * Work on Local Copy setting. - * - * @var bool - */ - public $workOnLocalCopy = FALSE; - - /** - * Bytes written to stream. - * - * @var int - */ - public $bytesWritten = 0; - - /** - * Lock Key setting. - * - * @var \Symfony\Component\Lock\Key - */ - public $lockKey; - - /** - * Write only setting. - * - * @var bool - */ - public $writeOnly = FALSE; - - /** - * Always Append setting. - * - * @var bool - */ - public $alwaysAppend = FALSE; - - /** - * Write Buffer Size. - * - * @var int - */ - public $writeBufferSize = 0; - - /** - * Resource handle. - * - * @var resource|false - */ - public $handle = FALSE; - - /** - * Adapter Factory options. - * - * @var array|null - */ - public $options = NULL; - - /** - * Class constructor. - * - * @param string $configuration - * Name of configuration file for adapter. - * @param \Drupal\Core\Config\CachedStorage $config_storage - * Config Storage service. - */ - public function __construct(string $configuration, CachedStorage $config_storage) { - \Drupal::logger('FlyStreamWrapper')->notice('Calling ' . __METHOD__); - \Drupal::logger('FlyStreamWrapper')->notice('Configuration: ' . $configuration); - \Drupal::logger('FlyStreamWrapper')->notice('config.storage ' . isset($config_storage)); - - $this->configuration = $configuration; - $this->configStorage = $config_storage; - - $config = $this->configStorage->read($configuration); - - $adapterClass = new \ReflectionClass($config['sub_adapter_config']['plugin_adapter_class']); - - $adapterFactory = $adapterClass->newInstance(); - - $adapterFactoryInstance = $adapterFactory::create($config['sub_adapter_config']); - - $this->options = $adapterFactoryInstance['options']; - $this->filesystem = new Filesystem($adapterFactoryInstance['adapter']); + // phpcs:disable Drupal.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + public function __construct(FlyStreamData $current = NULL) { + $this->current = $current ?? new FlyStreamData(); } - // phpcs:disable Drupal.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** * {@inheritdoc} * * @todo Done */ public function dir_closedir(): bool { - \Drupal::logger('FlyStreamWrapper')->notice('Calling ' . __METHOD__); - unset($this->dirListing); + unset($this->current->dirListing); return TRUE; } @@ -218,23 +86,23 @@ class FlyStreamWrapperBase implements PhpStreamWrapperInterface, FlyStreamWrappe * @todo Done */ public function dir_opendir($path, $options): bool { - \Drupal::logger('FlyStreamWrapper')->notice('Calling ' . __METHOD__); - $this->setPath($path); + + $this->current->setPath($path); try { - $listing = $this->filesystem->listContents($this->file)->getIterator(); - $this->dirListing = ($listing instanceof \Iterator) ? $listing : new \IteratorIterator($listing); + $listing = $this->current->filesystem->listContents($this->current->file)->getIterator(); + $this->current->dirListing = ($listing instanceof \Iterator) ? $listing : new \IteratorIterator($listing); } catch (FilesystemException $e) { return $this->triggerError( - DirectoryNotFoundException::atLocation(__METHOD__, $path, $e) - ); + DirectoryNotFoundException::atLocation(__METHOD__, $path, $e) + ); } $valid = @is_dir($path); if (!$valid) { return self::triggerError( - DirectoryNotFoundException::atLocation(__METHOD__, $path) - ); + DirectoryNotFoundException::atLocation(__METHOD__, $path) + ); } return TRUE; @@ -247,14 +115,14 @@ class FlyStreamWrapperBase implements PhpStreamWrapperInterface, FlyStreamWrappe * @todo Done */ public function dir_readdir(): string|bool { - \Drupal::logger('FlyStreamWrapper')->notice('Calling ' . __METHOD__); - if (!$this->dirListing->valid()) { + + if (!$this->current->dirListing->valid()) { return FALSE; } - $item = $this->dirListing->current(); + $item = $this->current->dirListing->current(); - $this->dirListing->next(); + $this->current->dirListing->next(); return basename($item->path()); @@ -266,10 +134,10 @@ class FlyStreamWrapperBase implements PhpStreamWrapperInterface, FlyStreamWrappe * @todo Done */ public function dir_rewinddir(): bool { - \Drupal::logger('FlyStreamWrapper')->notice('Calling ' . __METHOD__); + try { - $listing = $this->filesystem->listContents($this->file)->getIterator(); - $this->dirListing = ($listing instanceof \Iterator) ? $listing : new \IteratorIterator($listing); + $listing = $this->current->filesystem->listContents($this->current->file)->getIterator(); + $this->current->dirListing = ($listing instanceof \Iterator) ? $listing : new \IteratorIterator($listing); } catch (FilesystemException $e) { return self::triggerError($e); @@ -285,19 +153,19 @@ class FlyStreamWrapperBase implements PhpStreamWrapperInterface, FlyStreamWrappe * @todo Done */ public function mkdir($path, $mode, $options): bool { - \Drupal::logger('FlyStreamWrapper')->notice('Calling ' . __METHOD__); + if (file_exists($path)) { return self::triggerError(DirectoryExistsException::atLocation(__METHOD__, $path)); } - $this->setPath($path); + $this->current->setPath($path); try { $visibility = new PortableVisibilityConverter(); $config = [ Config::OPTION_VISIBILITY => $visibility->inverseForDirectory($mode), ]; - $this->filesystem->createDirectory($this->file, $config); + $this->current->filesystem->createDirectory($this->current->file, $config); return TRUE; } @@ -314,8 +182,7 @@ class FlyStreamWrapperBase implements PhpStreamWrapperInterface, FlyStreamWrappe * @todo Done */ public function rename($path_from, $path_to): bool { - \Drupal::logger('FlyStreamWrapper')->notice('Calling ' . __METHOD__); - $this->setPath($path_from); + $this->current->setPath($path_from); $errorLocation = $path_from . ',' . $path_to; if (!file_exists($path_from)) { return self::triggerError(FileNotFoundException::atLocation(__METHOD__, $errorLocation)); @@ -324,24 +191,24 @@ class FlyStreamWrapperBase implements PhpStreamWrapperInterface, FlyStreamWrappe if (file_exists($path_to)) { if (is_file($path_from) && is_dir($path_to)) { return self::triggerError( - IsDirectoryException::atLocation(__METHOD__, $errorLocation) - ); + IsDirectoryException::atLocation(__METHOD__, $errorLocation) + ); } if (is_dir($path_from) && is_file($path_to)) { return self::triggerError( - IsNotDirectoryException::atLocation(__METHOD__, $errorLocation) - ); + IsNotDirectoryException::atLocation(__METHOD__, $errorLocation) + ); } } try { - $this->filesystem->move($this->file, $this->getFile($path_to)); + $this->current->filesystem->move($this->current->file, FlyStreamData::getFile($path_to)); return TRUE; } catch (FilesystemException $e) { return self::triggerError( - DirectoryNotEmptyException::atLocation(__METHOD__, $errorLocation, $e) - ); + DirectoryNotEmptyException::atLocation(__METHOD__, $errorLocation, $e) + ); } } @@ -351,36 +218,36 @@ class FlyStreamWrapperBase implements PhpStreamWrapperInterface, FlyStreamWrappe * @todo Done */ public function rmdir($path, $options): bool { - \Drupal::logger('FlyStreamWrapper')->notice('Calling ' . __METHOD__); - $this->setPath($path); + + $this->current->setPath($path); $n = new WhitespacePathNormalizer(); - $n->normalizePath($this->file); - if ('' === $n->normalizePath($this->file)) { + $n->normalizePath($this->current->file); + if ('' === $n->normalizePath($this->current->file)) { return self::triggerError( - RootDirectoryException::atLocation(__METHOD__, $this->path) - ); + RootDirectoryException::atLocation(__METHOD__, $this->current->path) + ); } if (($options & STREAM_MKDIR_RECURSIVE) !== 0) { try { - $this->filesystem->deleteDirectory($this->file); + $this->current->filesystem->deleteDirectory($this->current->file); return TRUE; } catch (FilesystemException $e) { return self::triggerError( - CouldNotRemoveDirectoryException::atLocation(__METHOD__, $this->path, $e) - ); + CouldNotRemoveDirectoryException::atLocation(__METHOD__, $this->current->path, $e) + ); } } try { - $listing = $this->filesystem->listContents($this->file); + $listing = $this->current->filesystem->listContents($this->current->file); } catch (FilesystemException $e) { return self::triggerError( - DirectoryNotEmptyException::atLocation(__METHOD__, $this->path) - ); + DirectoryNotEmptyException::atLocation(__METHOD__, $this->current->path) + ); } foreach ($listing as $ignored) { @@ -389,18 +256,18 @@ class FlyStreamWrapperBase implements PhpStreamWrapperInterface, FlyStreamWrappe } return self::triggerError( - DirectoryNotEmptyException::atLocation(__METHOD__, $this->path) - ); + DirectoryNotEmptyException::atLocation(__METHOD__, $this->current->path) + ); } try { - $this->filesystem->deleteDirectory($this->file); + $this->current->filesystem->deleteDirectory($this->current->file); return TRUE; } catch (FilesystemException $e) { return self::triggerError( - CouldNotRemoveDirectoryException::atLocation(__METHOD__, $this->path, $e) - ); + CouldNotRemoveDirectoryException::atLocation(__METHOD__, $this->current->path, $e) + ); } } @@ -410,8 +277,7 @@ class FlyStreamWrapperBase implements PhpStreamWrapperInterface, FlyStreamWrappe * @todo Done */ public function stream_cast($cast_as) { - \Drupal::logger('FlyStreamWrapper')->notice('Calling ' . __METHOD__); - return $this->handle; + return $this->current->handle; } /** @@ -420,26 +286,26 @@ class FlyStreamWrapperBase implements PhpStreamWrapperInterface, FlyStreamWrappe * @todo Done */ public function stream_close(): void { - \Drupal::logger('FlyStreamWrapper')->notice('Calling ' . __METHOD__); - if (!is_resource($this->handle)) { + + if (!is_resource($this->current->handle)) { return; } - if ($this->workOnLocalCopy) { - fflush($this->handle); - rewind($this->handle); + if ($this->current->workOnLocalCopy) { + fflush($this->current->handle); + rewind($this->current->handle); try { - $this->filesystem->writeStream($this->file, $this->handle); + $this->current->filesystem->writeStream($this->current->file, $this->current->handle); } catch (FilesystemException $e) { trigger_error( - 'stream_close(' . $this->path . ') Unable to sync file : ' . $e->getMessage(), + 'stream_close(' . $this->current->path . ') Unable to sync file : ' . $e->getMessage(), E_USER_WARNING - ); + ); } } - fclose($this->handle); + fclose($this->current->handle); } /** @@ -448,12 +314,11 @@ class FlyStreamWrapperBase implements PhpStreamWrapperInterface, FlyStreamWrappe * @todo Done */ public function stream_eof(): bool { - \Drupal::logger('FlyStreamWrapper')->notice('Calling ' . __METHOD__); - if (!is_resource($this->handle)) { + if (!is_resource($this->current->handle)) { return FALSE; } - return feof($this->handle); + return feof($this->current->handle); } /** @@ -462,8 +327,8 @@ class FlyStreamWrapperBase implements PhpStreamWrapperInterface, FlyStreamWrappe * @todo Done */ public function stream_flush(): bool { - \Drupal::logger('FlyStreamWrapper')->notice('Calling ' . __METHOD__); - if (!is_resource($this->handle)) { + + if (!is_resource($this->current->handle)) { trigger_error( 'stream_flush(): Supplied resource is not a valid stream resource', E_USER_WARNING @@ -472,32 +337,32 @@ class FlyStreamWrapperBase implements PhpStreamWrapperInterface, FlyStreamWrappe return FALSE; } - $success = fflush($this->handle); + $success = fflush($this->current->handle); - if ($this->workOnLocalCopy) { - fflush($this->handle); - $currentPosition = ftell($this->handle); - rewind($this->handle); + if ($this->current->workOnLocalCopy) { + fflush($this->current->handle); + $currentPosition = ftell($this->current->handle); + rewind($this->current->handle); try { - $this->filesystem->writeStream($this->file, $this->handle); + $this->current->filesystem->writeStream($this->current->file, $this->current->handle); } catch (FilesystemException $e) { trigger_error( - 'stream_flush(' . $this->path . ') Unable to sync file : ' . $e->getMessage(), + 'stream_flush(' . $this->current->path . ') Unable to sync file : ' . $e->getMessage(), E_USER_WARNING ); $success = FALSE; } if (FALSE !== $currentPosition) { - if (is_resource($this->handle)) { - fseek($this->handle, $currentPosition); + if (is_resource($this->current->handle)) { + fseek($this->current->handle, $currentPosition); } } } - $this->bytesWritten = 0; + $this->current->bytesWritten = 0; return $success; } @@ -508,17 +373,16 @@ class FlyStreamWrapperBase implements PhpStreamWrapperInterface, FlyStreamWrappe * @todo In progress */ public function stream_lock($operation): bool { - \Drupal::logger('FlyStreamWrapper')->notice('Calling ' . __METHOD__); - if (NULL === $this->lockKey) { - $this->lockKey = new Key($this->path); + if (NULL === $this->current->lockKey) { + $this->current->lockKey = new Key($this->current->path); } - $store = StoreFactory::createStore((string) $this->config[FlyStreamWrapperInterface::LOCK_STORE]); + $store = StoreFactory::createStore((string) $this->current->config[FlyStreamWrapperInterface::LOCK_STORE]); $lock = new Lock( - $this->lockKey, - $store, - (float) $this->config[FlyStreamWrapperInterface::LOCK_TTL], - FALSE + $this->current->lockKey, + $store, + (float) $this->current->config[FlyStreamWrapperInterface::LOCK_TTL], + FALSE ); switch ($operation) { @@ -548,26 +412,26 @@ class FlyStreamWrapperBase implements PhpStreamWrapperInterface, FlyStreamWrappe * @todo Done */ public function stream_metadata($path, $option, $value): bool { - \Drupal::logger('FlyStreamWrapper')->notice('Calling ' . __METHOD__); - $this->setPath($path); - $filesystem = $this->filesystem; - $file = $this->file; - $converter = $this->options['visibility'] ?? new PortableVisibilityConverter(); + $this->current->setPath($path); + $filesystem = $this->current->filesystem; + $file = $this->current->file; + switch ($option) { case STREAM_META_ACCESS: if (!is_int($value)) { $value = (int) $value; } + $converter = new PortableVisibilityConverter(); $visibility = is_dir($path) ? $converter->inverseForDirectory($value) : $converter->inverseForFile($value); try { $filesystem->setVisibility($file, $visibility); } catch (FilesystemException $e) { - if (!$this->ignoreVisibilityErrors()) { + if (!$this->current->ignoreVisibilityErrors()) { return self::triggerError(UnableToChangePermissionsException::atLocation( __METHOD__, - $this->path, + $this->current->path, decoct($value), $e )); @@ -583,9 +447,9 @@ class FlyStreamWrapperBase implements PhpStreamWrapperInterface, FlyStreamWrappe } catch (FilesystemException $e) { return self::triggerError(UnableToWriteException::atLocation( - __METHOD__, - $this->path, - $e + __METHOD__, + $this->current->path, + $e )); } @@ -603,71 +467,70 @@ class FlyStreamWrapperBase implements PhpStreamWrapperInterface, FlyStreamWrappe * @todo Done */ public function stream_open($path, $mode, $options, &$openedPath = NULL): bool { - \Drupal::logger('FlyStreamWrapper')->notice('Calling ' . __METHOD__); - $this->setPath($path); - $filesystem = $this->filesystem; - $file = $this->file; + $this->current->setPath($path); + $filesystem = $this->current->filesystem; + $file = $this->current->file; if (!preg_match('/^[rwacx](\+b?|b\+?)?$/', $mode)) { return self::triggerError(InvalidStreamModeException::atLocation( __METHOD__, - $this->path, + $this->current->path, $mode )); } - $this->writeOnly = !strpos($mode, '+'); + $this->current->writeOnly = !strpos($mode, '+'); try { - if ('r' === $mode[0] && $this->writeOnly) { - $this->handle = $filesystem->readStream($file); - $this->workOnLocalCopy = FALSE; - $this->writeOnly = FALSE; + if ('r' === $mode[0] && $this->current->writeOnly) { + $this->current->handle = $filesystem->readStream($file); + $this->current->workOnLocalCopy = FALSE; + $this->current->writeOnly = FALSE; } else { - $this->handle = fopen('php://temp', 'w+b'); - $this->workOnLocalCopy = TRUE; + $this->current->handle = fopen('php://temp', 'w+b'); + $this->current->workOnLocalCopy = TRUE; if ('w' !== $mode[0] && $filesystem->fileExists($file)) { if ('x' === $mode[0]) { - throw UnableToWriteException::atLocation(__METHOD__, $this->path); + throw UnableToWriteException::atLocation(__METHOD__, $this->current->path); } $result = FALSE; - if (is_resource($this->handle)) { - $result = stream_copy_to_stream($filesystem->readStream($file), $this->handle); + if (is_resource($this->current->handle)) { + $result = stream_copy_to_stream($filesystem->readStream($file), $this->current->handle); } if (!$result) { - throw UnableToWriteException::atLocation(__METHOD__, $this->path); + throw UnableToWriteException::atLocation(__METHOD__, $this->current->path); } } } - $this->alwaysAppend = 'a' === $mode[0]; - if (is_resource($this->handle) && !$this->alwaysAppend) { - @rewind($this->handle); + $this->current->alwaysAppend = 'a' === $mode[0]; + if (is_resource($this->current->handle) && !$this->current->alwaysAppend) { + @rewind($this->current->handle); } } catch (FilesystemException $e) { if (($options & STREAM_REPORT_ERRORS) !== 0) { return self::triggerError(UnableToReadException::atLocation( __METHOD__, - $this->path, + $this->current->path, $e )); } return FALSE; } - if ($this->handle && $options & STREAM_USE_PATH) { + if ($this->current->handle && $options & STREAM_USE_PATH) { $openedPath = $path; } - if (is_resource($this->handle)) { + if (is_resource($this->current->handle)) { return TRUE; } if (($options & STREAM_REPORT_ERRORS) !== 0) { - return self::triggerError(FileNotFoundException::atLocation(__METHOD__, $this->path)); + return self::triggerError(FileNotFoundException::atLocation(__METHOD__, $this->current->path)); } return FALSE; @@ -679,52 +542,54 @@ class FlyStreamWrapperBase implements PhpStreamWrapperInterface, FlyStreamWrappe * @todo DONE */ public function stream_read($count): string { - \Drupal::logger('FlyStreamWrapper')->notice('Calling ' . __METHOD__); - if ($this->writeOnly || !is_resource($this->handle) || $count < 0) { + + if ($this->current->writeOnly || !is_resource($this->current->handle) || $count < 0) { return ''; } - return (string) fread($this->handle, $count); + return (string) fread($this->current->handle, $count); } /** * {@inheritdoc} + * + * @todo Done */ public function stream_seek($offset, $whence = SEEK_SET): bool { - \Drupal::logger('FlyStreamWrapper')->notice('Calling ' . __METHOD__); - if (!is_resource($this->handle)) { + if (!is_resource($this->current->handle)) { return FALSE; } - return 0 === fseek($this->handle, $offset, $whence); + return 0 === fseek($this->current->handle, $offset, $whence); } /** * {@inheritdoc} + * + * @todo Done */ public function stream_set_option($option, $arg1, $arg2 = NULL): bool { - \Drupal::logger('FlyStreamWrapper')->notice('Calling ' . __METHOD__); - if (!is_resource($this->handle)) { + if (!is_resource($this->current->handle)) { return FALSE; } switch ($option) { case STREAM_OPTION_BLOCKING: - return stream_set_blocking($this->handle, 1 === $arg1); + return stream_set_blocking($this->current->handle, 1 === $arg1); case STREAM_OPTION_READ_BUFFER: return 0 === stream_set_read_buffer( - $this->handle, + $this->current->handle, STREAM_BUFFER_NONE === $arg1 ? 0 : (int) $arg2 ); case STREAM_OPTION_WRITE_BUFFER: - $this->writeBufferSize = STREAM_BUFFER_NONE === $arg1 ? 0 : (int) $arg2; + $this->current->writeBufferSize = STREAM_BUFFER_NONE === $arg1 ? 0 : (int) $arg2; return TRUE; case STREAM_OPTION_READ_TIMEOUT: - return stream_set_timeout($this->handle, $arg1, (int) $arg2); + return stream_set_timeout($this->current->handle, $arg1, (int) $arg2); } return FALSE; @@ -732,14 +597,15 @@ class FlyStreamWrapperBase implements PhpStreamWrapperInterface, FlyStreamWrappe /** * {@inheritdoc} + * + * @todo Done */ public function stream_stat(): array|false { - \Drupal::logger('FlyStreamWrapper')->notice('Calling ' . __METHOD__); try { - return $this->getStat(); + return $this->getStat($this->current); } catch (FilesystemException $e) { - self::triggerError(StatFailedException::atLocation(__METHOD__, $this->path, $e)); + self::triggerError(StatFailedException::atLocation(__METHOD__, $this->current->path, $e)); return FALSE; } @@ -748,50 +614,54 @@ class FlyStreamWrapperBase implements PhpStreamWrapperInterface, FlyStreamWrappe /** * {@inheritdoc} + * + * @todo Done */ public function stream_tell(): int { - \Drupal::logger('FlyStreamWrapper')->notice('Calling ' . __METHOD__); - if (!is_resource($this->handle)) { + if (!is_resource($this->current->handle)) { return 0; } - if ($this->alwaysAppend && $this->writeOnly) { + if ($this->current->alwaysAppend && $this->current->writeOnly) { return 0; } - return (int) ftell($this->handle); + return (int) ftell($this->current->handle); } /** * {@inheritdoc} + * + * @todo Done */ public function stream_truncate($new_size): bool { - \Drupal::logger('FlyStreamWrapper')->notice('Calling ' . __METHOD__); - if (!is_resource($this->handle) || $new_size < 0) { + if (!is_resource($this->current->handle) || $new_size < 0) { return FALSE; } - return ftruncate($this->handle, $new_size); + return ftruncate($this->current->handle, $new_size); } /** * {@inheritdoc} + * + * @todo Done */ public function stream_write($data): int|false { - \Drupal::logger('FlyStreamWrapper')->notice('Calling ' . __METHOD__); - if (!is_resource($this->handle)) { + + if (!is_resource($this->current->handle)) { return 0; } - if ($this->alwaysAppend) { - fseek($this->handle, 0, SEEK_END); + if ($this->current->alwaysAppend) { + fseek($this->current->handle, 0, SEEK_END); } - $size = (int) fwrite($this->handle, $data); - $this->bytesWritten += $size; + $size = (int) fwrite($this->current->handle, $data); + $this->current->bytesWritten += $size; - if ($this->alwaysAppend) { - fseek($this->handle, 0, SEEK_SET); + if ($this->current->alwaysAppend) { + fseek($this->current->handle, 0, SEEK_SET); } return $size; @@ -799,22 +669,24 @@ class FlyStreamWrapperBase implements PhpStreamWrapperInterface, FlyStreamWrappe /** * {@inheritdoc} + * + * @todo done */ public function unlink($path): bool { - \Drupal::logger('FlyStreamWrapper')->notice('Calling ' . __METHOD__); - $this->setPath($path); - if (!file_exists($this->path)) { - return self::triggerError(FileNotFoundException::atLocation(__METHOD__, $this->path)); + $this->current->setPath($path); + + if (!file_exists($this->current->path)) { + return self::triggerError(FileNotFoundException::atLocation(__METHOD__, $this->current->path)); } try { - $this->filesystem->delete($this->file); + $this->current->filesystem->delete($this->current->file); return TRUE; } catch (FilesystemException $e) { return self::triggerError( - CouldNotDeleteFileException::atLocation(__METHOD__, $this->path, $e) + CouldNotDeleteFileException::atLocation(__METHOD__, $this->current->path, $e) ); } } @@ -823,11 +695,10 @@ class FlyStreamWrapperBase implements PhpStreamWrapperInterface, FlyStreamWrappe * {@inheritdoc} */ public function url_stat($path, $flags): array|false { - \Drupal::logger('FlyStreamWrapper')->notice('Calling ' . __METHOD__); - $this->setPath($path); + $this->current->setPath($path); try { - return $this->getStat(); + return $this->getStat($this->current); } catch (FilesystemException $e) { if (($flags & STREAM_URL_STAT_QUIET) !== 0) { @@ -850,23 +721,22 @@ class FlyStreamWrapperBase implements PhpStreamWrapperInterface, FlyStreamWrappe * * @throws \League\Flysystem\FilesystemException */ - protected function getStat() { - \Drupal::logger('FlyStreamWrapper')->notice('Calling ' . __METHOD__); + protected function getStat(FlyStreamData $current) { $stats = []; - if ($this->workOnLocalCopy && is_resource($this->handle)) { - $stats = fstat($this->handle); + if ($current->workOnLocalCopy && is_resource($current->handle)) { + $stats = fstat($current->handle); if (!$stats) { return FALSE; } - if ($this->filesystem->fileExists($this->file)) { - [$mode, $size, $time] = $this->getRemoteStats(); + if ($current->filesystem->fileExists($current->file)) { + [$mode, $size, $time] = $this->getRemoteStats($current); unset($size); } } else { - [$mode, $size, $time] = $this->getRemoteStats(); + [$mode, $size, $time] = $this->getRemoteStats($current); } foreach (self::STATS_ZERO as $key) { @@ -895,8 +765,8 @@ class FlyStreamWrapperBase implements PhpStreamWrapperInterface, FlyStreamWrappe } } - $stats['uid'] = $stats[4] = (int) $this->config[FlyStreamWrapperInterface::UID]; - $stats['gid'] = $stats[5] = (int) $this->config[FlyStreamWrapperInterface::GID]; + $stats['uid'] = $stats[4] = (int) $current->config[FlyStreamWrapperInterface::UID]; + $stats['gid'] = $stats[5] = (int) $current->config[FlyStreamWrapperInterface::GID]; return $stats; } @@ -909,22 +779,20 @@ class FlyStreamWrapperBase implements PhpStreamWrapperInterface, FlyStreamWrappe * @return array<int,int> * Requested stats. */ - protected function getRemoteStats(): array { - \Drupal::logger('FlyStreamWrapper')->notice('Calling ' . __METHOD__); - $newConverter = new PortableVisibilityConverter( - (int) $this->config[FlyStreamWrapperInterface::VISIBILITY_FILE_PUBLIC], - (int) $this->config[FlyStreamWrapperInterface::VISIBILITY_FILE_PRIVATE], - (int) $this->config[FlyStreamWrapperInterface::VISIBILITY_DIRECTORY_PUBLIC], - (int) $this->config[FlyStreamWrapperInterface::VISIBILITY_DIRECTORY_PRIVATE], - (string) $this->config[FlyStreamWrapperInterface::VISIBILITY_DEFAULT_FOR_DIRECTORIES] + protected function getRemoteStats(FlyStreamData $current): array { + $converter = new PortableVisibilityConverter( + (int) $current->config[FlyStreamWrapperInterface::VISIBILITY_FILE_PUBLIC], + (int) $current->config[FlyStreamWrapperInterface::VISIBILITY_FILE_PRIVATE], + (int) $current->config[FlyStreamWrapperInterface::VISIBILITY_DIRECTORY_PUBLIC], + (int) $current->config[FlyStreamWrapperInterface::VISIBILITY_DIRECTORY_PRIVATE], + (string) $current->config[FlyStreamWrapperInterface::VISIBILITY_DEFAULT_FOR_DIRECTORIES] ); - $converter = $this->options['visibility'] ?? $newConverter; try { - $visibility = $this->filesystem->visibility($this->file); + $visibility = $current->filesystem->visibility($current->file); } catch (UnableToRetrieveMetadata | \TypeError $e) { - if (!$this->ignoreVisibilityErrors()) { + if (!$current->ignoreVisibilityErrors()) { throw $e; } @@ -936,20 +804,20 @@ class FlyStreamWrapperBase implements PhpStreamWrapperInterface, FlyStreamWrappe $lastModified = 0; try { - if ('directory' === $this->filesystem->mimeType($this->file)) { - [$mode, $size, $lastModified] = $this->getRemoteDirectoryStats($converter, $visibility); + if ('directory' === $current->filesystem->mimeType($current->file)) { + [$mode, $size, $lastModified] = $this->getRemoteDirectoryStats($current, $converter, $visibility); } else { - [$mode, $size, $lastModified] = $this->getRemoteFileStats($converter, $visibility); + [$mode, $size, $lastModified] = $this->getRemoteFileStats($current, $converter, $visibility); } } catch (UnableToRetrieveMetadata $e) { - if (method_exists($this->filesystem, 'directoryExists')) { - if ($this->filesystem->directoryExists($this->file)) { - [$mode, $size, $lastModified] = $this->getRemoteDirectoryStats($converter, $visibility); + if (method_exists($current->filesystem, 'directoryExists')) { + if ($current->filesystem->directoryExists($current->file)) { + [$mode, $size, $lastModified] = $this->getRemoteDirectoryStats($current, $converter, $visibility); } - elseif ($this->filesystem->fileExists($this->file)) { - [$mode, $size, $lastModified] = $this->getRemoteFileStats($converter, $visibility); + elseif ($current->filesystem->fileExists($current->file)) { + [$mode, $size, $lastModified] = $this->getRemoteFileStats($current, $converter, $visibility); } } else { @@ -969,13 +837,13 @@ class FlyStreamWrapperBase implements PhpStreamWrapperInterface, FlyStreamWrappe * @throws \League\Flysystem\FilesystemException */ private function getRemoteDirectoryStats( + FlyStreamData $current, PortableVisibilityConverter $converter, string $visibility, ): array { - \Drupal::logger('FlyStreamWrapper')->notice('Calling ' . __METHOD__); $mode = 040000 + $converter->forDirectory($visibility); $size = 0; - $lastModified = $this->getRemoteDirectoryLastModified(); + $lastModified = $this->getRemoteDirectoryLastModified($current); return [$mode, $size, $lastModified]; } @@ -988,32 +856,34 @@ class FlyStreamWrapperBase implements PhpStreamWrapperInterface, FlyStreamWrappe * @throws \League\Flysystem\FilesystemException */ private function getRemoteFileStats( + FlyStreamData $current, PortableVisibilityConverter $converter, string $visibility, ): array { - \Drupal::logger('FlyStreamWrapper')->notice('Calling ' . __METHOD__); $mode = 0100000 + $converter->forFile($visibility); - $size = $this->filesystem->fileSize($this->file); - $lastModified = $this->filesystem->lastModified($this->file); + $size = $current->filesystem->fileSize($current->file); + $lastModified = $current->filesystem->lastModified($current->file); return [$mode, $size, $lastModified]; } /** * Gets Last Modified stat for remote directory. * + * @param FlyStreamData $current + * Current resource data object. + * * @return int * Last modified stat. * * @throws \League\Flysystem\FilesystemException */ - private function getRemoteDirectoryLastModified(): int { - \Drupal::logger('FlyStreamWrapper')->notice('Calling ' . __METHOD__); - if (!$this->emulateDirectoryLastModified()) { - return $this->filesystem->lastModified($this->file); + private function getRemoteDirectoryLastModified(FlyStreamData $current): int { + if (!$current->emulateDirectoryLastModified()) { + return $current->filesystem->lastModified($current->file); } $lastModified = 0; - $listing = $this->filesystem->listContents($this->file)->getIterator(); + $listing = $current->filesystem->listContents($current->file)->getIterator(); $dirListing = $listing instanceof \Iterator ? $listing : new \IteratorIterator($listing); /** @var \League\Flysystem\FileAttributes $item */ @@ -1023,53 +893,4 @@ class FlyStreamWrapperBase implements PhpStreamWrapperInterface, FlyStreamWrappe return $lastModified; } - /** - * Get the file path. - * - * @param string $path - * File path. - * - * @return string - * File path converted. - */ - private function getFile(string $path): string { - \Drupal::logger('FlyStreamWrapper')->notice('Calling ' . __METHOD__); - return (string) substr($path, strpos($path, '://') + 3); - } - - /** - * Configures settings based on path. - * - * @param string $path - * File path. - */ - private function setPath(string $path): void { - $this->path = $path; - $this->scheme = substr($path, 0, (int) strpos($path, '://')); - $this->file = $this->getFile($path); - } - - /** - * Gets Emulate Directory Last Modified settings. - * - * @return bool - * Boolean setting. - */ - private function emulateDirectoryLastModified(): bool { - \Drupal::logger('FlyStreamWrapper')->notice('Calling ' . __METHOD__); - // @refactor?? - return (bool) $this->config[FlyStreamWrapper::EMULATE_DIRECTORY_LAST_MODIFIED]; - } - - /** - * Gets Ignore Visibility Errors settings. - * - * @return bool - * Boolean setting. - */ - private function ignoreVisibilityErrors(): bool { - \Drupal::logger('FlyStreamWrapper')->notice('Calling ' . __METHOD__); - return (bool) $this->config[FlyStreamWrapper::IGNORE_VISIBILITY_ERRORS]; - } - } diff --git a/src/FlysystemAdapterConfigInterface.php b/src/FlysystemAdapterConfigInterface.php index 43b12e4d2f04c329e716c4d304d25590142c0ac6..a42b7964746bf3735523a7f31ff9621e694e51b5 100644 --- a/src/FlysystemAdapterConfigInterface.php +++ b/src/FlysystemAdapterConfigInterface.php @@ -64,5 +64,4 @@ interface FlysystemAdapterConfigInterface extends ConfigEntityInterface { * Value to return from array key. */ public function getSubAdapterConfigItem($key); - } diff --git a/src/FlysystemServiceProvider.php b/src/FlysystemServiceProvider.php index aef46269534d9b7d5a88c0c6bcce91b402078c94..0a0eb933ab26cc7c412a8dc988813d21241509eb 100644 --- a/src/FlysystemServiceProvider.php +++ b/src/FlysystemServiceProvider.php @@ -2,10 +2,10 @@ namespace Drupal\flysystem; +use Drupal\Core\DependencyInjection\Compiler\RegisterStreamWrappersPass; use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\DependencyInjection\ServiceProviderBase; -use Symfony\Component\DependencyInjection\Reference; -use Symfony\Component\DependencyInjection\ContainerInterface; +use Drupal\flysystem\Compiler\FlysystemRegisterStreamWrappers; /** * Registers Flysystem Stream Wrappers. @@ -18,30 +18,10 @@ class FlysystemServiceProvider extends ServiceProviderBase { * {@inheritdoc} */ public function register(ContainerBuilder $container): void { - - /** @var \Drupal\Core\Config\DatabaseStorage $config_storage */ - $config_storage = $container->get('config.storage.active'); - $entity_config_names = $config_storage->listAll('flysystem.flysystem_adapter_config'); - - if (!empty($entity_config_names)) { - $configured_entities = $config_storage->readMultiple($entity_config_names); - - foreach ($configured_entities as $key => $value) { - if (empty($value)) { - // This should never happen, however if it does skip this entry. - continue; - } - - if ($value['status'] !== TRUE) { - // Scheme is not enabled. - continue; - } - $container - ->register('stream_wrapper.' . $value['id'], 'Drupal\flysystem\FlyStream\FlyStreamWrapper') - ->addTag('stream_wrapper', ['scheme' => $value['id']]) - ->setArguments([$key, new Reference('config.storage')]); - } - } + //Create the stream wrappers from configured Flysystem Adapters. + $container->addCompilerPass(new FlysystemRegisterStreamWrappers()); + // Register the stream wrappers configured above. + $container->addCompilerPass(new RegisterStreamWrappersPass()); } } diff --git a/src/FlysystemSubAdapterInterface.php b/src/FlysystemSubAdapterInterface.php index bf78c2df0afa2a067a91a3e1c9b1c5664ad1e8a3..fad0609a5e8c78bc7409fb83ae31f8a3ee7a43d2 100644 --- a/src/FlysystemSubAdapterInterface.php +++ b/src/FlysystemSubAdapterInterface.php @@ -8,9 +8,9 @@ use Drupal\Component\Plugin\ConfigurableInterface; use Drupal\Component\Plugin\DependentPluginInterface; use Drupal\Component\Plugin\DerivativeInspectionInterface; use Drupal\Component\Plugin\PluginInspectionInterface; -use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Plugin\PluginFormInterface; +use Drupal\Core\Form\FormStateInterface; /** * Interface for flysystem_adapter plugins. diff --git a/src/Form/FlysystemAdapterConfigForm.php b/src/Form/FlysystemAdapterConfigForm.php index 8e60efac00fc048a19b048185a4242a98d785d30..ab384324d7b4477af4e422e98010f1e24acfcc6a 100644 --- a/src/Form/FlysystemAdapterConfigForm.php +++ b/src/Form/FlysystemAdapterConfigForm.php @@ -72,8 +72,6 @@ final class FlysystemAdapterConfigForm extends EntityForm { /** @var \Drupal\flysystem\FlysystemAdapterConfigInterface $flysystem_adapter_config */ $flysystem_adapter_config = $this->getEntity(); - - // var_dump($flysystem_adapter_config); die; // Set the page title according to whether we are creating or editing the // adapter. if ($flysystem_adapter_config->isNew()) { @@ -84,11 +82,13 @@ final class FlysystemAdapterConfigForm extends EntityForm { } $this->buildEntityConfigForm($form, $form_state, $flysystem_adapter_config); + // Skip adding the adapter config form if we cleared the adapter form due to // an error. if ($form) { - $this->buildSubAdapterConfigForm($form, $form_state, $flysystem_adapter_config); + $form = $this->buildSubAdapterConfigForm($form, $form_state, $flysystem_adapter_config); } + return $form; } @@ -103,10 +103,10 @@ final class FlysystemAdapterConfigForm extends EntityForm { * The server that is being created or edited. */ protected function buildEntityConfigForm(array &$form, FormStateInterface $form_state, FlysystemAdapterConfigInterface $flysystem_adapter_config) { + // var_dump($flysystem_adapter_config); die;. $form['label'] = [ '#type' => 'textfield', - '#title' => $this->t('Scheme'), - '#description' => $this->t('The scheme used to identify files managed with this adapter.'), + '#title' => $this->t('Label'), '#maxlength' => 255, '#default_value' => $flysystem_adapter_config->label(), '#required' => TRUE, @@ -210,14 +210,13 @@ final class FlysystemAdapterConfigForm extends EntityForm { * The adapter that is being created or edited. */ public function buildSubAdapterConfigForm(array &$form, FormStateInterface $form_state, FlysystemAdapterConfigInterface $flysystem_adapter_config) { - // var_dump($form_state); die; // var_dump($flysystem_adapter_config); die(__METHOD__ . ":" . __LINE__); // var_dump($form_state->getValues()); die(__METHOD__ . ":" . __LINE__);. $form['sub_adapter_config'] = []; - if ($flysystem_adapter_config->hasValidSubAdapter()) { // var_dump($flysystem_adapter_config); die(__METHOD__ . ":" . __LINE__);. $sub_adapter_plugin = $flysystem_adapter_config->getSubAdapter(); + $form_state->set('sub_adapter', $sub_adapter_plugin->getPluginId()); $form_state->set(['sub_adapter_config', 'schema'], $flysystem_adapter_config->getSubAdapterConfigItem('schema')); @@ -228,12 +227,11 @@ final class FlysystemAdapterConfigForm extends EntityForm { // Attach the subadapter plugin configuration form. $form['sub_adapter_config'] = $sub_adapter_plugin->buildSubConfigurationForm($form['sub_adapter_config'], $form_state, $flysystem_adapter_config); - + // var_dump($form['sub_adapter_config']['schema']); die; // Modify the backend plugin configuration container element. $form['sub_adapter_config']['#type'] = 'details'; $form['sub_adapter_config']['#title'] = $this->t('Configure %plugin configuration', ['%plugin' => $sub_adapter_plugin->label()]); $form['sub_adapter_config']['#open'] = TRUE; - // var_dump($form['sub_adapter_config']); die;. } } // Only notify the user of a missing backend plugin if we're editing an @@ -308,4 +306,5 @@ final class FlysystemAdapterConfigForm extends EntityForm { return Markup::create(Html::escape((string) $text)); } + } diff --git a/src/Plugin/FlysystemAdapterPluginBase.php b/src/Plugin/FlysystemAdapterPluginBase.php index 494cb34e053671c3e8033e8f88fe8e94617a1326..0dbf8666bc22467fdbd0daf2e724b7c56e2dd470 100644 --- a/src/Plugin/FlysystemAdapterPluginBase.php +++ b/src/Plugin/FlysystemAdapterPluginBase.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace Drupal\flysystem\Plugin; use Drupal\Component\Plugin\PluginBase; +use Drupal\Component\Utility\NestedArray; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Plugin\PluginDependencyTrait; use Drupal\Core\StringTranslation\StringTranslationTrait;