web-dev-qa-db-ja.com

依存性注入の問題(File :: loadおよび\ Drupal :: service)

Managed_fileフィールドを永続的にするために、モジュール構成フォームで次のようにしました。

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

}

この場合、依存性注入の原則を使用するように警告が表示されます。

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

そして

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

私は フォームの依存性注入 を調べましたが、実際に取得できるかどうかはまだわかりません。

誰かがこの特定のケースで何をする必要があるかを私に説明して、この問題をよりよく理解して理解できるようにすることはできますか?

4
mixerowsky

FormBase を拡張する場合は、createを使用して依存関係を注入できます。この場合、あなたが望むのは_entity_type.manager_サービスと_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')
    );
  }
_

その他の例については、この ドキュメントページ を参照してください。

createメソッドはコンストラクターに引数を送信し、それらをインスタンス変数に設定すると、依存関係があります。必ず必要なuseステートメントでファイルを更新し、フォームクラスの上部で保護されたメンバー(entityTypeManagerおよびfileUsage)を宣言してください。

したがって、静的::サービスコールを削除して使用できます。

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

また、エンティティタイプマネージャーサービスを渡す理由は、File :: loadを次のものに置き換えるためです。

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

そのオブジェクトが返す以上のものが必要な場合は、別のサービスを使用する必要があるかもしれませんが、私は頭の中でそれを知りません。

7
Kevin