get('mymodule.cron_last_run', REQUEST_TIME); db_delete('mymodule_table') ->condition('expires', $expires, '>=') ->execute(); \Drupal::state()->set('mymodule.cron_last_run', REQUEST_TIME); // Long-running operation example, leveraging a queue: // Fetch feeds from other sites. $result = db_query('SELECT * FROM {aggregator_feed} WHERE checked + refresh < :time AND refresh <> :never', array( ':time' => REQUEST_TIME, ':never' => AGGREGATOR_CLEAR_NEVER, )); $queue = \Drupal::queue('aggregator_feeds'); foreach ($result as $feed) { $queue->createItem($feed); } } /** * Alter available data types for typed data wrappers. * * @param array $data_types * An array of data type information. * * @see hook_data_type_info() */ function hook_data_type_info_alter(&$data_types) { $data_types['email']['class'] = '\Drupal\mymodule\Type\Email'; } /** * Alter cron queue information before cron runs. * * Called by \Drupal\Core\Cron to allow modules to alter cron queue settings * before any jobs are processesed. * * @param array $queues * An array of cron queue information. * * @see \Drupal\Core\QueueWorker\QueueWorkerInterface * @see \Drupal\Core\Annotation\QueueWorker * @see \Drupal\Core\Cron */ function hook_queue_info_alter(&$queues) { // This site has many feeds so let's spend 90 seconds on each cron run // updating feeds instead of the default 60. $queues['aggregator_feeds']['cron']['time'] = 90; } /** * Alters all the menu links discovered by the menu link plugin manager. * * @param array $links * The link definitions to be altered. * * @return array * An array of discovered menu links. Each link has a key that is the machine * name, which must be unique. By default, use the route name as the * machine name. In cases where multiple links use the same route name, such * as two links to the same page in different menus, or two links using the * same route name but different route parameters, the suggested machine name * patten is the route name followed by a dot and a unique suffix. For * example, an additional logout link might have a machine name of * user.logout.navigation, and default links provided to edit the article and * page content types could use machine names * entity.node_type.edit_form.article and entity.node_type.edit_form.page. * Since the machine name may be arbitrary, you should never write code that * assumes it is identical to the route name. * * The value corresponding to each machine name key is an associative array * that may contain the following key-value pairs: * - title: (required) The untranslated title of the menu link. * - description: The untranslated description of the link. * - route_name: (optional) The route name to be used to build the path. * Either a route_name or a link_path must be provided. * - route_parameters: (optional) The route parameters to build the path. * - link_path: (optional) If you have an external link use link_path instead * of providing a route_name. * - parent: (optional) The machine name of the link that is this link's menu * parent. * - weight: (optional) An integer that determines the relative position of * items in the menu; higher-weighted items sink. Defaults to 0. Menu items * with the same weight are ordered alphabetically. * - menu_name: (optional) The machine name of a menu to put the link in, if * not the default Tools menu. * - expanded: (optional) If set to TRUE, and if a menu link is provided for * this menu item (as a result of other properties), then the menu link is * always expanded, equivalent to its 'always expanded' checkbox being set * in the UI. * - options: (optional) An array of options to be passed to _l() when * generating a link from this menu item. * * @ingroup menu */ function hook_menu_links_discovered_alter(&$links) { // Change the weight and title of the user.logout link. $links['user.logout']['weight'] = -10; $links['user.logout']['title'] = 'Logout'; } /** * Alter tabs and actions displayed on the page before they are rendered. * * This hook is invoked by menu_local_tasks(). The system-determined tabs and * actions are passed in by reference. Additional tabs or actions may be added. * * Each tab or action is an associative array containing: * - #theme: The theme function to use to render. * - #link: An associative array containing: * - title: The localized title of the link. * - href: The system path to link to. * - localized_options: An array of options to pass to _l(). * - #weight: The link's weight compared to other links. * - #active: Whether the link should be marked as 'active'. * * @param array $data * An associative array containing: * - actions: A list of of actions keyed by their href, each one being an * associative array as described above. * - tabs: A list of (up to 2) tab levels that contain a list of of tabs keyed * by their href, each one being an associative array as described above. * @param string $route_name * The route name of the page. */ function hook_menu_local_tasks(&$data, $route_name) { // Add an action linking to node/add to all pages. $data['actions']['node/add'] = array( '#theme' => 'menu_local_action', '#link' => array( 'title' => t('Add content'), 'url' => Url::fromRoute('node.add_page'), 'localized_options' => array( 'attributes' => array( 'title' => t('Add content'), ), ), ), ); // Add a tab linking to node/add to all pages. $data['tabs'][0]['node/add'] = array( '#theme' => 'menu_local_task', '#link' => array( 'title' => t('Example tab'), 'url' => Url::fromRoute('node.add_page'), 'localized_options' => array( 'attributes' => array( 'title' => t('Add content'), ), ), ), ); } /** * Alter tabs and actions displayed on the page before they are rendered. * * This hook is invoked by menu_local_tasks(). The system-determined tabs and * actions are passed in by reference. Existing tabs or actions may be altered. * * @param array $data * An associative array containing tabs and actions. See * hook_menu_local_tasks() for details. * @param string $route_name * The route name of the page. * * @see hook_menu_local_tasks() * * @ingroup menu */ function hook_menu_local_tasks_alter(&$data, $route_name) { } /** * Alter local actions plugins. * * @param array $local_actions * The array of local action plugin definitions, keyed by plugin ID. * * @see \Drupal\Core\Menu\LocalActionInterface * @see \Drupal\Core\Menu\LocalActionManager * * @ingroup menu */ function hook_menu_local_actions_alter(&$local_actions) { } /** * Alter local tasks plugins. * * @param array $local_tasks * The array of local tasks plugin definitions, keyed by plugin ID. * * @see \Drupal\Core\Menu\LocalTaskInterface * @see \Drupal\Core\Menu\LocalTaskManager */ function hook_local_tasks_alter(&$local_tasks) { // Remove a specified local task plugin. unset($local_tasks['example_plugin_id']); } /** * Alter contextual links before they are rendered. * * This hook is invoked by * \Drupal\Core\Menu\ContextualLinkManager::getContextualLinkPluginsByGroup(). * The system-determined contextual links are passed in by reference. Additional * links may be added and existing links can be altered. * * Each contextual link contains the following entries: * - title: The localized title of the link. * - route_name: The route name of the link. * - route_parameters: The route parameters of the link. * - localized_options: An array of options to pass to _url(). * - (optional) weight: The weight of the link, which is used to sort the links. * * * @param array $links * An associative array containing contextual links for the given $group, * as described above. The array keys are used to build CSS class names for * contextual links and must therefore be unique for each set of contextual * links. * @param string $group * The group of contextual links being rendered. * @param array $route_parameters. * The route parameters passed to each route_name of the contextual links. * For example: * @code * array('node' => $node->id()) * @endcode * * @see \Drupal\Core\Menu\ContextualLinkManager * * @ingroup menu */ function hook_contextual_links_alter(array &$links, $group, array $route_parameters) { if ($group == 'menu') { // Dynamically use the menu name for the title of the menu_edit contextual // link. $menu = \Drupal::entityManager()->getStorage('menu')->load($route_parameters['menu']); $links['menu_edit']['title'] = t('Edit menu: !label', array('!label' => $menu->label())); } } /** * Alter the plugin definition of contextual links. * * @param array $contextual_links * An array of contextual_links plugin definitions, keyed by contextual link * ID. Each entry contains the following keys: * - title: The displayed title of the link * - route_name: The route_name of the contextual link to be displayed * - group: The group under which the contextual links should be added to. * Possible values are e.g. 'node' or 'menu'. * * @see \Drupal\Core\Menu\ContextualLinkManager */ function hook_contextual_links_plugins_alter(array &$contextual_links) { $contextual_links['menu_edit']['title'] = 'Edit the menu'; } /** * Alter an email message created with MailManagerInterface->mail(). * * hook_mail_alter() allows modification of email messages created and sent * with MailManagerInterface->mail(). Usage examples include adding and/or * changing message text, message fields, and message headers. * * Email messages sent using functions other than MailManagerInterface->mail() * will not invoke hook_mail_alter(). For example, a contributed module directly * calling the MailInterface->mail() or PHP mail() function will not invoke * this hook. All core modules use MailManagerInterface->mail() for messaging, * it is best practice but not mandatory in contributed modules. * * @param $message * An array containing the message data. Keys in this array include: * - 'id': * The MailManagerInterface->mail() id of the message. Look at module source * code or MailManagerInterface->mail() for possible id values. * - 'to': * The address or addresses the message will be sent to. The * formatting of this string must comply with RFC 2822. * - 'from': * The address the message will be marked as being from, which is * either a custom address or the site-wide default email address. * - 'subject': * Subject of the email to be sent. This must not contain any newline * characters, or the email may not be sent properly. * - 'body': * An array of strings containing the message text. The message body is * created by concatenating the individual array strings into a single text * string using "\n\n" as a separator. * - 'headers': * Associative array containing mail headers, such as From, Sender, * MIME-Version, Content-Type, etc. * - 'params': * An array of optional parameters supplied by the caller of * MailManagerInterface->mail() that is used to build the message before * hook_mail_alter() is invoked. * - 'language': * The language object used to build the message before hook_mail_alter() * is invoked. * - 'send': * Set to FALSE to abort sending this email message. * * @see \Drupal\Core\Mail\MailManagerInterface::mail() */ function hook_mail_alter(&$message) { if ($message['id'] == 'modulename_messagekey') { if (!example_notifications_optin($message['to'], $message['id'])) { // If the recipient has opted to not receive such messages, cancel // sending. $message['send'] = FALSE; return; } $message['body'][] = "--\nMail sent out from " . \Drupal::config('system.site')->get('name'); } } /** * Perform alterations to the breadcrumb built by the BreadcrumbManager. * * @param array $breadcrumb * An array of breadcrumb link a tags, returned by the breadcrumb manager * build method, for example * @code * array('Home'); * @endcode * @param \Drupal\Core\Routing\RouteMatchInterface $route_match * The current route match. * @param array $context * May include the following key: * - builder: the instance of * \Drupal\Core\Breadcrumb\BreadcrumbBuilderInterface that constructed this * breadcrumb, or NULL if no builder acted based on the current attributes. */ function hook_system_breadcrumb_alter(array &$breadcrumb, \Drupal\Core\Routing\RouteMatchInterface $route_match, array $context) { // Add an item to the end of the breadcrumb. $breadcrumb[] = Drupal::l(t('Text'), 'example_route_name'); } /** * Prepares a message based on parameters; * * This hook is called from MailManagerInterface->mail(). Note that hook_mail(), * unlike hook_mail_alter(), is only called on the $module argument to * MailManagerInterface->mail(), not all modules. * * @param $key * An identifier of the mail. * @param $message * An array to be filled in. Elements in this array include: * - id: An ID to identify the mail sent. Look at module source code or * MailManagerInterface->mail() for possible id values. * - to: The address or addresses the message will be sent to. The * formatting of this string must comply with RFC 2822. * - subject: Subject of the email to be sent. This must not contain any * newline characters, or the mail may not be sent properly. * MailManagerInterface->mail() sets this to an empty * string when the hook is invoked. * - body: An array of lines containing the message to be sent. Drupal will * format the correct line endings for you. MailManagerInterface->mail() * sets this to an empty array when the hook is invoked. * - from: The address the message will be marked as being from, which is * set by MailManagerInterface->mail() to either a custom address or the * site-wide default email address when the hook is invoked. * - headers: Associative array containing mail headers, such as From, * Sender, MIME-Version, Content-Type, etc. * MailManagerInterface->mail() pre-fills several headers in this array. * @param $params * An array of parameters supplied by the caller of * MailManagerInterface->mail(). * * @see \Drupal\Core\Mail\MailManagerInterface->mail() */ function hook_mail($key, &$message, $params) { $account = $params['account']; $context = $params['context']; $variables = array( '%site_name' => \Drupal::config('system.site')->get('name'), '%username' => user_format_name($account), ); if ($context['hook'] == 'taxonomy') { $entity = $params['entity']; $vocabulary = entity_load('taxonomy_vocabulary', $entity->id()); $variables += array( '%term_name' => $entity->name, '%term_description' => $entity->description, '%term_id' => $entity->id(), '%vocabulary_name' => $vocabulary->label(), '%vocabulary_description' => $vocabulary->getDescription(), '%vocabulary_id' => $vocabulary->id(), ); } // Node-based variable translation is only available if we have a node. if (isset($params['node'])) { /** @var \Drupal\node\NodeInterface $node */ $node = $params['node']; $variables += array( '%uid' => $node->getOwnerId(), '%url' => $node->url('canonical', array('absolute' => TRUE)), '%node_type' => node_get_type_label($node), '%title' => $node->getTitle(), '%teaser' => $node->teaser, '%body' => $node->body, ); } $subject = strtr($context['subject'], $variables); $body = strtr($context['message'], $variables); $message['subject'] .= str_replace(array("\r", "\n"), '', $subject); $message['body'][] = MailFormatHelper::htmlToText($body); } /** * Flush all persistent and static caches. * * This hook asks your module to clear all of its static caches, * in order to ensure a clean environment for subsequently * invoked data rebuilds. * * Do NOT use this hook for rebuilding information. Only use it to flush custom * caches. * * Static caches using drupal_static() do not need to be reset manually. * However, all other static variables that do not use drupal_static() must be * manually reset. * * This hook is invoked by drupal_flush_all_caches(). It runs before module data * is updated and before hook_rebuild(). * * @see drupal_flush_all_caches() * @see hook_rebuild() */ function hook_cache_flush() { if (defined('MAINTENANCE_MODE') && MAINTENANCE_MODE == 'update') { _update_cache_clear(); } } /** * Rebuild data based upon refreshed caches. * * This hook allows your module to rebuild its data based on the latest/current * module data. It runs after hook_cache_flush() and after all module data has * been updated. * * This hook is only invoked after the system has been completely cleared; * i.e., all previously cached data is known to be gone and every API in the * system is known to return current information, so your module can safely rely * on all available data to rebuild its own. * * @see hook_cache_flush() * @see drupal_flush_all_caches() */ function hook_rebuild() { $themes = list_themes(); foreach ($themes as $theme) { _block_rehash($theme->getName()); } } /** * Define the current version of the database schema. * * A Drupal schema definition is an array structure representing one or more * tables and their related keys and indexes. A schema is defined by * hook_schema() which must live in your module's .install file. * * The tables declared by this hook will be automatically created when the * module is installed, and removed when the module is uninstalled. This happens * before hook_install() is invoked, and after hook_uninstall() is invoked, * respectively. * * By declaring the tables used by your module via an implementation of * hook_schema(), these tables will be available on all supported database * engines. You don't have to deal with the different SQL dialects for table * creation and alteration of the supported database engines. * * See the Schema API Handbook at http://drupal.org/node/146843 for details on * schema definition structures. * * @return array * A schema definition structure array. For each element of the * array, the key is a table name and the value is a table structure * definition. * * @see hook_schema_alter() * * @ingroup schemaapi */ function hook_schema() { $schema['node'] = array( // Example (partial) specification for table "node". 'description' => 'The base table for nodes.', 'fields' => array( 'nid' => array( 'description' => 'The primary identifier for a node.', 'type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, ), 'vid' => array( 'description' => 'The current {node_field_revision}.vid version identifier.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, ), 'type' => array( 'description' => 'The type of this node.', 'type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => '', ), 'title' => array( 'description' => 'The title of this node, always treated as non-markup plain text.', 'type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', ), ), 'indexes' => array( 'node_changed' => array('changed'), 'node_created' => array('created'), ), 'unique keys' => array( 'nid_vid' => array('nid', 'vid'), 'vid' => array('vid'), ), 'foreign keys' => array( 'node_revision' => array( 'table' => 'node_field_revision', 'columns' => array('vid' => 'vid'), ), 'node_author' => array( 'table' => 'users', 'columns' => array('uid' => 'uid'), ), ), 'primary key' => array('nid'), ); return $schema; } /** * Perform alterations to existing database schemas. * * When a module modifies the database structure of another module (by * changing, adding or removing fields, keys or indexes), it should * implement hook_schema_alter() to update the default $schema to take its * changes into account. * * See hook_schema() for details on the schema definition structure. * * @param $schema * Nested array describing the schemas for all modules. * * @ingroup schemaapi */ function hook_schema_alter(&$schema) { // Add field to existing schema. $schema['users']['fields']['timezone_id'] = array( 'type' => 'int', 'not null' => TRUE, 'default' => 0, 'description' => 'Per-user timezone configuration.', ); } /** * Perform alterations to a structured query. * * Structured (aka dynamic) queries that have tags associated may be altered by any module * before the query is executed. * * @param $query * A Query object describing the composite parts of a SQL query. * * @see hook_query_TAG_alter() * @see node_query_node_access_alter() * @see AlterableInterface * @see SelectInterface */ function hook_query_alter(Drupal\Core\Database\Query\AlterableInterface $query) { if ($query->hasTag('micro_limit')) { $query->range(0, 2); } } /** * Perform alterations to a structured query for a given tag. * * @param $query * An Query object describing the composite parts of a SQL query. * * @see hook_query_alter() * @see node_query_node_access_alter() * @see AlterableInterface * @see SelectInterface */ function hook_query_TAG_alter(Drupal\Core\Database\Query\AlterableInterface $query) { // Skip the extra expensive alterations if site has no node access control modules. if (!node_access_view_all_nodes()) { // Prevent duplicates records. $query->distinct(); // The recognized operations are 'view', 'update', 'delete'. if (!$op = $query->getMetaData('op')) { $op = 'view'; } // Skip the extra joins and conditions for node admins. if (!\Drupal::currentUser()->hasPermission('bypass node access')) { // The node_access table has the access grants for any given node. $access_alias = $query->join('node_access', 'na', '%alias.nid = n.nid'); $or = db_or(); // If any grant exists for the specified user, then user has access to the node for the specified operation. foreach (node_access_grants($op, $query->getMetaData('account')) as $realm => $gids) { foreach ($gids as $gid) { $or->condition(db_and() ->condition($access_alias . '.gid', $gid) ->condition($access_alias . '.realm', $realm) ); } } if (count($or->conditions())) { $query->condition($or); } $query->condition($access_alias . 'grant_' . $op, 1, '>='); } } } /** * Alter the list of mail backend plugin definitions. * * @param array $info * The mail backend plugin definitions to be altered. * * @see \Drupal\Core\Annotation\Mail * @see \Drupal\Core\Mail\MailManager */ function hook_mail_backend_info_alter(&$info) { unset($info['test_mail_collector']); } /** * Alters theme operation links. * * @param $theme_groups * An associative array containing groups of themes. * * @see system_themes_page() */ function hook_system_themes_page_alter(&$theme_groups) { foreach ($theme_groups as $state => &$group) { foreach ($theme_groups[$state] as &$theme) { // Add a foo link to each list of theme operations. $theme->operations[] = array( 'title' => t('Foo'), 'url' => Url::fromRoute('system.themes_page'), 'query' => array('theme' => $theme->getName()) ); } } } /** * Provide replacement values for placeholder tokens. * * This hook is invoked when someone calls * \Drupal\Core\Utility\Token::replace(). That function first scans the text for * [type:token] patterns, and splits the needed tokens into groups by type. * Then hook_tokens() is invoked on each token-type group, allowing your module * to respond by providing replacement text for any of the tokens in the group * that your module knows how to process. * * A module implementing this hook should also implement hook_token_info() in * order to list its available tokens on editing screens. * * @param $type * The machine-readable name of the type (group) of token being replaced, such * as 'node', 'user', or another type defined by a hook_token_info() * implementation. * @param $tokens * An array of tokens to be replaced. The keys are the machine-readable token * names, and the values are the raw [type:token] strings that appeared in the * original text. * @param $data * (optional) An associative array of data objects to be used when generating * replacement values, as supplied in the $data parameter to * \Drupal\Core\Utility\Token::replace(). * @param $options * (optional) An associative array of options for token replacement; see * \Drupal\Core\Utility\Token::replace() for possible values. * * @return * An associative array of replacement values, keyed by the raw [type:token] * strings from the original text. * * @see hook_token_info() * @see hook_tokens_alter() */ function hook_tokens($type, $tokens, array $data = array(), array $options = array()) { $token_service = \Drupal::token(); $url_options = array('absolute' => TRUE); if (isset($options['langcode'])) { $url_options['language'] = language_load($options['langcode']); $langcode = $options['langcode']; } else { $langcode = NULL; } $sanitize = !empty($options['sanitize']); $replacements = array(); if ($type == 'node' && !empty($data['node'])) { /** @var \Drupal\node\NodeInterface $node */ $node = $data['node']; foreach ($tokens as $name => $original) { switch ($name) { // Simple key values on the node. case 'nid': $replacements[$original] = $node->nid; break; case 'title': $replacements[$original] = $sanitize ? String::checkPlain($node->getTitle()) : $node->getTitle(); break; case 'edit-url': $replacements[$original] = $node->url('edit-form', $url_options); break; // Default values for the chained tokens handled below. case 'author': $account = $node->getOwner() ? $node->getOwner() : user_load(0); $replacements[$original] = $sanitize ? String::checkPlain($account->label()) : $account->label(); break; case 'created': $replacements[$original] = format_date($node->getCreatedTime(), 'medium', '', NULL, $langcode); break; } } if ($author_tokens = $token_service->findWithPrefix($tokens, 'author')) { $replacements += $token_service->generate('user', $author_tokens, array('user' => $node->getOwner()), $options); } if ($created_tokens = $token_service->findWithPrefix($tokens, 'created')) { $replacements += $token_service->generate('date', $created_tokens, array('date' => $node->getCreatedTime()), $options); } } return $replacements; } /** * Alter replacement values for placeholder tokens. * * @param $replacements * An associative array of replacements returned by hook_tokens(). * @param $context * The context in which hook_tokens() was called. An associative array with * the following keys, which have the same meaning as the corresponding * parameters of hook_tokens(): * - 'type' * - 'tokens' * - 'data' * - 'options' * * @see hook_tokens() */ function hook_tokens_alter(array &$replacements, array $context) { $options = $context['options']; if (isset($options['langcode'])) { $url_options['language'] = language_load($options['langcode']); $langcode = $options['langcode']; } else { $langcode = NULL; } if ($context['type'] == 'node' && !empty($context['data']['node'])) { $node = $context['data']['node']; // Alter the [node:title] token, and replace it with the rendered content // of a field (field_title). if (isset($context['tokens']['title'])) { $title = $node->field_title->view('default'); $replacements[$context['tokens']['title']] = drupal_render($title); } } } /** * Provide information about available placeholder tokens and token types. * * Tokens are placeholders that can be put into text by using the syntax * [type:token], where type is the machine-readable name of a token type, and * token is the machine-readable name of a token within this group. This hook * provides a list of types and tokens to be displayed on text editing screens, * so that people editing text can see what their token options are. * * The actual token replacement is done by * \Drupal\Core\Utility\Token::replace(), which invokes hook_tokens(). Your * module will need to implement that hook in order to generate token * replacements from the tokens defined here. * * @return * An associative array of available tokens and token types. The outer array * has two components: * - types: An associative array of token types (groups). Each token type is * an associative array with the following components: * - name: The translated human-readable short name of the token type. * - description (optional): A translated longer description of the token * type. * - needs-data: The type of data that must be provided to * \Drupal\Core\Utility\Token::replace() in the $data argument (i.e., the * key name in $data) in order for tokens of this type to be used in the * $text being processed. For instance, if the token needs a node object, * 'needs-data' should be 'node', and to use this token in * \Drupal\Core\Utility\Token::replace(), the caller needs to supply a * node object as $data['node']. Some token data can also be supplied * indirectly; for instance, a node object in $data supplies a user object * (the author of the node), allowing user tokens to be used when only * a node data object is supplied. * - tokens: An associative array of tokens. The outer array is keyed by the * group name (the same key as in the types array). Within each group of * tokens, each token item is keyed by the machine name of the token, and * each token item has the following components: * - name: The translated human-readable short name of the token. * - description (optional): A translated longer description of the token. * - type (optional): A 'needs-data' data type supplied by this token, which * should match a 'needs-data' value from another token type. For example, * the node author token provides a user object, which can then be used * for token replacement data in \Drupal\Core\Utility\Token::replace() * without having to supply a separate user object. * * @see hook_token_info_alter() * @see hook_tokens() */ function hook_token_info() { $type = array( 'name' => t('Nodes'), 'description' => t('Tokens related to individual nodes.'), 'needs-data' => 'node', ); // Core tokens for nodes. $node['nid'] = array( 'name' => t("Node ID"), 'description' => t("The unique ID of the node."), ); $node['title'] = array( 'name' => t("Title"), ); $node['edit-url'] = array( 'name' => t("Edit URL"), 'description' => t("The URL of the node's edit page."), ); // Chained tokens for nodes. $node['created'] = array( 'name' => t("Date created"), 'type' => 'date', ); $node['author'] = array( 'name' => t("Author"), 'type' => 'user', ); return array( 'types' => array('node' => $type), 'tokens' => array('node' => $node), ); } /** * Alter the metadata about available placeholder tokens and token types. * * @param $data * The associative array of token definitions from hook_token_info(). * * @see hook_token_info() */ function hook_token_info_alter(&$data) { // Modify description of node tokens for our site. $data['tokens']['node']['nid'] = array( 'name' => t("Node ID"), 'description' => t("The unique ID of the article."), ); $data['tokens']['node']['title'] = array( 'name' => t("Title"), 'description' => t("The title of the article."), ); // Chained tokens for nodes. $data['tokens']['node']['created'] = array( 'name' => t("Date created"), 'description' => t("The date the article was posted."), 'type' => 'date', ); } /** * Alter the default country list. * * @param $countries * The associative array of countries keyed by two-letter country code. * * @see \Drupal\Core\Locale\CountryManager::getList(). */ function hook_countries_alter(&$countries) { // Elbonia is now independent, so add it to the country list. $countries['EB'] = 'Elbonia'; } /** * Alter the parameters for links. * * @param array $variables * An associative array of variables defining a link. The link may be either a * "route link" using \Drupal\Core\Utility\LinkGenerator::link(), which is * exposed as the 'link_generator' service or a link generated by _l(). If the * link is a "route link", 'route_name' will be set, otherwise 'path' will be * set. The following keys can be altered: * - text: The link text for the anchor tag as a translated string. * - url_is_active: Whether or not the link points to the currently active * URL. * - url: The \Drupal\Core\Url object. * - options: An associative array of additional options that will be passed * to either \Drupal\Core\Routing\UrlGenerator::generateFromPath() or * \Drupal\Core\Routing\UrlGenerator::generateFromRoute() to generate the * href attribute for this link, and also used when generating the link. * Defaults to an empty array. It may contain the following elements: * - 'query': An array of query key/value-pairs (without any URL-encoding) to * append to the URL. * - absolute: Whether to force the output to be an absolute link (beginning * with http:). Useful for links that will be displayed outside the site, * such as in an RSS feed. Defaults to FALSE. * - language: An optional language object. May affect the rendering of * the anchor tag, such as by adding a language prefix to the path. * - attributes: An associative array of HTML attributes to apply to the * anchor tag. If element 'class' is included, it must be an array; 'title' * must be a string; other elements are more flexible, as they just need * to work as an argument for the constructor of the class * Drupal\Core\Template\Attribute($options['attributes']). * - html: Whether or not HTML should be allowed as the link text. If FALSE, * the text will be run through * \Drupal\Component\Utility\String::checkPlain() before being output. * * @see \Drupal\Core\Routing\UrlGenerator::generateFromPath() * @see \Drupal\Core\Routing\UrlGenerator::generateFromRoute() */ function hook_link_alter(&$variables) { // Add a warning to the end of route links to the admin section. if (isset($variables['route_name']) && strpos($variables['route_name'], 'admin') !== FALSE) { $variables['text'] .= ' (Warning!)'; } } /** * Alter the configuration synchronization steps. * * @param array $sync_steps * A one-dimensional array of \Drupal\Core\Config\ConfigImporter method names * or callables that are invoked to complete the import, in the order that * they will be processed. Each callable item defined in $sync_steps should * either be a global function or a public static method. The callable should * accept a $context array by reference. For example: * * function _additional_configuration_step(&$context) { * // Do stuff. * // If finished set $context['finished'] = 1. * } * * For more information on creating batches, see the * @link batch Batch operations @endlink documentation. * * @see callback_batch_operation() * @see \Drupal\Core\Config\ConfigImporter::initialize() */ function hook_config_import_steps_alter(&$sync_steps, \Drupal\Core\Config\ConfigImporter $config_importer) { $deletes = $config_importer->getUnprocessedConfiguration('delete'); if (isset($deletes['field.storage.node.body'])) { $sync_steps[] = '_additional_configuration_step'; } } /** * Alter config typed data definitions. * * For example you can alter the typed data types representing each * configuration schema type to change default labels or form element renderers * used for configuration translation. * * It is strongly advised not to use this hook to add new data types or to * change the structure of existing ones. Keep in mind that there are tools * that may use the configuration schema for static analysis of configuration * files, like the string extractor for the localization system. Such systems * won't work with dynamically defined configuration schemas. * * For adding new data types use configuration schema YAML files instead. * * @param $definitions * Associative array of configuration type definitions keyed by schema type * names. The elements are themselves array with information about the type. */ function hook_config_schema_info_alter(&$definitions) { // Enhance the text and date type definitions with classes to generate proper // form elements in ConfigTranslationFormBase. Other translatable types will // appear as a one line textfield. $definitions['text']['form_element_class'] = '\Drupal\config_translation\FormElement\Textarea'; $definitions['date_format']['form_element_class'] = '\Drupal\config_translation\FormElement\DateFormat'; } /** * @} End of "addtogroup hooks". */