Thursday 14 March 2019

Use Dependency Injection in creating custom form in Drupal 8

Inject Service in custom form with the help of Dependency Injection.

In previous post, While creating custom form, "database" service is injected with the global service containers which is not a right practice to use service in class. Now in this post, "database" service will be injected with the dependency injection.

Inject service in Form class created in previous post.
CompanyAddForm.php in fisrtcustommodule > src > Form .

<?php

/**
 * @file
 * Contains \Drupal\firstcustommodule\Form\CompanyAddForm
 */

namespace Drupal\firstcustommodule\Form;

use Drupal\Core\Form\FormBase;
use Drupal\core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Database\Connection;

/**
 * Provides company add form.
 */
class CompanyAddForm extends FormBase {
  /**
   * Database connection object.
   *
   * @var Drupal\Core\Database\Connection
   */
  protected $database;

  /*
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    // Instantiate this form class.
return new static (
  // Load the service required to construct this class.
  $container->get('database')
);
  }

  /**
   * Class constructor.
   */
  public function __construct(Connection $database) {
    $this->database = $database;
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'company_add_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    // Form fields.
  $form['company_name'] = array(
    '#title' => $this->t('Company Name:'),
    '#type' => 'textfield',
    '#default_value' => '',
    '#maxlength' => 60,
    '#required' => TRUE,
  );
  $form['company_email'] = array(
    '#title' => $this->t('Company Email:'),
    '#type' => 'textfield',
    '#default_value' => '',
    '#maxlength' => 60,
    '#required' => TRUE,
  );
  $form['telephone'] = array(
    '#title' => $this->t('Tel:'),
    '#type' => 'textfield',
    '#default_value' => '',
  );
  $form['address'] = array(
    '#title' => $this->t('Address:'),
    '#type' => 'textfield',
    '#default_value' => '',
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => $this->t('Save'),
  );
  return $form;
  }

  /**
   *
   */
public function submitForm(array &$form, FormStateInterface $form_state) {
  // To save company information in custom table.
  // Database connection service is used.
  // Insert query.
  $insert = $this->database->insert('company_information')
    ->fields(
      [
        'company_name' => $form_state->getValue('company_name'),
        'company_email' => $form_state->getValue('company_email'),
        'company_address' => $form_state->getValue('address'),
        'company_telephone' => $form_state->getValue('telephone'),
        'created' => time(),
      ]
    )->execute();
if ($insert) {
  drupal_set_message($this->t('Company information has been saved successfully'));
}
  }
}
In above code:
use Symfony\Component\DependencyInjection\ContainerInterface;
is used to create service container.
use Drupal\Core\Database\Connection;
Database service class which will be injected.

Created protected variable $database;

Then implemented create() method which is having ContainerInterface as argument. This returns service container object.
In this method
  • This form class is instantiated
  • Database service is loaded which is required to construct this class.
  • This returns service container object.
/**
  * Class constructor.
  */
  public function __construct(Connection $database) {
    $this->database = $database;
  }
Now database service is available in service container with variable $database.
Whenever database service is required, it can be access as below:
$this->database
In above formSubmit() method, database service is used with above syntax.

No comments:

Post a Comment