Snippets

Een verzameling kleine code fragmenten voor relatief simpele aanpassingen

Een redirect na login wordt vaak toegevoegd op hook_user_login, maar dat is niet juist. Dit zorgt er voor dat de andere hook_user_login implementaties niet worden uitgevoerd. Het is beter om deze redirect in een custom submit handler te zetten.

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;

/**
 * Implements hook_form_FORM_ID_alter().
 */
function MY_MODULE_form_user_login_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  $form['#submit'][] = 'MY_MODULE_user_login_form_submit';
}

/**
 * Custom submit handler for the login form.
 */ 
function MY_MODULE_user_login_form_submit($form, FormStateInterface $form_state) {
  $url = Url::fromRoute('');
  $form_state->setRedirectUrl($url); 
}

Hoe kun je een node of entity renderen in Drupal 8 zoals met node_view() in Drupal 7 ?
Hoe toon je een node of entity met een display mode?

$nid = 1;
$entity_type = 'node';
$view_mode = 'teaser';
$view_builder = \Drupal::entityTypeManager()->getViewBuilder($entity_type);

// You could also use Node::load($nid);
$storage = \Drupal::entityTypeManager()->getStorage($entity_type);
$node = $storage->load($nid);

$build = $view_builder->view($node, $view_mode);
$output = render($build);

If you want to add a submenu link you first have to load the parent link and then create a submenu link:

use Drupal\menu_link_content\Entity\MenuLinkContent;

function MY_MODULE_update_8001() {
  $menu_link_parents = \Drupal::entityTypeManager()
    ->getStorage('menu_link_content')
    ->loadByProperties([
      'title' => 'Dashboard',
      'menu_name' => 'main',
    ]);

  $menu_link_parent = reset($menu_link_parents);

  if ($menu_link_parent) {
    MenuLinkContent::create([
      'title' => 'Add tasks',
      'link' => ['uri' => 'internal:/add-task'],
      'menu_name' => 'main',
      'weight' => -50,
      'parent' => $menu_link_parent->getPluginId(),
    ])->save();
  }
}

Soms moet je een veld van een content type aanpassen nadat het al gedefinieerd is en gebruikt wordt.

Als je dat via de admin pagina's doet, krijg je de foutmelding "Er zijn reeds gegevens voor dit veld in de database. De veldinstellingen kunnen niet meer gewijzigd worden.".

Het veld kan niet gewijzigd worden aangezien er al data in zit.

Een manier om het op te lossen is via een hook_update_N implementatie, in mijn geval om een veld van “Text (plain)” naar “Text (formatted, long)” aan te passen.

  $entityType = 'node';
  $fieldName = 'field_text';

  $database = \Drupal::database();
  $table = $entityType . '__' . $fieldName;
  $currentRows = NULL;
  $newFieldsList = [];
  $fieldStorage = FieldStorageConfig::loadByName($entityType, $fieldName);

  if (is_null($fieldStorage)) {
    return;
  }

  // Get all current data from DB.
  if ($database->schema()->tableExists($table)) {
    // The table data to restore after the update is completed.
    $currentRows = $database->select($table, 'n')
      ->fields('n')
      ->execute()
      ->fetchAll();
  }

  // Use existing field config for new field.
  foreach ($fieldStorage->getBundles() as $bundle => $label) {
    $field = FieldConfig::loadByName($entityType, $bundle, $fieldName);
    $newField = $field->toArray();
    $newField['field_type'] = 'text_long';
    $newField['settings'] = [];
    $newFieldsList[] = $newField;
  }

  // Deleting field storage which will also delete bundles(fields).
  $newFieldStorage = $fieldStorage->toArray();
  $newFieldStorage['type'] = 'text_long';
  $newFieldStorage['settings'] = [];

  $fieldStorage->delete();

  // Purge field data now to allow new field and field_storage with same name
  // to be created.
  field_purge_batch(40);

  // Create new field storage.
  $newFieldStorage = FieldStorageConfig::create($newFieldStorage);
  $newFieldStorage->save();

  // Create new fields.
  foreach ($newFieldsList as $nfield) {
    $nfieldConfig = FieldConfig::create($nfield);
    $nfieldConfig->save();
  }

  // Restore existing data in new table.
  if (!is_null($currentRows)) {
    foreach ($currentRows as $row) {
      $database->insert($table)
        ->fields((array) $row)
        ->execute();
    }
  }
$alias = \Drupal\path_alias\Entity\PathAlias::create([
    'path' => '/news',
    'alias' => '/nieuws',
    'langcode' => 'nl',
  ]);
  $alias->save();

Hoe zet je de versie van een module terug naar een specifieke versie (om bijv. updates opnieuw uit te voeren)?

 

# Drupal 7:
drush sqlq "UPDATE system SET schema_version=[schema_version] WHERE name='[module_name]' AND type='module'";

# Drupal 8 / 9
drush ev "drupal_set_installed_schema_version('[module_name]', [schema_version])"