web-dev-qa-db-fra.com

Problème avec l'injection de dépendances (File :: load et \ Drupal :: service)

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?

4
mixerowsky

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.

7
Kevin