nextcloud_webdav_client-1.0.x-dev/src/NextCloudWebDavManager.php
src/NextCloudWebDavManager.php
<?php
namespace Drupal\nextcloud_webdav_client;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\Logger\LoggerChannelInterface;
use Drupal\file\FileInterface;
use Drupal\nextcloud_webdav_client\Service\NextCloudWebDavClient;
/**
* Manager class for NextCloud WebDAV operations.
*/
class NextCloudWebDavManager {
/**
* The NextCloud WebDAV client service.
*
* @var \Drupal\nextcloud_webdav_client\Service\NextCloudWebDavClient
*/
protected $webdavClient;
/**
* The file system service.
*
* @var \Drupal\Core\File\FileSystemInterface
*/
protected $fileSystem;
/**
* The logger channel.
*
* @var \Drupal\Core\Logger\LoggerChannelInterface
*/
protected $logger;
/**
* Constructs a NextCloudWebDavManager object.
*
* @param \Drupal\nextcloud_webdav_client\Service\NextCloudWebDavClient $webdav_client
* The NextCloud WebDAV client service.
* @param \Drupal\Core\File\FileSystemInterface $file_system
* The file system service.
* @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $logger_factory
* The logger factory.
*/
public function __construct(NextCloudWebDavClient $webdav_client, FileSystemInterface $file_system, LoggerChannelFactoryInterface $logger_factory) {
$this->webdavClient = $webdav_client;
$this->fileSystem = $file_system;
$this->logger = $logger_factory->get('nextcloud_webdav_client');
}
/**
* Checks if the WebDAV client is properly configured.
*
* @return bool
* TRUE if configured, FALSE otherwise.
*/
public function isConfigured(): bool {
return $this->webdavClient->isConfigured();
}
/**
* Tests the connection to NextCloud.
*
* @return bool
* TRUE if connection is successful, FALSE otherwise.
*/
public function testConnection(): bool {
return $this->webdavClient->testConnection();
}
/**
* Creates a folder structure in NextCloud.
*
* @param string $path
* The folder path to create (can be nested).
*
* @return bool
* TRUE if folder was created successfully, FALSE otherwise.
*/
public function createFolder(string $path): bool {
if (!$this->isConfigured()) {
$this->logger->error('NextCloud WebDAV client is not configured');
return FALSE;
}
// Normalize path.
$path = trim($path, '/');
if (empty($path)) {
return TRUE; // Root folder always exists.
}
// Create parent folders if they don't exist.
$parts = explode('/', $path);
$current_path = '';
foreach ($parts as $part) {
$current_path .= '/' . $part;
$current_path = ltrim($current_path, '/');
if (!$this->webdavClient->createFolder($current_path)) {
// If creation fails, it might already exist, which is fine.
// We continue to try creating the rest of the path.
}
}
return TRUE;
}
/**
* Uploads a Drupal file entity to NextCloud.
*
* @param \Drupal\file\FileInterface $file
* The Drupal file entity.
* @param string $remote_path
* The remote path in NextCloud (optional, defaults to filename).
* @param bool $create_folders
* Whether to create parent folders if they don't exist.
*
* @return bool
* TRUE if file was uploaded successfully, FALSE otherwise.
*/
public function uploadDrupalFile(FileInterface $file, string $remote_path = '', bool $create_folders = TRUE): bool {
if (!$this->isConfigured()) {
$this->logger->error('NextCloud WebDAV client is not configured');
return FALSE;
}
$local_path = $this->fileSystem->realpath($file->getFileUri());
if (!$local_path || !file_exists($local_path)) {
$this->logger->error('Local file does not exist: @uri', ['@uri' => $file->getFileUri()]);
return FALSE;
}
// Use filename if no remote path specified.
if (empty($remote_path)) {
$remote_path = $file->getFilename();
}
// Create parent folders if requested.
if ($create_folders) {
$parent_path = dirname($remote_path);
if ($parent_path !== '.' && $parent_path !== '/') {
$this->createFolder($parent_path);
}
}
return $this->webdavClient->uploadFile($local_path, $remote_path);
}
/**
* Uploads a file from a local path to NextCloud.
*
* @param string $local_path
* The local file path.
* @param string $remote_path
* The remote path in NextCloud.
* @param bool $create_folders
* Whether to create parent folders if they don't exist.
*
* @return bool
* TRUE if file was uploaded successfully, FALSE otherwise.
*/
public function uploadFile(string $local_path, string $remote_path, bool $create_folders = TRUE): bool {
if (!$this->isConfigured()) {
$this->logger->error('NextCloud WebDAV client is not configured');
return FALSE;
}
// Create parent folders if requested.
if ($create_folders) {
$parent_path = dirname($remote_path);
if ($parent_path !== '.' && $parent_path !== '/') {
$this->createFolder($parent_path);
}
}
return $this->webdavClient->uploadFile($local_path, $remote_path);
}
/**
* Uploads content as a file to NextCloud.
*
* @param string $content
* The file content.
* @param string $remote_path
* The remote path in NextCloud.
* @param bool $create_folders
* Whether to create parent folders if they don't exist.
*
* @return bool
* TRUE if content was uploaded successfully, FALSE otherwise.
*/
public function uploadContent(string $content, string $remote_path, bool $create_folders = TRUE): bool {
if (!$this->isConfigured()) {
$this->logger->error('NextCloud WebDAV client is not configured');
return FALSE;
}
// Create parent folders if requested.
if ($create_folders) {
$parent_path = dirname($remote_path);
if ($parent_path !== '.' && $parent_path !== '/') {
$this->createFolder($parent_path);
}
}
return $this->webdavClient->uploadContent($content, $remote_path);
}
/**
* Lists files and folders in a NextCloud directory.
*
* @param string $path
* The directory path to list.
*
* @return array|false
* Array of files and folders, or FALSE on error.
*/
public function listDirectory(string $path = ''): array|false {
if (!$this->isConfigured()) {
$this->logger->error('NextCloud WebDAV client is not configured');
return FALSE;
}
return $this->webdavClient->listDirectory($path);
}
/**
* Uploads multiple files to NextCloud.
*
* @param array $files
* Array of file information. Each item should be an array with:
* - 'local_path': The local file path
* - 'remote_path': The remote path in NextCloud
* Or a FileInterface object with optional 'remote_path' key.
* @param bool $create_folders
* Whether to create parent folders if they don't exist.
*
* @return array
* Array with 'success' and 'failed' keys containing file paths.
*/
public function uploadMultipleFiles(array $files, bool $create_folders = TRUE): array {
$results = [
'success' => [],
'failed' => [],
];
foreach ($files as $file_info) {
$success = FALSE;
if ($file_info instanceof FileInterface) {
$remote_path = $file_info->remote_path ?? $file_info->getFilename();
$success = $this->uploadDrupalFile($file_info, $remote_path, $create_folders);
$identifier = $file_info->getFileUri();
}
elseif (is_array($file_info) && isset($file_info['local_path'], $file_info['remote_path'])) {
$success = $this->uploadFile($file_info['local_path'], $file_info['remote_path'], $create_folders);
$identifier = $file_info['local_path'];
}
else {
$this->logger->error('Invalid file information provided for batch upload');
continue;
}
if ($success) {
$results['success'][] = $identifier;
}
else {
$results['failed'][] = $identifier;
}
}
return $results;
}
} 