devel.module
Same filename in other branches
This module holds functions useful for Drupal development.
Please contribute!
Devel is allowed to use its own functions kpr(), dpm() and dpq() so disable the coding standard which gives warnings for using these. phpcs:disable Drupal.Functions.DiscouragedFunctions
File
View source
<?php
/**
* @file
* This module holds functions useful for Drupal development.
*
* Please contribute!
*
* Devel is allowed to use its own functions kpr(), dpm() and dpq() so disable
* the coding standard which gives warnings for using these.
* phpcs:disable Drupal.Functions.DiscouragedFunctions
*/
define('DEVEL_ERROR_HANDLER_NONE', 0);
define('DEVEL_ERROR_HANDLER_STANDARD', 1);
define('DEVEL_ERROR_HANDLER_BACKTRACE_KINT', 2);
define('DEVEL_ERROR_HANDLER_BACKTRACE_DPM', 4);
use Drupal\Core\Database\Query\AlterableInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Logger\RfcLogLevel;
use Drupal\Core\Menu\LocalTaskDefault;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Render\Element;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Drupal\Core\Utility\Error;
use Drupal\devel\EntityTypeInfo;
use Drupal\devel\ToolbarHandler;
/**
* Implements hook_help().
*/
function devel_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
case 'help.page.devel':
$output = '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('The Devel module provides a suite of modules containing fun for module developers and themers. For more information, see the <a href=":url">online documentation for the Devel module</a>.', [
':url' => 'https://www.drupal.org/docs/contributed-modules/devel',
]) . '</p>';
$output .= '<h3>' . t('Uses') . '</h3>';
$output .= '<dl>';
$output .= '<dt>' . t('Inspecting Service Container') . '</dt>';
$output .= '<dd>' . t('The module allows you to inspect Services and Parameters registered in the Service Container. You can see those informations on <a href=":url">Container info</a> page.', [
':url' => Url::fromRoute('devel.container_info.service')->toString(),
]) . '</dd>';
$output .= '<dt>' . t('Inspecting Routes') . '</dt>';
$output .= '<dd>' . t('The module allows you to inspect routes information, gathering all routing data from <em>.routing.yml</em> files and from classes which subscribe to the route build/alter events. You can see those informations on <a href=":url">Routes info</a> page.', [
':url' => Url::fromRoute('devel.route_info')->toString(),
]) . '</dd>';
$output .= '<dt>' . t('Inspecting Events') . '</dt>';
$output .= '<dd>' . t('The module allow you to inspect listeners registered in the event dispatcher. You can see those informations on <a href=":url">Events info</a> page.', [
':url' => Url::fromRoute('devel.event_info')->toString(),
]) . '</dd>';
$output .= '</dl>';
return $output;
case 'devel.container_info.service':
case 'devel.container_info.parameter':
return '<p>' . t('Displays Services and Parameters registered in the Service Container. For more informations on the Service Container, see the <a href=":url">Symfony online documentation</a>.', [
':url' => 'http://symfony.com/doc/current/service_container.html',
]) . '</p>';
case 'devel.route_info':
return '<p>' . t('Displays registered routes for the site. For a complete overview of the routing system, see the <a href=":url">online documentation</a>.', [
':url' => 'https://www.drupal.org/docs/drupal-apis/routing-system',
]) . '</p>';
case 'devel.event_info':
return '<p>' . t('Displays events and listeners registered in the event dispatcher. For a complete overview of the event system, see the <a href=":url">Symfony online documentation</a>.', [
':url' => 'http://symfony.com/doc/current/components/event_dispatcher.html',
]) . '</p>';
case 'devel.reinstall':
$output = '<p>' . t('<strong>Warning</strong> - will delete your module tables and configuration.') . '</p>';
$output .= '<p>' . t('Uninstall and then install the selected modules. <code>hook_uninstall()</code> and <code>hook_install()</code> will be executed and the schema version number will be set to the most recent update number.') . '</p>';
return $output;
case 'devel/session':
return '<p>' . t('Here are the contents of your <code>$_SESSION</code> variable.') . '</p>';
case 'devel.state_system_page':
return '<p>' . t('This is a list of state variables and their values. For more information read online documentation of <a href=":documentation">State API in Drupal 8</a>.', [
':documentation' => "https://www.drupal.org/docs/develop/drupal-apis/state-api",
]) . '</p>';
case 'devel.layout_info':
return '<p>' . t('Displays layouts available to the site. For a complete overview of the layout system, see the <a href=":url">Layout API documentation</a>.', [
':url' => 'https://www.drupal.org/docs/drupal-apis/layout-api',
]) . '</p>';
}
}
/**
* Implements hook_entity_type_alter().
*/
function devel_entity_type_alter(array &$entity_types) {
Drupal::service('class_resolver')->getInstanceFromDefinition(EntityTypeInfo::class)
->entityTypeAlter($entity_types);
}
/**
* Implements hook_entity_operation().
*/
function devel_entity_operation(EntityInterface $entity) {
return Drupal::service('class_resolver')->getInstanceFromDefinition(EntityTypeInfo::class)
->entityOperation($entity);
}
/**
* Implements hook_toolbar().
*/
function devel_toolbar() {
return Drupal::service('class_resolver')->getInstanceFromDefinition(ToolbarHandler::class)
->toolbar();
}
/**
* Implements hook_menu_links_discovered_alter().
*/
function devel_menu_links_discovered_alter(&$links) {
// Conditionally add the Layouts info menu link.
if (Drupal::moduleHandler()->moduleExists('layout_discovery')) {
$links['devel.layout_info'] = [
'title' => new TranslatableMarkup('Layouts Info'),
'route_name' => 'devel.layout_info',
'description' => new TranslatableMarkup('Overview of layouts available to the site.'),
'menu_name' => 'devel',
];
}
}
/**
* Implements hook_local_tasks_alter().
*/
function devel_local_tasks_alter(&$local_tasks) {
if (Drupal::moduleHandler()->moduleExists('toolbar')) {
$local_tasks['devel.toolbar.settings_form'] = [
'title' => 'Toolbar Settings',
'base_route' => 'devel.admin_settings',
'route_name' => 'devel.toolbar.settings_form',
'class' => LocalTaskDefault::class,
'options' => [],
];
}
}
/**
* Sets message.
*/
function devel_set_message($msg, $type = NULL) {
if (function_exists('drush_log')) {
drush_log($msg, $type);
}
else {
Drupal::messenger()->addMessage($msg, $type, TRUE);
}
}
/**
* Gets error handlers.
*/
function devel_get_handlers() {
$error_handlers = Drupal::config('devel.settings')->get('error_handlers');
if (!empty($error_handlers)) {
unset($error_handlers[DEVEL_ERROR_HANDLER_NONE]);
}
return $error_handlers;
}
/**
* Sets a new error handler or restores the prior one.
*/
function devel_set_handler($handlers) {
if (empty($handlers)) {
restore_error_handler();
}
elseif (count($handlers) == 1 && isset($handlers[DEVEL_ERROR_HANDLER_STANDARD])) {
// Do nothing.
}
else {
set_error_handler('backtrace_error_handler');
}
}
/**
* Displays backtrace showing the route of calls to the current error.
*
* @param int $error_level
* The level of the error raised.
* @param string $message
* The error message.
* @param string $filename
* (optional) The filename that the error was raised in.
* @param int $line
* (optional) The line number the error was raised at.
* @param array $context
* (optional) An array that points to the active symbol table at the point the
* error occurred.
*/
function backtrace_error_handler($error_level, $message, $filename = NULL, $line = NULL, ?array $context = NULL) {
// Hide stack trace and parameters from unqualified users.
if (!Drupal::currentUser()->hasPermission('access devel information')) {
// Do what core does in bootstrap.inc and errors.inc.
// (We need to duplicate the core code here rather than calling it
// to avoid having the backtrace_error_handler() on top of the call stack.)
if ($error_level & error_reporting()) {
$types = drupal_error_levels();
[
$severity_msg,
$severity_level,
] = $types[$error_level];
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
$caller = Error::getLastCaller($backtrace);
// We treat recoverable errors as fatal.
_drupal_log_error([
'%type' => isset($types[$error_level]) ? $severity_msg : 'Unknown error',
'@message' => $message,
'%function' => $caller['function'],
'%file' => $caller['file'],
'%line' => $caller['line'],
'severity_level' => $severity_level,
'backtrace' => $backtrace,
], $error_level == E_RECOVERABLE_ERROR);
}
return;
}
// Don't respond to the error if it was suppressed with a '@'.
if (error_reporting() == 0) {
return;
}
// Don't respond to warning caused by ourselves.
if (preg_match('#Cannot modify header information - headers already sent by \\([^\\)]*[/\\\\]devel[/\\\\]#', $message)) {
return;
}
if ($error_level & error_reporting()) {
// Only write each distinct NOTICE message once, as repeats do not give any
// further information and can choke the page output.
if ($error_level == E_NOTICE) {
static $written = [];
if (!empty($written[$line][$filename][$message])) {
return;
}
$written[$line][$filename][$message] = TRUE;
}
$types = drupal_error_levels();
[
$severity_msg,
$severity_level,
] = $types[$error_level];
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
$caller = Error::getLastCaller($backtrace);
$variables = [
'%type' => isset($types[$error_level]) ? $severity_msg : 'Unknown error',
'@message' => $message,
'%function' => $caller['function'],
'%file' => $caller['file'],
'%line' => $caller['line'],
];
$msg = t('%type: @message in %function (line %line of %file).', $variables);
// Show message if error_level is ERROR_REPORTING_DISPLAY_SOME or higher.
// (This is Drupal's error_level, which is different from $error_level,
// and we purposely ignore the difference between _SOME and _ALL,
// see #970688!)
if (Drupal::config('system.logging')->get('error_level') != 'hide') {
$error_handlers = devel_get_handlers();
if (!empty($error_handlers[DEVEL_ERROR_HANDLER_STANDARD])) {
Drupal::messenger()->addMessage($msg, $severity_level <= RfcLogLevel::NOTICE ? MessengerInterface::TYPE_ERROR : MessengerInterface::TYPE_WARNING, TRUE);
}
if (!empty($error_handlers[DEVEL_ERROR_HANDLER_BACKTRACE_KINT])) {
$input = ddebug_backtrace(return: TRUE, pop: 1);
print Drupal::service('devel.dumper')->dumpOrExport(input: $input, name: $msg);
}
if (!empty($error_handlers[DEVEL_ERROR_HANDLER_BACKTRACE_DPM])) {
$input = ddebug_backtrace(return: TRUE, pop: 1);
Drupal::service('devel.dumper')->message(input: $input, name: $msg, type: MessengerInterface::TYPE_WARNING);
}
}
Drupal::logger('php')->log($severity_level, $msg);
}
}
/**
* Implements hook_page_attachments_alter().
*/
function devel_page_attachments_alter(array &$attachments) : void {
if (Drupal::currentUser()->hasPermission('access devel information') && Drupal::config('devel.settings')->get('page_alter')) {
Drupal::service('devel.dumper')->message(input: $attachments, name: 'attachments');
}
}
/**
* Dumps information about a variable.
*
* Wrapper for DevelDumperManager::dump().
*
* @param mixed $input
* The variable to dump.
* @param string $name
* (optional) The label to output before variable, defaults to NULL.
* @param string $plugin_id
* (optional) The plugin ID, defaults to NULL.
*
* @see \Drupal\devel\DevelDumperManager::dump()
*/
function devel_dump($input, $name = NULL, $plugin_id = NULL) {
Drupal::service('devel.dumper')->dump($input, $name, $plugin_id);
}
/**
* Returns a string representation of a variable.
*
* Wrapper for DevelDumperManager::export().
*
* @param mixed $input
* The variable to dump.
* @param string $name
* (optional) The label to output before variable, defaults to NULL.
* @param string $plugin_id
* (optional) The plugin ID, defaults to NULL.
*
* @return string
* String representation of a variable.
*
* @see \Drupal\devel\DevelDumperManager::export()
*/
function devel_export($input, $name = NULL, $plugin_id = NULL) {
return Drupal::service('devel.dumper')->export($input, $name, $plugin_id);
}
/**
* Sets a message with a string representation of a variable.
*
* Wrapper for DevelDumperManager::message().
*
* @param mixed $input
* The variable to dump.
* @param string|null $name
* (optional) The label to output before variable, defaults to NULL.
* @param string $type
* (optional) The message's type. Defaults to 'status'.
* @param string|null $plugin_id
* (optional) The plugin ID, defaults to NULL.
*
* @see \Drupal\devel\DevelDumperManager::message()
*/
function devel_message(mixed $input, ?string $name = NULL, string $type = MessengerInterface::TYPE_STATUS, ?string $plugin_id = NULL) : void {
Drupal::service('devel.dumper')->message(input: $input, name: $name, type: $type, plugin_id: $plugin_id);
}
/**
* Logs a variable to a drupal_debug.txt in the site's temp directory.
*
* Wrapper for DevelDumperManager::debug().
*
* @param mixed $input
* The variable to log to the drupal_debug.txt log file.
* @param string $name
* (optional) If set, a label to output before $data in the log file.
* @param string $plugin_id
* (optional) The plugin ID, defaults to NULL.
*
* @return null|false
* Empty if successful, FALSE if the log file could not be written.
*
* @see \Drupal\devel\DevelDumperManager::debug()
*/
function devel_debug($input, $name = NULL, $plugin_id = NULL) {
return Drupal::service('devel.dumper')->debug($input, $name, $plugin_id);
}
/**
* Wrapper for DevelDumperManager::dump().
*
* Calls the http://www.firephp.org/ fb() function if it is found.
*
* @see \Drupal\devel\DevelDumperManager::dump()
*/
function dfb() {
$args = func_get_args();
Drupal::service('devel.dumper')->dump($args, NULL, 'firephp');
}
/**
* Wrapper for DevelDumperManager::dump().
*
* Calls dfb() to output a backtrace.
*
* @see \Drupal\devel\DevelDumperManager::dump()
*/
function dfbt($label) {
Drupal::service('devel.dumper')->dump(FirePHP::TRACE, $label, 'firephp');
}
if (!function_exists('ddm')) {
/**
* Wrapper for DevelDumperManager::debug() to replace previous dd function.
*
* @see \Drupal\devel\DevelDumperManager::debug()
*/
function ddm($data, $label = NULL) {
return Drupal::service('devel.dumper')->debug($data, $label, 'default');
}
}
if (!function_exists('kint')) {
/**
* Prints passed argument(s) using Kint debug tool.
*
* Wrapper for DevelDumperManager::dump().
*
* @see \Drupal\devel\DevelDumperManager::dump()
*/
function kint() {
$args = func_get_args();
if (count($args) == 1) {
// Pass a single argument directly, which works for any plug-in.
$args = $args[0];
$name = NULL;
}
else {
// Pass an array marked with a special name. The kint plug-in expands the
// arguments and prints each separately.
$name = '__ARGS__';
}
Drupal::service('devel.dumper')->dump($args, $name, 'kint');
}
}
if (!function_exists('ksm')) {
/**
* Prints passed argument(s) to the 'message' area of the page.
*
* Wrapper for DevelDumperManager::message().
*
* @see \Drupal\devel\DevelDumperManager::message()
*/
function ksm() : void {
$args = func_get_args();
if (count($args) == 1) {
// Pass a single argument directly, which works for any plug-in.
$args = $args[0];
$name = NULL;
}
else {
// Pass an array marked with a special name. The kint plug-in expands the
// arguments and prints each separately.
$name = '__ARGS__';
}
Drupal::service('devel.dumper')->message(input: $args, name: $name, plugin_id: 'kint');
}
}
/**
* Wrapper for DevelDumperManager::message().
*
* Prints a variable to the 'message' area of the page.
*
* Uses Drupal\Core\Messenger\MessengerInterface::addMessage()
*
* @param mixed $input
* An arbitrary value to output.
* @param string|null $name
* Optional name for identifying the output.
* @param string $type
* Optional message type see MessengerInterface, defaults to TYPE_STATUS.
* @param bool $load_dependencies
* Optional load dependencies if an entity is passed.
*
* @return mixed
* The unaltered input value.
*
* @see \Drupal\devel\DevelDumperManager::message()
*/
function dpm(mixed $input, ?string $name = NULL, string $type = MessengerInterface::TYPE_STATUS, bool $load_dependencies = FALSE) : mixed {
Drupal::service('devel.dumper')->message(input: $input, name: $name, type: $type, load_references: $load_dependencies);
return $input;
}
/**
* Wrapper for DevelDumperManager::message().
*
* Displays a Variable::export() variable to the 'message' area of the page.
*
* Uses Drupal\Core\Messenger\MessengerInterface::addMessage()
*
* @param mixed $input
* An arbitrary value to output.
* @param string|null $name
* Optional name for identifying the output.
* @param bool $load_dependencies
* Optional load dependencies if an entity is passed.
*
* @return mixed
* The unaltered input value.
*
* @see \Drupal\devel\DevelDumperManager::message()
*/
function dvm(mixed $input, ?string $name = NULL, bool $load_dependencies = FALSE) : mixed {
Drupal::service('devel.dumper')->message(input: $input, name: $name, plugin_id: 'drupal_variable', load_references: $load_dependencies);
return $input;
}
/**
* An alias for dpm(), for historic reasons.
*/
function dsm($input, $name = NULL, $load_dependencies = FALSE) {
Drupal::service('devel.dumper')->message(input: $input, name: $name, load_references: $load_dependencies);
}
/**
* Wrapper for DevelDumperManager::dumpOrExport().
*
* An alias for the 'devel.dumper' service. Saves carpal tunnel syndrome.
*
* @see \Drupal\devel\DevelDumperManager::dumpOrExport()
*/
function dpr($input, $export = FALSE, $name = NULL) {
return Drupal::service('devel.dumper')->dumpOrExport(input: $input, name: $name, export: $export, plugin_id: 'default');
}
/**
* Wrapper for DevelDumperManager::dumpOrExport().
*
* An alias for devel_dump(). Saves carpal tunnel syndrome.
*
* @see \Drupal\devel\DevelDumperManager::dumpOrExport()
*/
function kpr($input, $export = FALSE, $name = NULL) {
return Drupal::service('devel.dumper')->dumpOrExport(input: $input, name: $name, export: $export);
}
/**
* Wrapper for DevelDumperManager::dumpOrExport().
*
* Like dpr(), but uses Variable::export() instead.
*
* @see \Drupal\devel\DevelDumperManager::dumpOrExport()
*/
function dvr($input, $export = FALSE, $name = NULL) {
return Drupal::service('devel.dumper')->dumpOrExport(input: $input, name: $name, export: $export, plugin_id: 'drupal_variable');
}
/**
* Prints the arguments passed into the current function.
*/
function dargs($always = TRUE) {
static $printed;
if ($always || !$printed) {
$bt = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
print Drupal::service('devel.dumper')->dumpOrExport(input: $bt[1]['args']);
$printed = TRUE;
}
}
/**
* Prints a SQL string from a DBTNG Select object. Includes quoted arguments.
*
* @param object $query
* An object that implements the SelectInterface interface.
* @param bool $return
* Whether to return the string. Default is FALSE, meaning to print it
* and return $query instead.
* @param string $name
* Optional name for identifying the output.
*
* @return object|string
* The $query object, or the query string if $return was TRUE.
*/
function dpq($query, $return = FALSE, $name = NULL) {
if (Drupal::currentUser()->hasPermission('access devel information')) {
if (method_exists($query, 'preExecute')) {
$query->preExecute();
}
$sql = (string) $query;
$quoted = [];
$database = Drupal::database();
foreach ((array) $query->arguments() as $key => $val) {
$quoted[$key] = is_null($val) ? 'NULL' : $database->quote($val);
}
$sql = strtr($sql, $quoted);
if ($return) {
return $sql;
}
Drupal::service('devel.dumper')->message(input: $sql, name: $name);
}
return $return ? NULL : $query;
}
/**
* Prints a renderable array element to the screen using kprint_r().
*
* #pre_render and/or #post_render pass-through callback for kprint_r().
*
* @todo Investigate appending to #suffix.
* @todo Investigate label derived from #id, #title, #name, and #theme.
*/
function devel_render() {
$args = func_get_args();
// #pre_render and #post_render pass the rendered $element as last argument.
Drupal::service('devel.dumper')->dumpOrExport(input: end($args), export: FALSE);
// #pre_render and #post_render expect the first argument to be returned.
return reset($args);
}
/**
* Prints the function call stack.
*
* @param bool $return
* Pass TRUE to return the formatted backtrace rather than displaying it in
* the browser via kprint_r().
* @param int $pop
* How many items to pop from the top of the stack; useful when calling from
* an error handler.
* @param int $options
* Options (treated as a bit mask) to pass on to PHP's debug_backtrace().
*
* @return array|null
* The formatted backtrace, if requested, or NULL.
*
* @see http://php.net/manual/en/function.debug-backtrace.php
*/
function ddebug_backtrace(bool $return = FALSE, int $pop = 0, int $options = DEBUG_BACKTRACE_PROVIDE_OBJECT) : ?array {
if (Drupal::currentUser()->hasPermission('access devel information') === FALSE) {
return NULL;
}
$backtrace = debug_backtrace($options);
while ($pop-- > 0) {
array_shift($backtrace);
}
$counter = count($backtrace);
$path = $backtrace[$counter - 1]['file'];
$path = substr($path, 0, strlen($path) - 10);
$paths[$path] = strlen($path) + 1;
$paths[DRUPAL_ROOT] = strlen(DRUPAL_ROOT) + 1;
$nbsp = " ";
// Show message if error_level is ERROR_REPORTING_DISPLAY_SOME or higher.
// (This is Drupal's error_level, which is different from $error_level,
// and we purposely ignore the difference between _SOME and _ALL,
// see #970688!)
if (Drupal::config('system.logging')->get('error_level') === ERROR_REPORTING_HIDE) {
return NULL;
}
$nicetrace = [];
while (!empty($backtrace)) {
$call = [];
if (isset($backtrace[0]['file'])) {
$call['file'] = $backtrace[0]['file'];
foreach ($paths as $path => $len) {
if (strpos($backtrace[0]['file'], $path) === 0) {
$call['file'] = substr($backtrace[0]['file'], $len);
}
}
$call['file'] .= ':' . $backtrace[0]['line'];
}
if (isset($backtrace[1])) {
if (isset($backtrace[1]['class'])) {
$function = $backtrace[1]['class'] . $backtrace[1]['type'] . $backtrace[1]['function'] . '()';
}
else {
$function = $backtrace[1]['function'] . '()';
}
$backtrace[1] += [
'args' => [],
];
foreach ($backtrace[1]['args'] as $key => $value) {
$call['args'][$key] = $value;
}
}
else {
$function = 'main()';
$requestStack = Drupal::service('request_stack');
$call['args'] = $requestStack->getCurrentRequest()->query
->all();
}
$nicetrace[($counter <= 10 ? $nbsp : '') . --$counter . ': ' . $function] = $call;
array_shift($backtrace);
}
if ($return) {
return $nicetrace;
}
Drupal::service('devel.dumper')->dumpOrExport(input: $nicetrace, export: FALSE);
return NULL;
}
/**
* Implements hook_form_FORM_ID_alter().
*
* Adds mouse-over hints on the Permissions page to display
* language-independent machine names and module base names.
*
* @see \Drupal\user\Form\UserPermissionsForm::buildForm()
*/
function devel_form_user_admin_permissions_alter(&$form, FormStateInterface $form_state) {
if (Drupal::currentUser()->hasPermission('access devel information') && Drupal::config('devel.settings')->get('raw_names')) {
foreach (Element::children($form['permissions']) as $key) {
if (isset($form['permissions'][$key][0])) {
$form['permissions'][$key][0]['#wrapper_attributes']['title'] = $key;
}
elseif (isset($form['permissions'][$key]['description'])) {
$form['permissions'][$key]['description']['#wrapper_attributes']['title'] = $key;
}
}
}
}
/**
* Implements hook_form_FORM_ID_alter().
*
* Adds mouse-over hints on the Modules page to display module base names.
*
* @see \Drupal\system\Form\ModulesListForm::buildForm()
* @see theme_system_modules_details()
*/
function devel_form_system_modules_alter(&$form, FormStateInterface $form_state) {
if (Drupal::currentUser()->hasPermission('access devel information') && Drupal::config('devel.settings')->get('raw_names') && isset($form['modules']) && is_array($form['modules'])) {
foreach (Element::children($form['modules']) as $group) {
if (is_array($form['modules'][$group])) {
foreach (Element::children($form['modules'][$group]) as $key) {
if (isset($form['modules'][$group][$key]['name']['#markup'])) {
$form['modules'][$group][$key]['name']['#markup'] = '<span title="' . $key . '">' . $form['modules'][$group][$key]['name']['#markup'] . '</span>';
}
}
}
}
}
}
/**
* Implements hook_query_TAG_alter().
*
* Makes debugging entity query much easier.
*
* Example usage:
*
* @code
* $query = \Drupal::entityQuery('node');
* $query->condition('status', NODE_PUBLISHED);
* $query->addTag('debug');
* $query->execute();
* @endcode
*/
function devel_query_debug_alter(AlterableInterface $query) {
if (!$query->hasTag('debug-semaphore')) {
$query->addTag('debug-semaphore');
// @phpstan-ignore-next-line
dpq($query);
}
}
Functions
Title | Deprecated | Summary |
---|---|---|
backtrace_error_handler | Displays backtrace showing the route of calls to the current error. | |
dargs | Prints the arguments passed into the current function. | |
ddebug_backtrace | Prints the function call stack. | |
devel_debug | Logs a variable to a drupal_debug.txt in the site's temp directory. | |
devel_dump | Dumps information about a variable. | |
devel_entity_operation | Implements hook_entity_operation(). | |
devel_entity_type_alter | Implements hook_entity_type_alter(). | |
devel_export | Returns a string representation of a variable. | |
devel_form_system_modules_alter | Implements hook_form_FORM_ID_alter(). | |
devel_form_user_admin_permissions_alter | Implements hook_form_FORM_ID_alter(). | |
devel_get_handlers | Gets error handlers. | |
devel_help | Implements hook_help(). | |
devel_local_tasks_alter | Implements hook_local_tasks_alter(). | |
devel_menu_links_discovered_alter | Implements hook_menu_links_discovered_alter(). | |
devel_message | Sets a message with a string representation of a variable. | |
devel_page_attachments_alter | Implements hook_page_attachments_alter(). | |
devel_query_debug_alter | Implements hook_query_TAG_alter(). | |
devel_render | Prints a renderable array element to the screen using kprint_r(). | |
devel_set_handler | Sets a new error handler or restores the prior one. | |
devel_set_message | Sets message. | |
devel_toolbar | Implements hook_toolbar(). | |
dfb | Wrapper for DevelDumperManager::dump(). | |
dfbt | Wrapper for DevelDumperManager::dump(). | |
dpm | Wrapper for DevelDumperManager::message(). | |
dpq | Prints a SQL string from a DBTNG Select object. Includes quoted arguments. | |
dpr | Wrapper for DevelDumperManager::dumpOrExport(). | |
dsm | An alias for dpm(), for historic reasons. | |
dvm | Wrapper for DevelDumperManager::message(). | |
dvr | Wrapper for DevelDumperManager::dumpOrExport(). | |
kpr | Wrapper for DevelDumperManager::dumpOrExport(). |
Constants
Title | Deprecated | Summary |
---|---|---|
DEVEL_ERROR_HANDLER_BACKTRACE_DPM | ||
DEVEL_ERROR_HANDLER_BACKTRACE_KINT | ||
DEVEL_ERROR_HANDLER_NONE | @file This module holds functions useful for Drupal development. | |
DEVEL_ERROR_HANDLER_STANDARD |