filebrowser-8.x-2.x-dev/src/Form/UploadForm.php
src/Form/UploadForm.php
<?php
namespace Drupal\filebrowser\Form;
use Drupal;
use Drupal\Core\File\FileSystem;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Cache\Cache;
use Drupal\file\Entity\File;
use Drupal\Core\File\FileExists;
use Drupal\filebrowser\Services\Common;
use Drupal\node\Entity\Node;
use Drupal\node\NodeInterface;
class UploadForm extends FormBase {
/**
* @var int
*/
protected $queryFid;
/**
* @var string
*/
protected $relativeRoot;
/**
* @var NodeInterface
*/
protected $node;
/**
* @var integer
*/
protected $nid;
/**
* @var Common
*/
protected $common;
/**
* {@inheritdoc}
*/
public function getFormId(): string {
return 'upload_form';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state, $nid= null, $query_fid = null, $fids = null, $ajax = null): array {
$this->common = Drupal::service('filebrowser.common');
$this->relativeRoot = $this->common->relativePath($query_fid);
$this->node = Node::load($nid);
$this->queryFid = $query_fid;
$this->nid = $nid;
$accepted = $this->node?->filebrowser->accepted ?? '';
$extensions = is_array($accepted) ? implode(' ', $accepted) : (string) $accepted;
// if this form is opened by ajax add a close link.
if ($ajax) {
$form['#attributes'] = [
'class' => [
'form-in-slide-down'
],
];
$form['close'] = $this->common->closeButtonMarkup();
}
// The widget will upload to temporary:// so incomplete and abandoned uploads are
// auto-cleaned by cron.
// During submit we will move the file to the final destination.
$tmp_base = 'temporary://filebrowser';
$tmp_dir = $this->common->joinURI($tmp_base, $this->nid . '/' . ($this->relativeRoot ?? ''));
$form['u_file'] = [
'#title' => $this->t('Upload file'),
'#type' => 'managed_file',
'#description' => $this->t('File types accepted: @accepted', ['@accepted' => $extensions]) . '<br>' . $this->t('You can upload multiple files.'),
'#multiple' => TRUE,
'#upload_validators' => [
'FileExtension' => ['extensions' => $extensions],
'FileExtensionSecure' => [],
],
'#upload_location' => $tmp_dir,
'#progress_indicator' => 'bar',
'#progress_message' => $this->t('Please wait...'),
];
$form['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Save Upload'),
];
return $form;
}
/**
* @inheritdoc
*/
public function validateForm(array &$form, FormStateInterface $form_state): void{
}
/**
* @inheritdoc
*/
public function submitForm(array &$form, FormStateInterface $form_state) :void {
// While we are using the managed_file widget (for convenience), we don't
// want to save the file in the file_managed table, so we will delete it
// here.
// A bit hackish, but it works.
// Grab FIDs from managed_file value. It can be either:
// - an array of FIDs or
// - ['fids' => [...]] depending on context.
$value = (array)$form_state->getValue('u_file');
$fids = isset($value['fids']) ? (array)$value['fids'] : $value;
$fids = array_values(array_filter(array_map('intval', $fids)));
if ($fids) {
/** @var NodeInterface|null $node */
$node = $this->node instanceof NodeInterface ? $this->node : NULL;
$node_fb = $node?->filebrowser;
// Final destination path from node folderPath + relativeRoot.
$folderPath = (string)($node_fb->folderPath ?? 'public://');
$upload_location = $this->common->joinURI($folderPath, $this->relativeRoot ?? '');
/** @var FileSystem $fs */
$fs = Drupal::service('file_system');
$fs->prepareDirectory($upload_location, FileSystemInterface::CREATE_DIRECTORY);
// Overwrite policy: node override > config > FALSE.
$cfg = Drupal::config('filebrowser.settings')->get('filebrowser') ?: [];
$allowOverwrite = isset($node_fb->allowOverwrite)
? (bool)$node_fb->allowOverwrite
: (bool)($cfg['uploads']['allow_overwrite'] ?? FALSE);
$mode = $this->existsMode($allowOverwrite);
foreach (File::loadMultiple($fids) as $file) {
$src = $file->getFileUri();
$dest = $this->common->joinURI($upload_location, $file->getFilename());
try {
$fs->copy($src, $dest, $mode);
$file->delete();
} catch (\Throwable $e) {
$this->messenger()->addError($this->t('Failed to store %name: %msg', [
'%name' => $file->getFilename(),
'%msg' => $e->getMessage(),
]));
}
}
$this->messenger()->addMessage($this->t('Your Filebrowser upload completed successfully.'));
}
// invalidate the cache for this node
Cache::invalidateTags(['filebrowser:node:' . $this->nid]);
$route = $this->common->redirectRoute($this->queryFid, $this->node?->id() ?? $this->nid);
$form_state->setRedirect($route['name'], $route['node'], $route['query']);
}
/**
* Prepare for deprecation.
*/
private function existsMode(bool $allowOverwrite) {
if (class_exists(FileExists::class)) {
// Drupal ≥ 10.3: prefer the enum.
return $allowOverwrite ? FileExists::Replace : FileExists::Rename;
}
// Drupal < 10.3: fall back to legacy constants.
return $allowOverwrite
? FileSystemInterface::EXISTS_REPLACE
: FileSystemInterface::EXISTS_RENAME;
}
}
