Skip to content

Instantly share code, notes, and snippets.

@adinan-cenci
Last active April 3, 2025 08:38
Show Gist options
  • Save adinan-cenci/d35e66e7b1ad9e2bd4ad5ca44e15a663 to your computer and use it in GitHub Desktop.
Save adinan-cenci/d35e66e7b1ad9e2bd4ad5ca44e15a663 to your computer and use it in GitHub Desktop.
Useful Drupal snippets
// Purging an URL from cloudflare.
(new \CloudFlarePhpSdk\ApiEndpoints\ZoneApi(
  Drupal::config('cloudflare.settings')->get('apikey'),
  Drupal::config('cloudflare.settings')->get('email')
))
  ->purgeIndividualFiles(
    Drupal::config('cloudflare.settings')->get('zone_id'),
    ['https://url.goes.here.com']
  );

Drush

Need to run the same update hook ( e.g. 8003 ) twice ?

# NOTE: this will cause all module_name_update_N > 8002 to run again.
drush sqlq "UPDATE key_value SET value = 'i:8002;' WHERE name = 'module_name' AND collection = 'system.schema'"

Need to update a configuration ?

# If for whatever reason `drush cset` does not cut it.
drush eval "Drupal::service('config.factory')->getEditable('name_of_the_module.something_something')->set('piece_of_anoyance', ['value' => ''])->save()"

Send email

drush eval "Drupal::service('plugin.manager.mail')->mail('system', 'general_mail', '[email protected]', 'en', ['message' => 'this is a test email message', 'subject' => 'test mail', 'context' => ['message' => 'this is a test email message', 'subject' => 'test mail']], NULL, TRUE)"

## Send email ( Drupal 7 )
drush eval "drupal_mail('system', 'general_mail', '[email protected]', 'en', ['message' => 'this is a test email message', 'subject' => 'test mail', 'context' => ['message' => 'this is a test email message', 'subject' => 'test mail']], NULL)"

Select nodes that have no aliases

drush sqlq "SELECT n.nid, DATE_FORMAT(FROM_UNIXTIME(n.changed), '%e %b %Y %H:%i:%s') FROM node_field_data n LEFT JOIN path_alias p ON REPLACE(p.path, '/node/', '') = n.nid LEFT JOIN domain_path d ON REPLACE(d.source, '/node/', '') = n.nid WHERE n.status = 1 AND p.path IS NULL AND d.source IS NULL ORDER BY n.changed DESC"

Manually uninstall module

drush sqlq "DELETE FROM key_value WHERE collection = 'system.schema' AND name IN ('module_name')";
drush cdel core.extension module.module_name;
# Alternatively:
drush eval "\Drupal::configFactory()->getEditable('core.extension')->clear('module.module_name')->save()";

Entities

Load ant iterate through multiple entities

$storage = $order_items = \Drupal::entityTypeManager()
  ->getStorage('node');

$query = $storage->getQuery()
  ->accessCheck(FALSE)
  ->condition('field_something', 'foo bar', '=')
  ->sort('created', 'DESC');
$ids = $query->execute();

$chunk_size = 50;
$chunks = array_chunk($ids, $chunk_size);

foreach ($chunks as $chunk) {
  $nodes = $storage->loadMultiple($chunk);
  foreach ($nodes as $node) {
    // ... do something ...
  }
  $nodes = [];
  $storage->resetCache($chunk);
}

Desasociate entities

foreach ($entity->field_whatever_reference as $key => $value) {
  if ($value->target_id == $undesirable_id) {
    unset($entity->field_whatever_reference[$key]);
  }
}
$entity->save();

Paragraphs

Load term children

$vid = 'my_vocab_machine_name';
$parent_term_id = 87; // the parent term id
$depth = 1; // 1 to get only immediate children, NULL to load entire tree
$load_entities = FALSE; // True will return loaded entities rather than ids
$child_tids = \Drupal::entityTypeManager()
  ->getStorage('taxonomy_term')
  ->loadTree($vid, $parent_term_id, $depth, $load_entities);
<?php
// TODO: refactor this thing
// Function to search for a string in all tables and columns
function search_string_in_database($search_string) {
// Get the database connection
$connection = \Drupal\Core\Database\Database::getConnection();
// Get all tables in the database
$tables = $connection->query('SHOW TABLES')->fetchCol();
foreach ($tables as $table_name) {
// Get all columns for the current table
$columns = $connection->query("DESCRIBE {$table_name}")->fetchAll();
foreach ($columns as $column) {
// Get the column type
$column_name = $column->Field;
$column_type = $column->Type;
// Check if the column type is a string type
if (!is_text_type($column_type)) {
continue;
}
// Construct and execute the search query
$query = $connection->select(str_replace('eq_', '', $table_name), 't')
->fields('t')
->condition($column_name, '%' . $search_string . '%', 'LIKE');
try {
$results = $query->execute()->fetchAll();
}
catch(\Exception $e) {
$fuck = $e;
}
$index = [];
if (!empty($results)) {
// Print the results
foreach ($results as $result) {
$key = "$search_string.$table_name.$column_name";
if (isset($index[$key])) {
continue;
}
$index[$key] = 1;
// You can customize the output as needed
echo "$search_string found in $table_name.$column_name";
echo "\n";
}
}
}
}
}
function search_strings_in_the_database() {
$search_for = [
'www.linkedin.com',
'www.facebook.com',
'www.twitter.com',
];
foreach ($search_for as $url) {
search_string_in_database($url);
}
}
function is_text_type(string $column_type) {
if (substr_count($column_type, 'string')) {
return TRUE;
}
if (substr_count($column_type, 'text')) {
return TRUE;
}
if (substr_count($column_type, 'varchar')) {
return TRUE;
}
if (substr_count($column_type, 'longtext')) {
return TRUE;
}
return FALSE;
}

Request

// Get the current route name.
\Drupal::routeMatch()->getRouteName();

// Check if the current route is an admin one.
\Drupal::service('router.admin_context')->isAdminRoute();

// Get a http header
\Drupal::request()->headers->get('header_name');

// Get a $_GET variable.
\Drupal::request()->query->get('variable_name');

// Get a $_POST variable.
\Drupal::request()->request->get('variable_name');

// Get the host name.
\Drupal::request()->getHost();

// get the full url
\Drupal::request()->getSchemeAndHttpHost() . \Drupal::request()->getRequestUri();

Routing

No cache

module.no_cache:
  path: '/whatever'
  defaults:
    _controller: '\Drupal\module\Controller\What:ever'
  options:
    no_cache: TRUE

Deletes a specific item from a search index.

Drupal\search_api\Entity\Index::load('search_content')
  ->trackItemsDeleted('entity:node', ['1499:en'])

Indexes it again

Drupal\search_api\Entity\Index::load('search_content')
  ->indexSpecificItems([
    'entity:node/1499:en' => Drupal\node\Entity\Node::load(1499)->getTypedData()
  ]);

Retrieve documents from solr

$index = Drupal\search_api\Entity\Index::load('site_search');
$query = $index->query();
$query->addCondition('search_api_id', 'entity:node/2124565:en');
$results = $query->execute();
$items = $results->getResultItems();
$first = reset($items) ?: NULL;
$first->getFields();

Preprocess node

Change date field, but keep date format.

$node = $variables['node'];
$date = something_something_get_date_value_to_override($node->get('field_deadline')->value);

$bundle = $node->getType();
$view_mode = $variables['view_mode'];
$view_mode = $view_mode == 'full'
  ? 'default'
  : $view_mode;

$settings = \Drupal::entityTypeManager()
  ->getStorage('entity_view_display')
  ?->load("node.$bundle.$view_mode")
  ?->getComponent('field_deadline');

$pattern = 'j F Y';
if ($settings && isset($settings['settings']['date_format'])) {
  $pattern = $settings['settings']['date_format'];
}
elseif ($settings && isset($settings['settings']['format_type'])) {
  $format_type = $settings['settings']['format_type'];
  $format = \Drupal::entityTypeManager()->getStorage('date_format')
    ->load($format_type);
  $pattern = $format->getPattern();
}

$variables['content']['field_deadline'][0]['#text'] =
$variables['content']['field_deadline'][0]['#markup'] =
$variables['elements']['field_deadline'][0]['#markup'] = $date->format($pattern);

Preprocess view

/*
 * Implements template_preprocess_views_view().
 * field_event_time is a multi-value field, so the same node can appear 
 * multiple times in the same view. We need to make sure the correct date
 * is displayed.
 */
function my_module_preprocess_views_view(&$variables) {
  $view = $variables['view'];
  if ($view->id() == 'events') {
    $results = $view->result;

    foreach ($variables['rows'][0]['#rows'] as $row_n => &$row) {
      $node = $row['#node'];

      if ($node->get('field_event_time')->count() > 1) {
        $result = $results[$row_n];
        $date_string = $result->node__field_event_time_field_event_time_value_day;
        $date = new Drupal\Component\Datetime\DateTimePlus($date_string);
        $human_format = $date->format('F d, Y');
        $unix_format = $date->format('Y-m-d');
        $row['field_event_time'][0]['start_date'] = [
          '#theme' => 'time',
          '#text' => $human_format,
          '#attributes' => [
            'datetime' => $unix_format
          ]
        ];
        $row['#cache']['max-age'] = 0;
      }
    }
  }
}

Twig

{# For whatever reason this seems to erase other proprieties #}
{{ content.field_link.0|merge({
  '#attributes': { 'target': '_blank' },
}) }}

{# try this #}
{% set link = content.field_box_link.0 %}
{% set href = link['#url'].external ? link['#url'].uri : path(link['#url'].routeName, link['#url'].routeParameters) %}
<a href="{{ href }}" {{ link.attributes|without('target') }} target="_blank">{{ link['#title'] }}</a>

Update

Update hook

// Enable module
function update_module_update_8005() {
  \Drupal::service('module_installer')
    ->install(['some_module','or_another',]);
}

Post update

// Delete bundle ( remember to delete entities first )
function gstt_components_post_update_02_delete_alert_box_paragraph_bundle() {
  $storage = \Drupal::entityTypeManager()->getStorage('paragraphs_type');

  if ($storage) {
    $paragraph_bundle = $storage->load('alert_box');

    if ($paragraph_bundle) {
      $paragraph_bundle->delete();
    }
  }
}

User

// Get the current user
\Drupal\user\Entity\User::load(\Drupal::currentUser()->id());

// Get the current language code
\Drupal::languageManager()->getCurrentLanguage()->getId();

move this to a different file

// get the settings for a webform field inside a presave hook
function module_name_webform_submission_presave($submission) {
  $form = $submission->getWebform();
  $elements = $form->getElementsDecodedAndFlattened();  
  $elements['the_name_of_the_field_here'];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment