こちらのサイトではDRUPAL10に関連する記事を掲載しています。
この記事はこちらのサイトを日本語訳しています。
Drupal サービスまたはカスタム サービスを必要とするフォームは、依存性注入を使用してサービスにアクセスする必要があります。
current_userサービスを呼び出す
サンプル フォーム ( Drupal 8 のフォーム APIで使用されるフォームと同様) では、’current_user’ サービスを使用して現在のユーザーの uid を取得します。 のファイル内容 /modules/example/src/Form/ExampleForm.php
モジュールが入っている場合 /modules/example
:
<?php
namespace Drupal\example\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Implements an example form.
*/
class ExampleForm extends FormBase {
/**
* @var \Drupal\Core\Session\AccountInterface
*/
protected $account;
/**
* @param \Drupal\Core\Session\AccountInterface $account
*/
public function __construct(AccountInterface $account) {
$this->account = $account;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
// Instantiates this form class.
return new static(
// Load the service required to construct this class.
$container->get('current_user')
);
}
/**
* {@inheritdoc}.
*/
public function getFormId() {
return 'example_form';
}
/**
* {@inheritdoc}.
*/
public function buildForm(array $form, FormStateInterface $form_state) {
// Get current user data.
$uid = $this->account->id();
// ...
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
// ...
}
}
の create
メソッドは、の新しいインスタンスを返すファクトリ メソッドです。 ExampleForm
物体。 の ExampleForm::create
1 つ以上のサービスをロードします。 これは、で定義されている任意のコア サービスにすることができます core.services.yml
または任意 *.services.yml
ファイル。
ExampleForm::__construct
によってロードされるサービスを使用します ExampleForm::create
クラスのプロパティに保存します。 サービスが読み込まれる順序 ExampleForm::create
のパラメータの順序と等しくなければなりません ExampleForm::__construct
方法。
の create
メソッドは Drupal\Core\DependencyInjection\ContainerInjectionInterface
これにより、コントローラーをサービスでインスタンス化できます。 Drupal\Core\Form\FormBase
はすでにこのインターフェースを実装しています。 拡張する任意のフォーム Drupal\Core\Form\FormBase
ConfigFormBase や ConfirmFormBase などは、この依存性注入の機能を備えています。
<?php
namespace Drupal\example\Form;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Session\AccountProxyInterface;
/**
* Implements an example configuration form.
*/
class ExampleConfigForm extends ConfigFormBase {
/**
* Drupal\Core\Session\AccountProxyInterface definition.
*
* @var AccountProxyInterface $currentUser
*/
protected $currentUser;
/**
* Class constructor.
*/
public function __construct(ConfigFactoryInterface $config_factory, AccountProxyInterface $current_user) {
parent::__construct($config_factory);
$this->currentUser = $current_user;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('config.factory'),
$container->get('current_user')
);
}
/**
* {@inheritdoc}
*/
protected function getEditableConfigNames() {
return [
'example.config_form',
];
}
/**
* {@inheritdoc}.
*/
public function getFormId() {
return 'example_config_form';
}
/**
* {@inheritdoc}.
*/
public function buildForm(array $form, FormStateInterface $form_state) {
// Get current user data.
$uid = $this->currentUser->id();
drupal_set_message($uid);
// ...
$config = $this->config('example.config_form');
return parent::buildForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->config('example.config_form')->save();
parent::submitForm($form, $form_state);
}
}
上記のコンストラクタ プロパティ プロモーションを使用した例 (PHP 8.0):
…
class ExampleConfigForm extends ConfigFormBase {
/**
* Class constructor.
*/
public function __construct(
ConfigFactoryInterface $config_factory,
protected AccountProxyInterface $currentUser
) {
parent::__construct($config_factory);
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('config.factory'),
$container->get('current_user')
);
}
…
@todo 同じクラス インターフェイスでパラメーターを定義するだけで、FormController が $route 情報を buildForm() メソッドに自動的に挿入する方法を示します。
例
buildForm(array $form, FormStateInterface $form_state, Request $request = NULL)
カスタム ブロック プラグイン内にカスタム/コア サービスを挿入して、使用する必要があります。
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
という名前のカスタム ブロックがあるとします 「drupalise」カスタム サービス 「drupalise」を挿入します。。次のように、カスタム ブロック コード内に
<?php
namespace Drupal\drupalise\Plugin\Block;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\drupalise\Services\DrupaliseMe;
/**
* Provides a 'Drupalise' block.
*
* @Block(
* id = "drupalise",
* admin_label = @Translation("Drupalise"),
* )
*/
class Drupalise extends BlockBase implements ContainerFactoryPluginInterface {
/**
* @var $drupalise \Drupal\drupalise\Services\DrupaliseMe
*/
protected $drupalise;
/**
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container
* @param array $configuration
* @param string $plugin_id
* @param mixed $plugin_definition
*
* @return static
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('drupalise')
);
}
/**
* @param array $configuration
* @param string $plugin_id
* @param mixed $plugin_definition
* @param \Drupal\drupalise\Services\DrupaliseMe $drupalise_me
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, DrupaliseMe $drupalise_me) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->drupalise = $drupalise_me;
}
/**
* {@inheritdoc}
*/
public function build() {
$slogan= $this->drupalise->Drupalise(); // Function from your service file will return 'Drop Drop Drupal !!!'
$build = [];
$build['drupalise']['#markup'] = 'Drupalise is best' . $slogan;
return $build;
}
}
シリアル化に関する考慮事項
サービス オブジェクトが drupal によってシリアル化されると、プライベート プロパティが失われます。
でください。 ないプライベートな可視性を持つようにフォーム クラスのサービス プロパティを設定し
たとえば、フォームが ajax を介して再構築された場合、 #ajax
フォーム要素への定義、フォーム クラスがシリアル化される
クラスのプライベート プロパティに割り当てられている ajax リクエストとサービスは失われます。 これにより、ajax が実行されて正常に処理され、後続の ajax リクエストで null プロパティ値が原因でエラーが生成されるフォームが生成されます。
定義済みの要素がある場合 #ajax
以下のようなハンドラーでは、サービスがフォーム クラスに挿入されていることを確認する必要があります。
プライベートではありません。
'#ajax' => [
'callback' => '::myAjaxCallback', 'event' => 'change', 'wrapper' => 'my-ajax-wrapper', 'progress' => [
'type' => 'throbber', 'message' => $this->t('Verifying entry...'),
],
]
例:
class MyEntityForm extends EntityForm
/**
* Drupal routeBuilder object, for rebuilding routes on form save.
*
* This is an injected service and must not be declared private or
* it will be lost on serialisation of this form object.
*
* @var \Drupal\Core\Routing\RouteBuilder
*/
protected $routeBuilder
/**
* MyEntityForm constructor.
*
* The injected service properties, eg $this->routeBuilder must
* be not be declared private as this form is reloaded with ajax and
* cached, private properties aren't serialisable.
*
* @param \Drupal\Core\Routing\RouteBuilderInterface $routeBuilder
*/
public function __construct(RouteBuilderInterface $routeBuilder) {
$this->routeBuilder = $routeBuilder
}
}
DRUPAL10のアカウントユーザ関連API
アカウントユーザ関連API関数
この記事またはDrupalに関するご質問がございましたら、お気軽にお問い合わせください。