Sunday 3 May 2020

Services injection in custom Controller

In custom controller, if it is extending ControllerBase class then no need to inject (with service container) some of the services explained in this post. ControllerBase already having some of the services which we can directly access in the custom controller without injecting it.

Below example will show how to use those services.

Custom Controller Class code

<?php

namespace Drupal\custom_module\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\StringTranslation\StringTranslationTrait;

/**
 * Class ControllerServicesInjectionController.
 *
 * @package Drupal\custom_module\Controller
 */
class ControllerServicesInjectionController extends ControllerBase {

  // Below trait is used to make translatable string in controller class.
  use StringTranslationTrait;

  /**
   * Function having information about services which need not to inject.
   */
  public function useServicesWithoutInjecting() {

// Get current user object without injecting user service.
// Returns the current user.
       $user_object = $this->currentUser();

// Get entityTypeManager service without injecting entityTypeManager service.
// Retrieves the entity type manager.
$entity_type_manager = $this->entityTypeManager();

// Get moduleHandler service without injecting moduleHandler service.
// Returns the module handler.
$module_handler = $this->moduleHandler();

// Get languageManager service without injecting languageManager service.
// Returns the language manager service.
$language_manager = $this->languageManager();

// Get entityFormBuilder service without injecting entityFormBuilder service.
// Retrieves the entity form builder.
$entity_form_builder = $this->entityFormBuilder();

// Get formBuilder service without injecting formBuilder service.
// Returns the form builder service.
$form_builder = $this->formBuilder();

// Get state service without injecting state service.
// Returns the state storage service.
$state_object = $this->state();

// Get keyValue service without injecting keyValue service.
// Returns a key/value storage collection.
$keyvalue_object = $this->keyValue('config_key');

        // Translate string in controller class with StringTranslationTrait.
$this->t('This is translatable string.');

        // To only check the above services output.
        print_r($user_object);
        print_r($entity_type_manager);
        print_r($module_handler);
        print_r($language_manager);
        print_r($entity_form_builder);
        print_r($form_builder);
        print_r($state_object);
        print_r($keyvalue_object);
  }
}

Sunday 26 April 2020

Import Field Configurations Programmatically in Drupal 8

Import Field Configurations Programmatically in Drupal 8


In one of my project, feature module was used to move configurations from one environment to another environment.
With the help of feature module it is easy to move configurations and sync of configurations is easy but when we are moving these configs to production environment we are not having access of it to revert feature changes.

So I decided to write hook_update_n in install file of the module to import configurations of any field. With the help of below code, configurations can be imported to create field.


Create a custom module having below directory structure or place config file in already created custom module in config/install directory and create a modulename.install file

config_import
  config_import.info.yml
  config_import.module
  config_import.install
  config
    install
       // Place all config files here as below
       field.storage.node.field_second_field.yml
       field.field.node.home_stage.field_second_field.yml
       core.entity_form_display.node.home_stage.default.yml
       core.entity_view_display.node.home_stage.default.yml

Code which should available in config_import.install file as below
<?


<?php

/**
 * @file
 * Add search placeholder field.
 */

use Drupal\Core\Config\FileStorage;

/**
 * Add configurations to configs.
 */
function import_config_update_8002() {
  // Get config storage.
  $config_storage = \Drupal::service('config.storage');

  $module = 'import_config';
  // Get config files path.
  $config_path = drupal_get_path('module', 'import_config') . '/config/install';
  // Get file storage for config files.
  $source = new FileStorage($config_path);

  // Create field storage for second field.
  try {
    \Drupal::entityTypeManager()->getStorage('field_storage_config')
      ->create($source->read('field.storage.node.field_second_field'))
      ->save();
  } catch (\Exception $e) {
    Drupal::logger($module)
      ->error('Storage for field field_second_field could not be created. ' . $e->getMessage());
  }

  try {
    // Create field
    \Drupal::entityTypeManager()->getStorage('field_config')
      ->create($source->read('field.field.node.home_stage.field_second_field'))
      ->save();
  } catch (\Exception $e) {
    Drupal::logger($module)
      ->error('Field field_second_field for entity home_stage could not be created. ' . $e->getMessage());
  }

  // Add termscondition field in recipe configurations config pages.
  $config_storage->write('core.entity_form_display.node.home_stage.default', $source->read('core.entity_form_display.node.home_stage.default'));
  $config_storage->write('core.entity_view_display.node.home_stage.default', $source->read('core.entity_view_display.node.home_stage.default'));


}

With above code when you will run drush updb then field "field_second_field" will be created.

For reference :