sobki_profile_dsfr-10.0.0-alpha2/modules/sobki_assets/src/Form/AssetsUploadForm.php
modules/sobki_assets/src/Form/AssetsUploadForm.php
<?php
declare(strict_types=1);
namespace Drupal\sobki_assets\Form;
use Drupal\Component\Utility\Environment;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\ByteSizeMarkup;
use Drupal\sobki_assets\Service\ArchiveExtractorInterface;
use Drupal\sobki_assets\Service\DestinationDirectoryPurgerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Form to upload assets.
*/
class AssetsUploadForm extends FormBase {
public const string DESTINATION_DIRECTORY = 'public://sobki_assets';
/**
* The entity type manager service.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected EntityTypeManagerInterface $entityTypeManager;
/**
* The file system service.
*
* @var \Drupal\Core\File\FileSystemInterface
*/
protected FileSystemInterface $fileSystem;
/**
* Destination directory purger service.
*
* @var \Drupal\sobki_assets\Service\DestinationDirectoryPurgerInterface
*/
protected DestinationDirectoryPurgerInterface $destinationDirectoryPurger;
/**
* Archive extractor service.
*
* @var \Drupal\sobki_assets\Service\ArchiveExtractorInterface
*/
protected ArchiveExtractorInterface $archiveExtractor;
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container): static {
/** @var static $instance */
$instance = parent::create($container);
$instance->entityTypeManager = $container->get('entity_type.manager');
$instance->fileSystem = $container->get('file_system');
$instance->destinationDirectoryPurger = $container->get('sobki_assets.destination_directory_purger');
$instance->archiveExtractor = $container->get('sobki_assets.archive_extractor');
return $instance;
}
/**
* {@inheritdoc}
*/
public function getFormId(): string {
return 'sobki_assets.assets_upload';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state): array {
$size = Environment::getUploadMaxSize();
$formatted_size = ByteSizeMarkup::create($size);
$directory = static::DESTINATION_DIRECTORY;
if (!$this->fileSystem->prepareDirectory($directory)) {
if (!$this->fileSystem->mkdir($directory)) {
$this->messenger()->addError($this->t('Impossible to create the assets directory.'));
return $form;
}
}
$form['archive'] = [
'#type' => 'managed_file',
'#title' => $this->t('Upload assets'),
'#upload_location' => static::DESTINATION_DIRECTORY,
'#required' => TRUE,
'#description' => $this->t("Upload your assets compressed in a .zip format, all at the root of the archive.<br>Total upload size cannot exceed server's @size max limit", [
'@size' => $formatted_size,
]),
'#upload_validators' => [
'FileExtension' => ['extensions' => 'zip'],
'FileSizeLimit' => ['fileLimit' => $size],
],
];
/** @var object{"filename": string}[] $existingFiles */
$existingFiles = $this->fileSystem->scanDirectory($directory, '/.*/');
if (!empty($existingFiles)) {
$files = [];
foreach ($existingFiles as $file) {
$files[] = $file->filename;
}
$form['uploaded_files'] = [
'#theme' => 'item_list',
'#title' => $this->formatPlural(\count($existingFiles), 'Uploaded asset', 'Uploaded assets'),
'#items' => $files,
];
}
$form['actions'] = [
'#type' => 'actions',
'submit' => [
'#type' => 'submit',
'#value' => $this->t('Upload'),
],
];
if (!empty($existingFiles)) {
$form['actions']['delete'] = [
'#type' => 'submit',
'#value' => $this->t('Delete'),
'#submit' => ['::deleteFormSubmit'],
'#limit_validation_errors' => [],
];
}
return $form;
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state): void {
/** @var string|null $fid */
[$fid] = \is_array($form_state->getValue('archive')) ? $form_state->getValue('archive') : [NULL];
$this->destinationDirectoryPurger->purge($fid);
if ($fid == NULL) {
$this->messenger()->addError($this->t('Failed to load the archive.'));
return;
}
$archive = $this->entityTypeManager->getStorage('file')->load($fid);
if ($archive == NULL) {
$this->messenger()->addError($this->t('Failed to load the archive.'));
return;
}
$archive_uri = $archive->getFileUri();
if ($archive_uri == NULL) {
$this->messenger()->addError($this->t('Failed to get the archive URI.'));
return;
}
$archive_path = $this->fileSystem->realpath($archive_uri);
if (!$archive_path) {
$this->messenger()->addError($this->t('Failed to get the archive path.'));
return;
}
$destination = $this->fileSystem->realpath(static::DESTINATION_DIRECTORY);
if (!$destination) {
$this->messenger()->addError($this->t('Failed to get the destination path.'));
return;
}
$this->archiveExtractor->extract(
$archive_path,
$destination,
fn (array $filenames) => $this->messenger()->addStatus($this->formatPlural(
\count($filenames),
'File uploaded and extracted successfully.',
'Files uploaded and extracted successfully.'
)),
fn () => $this->messenger()->addError($this->t('Failed to extract the archive.')),
);
}
/**
* Delete form handler.
*/
public function deleteFormSubmit(): void {
$this->destinationDirectoryPurger->purge();
$this->messenger()->addStatus($this->t('Files have been deleted successfully.'));
}
}
