Afin de rendre permanent un champ managed_file, je l'ai fait dans le formulaire de configuration de mon module:
<?php
namespace Drupal\my_module\Form;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
/**
* Class MymoduleSettings.
*/
class MymoduleSettings extends ConfigFormBase {
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'my_module_settings';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$config = $this->config('my_module.settings');
$form['my_module_title'] = [
'#type' => 'textfield',
'#title' => $this->t('Title'),
'#description' => $this->t("Enter the title"),
'#maxlength' => 64,
'#size' => 64,
'#required' => TRUE,
'#default_value' => $config->get('my_module_title'),
];
$form['mymodule_icon'] = [
'#type' => 'managed_file',
'#title' => $this->t('Icon'),
'#description' => $this->t("Upload the image file for the icon"),
'#upload_location' => 'public://',
'#upload_validators' => [
'file_validate_extensions' => ['gif png jpg jpeg'],
],
'#default_value' => $config->get('my_module_icon'),
];
return parent::buildForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
parent::submitForm($form, $form_state);
$this->config('my_module.settings')
->set('my_module_title', $form_state->getValue('my_module_title'))
->set('my_module_icon', $form_state->getValue('my_module_icon'))
->save();
// First we just grab the file ID for the icon we uploaded, if any.
$icon_field = $form_state->getValue('my_module_icon');
$file_id = empty($icon_field) ? FALSE : reset($icon_field);
if (!empty($file_id)) {
// Make this a permanent file so that cron doesn't delete it later.
$file = File::load($file_id);
$file->status = FILE_STATUS_PERMANENT;
$file->save();
$file_usage = \Drupal::service('file.usage');
$file_usage->add($file, 'my_module', 'file', $file_id);
}
}
/**
* {@inheritdoc}
*/
protected function getEditableConfigNames() {
return [
'my_module.settings',
];
}
}
mais je reçois un avertissement pour utiliser le principe d'injection de dépendance dans ce cas:
File::load calls should be avoided in classes, use dependency injection instead
et
\Drupal calls should be avoided in classes, use dependency injection instead
J'ai regardé à travers Injection de dépendances pour un formulaire mais je ne suis toujours pas sûr de l'avoir vraiment.
Quelqu'un peut-il m'expliquer ce que je dois faire dans ce cas particulier afin que je puisse avoir une meilleure vue sur ce problème et le comprendre?
Si vous étendez FormBase vous pouvez utiliser create
pour injecter des dépendances. Dans ce cas, ce que je pense que vous voulez, c'est le service entity_type.manager
Et file.usage
.
/**
* Class constructor.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, FileUsageInterface $file_usage) {
$this->entityTypeManager = $entity_type_manager;
$this->fileUsage = $file_usage;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity_type.manager'),
$container->get('file.usage')
);
}
Voir ceci page docs pour plus d'exemples.
La méthode create
envoie des arguments au constructeur, puis vous les définissez sur des variables d'instance, et le tour est joué, il y a vos dépendances. Assurez-vous de mettre à jour votre fichier avec les instructions use
nécessaires et déclarez vos membres protégés (entityTypeManager
et fileUsage
) en haut de la classe du formulaire.
Par conséquent, vous pouvez supprimer l'appel static :: service et utiliser:
$this->fileUsage->add()...
En outre, la raison pour laquelle je transmets le service de gestionnaire de type d'entité est que vous remplaceriez File :: load par:
$this->entityTypeManager->getStorage('file')->load($id)
;
Si vous avez besoin de plus de retours que cet objet, vous devrez peut-être utiliser un service différent, mais je ne le sais pas du haut de ma tête.