it-swarm.com.de

Problem mit der Abhängigkeitsinjektion (File :: load und \ Drupal :: service)

Um ein Managed_File-Feld dauerhaft zu machen, habe ich dies in meinem Modulkonfigurationsformular getan:

<?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',
    ];
  }

}

in diesem Fall wird jedoch die Warnung angezeigt, das Prinzip der Abhängigkeitsinjektion zu verwenden:

File::load calls should be avoided in classes, use dependency injection instead

und

\Drupal calls should be avoided in classes, use dependency injection instead

Ich habe Abhängigkeitsinjektion für ein Formular durchgesehen, bin mir aber immer noch nicht sicher, ob ich es wirklich verstehe.

Kann mir jemand erklären, was ich in diesem speziellen Fall tun muss, damit ich mir dieses Problem besser ansehen und es herausfinden kann?

4
mixerowsky

Wenn Sie FormBase erweitern, können Sie create verwenden, um Abhängigkeiten einzufügen. In diesem Fall möchten Sie meiner Meinung nach den Dienst entity_type.manager Und 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')
    );
  }

Weitere Beispiele finden Sie unter Dokumentseite .

Die Methode create sendet Argumente an den Konstruktor, und dann setzen Sie diese auf Instanzvariablen, und voila, es gibt Ihre Abhängigkeiten. Stellen Sie sicher, dass Sie Ihre Datei mit den erforderlichen use -Anweisungen aktualisieren und Ihre geschützten Mitglieder (entityTypeManager und fileUsage) oben in der Formularklasse deklarieren.

Daher können Sie den static :: service-Aufruf entfernen und Folgendes verwenden:

$this->fileUsage->add()...

Der Grund, warum ich den Entity Type Manager-Dienst übergebe, ist, dass Sie File :: load durch Folgendes ersetzen würden:

$this->entityTypeManager->getStorage('file')->load($id);

Wenn Sie mehr als dieses Objekt benötigen, müssen Sie möglicherweise einen anderen Dienst verwenden, aber das weiß ich nicht genau.

7
Kevin