php
nested_array_merge_deep.php
use Drupal\Component\Utility\NestedArray;
// Parent array with default settings.
$parent_array = [
'config' => [
'theme' => 'dark',
'layout' => [
'width' => 800,
'height' => 600,
],
],
];
// Child array adds more nested data but doesn't override existing values.
$child_array = [
'config' => [
'layout' => [
'depth' => 300, // New nested key
],
'features' => [
'animations' => true, // New section
],
],
];
// Merge both arrays.
$merged_array = NestedArray::mergeDeep($parent_array, $child_array);nested_array_result.php
[
'config' => [
// Unchanged (not overridden)
'theme' => 'dark',
'layout' => [
// Keeps parent value
'width' => 800,
// Keeps parent value
'height' => 600,
// New nested key added
'depth' => 300,
],
'features' => [
// New section added
'animations' => true,
],
],
]
30.07.2026 | Lothar Ferreira Neumann
Merge multidimensional arrays in Drupal
cleanup_aliases.php
<?php
/** @var \Drupal\path_alias\PathAliasStorage */
$alias_storage = \Drupal::entityTypeManager()->getStorage('path_alias');
$db = \Drupal::database();
$langcodes = array_keys(\Drupal::languageManager()->getLanguages());
$total = 0;
$duplicates = "";
// Get a list of all distinct aliases.
$query = $db->select('path_alias', 'pa')
->fields('pa', ['alias'])
->orderBy('alias')
->distinct();
$all_aliases = $query->execute()->fetchAll(\Pdo::FETCH_COLUMN);
foreach ($all_aliases as $alias) {
// Some aliases are 'NULL'.
if (!$alias) {
continue;
}
// We only look for duplicates within the langcode.
foreach ($langcodes as $langcode) {
// (1) Get the newest ID for that alias and langcode.
$query = $db->select('path_alias', 'pa')
->fields('pa', ['id'])
->condition('alias', $alias)
->condition('langcode', $langcode)
->orderBy('id', 'DESC')
->range(0, 1);
$newest_id = $query->execute()->fetchField(0);
if (!$newest_id) {
// There is no alias for that langcode.
// So there are also no duplicates.
continue;
}
// (2) Select all ids lower than it with the same alias and langcode.
$query = $db->select('path_alias', 'pa')
->fields('pa', ['id'])
->condition('alias', $alias)
->condition('langcode', $langcode)
->condition('id', $newest_id, '<');
$duplicate_ids = $query->execute()->fetchAll(\PDO::FETCH_COLUMN);
if (!str_starts_with($alias, "/")) {
$query = $db->select('path_alias', 'pa')
->fields('pa', ['id'])
->condition('alias', "/" . $alias)
->condition('langcode', $langcode);
$ids_with_slash = $query->execute()->fetchAll(\PDO::FETCH_COLUMN);
if (count($ids_with_slash) > 0) {
// We can safely delete the one without.
$to_delete = $alias_storage->loadByProperties([
'alias' => $alias,
'langcode' => $langcode,
]);
$alias_storage->delete($to_delete);
} else {
// It's the only one? Update with slash.
$alias_entitys = $alias_storage->loadByProperties([
'alias' => $alias,
'langcode' => $langcode,
]);
if (!empty($alias_entitys)) {
$alias_entity = reset($alias_entitys);
$alias_entity->set('alias', '/' . $alias);
$alias_entity->save();
}
}
}
// We delete those with the alias storage since we want Drupal to handle it
// and it will delete revisions as well.
$duplicate_aliases = $alias_storage->loadMultiple($duplicate_ids);
$total += count($duplicate_aliases);
if (count($duplicate_aliases) > 0) {
$duplicates = $duplicates . $alias . PHP_EOL;
}
$alias_storage->delete($duplicate_aliases);
}
}
echo(sprintf("Deleting %d duplicate aliases..." . PHP_EOL, $total));
echo($duplicates);
echo("DONE" . PHP_EOL);
21.02.2025 | Nikolas Kopp
Clean up migrated path aliases
If this does not work...
broken_fapi_autocomplete.php
$form['nodes'] = [
'#title' => $this->t('Select articles'),
'#type' => 'entity_autocomplete',
'#target_type' => 'node',
'#tags' => TRUE,
'#selection_handler' => 'default',
'#selection_settings' => ['target_bundles' => ['article']],
'#default_value' => $default_nodes,
];...try adding an increased maxlength value:
fixed_fapi_autocomplete.php
$form['nodes'] = [
'#title' => $this->t('Select articles'),
'#type' => 'entity_autocomplete',
'#target_type' => 'node',
'#maxlength' => 1024,
'#tags' => TRUE,
'#selection_handler' => 'default',
'#selection_settings' => ['target_bundles' => ['article']],
'#default_value' => $default_nodes,
];
13.08.2026 | Pascal Crott
Can't save Form API autocomplete when referencing too many elements
static_or_nonstatic_that_is_the_question.php
// Static way.
$slot_paragraph = Paragraph::create([
'type' => 'slot',
]);
$slot_paragraph->save();
// Nonstatic way.
$entity_type_manager = \Drupal::entityTypeManager();
$storage = $entity_type_manager->getStorage('paragraphs');
$slot_paragraph = $storage->create([
'type' => 'slot',
]);
$slot_paragraph->save();
14.02.2025 | Lothar Ferreira Neumann
Best practice for entity creation using entity type manager
sort_by_weight.php
// ...
$build['content_1'] = [
'#markup' => "content 1",
'#custom_weight_property' => 10,
];
$build['content_2'] = [
'#markup' => "content 2",
'#custom_weight_property' => 5,
];
usort($build, function ($a, $b) {
return SortArray::sortByKeyInt($a, $b, '#custom_weight_property');
});The output looks like this:
content 2
content 1
Just a hint:
The custom weight system controls the display order of elements, where lower weight values appear earlier, as shown in the example: content_2 (with weight 5) is rendered before content_1 (with weight 10).
23.04.2026 | Lothar Ferreira Neumann
Sort render array by custom weight property
stringarray.php
<?php
declare(strict_types=1);
$string = "Example";
// This will print out "E".
echo($string[0]);
// You can also access the letters in a loop.
for ($i = 0; $i < strlen($string); $i++) {
echo($string[$i]);
}
17.01.2025 | Lothar Ferreira Neumann
How to get individual characters from a string
my_module.module
function my_module_local_tasks_alter(&$local_tasks) {
if (isset($local_tasks['entity.section_library_template.collection'])) {
$local_tasks['entity.section_library_template.collection']['weight'] = 110;
}
if (isset($local_tasks['feeds.admin'])) {
$local_tasks['feeds.admin']['weight'] = 120;
}
}
11.06.2026 | Michael Ebert
Change the order of local tasks
my_theme.theme
/**
* Implements hook_preprocess_HOOK() for layout.html.twig.
*/
function hook_preprocess_layout(&$variables) {
$layout = $variables['layout'];
foreach ($layout->getRegionNames() as $region_name) {
if (array_key_exists($region_name, $variables['content'])) {
uasort($variables['content'][$region_name], [\Drupal\Component\Utility\SortArray::class, 'sortByWeightProperty']);
}
}
}
12.12.2025 | Pascal Crott
Sort blocks inside layout regions by weight.
get_all_available_contexts.php
<?php
$all_available_contexts = \Drupal::service('context.repository')->getAvailableContexts();
30.04.2026 | Mathias Grab