diff --git a/src/Decorator/FlysystemFileSystemTrait.php b/src/Decorator/FlysystemFileSystemTrait.php index 766855b485d4b598ecf864877f408594978a760d..3d8d2d127d1dcb99d432dc374f1615e3be3b0392 100644 --- a/src/Decorator/FlysystemFileSystemTrait.php +++ b/src/Decorator/FlysystemFileSystemTrait.php @@ -31,7 +31,7 @@ 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__); + \Drupal::logger('flysystem')->notice('Calling ' . __METHOD__ . ', uri: ' . $uri); try { $drupalMode = NULL; if ($wrapper->filesystem->directoryExists($uri)) { @@ -76,7 +76,11 @@ 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__); + \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. @@ -109,7 +113,7 @@ trait FlysystemFileSystemTrait { * @todo finish writing, see inline todo comments. */ protected function rmdirFs($wrapper, $uri, $context = NULL): bool { - \Drupal::logger('flysystem')->notice('Calling ' . __METHOD__); + \Drupal::logger('flysystem')->notice('Calling ' . __METHOD__ . ', uri: ' . $uri); try { // @todo figure out how to utilize directory permissions, see notes on // Flysystem VisibilityConverter. @@ -144,7 +148,7 @@ trait FlysystemFileSystemTrait { * @todo Rewrite to leverage Flysystem (yes) */ protected function copyFs($wrapper, $source, $destination, $fileExists): string { - \Drupal::logger('flysystem')->notice('Calling ' . __METHOD__); + \Drupal::logger('flysystem')->notice('Calling ' . __METHOD__ . ', source: ' . $source . ', destination: ' . $destination); try { // @todo figure out how to utilize directory permissions, see notes on // Flysystem VisibilityConverter. @@ -174,7 +178,7 @@ trait FlysystemFileSystemTrait { * @todo finish writing, see inline todo comments. */ protected function deleteFs($wrapper, $path) { - \Drupal::logger('flysystem')->notice('Calling ' . __METHOD__); + \Drupal::logger('flysystem')->notice('Calling ' . __METHOD__ . ', path: ' . $path); if ($wrapper->filesystem->directoryExists($path)) { throw new NotRegularFileException("Cannot delete '$path' because it is a directory. Use deleteRecursive() instead."); } @@ -208,7 +212,7 @@ trait FlysystemFileSystemTrait { * TRUE if successful, FALSE if not. */ protected function deleteRecursiveFs($wrapper, $path, callable $callback = NULL): bool { - \Drupal::logger('flysystem')->notice('Calling ' . __METHOD__); + \Drupal::logger('flysystem')->notice('Calling ' . __METHOD__ . ', path: ' . $path); if (!$wrapper->filesystem->fileExists($path)) { return TRUE; } @@ -244,7 +248,7 @@ trait FlysystemFileSystemTrait { * @todo finish writing, see inline todo comments. */ protected function moveFs($wrapper, $source, $destination, $fileExists): string { - \Drupal::logger('flysystem')->notice('Calling ' . __METHOD__); + \Drupal::logger('flysystem')->notice('Calling ' . __METHOD__ . ', source: ' . $source . ', destination: ' . $destination); try { // @todo figure out how to utilize directory permissions, see notes on // Flysystem VisibilityConverter. @@ -281,7 +285,7 @@ trait FlysystemFileSystemTrait { * @todo finish writing, see inline todo comments. */ protected function saveDataFs($wrapper, $temp_nam, $destination, $fileExists) { - \Drupal::logger('flysystem')->notice('Calling ' . __METHOD__); + \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 @@ -320,7 +324,11 @@ trait FlysystemFileSystemTrait { * @see \League\Flysystem\FilesystemOperator::directoryExists() */ protected function prepareDirectoryFs($wrapper, &$directory, $options): bool { - \Drupal::logger('flysystem')->notice('Calling ' . __METHOD__); + \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(). @@ -331,6 +339,12 @@ 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()); @@ -343,7 +357,11 @@ trait FlysystemFileSystemTrait { if (!$wrapper->filesystem->directoryExists($directory)) { return FALSE; } - return $this->chmod($directory); + $writable = is_writable($directory); + if (!$writable && ($options & static::MODIFY_PERMISSIONS)) { + return $this->chmod($directory); + } + return $writeable; } /** @@ -368,7 +386,7 @@ 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__); + \Drupal::logger('flysystem')->notice('Calling ' . __METHOD__ . ', separator: ' . $separator . ', destination: ' . $destination . ', basename: ' . $basename . ', directory: ' . $directory); try { $exists = $wrapper->filesystem->fileExists($destination); if ($exists) { @@ -417,7 +435,7 @@ trait FlysystemFileSystemTrait { * @todo finish writing, see inline todo comments. */ protected function getDestinationFilenameFs($wrapper, $basename, $destination, $fileExists): string|bool { - \Drupal::logger('flysystem')->notice('Calling ' . __METHOD__); + \Drupal::logger('flysystem')->notice('Calling ' . __METHOD__ . ', basename: ' . $basename . ', destination: ' . $destination); try { if ($wrapper->filesystem->fileExists($destination)) { switch ($fileExists) {