Esempio n. 1
0
 /**
  * {@inheritdoc}
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $io = new DrupalStyle($input, $output);
     $modules = $input->getArgument('module');
     if (!$this->lock->acquire('cron', 900.0)) {
         $io->warning($this->trans('commands.cron.execute.messages.lock'));
         return 1;
     }
     if (in_array('all', $modules)) {
         $modules = $this->moduleHandler->getImplementations('cron');
     }
     foreach ($modules as $module) {
         if (!$this->moduleHandler->implementsHook($module, 'cron')) {
             $io->warning(sprintf($this->trans('commands.cron.execute.messages.module-invalid'), $module));
             continue;
         }
         try {
             $io->info(sprintf($this->trans('commands.cron.execute.messages.executing-cron'), $module));
             $this->moduleHandler->invoke($module, 'cron');
         } catch (\Exception $e) {
             watchdog_exception('cron', $e);
             $io->error($e->getMessage());
         }
     }
     $this->state->set('system.cron_last', REQUEST_TIME);
     $this->lock->release('cron');
     $this->chainQueue->addCommand('cache:rebuild', ['cache' => 'all']);
     $io->success($this->trans('commands.cron.execute.messages.success'));
     return 0;
 }
Esempio n. 2
0
 /**
  * {@inheritdoc}
  */
 public function listTopics()
 {
     $topics = [];
     foreach ($this->moduleHandler->getImplementations('help') as $module) {
         $title = $this->moduleHandler->getName($module);
         $topics[$title] = Link::createFromRoute($title, 'help.page', ['name' => $module]);
     }
     // Sort topics by title, which is the array key above.
     ksort($topics);
     return $topics;
 }
 /**
  * Implements Drupal\Component\Plugin\Discovery\DiscoveryInterface::getDefinitions().
  */
 public function getDefinitions()
 {
     $definitions = array();
     foreach ($this->moduleHandler->getImplementations($this->hook) as $module) {
         $result = $this->moduleHandler->invoke($module, $this->hook);
         foreach ($result as $plugin_id => $definition) {
             $definition['module'] = $module;
             $definitions[$plugin_id] = $definition;
         }
     }
     return $definitions;
 }
Esempio n. 4
0
 /**
  * {@inheritdoc}
  */
 protected function setUp()
 {
     parent::setUp();
     $this->moduleHandler = $this->prophesize(ModuleHandlerInterface::class);
     $this->moduleHandler->getImplementations('entity_type_build')->willReturn([]);
     $this->moduleHandler->alter('entity_type', Argument::type('array'))->willReturn(NULL);
     $this->cacheBackend = $this->prophesize(CacheBackendInterface::class);
     $this->translationManager = $this->prophesize(TranslationInterface::class);
     $this->entityTypeManager = new TestEntityTypeManager(new \ArrayObject(), $this->moduleHandler->reveal(), $this->cacheBackend->reveal(), $this->translationManager->reveal(), $this->getClassResolverStub());
     $this->discovery = $this->prophesize(DiscoveryInterface::class);
     $this->entityTypeManager->setDiscovery($this->discovery->reveal());
 }
Esempio n. 5
0
 /**
  * Gets all data invoked by hook_views_data().
  *
  * This is requested from the cache before being rebuilt.
  *
  * @return array
  *   An array of all data.
  */
 protected function getData()
 {
     $this->fullyLoaded = TRUE;
     if ($data = $this->cacheGet($this->baseCid)) {
         return $data->data;
     } else {
         $modules = $this->moduleHandler->getImplementations('views_data');
         $data = [];
         foreach ($modules as $module) {
             $views_data = $this->moduleHandler->invoke($module, 'views_data');
             // Set the provider key for each base table.
             foreach ($views_data as &$table) {
                 if (isset($table['table']) && !isset($table['table']['provider'])) {
                     $table['table']['provider'] = $module;
                 }
             }
             $data = NestedArray::mergeDeep($data, $views_data);
         }
         $this->moduleHandler->alter('views_data', $data);
         $this->processEntityTypes($data);
         // Keep a record with all data.
         $this->cacheSet($this->baseCid, $data);
         return $data;
     }
 }
Esempio n. 6
0
 /**
  * {@inheritdoc}
  */
 public function isReserved($alias, $source, $langcode = LanguageInterface::LANGCODE_NOT_SPECIFIED)
 {
     // Check if this alias already exists.
     if ($existing_source = $this->aliasManager->getPathByAlias($alias, $langcode)) {
         if ($existing_source != $alias) {
             // If it is an alias for the provided source, it is allowed to keep using
             // it. If not, then it is reserved.
             return $existing_source != $source;
         }
     }
     // Then check if there is a route with the same path.
     if ($this->isRoute($alias)) {
         return TRUE;
     }
     // Finally check if any other modules have reserved the alias.
     $args = array($alias, $source, $langcode);
     $implementations = $this->moduleHandler->getImplementations('pathauto_is_alias_reserved');
     foreach ($implementations as $module) {
         $result = $this->moduleHandler->invoke($module, 'pathauto_is_alias_reserved', $args);
         if (!empty($result)) {
             // As soon as the first module says that an alias is in fact reserved,
             // then there is no point in checking the rest of the modules.
             return TRUE;
         }
     }
     return FALSE;
 }
 /**
  * Returns a list with all modules which sends emails.
  *
  * Currently this is evaluated by the hook_mail implementation.
  *
  * @return array
  *   Associative array with all modules which sends emails:
  *   - module: label
  */
 protected function getModulesList()
 {
     $list = array('none' => $this->t('-- Select --'));
     foreach ($this->moduleHandler->getImplementations('mail') as $module) {
         $list[$module] = ucfirst($module);
     }
     return $list;
 }
Esempio n. 8
0
 /**
  * {@inheritdoc}
  */
 public function buildForm(array $form, array &$form_state)
 {
     $role_names = array();
     $role_permissions = array();
     foreach ($this->getRoles() as $role_name => $role) {
         // Retrieve role names for columns.
         $role_names[$role_name] = String::checkPlain($role->label());
         // Fetch permissions for the roles.
         $role_permissions[$role_name] = $role->getPermissions();
     }
     // Store $role_names for use when saving the data.
     $form['role_names'] = array('#type' => 'value', '#value' => $role_names);
     // Render role/permission overview:
     $options = array();
     $module_info = system_rebuild_module_data();
     $hide_descriptions = system_admin_compact_mode();
     // Get a list of all the modules implementing a hook_permission() and sort by
     // display name.
     $modules = array();
     foreach ($this->moduleHandler->getImplementations('permission') as $module) {
         $modules[$module] = $module_info[$module]->info['name'];
     }
     asort($modules);
     $form['system_compact_link'] = array('#theme' => 'system_compact_link');
     $form['permissions'] = array('#type' => 'table', '#header' => array($this->t('Permission')), '#id' => 'permissions', '#sticky' => TRUE);
     foreach ($role_names as $name) {
         $form['permissions']['#header'][] = array('data' => $name, 'class' => array('checkbox'));
     }
     foreach ($modules as $module => $display_name) {
         if ($permissions = $this->moduleHandler->invoke($module, 'permission')) {
             // Module name.
             $form['permissions'][$module] = array(array('#wrapper_attributes' => array('colspan' => count($role_names) + 1, 'class' => array('module'), 'id' => 'module-' . $module), '#markup' => $module_info[$module]->info['name']));
             foreach ($permissions as $perm => $perm_item) {
                 // Fill in default values for the permission.
                 $perm_item += array('description' => '', 'restrict access' => FALSE, 'warning' => !empty($perm_item['restrict access']) ? $this->t('Warning: Give to trusted roles only; this permission has security implications.') : '');
                 $options[$perm] = $perm_item['title'];
                 // Show the permission description.
                 if (!$hide_descriptions) {
                     $user_permission_description = $perm_item['description'];
                     // Append warning message.
                     if (!empty($perm_item['warning'])) {
                         $user_permission_description .= ' <em class="permission-warning">' . $perm_item['warning'] . '</em>';
                     }
                 }
                 $form['permissions'][$perm]['description'] = array('#wrapper_attributes' => array('class' => array('permission')), '#type' => 'item', '#markup' => $perm_item['title'], '#description' => $user_permission_description);
                 $options[$perm] = '';
                 foreach ($role_names as $rid => $name) {
                     $form['permissions'][$perm][$rid] = array('#title' => $name . ': ' . $perm_item['title'], '#title_display' => 'invisible', '#wrapper_attributes' => array('class' => array('checkbox')), '#type' => 'checkbox', '#default_value' => in_array($perm, $role_permissions[$rid]) ? 1 : 0, '#attributes' => array('class' => array('rid-' . $rid)), '#parents' => array($rid, $perm));
                 }
             }
         }
     }
     $form['actions'] = array('#type' => 'actions');
     $form['actions']['submit'] = array('#type' => 'submit', '#value' => $this->t('Save permissions'));
     $form['#attached']['library'][] = 'user/drupal.user.permissions';
     return $form;
 }
Esempio n. 9
0
 /**
  * {@inheritdoc}
  */
 protected function thirdPartySettingsForm(PluginSettingsInterface $plugin, FieldDefinitionInterface $field_definition, array $form, array &$form_state)
 {
     $settings_form = array();
     // Invoke hook_field_formatter_third_party_settings_form(), keying resulting
     // subforms by module name.
     foreach ($this->moduleHandler->getImplementations('field_formatter_third_party_settings_form') as $module) {
         $settings_form[$module] = $this->moduleHandler->invoke($module, 'field_formatter_third_party_settings_form', array($plugin, $field_definition, $this->mode, $form, $form_state));
     }
     return $settings_form;
 }
Esempio n. 10
0
 /**
  * {@inheritdoc}
  */
 public function build()
 {
     // Do not show on a 403 or 404 page.
     if ($this->request->attributes->has('exception')) {
         return [];
     }
     $implementations = $this->moduleHandler->getImplementations('help');
     $build = [];
     $args = [$this->routeMatch->getRouteName(), $this->routeMatch];
     foreach ($implementations as $module) {
         // Don't add empty strings to $build array.
         if ($help = $this->moduleHandler->invoke($module, 'help', $args)) {
             // Convert strings to #markup render arrays so that they will XSS admin
             // filtered.
             $build[] = is_array($help) ? $help : ['#markup' => $help];
         }
     }
     return $build;
 }
Esempio n. 11
0
 /**
  * Invokes any cron handlers implementing hook_cron.
  */
 protected function invokeCronHandlers()
 {
     // Iterate through the modules calling their cron handlers (if any):
     foreach ($this->moduleHandler->getImplementations('cron') as $module) {
         // Do not let an exception thrown by one module disturb another.
         try {
             $this->moduleHandler->invoke($module, 'cron');
         } catch (\Exception $e) {
             watchdog_exception('cron', $e);
         }
     }
 }
 /**
  * {@inheritdoc}
  */
 protected function setUp()
 {
     parent::setUp();
     $this->moduleHandler = $this->prophesize(ModuleHandlerInterface::class);
     $this->moduleHandler->getImplementations('entity_type_build')->willReturn([]);
     $this->moduleHandler->alter('entity_type', Argument::type('array'))->willReturn(NULL);
     $this->cacheBackend = $this->prophesize(CacheBackendInterface::class);
     $this->entityTypeManager = $this->prophesize(EntityTypeManagerInterface::class);
     $this->cacheTagsInvalidator = $this->prophesize(CacheTagsInvalidatorInterface::class);
     $language = new Language(['id' => 'en']);
     $this->languageManager = $this->prophesize(LanguageManagerInterface::class);
     $this->languageManager->getCurrentLanguage()->willReturn($language);
     $this->languageManager->getLanguages()->willReturn(['en' => (object) ['id' => 'en']]);
     $this->typedDataManager = $this->prophesize(TypedDataManagerInterface::class);
     $this->cacheBackend = $this->prophesize(CacheBackendInterface::class);
     $container = $this->prophesize(ContainerInterface::class);
     $container->get('cache_tags.invalidator')->willReturn($this->cacheTagsInvalidator->reveal());
     //$container->get('typed_data_manager')->willReturn($this->typedDataManager->reveal());
     \Drupal::setContainer($container->reveal());
     $this->entityTypeBundleInfo = new EntityTypeBundleInfo($this->entityTypeManager->reveal(), $this->languageManager->reveal(), $this->moduleHandler->reveal(), $this->typedDataManager->reveal(), $this->cacheBackend->reveal());
 }
Esempio n. 13
0
 /**
  * Invokes the specified prepare hook variant.
  *
  * @param string $hook
  *   The hook variant name.
  * @param \Drupal\Core\Form\FormStateInterface $form_state
  *   The current state of the form.
  */
 protected function prepareInvokeAll($hook, FormStateInterface $form_state)
 {
     $implementations = $this->moduleHandler->getImplementations($hook);
     foreach ($implementations as $module) {
         $function = $module . '_' . $hook;
         if (function_exists($function)) {
             // Ensure we pass an updated translation object and form display at
             // each invocation, since they depend on form state which is alterable.
             $args = array($this->entity, $this->operation, &$form_state);
             call_user_func_array($function, $args);
         }
     }
 }
Esempio n. 14
0
 public function getValueOptions()
 {
     if (!isset($this->value_options)) {
         $module_info = system_get_info('module');
         // Get a list of all the modules implementing a hook_permission() and sort by
         // display name.
         $modules = array();
         foreach ($this->moduleHandler->getImplementations('permission') as $module) {
             $modules[$module] = $module_info[$module]['name'];
         }
         asort($modules);
         $this->value_options = array();
         foreach ($modules as $module => $display_name) {
             if ($permissions = $this->moduleHandler->invoke($module, 'permission')) {
                 foreach ($permissions as $perm => $perm_item) {
                     $this->value_options[$display_name][$perm] = String::checkPlain(strip_tags($perm_item['title']));
                 }
             }
         }
     } else {
         return $this->value_options;
     }
 }
Esempio n. 15
0
 /**
  * @covers ::getFieldMapByFieldType
  */
 public function testGetFieldMapByFieldType()
 {
     // Set up a content entity type.
     $entity_type = $this->prophesize(ContentEntityTypeInterface::class);
     $entity_class = EntityManagerTestEntity::class;
     // Set up the module handler to return two bundles for the fieldable entity
     // type.
     $this->moduleHandler->getImplementations('entity_base_field_info')->willReturn([]);
     $this->moduleHandler->invokeAll('entity_bundle_info')->willReturn(['test_entity_type' => ['first_bundle' => [], 'second_bundle' => []]]);
     $this->moduleHandler->alter('entity_bundle_info', Argument::type('array'))->willReturn(NULL);
     // Define an ID field definition as a base field.
     $id_definition = $this->prophesize(FieldDefinitionInterface::class);
     $id_definition->getType()->willReturn('integer');
     $base_field_definitions = array('id' => $id_definition->reveal());
     $entity_class::$baseFieldDefinitions = $base_field_definitions;
     // Set up the stored bundle field map.
     $key_value_store = $this->prophesize(KeyValueStoreInterface::class);
     $this->keyValueFactory->get('entity.definitions.bundle_field_map')->willReturn($key_value_store->reveal());
     $key_value_store->getAll()->willReturn(['test_entity_type' => ['by_bundle' => ['type' => 'string', 'bundles' => ['second_bundle' => 'second_bundle']]]]);
     // Mock the base field definition override.
     $override_entity_type = $this->prophesize(EntityTypeInterface::class);
     $this->setUpEntityManager(array('test_entity_type' => $entity_type, 'base_field_override' => $override_entity_type));
     $entity_type->getClass()->willReturn($entity_class);
     $entity_type->getKeys()->willReturn(['default_langcode' => 'default_langcode']);
     $entity_type->id()->willReturn('test_entity_type');
     $entity_type->isSubclassOf(FieldableEntityInterface::class)->willReturn(TRUE);
     $entity_type->getBundleOf()->shouldBeCalled();
     $entity_type->isTranslatable()->shouldBeCalled();
     $entity_type->getProvider()->shouldBeCalled();
     $override_entity_type->getClass()->willReturn($entity_class);
     $override_entity_type->isSubclassOf(FieldableEntityInterface::class)->willReturn(FALSE);
     $override_entity_type->getHandlerClass('storage')->willReturn(TestConfigEntityStorage::class);
     $override_entity_type->getBundleOf()->shouldBeCalled();
     $override_entity_type->getLabel()->shouldBeCalled();
     $integerFields = $this->entityManager->getFieldMapByFieldType('integer');
     $this->assertCount(1, $integerFields['test_entity_type']);
     $this->assertArrayNotHasKey('non_fieldable', $integerFields);
     $this->assertArrayHasKey('id', $integerFields['test_entity_type']);
     $this->assertArrayNotHasKey('by_bundle', $integerFields['test_entity_type']);
     $stringFields = $this->entityManager->getFieldMapByFieldType('string');
     $this->assertCount(1, $stringFields['test_entity_type']);
     $this->assertArrayNotHasKey('non_fieldable', $stringFields);
     $this->assertArrayHasKey('by_bundle', $stringFields['test_entity_type']);
     $this->assertArrayNotHasKey('id', $stringFields['test_entity_type']);
 }
Esempio n. 16
0
 /**
  * Invokes the page top and bottom hooks.
  *
  * @param array &$html
  *   A #type 'html' render array, for which the page top and bottom hooks will
  *   be invoked, and to which the 'page_top' and 'page_bottom' children (also
  *   render arrays) will be added (if non-empty).
  *
  * @throws \LogicException
  *
  * @internal
  *
  * @see hook_page_top()
  * @see hook_page_bottom()
  * @see html.html.twig
  */
 public function buildPageTopAndBottom(array &$html)
 {
     // Modules can add render arrays to the top and bottom of the page.
     $page_top = [];
     $page_bottom = [];
     foreach ($this->moduleHandler->getImplementations('page_top') as $module) {
         $function = $module . '_page_top';
         $function($page_top);
     }
     foreach ($this->moduleHandler->getImplementations('page_bottom') as $module) {
         $function = $module . '_page_bottom';
         $function($page_bottom);
     }
     if (!empty($page_top)) {
         $html['page_top'] = $page_top;
     }
     if (!empty($page_bottom)) {
         $html['page_bottom'] = $page_bottom;
     }
 }
Esempio n. 17
0
 /**
  * {@inheritdoc}
  */
 public function write(NodeInterface $node, array $grants, $realm = NULL, $delete = TRUE)
 {
     if ($delete) {
         $query = $this->database->delete('node_access')->condition('nid', $node->id());
         if ($realm) {
             $query->condition('realm', array($realm, 'all'), 'IN');
         }
         $query->execute();
     }
     // Only perform work when node_access modules are active.
     if (!empty($grants) && count($this->moduleHandler->getImplementations('node_grants'))) {
         $query = $this->database->insert('node_access')->fields(array('nid', 'langcode', 'fallback', 'realm', 'gid', 'grant_view', 'grant_update', 'grant_delete'));
         // If we have defined a granted langcode, use it. But if not, add a grant
         // for every language this node is translated to.
         foreach ($grants as $grant) {
             if ($realm && $realm != $grant['realm']) {
                 continue;
             }
             if (isset($grant['langcode'])) {
                 $grant_languages = array($grant['langcode'] => $this->languageManager->getLanguage($grant['langcode']));
             } else {
                 $grant_languages = $node->getTranslationLanguages(TRUE);
             }
             foreach ($grant_languages as $grant_langcode => $grant_language) {
                 // Only write grants; denies are implicit.
                 if ($grant['grant_view'] || $grant['grant_update'] || $grant['grant_delete']) {
                     $grant['nid'] = $node->id();
                     $grant['langcode'] = $grant_langcode;
                     // The record with the original langcode is used as the fallback.
                     if ($grant['langcode'] == $node->language()->getId()) {
                         $grant['fallback'] = 1;
                     } else {
                         $grant['fallback'] = 0;
                     }
                     $query->values($grant);
                 }
             }
         }
         $query->execute();
     }
 }
Esempio n. 18
0
 /**
  * {@inheritdoc}
  */
 public function isReserved($alias, $source, $langcode = LanguageInterface::LANGCODE_NOT_SPECIFIED)
 {
     // First check whether the alias exists for another source.
     if ($this->aliasStorageHelper->exists($alias, $source, $langcode)) {
         return TRUE;
     }
     // Then check if there is a route with the same path.
     if ($this->isRoute($alias)) {
         return TRUE;
     }
     // Finally check if any other modules have reserved the alias.
     $args = array($alias, $source, $langcode);
     $implementations = $this->moduleHandler->getImplementations('pathauto_is_alias_reserved');
     foreach ($implementations as $module) {
         $result = $this->moduleHandler->invoke($module, 'pathauto_is_alias_reserved', $args);
         if (!empty($result)) {
             // As soon as the first module says that an alias is in fact reserved,
             // then there is no point in checking the rest of the modules.
             return TRUE;
         }
     }
     return FALSE;
 }
Esempio n. 19
0
 /**
  * Invokes any cron handlers implementing hook_cron.
  */
 protected function invokeCronHandlers()
 {
     $module_previous = '';
     // Iterate through the modules calling their cron handlers (if any):
     foreach ($this->moduleHandler->getImplementations('cron') as $module) {
         if (!$module_previous) {
             $this->logger->notice('Starting execution of @module_cron().', ['@module' => $module]);
         } else {
             $this->logger->notice('Starting execution of @module_cron(), execution of @module_previous_cron() took @time.', ['@module' => $module, '@module_previous' => $module_previous, '@time' => Timer::read('cron_' . $module_previous) . 'ms']);
         }
         Timer::start('cron_' . $module);
         // Do not let an exception thrown by one module disturb another.
         try {
             $this->moduleHandler->invoke($module, 'cron');
         } catch (\Exception $e) {
             watchdog_exception('cron', $e);
         }
         Timer::stop('cron_' . $module);
         $module_previous = $module;
     }
     if ($module_previous) {
         $this->logger->notice('Execution of @module_previous_cron() took @time.', ['@module_previous' => $module_previous, '@time' => Timer::read('cron_' . $module_previous) . 'ms']);
     }
 }
Esempio n. 20
0
 /**
  * Builds the theme registry cache.
  *
  * Theme hook definitions are collected in the following order:
  * - Modules
  * - Base theme engines
  * - Base themes
  * - Theme engine
  * - Theme
  *
  * All theme hook definitions are essentially just collated and merged in the
  * above order. However, various extension-specific default values and
  * customizations are required; e.g., to record the effective file path for
  * theme template. Therefore, this method first collects all extensions per
  * type, and then dispatches the processing for each extension to
  * processExtension().
  *
  * After completing the collection, modules are allowed to alter it. Lastly,
  * any derived and incomplete theme hook definitions that are hook suggestions
  * for base hooks (e.g., 'block__node' for the base hook 'block') need to be
  * determined based on the full registry and classified as 'base hook'.
  *
  * See the @link themeable Default theme implementations topic @endlink for
  * details.
  *
  * @return \Drupal\Core\Utility\ThemeRegistry
  *   The build theme registry.
  *
  * @see hook_theme_registry_alter()
  */
 protected function build()
 {
     $cache = array();
     // First, preprocess the theme hooks advertised by modules. This will
     // serve as the basic registry. Since the list of enabled modules is the
     // same regardless of the theme used, this is cached in its own entry to
     // save building it for every theme.
     if ($cached = $this->cache->get('theme_registry:build:modules')) {
         $cache = $cached->data;
     } else {
         foreach ($this->moduleHandler->getImplementations('theme') as $module) {
             $this->processExtension($cache, $module, 'module', $module, $this->getPath($module));
         }
         // Only cache this registry if all modules are loaded.
         if ($this->moduleHandler->isLoaded()) {
             $this->cache->set("theme_registry:build:modules", $cache, Cache::PERMANENT, array('theme_registry'));
         }
     }
     // Process each base theme.
     // Ensure that we start with the root of the parents, so that both CSS files
     // and preprocess functions comes first.
     foreach (array_reverse($this->theme->getBaseThemes()) as $base) {
         // If the base theme uses a theme engine, process its hooks.
         $base_path = $base->getPath();
         if ($this->theme->getEngine()) {
             $this->processExtension($cache, $this->theme->getEngine(), 'base_theme_engine', $base->getName(), $base_path);
         }
         $this->processExtension($cache, $base->getName(), 'base_theme', $base->getName(), $base_path);
     }
     // And then the same thing, but for the theme.
     if ($this->theme->getEngine()) {
         $this->processExtension($cache, $this->theme->getEngine(), 'theme_engine', $this->theme->getName(), $this->theme->getPath());
     }
     // Hooks provided by the theme itself.
     $this->processExtension($cache, $this->theme->getName(), 'theme', $this->theme->getName(), $this->theme->getPath());
     // Discover and add all preprocess functions for theme hook suggestions.
     $this->postProcessExtension($cache, $this->theme);
     // Let modules and themes alter the registry.
     $this->moduleHandler->alter('theme_registry', $cache);
     $this->themeManager->alterForTheme($this->theme, 'theme_registry', $cache);
     // @todo Implement more reduction of the theme registry entry.
     // Optimize the registry to not have empty arrays for functions.
     foreach ($cache as $hook => $info) {
         if (empty($info['preprocess functions'])) {
             unset($cache[$hook]['preprocess functions']);
         }
     }
     $this->registry[$this->theme->getName()] = $cache;
     return $this->registry[$this->theme->getName()];
 }
Esempio n. 21
0
 /**
  * Builds field storage definitions for an entity type.
  *
  * @param string $entity_type_id
  *   The entity type ID. Only entity types that implement
  *   \Drupal\Core\Entity\FieldableEntityInterface are supported
  *
  * @return \Drupal\Core\Field\FieldStorageDefinitionInterface[]
  *   An array of field storage definitions, keyed by field name.
  */
 protected function buildFieldStorageDefinitions($entity_type_id)
 {
     $entity_type = $this->entityTypeManager->getDefinition($entity_type_id);
     $field_definitions = [];
     // Retrieve base field definitions from modules.
     foreach ($this->moduleHandler->getImplementations('entity_field_storage_info') as $module) {
         $module_definitions = $this->moduleHandler->invoke($module, 'entity_field_storage_info', [$entity_type]);
         if (!empty($module_definitions)) {
             // Ensure the provider key actually matches the name of the provider
             // defining the field.
             foreach ($module_definitions as $field_name => $definition) {
                 // @todo Remove this check once FieldDefinitionInterface exposes a
                 //  proper provider setter. See https://www.drupal.org/node/2225961.
                 if ($definition instanceof BaseFieldDefinition) {
                     $definition->setProvider($module);
                 }
                 $field_definitions[$field_name] = $definition;
             }
         }
     }
     // Invoke alter hook.
     $this->moduleHandler->alter('entity_field_storage_info', $field_definitions, $entity_type);
     return $field_definitions;
 }
Esempio n. 22
0
 /**
  * {@inheritdoc}
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $io = new DrupalStyle($input, $output);
     $io->section($this->trans('commands.cron.debug.messages.module-list'));
     $io->table([$this->trans('commands.cron.debug.messages.module')], $this->moduleHandler->getImplementations('cron'), 'compact');
 }
Esempio n. 23
0
 /**
  * Builds the theme registry cache.
  *
  * Theme hook definitions are collected in the following order:
  * - Modules
  * - Base theme engines
  * - Base themes
  * - Theme engine
  * - Theme
  *
  * All theme hook definitions are essentially just collated and merged in the
  * above order. However, various extension-specific default values and
  * customizations are required; e.g., to record the effective file path for
  * theme template. Therefore, this method first collects all extensions per
  * type, and then dispatches the processing for each extension to
  * processExtension().
  *
  * After completing the collection, modules are allowed to alter it. Lastly,
  * any derived and incomplete theme hook definitions that are hook suggestions
  * for base hooks (e.g., 'block__node' for the base hook 'block') need to be
  * determined based on the full registry and classified as 'base hook'.
  *
  * @see _theme()
  * @see hook_theme_registry_alter()
  *
  * @return \Drupal\Core\Utility\ThemeRegistry
  *   The build theme registry.
  */
 protected function build()
 {
     $cache = array();
     // First, preprocess the theme hooks advertised by modules. This will
     // serve as the basic registry. Since the list of enabled modules is the
     // same regardless of the theme used, this is cached in its own entry to
     // save building it for every theme.
     if ($cached = $this->cache->get('theme_registry:build:modules')) {
         $cache = $cached->data;
     } else {
         foreach ($this->moduleHandler->getImplementations('theme') as $module) {
             $this->processExtension($cache, $module, 'module', $module, $this->getPath($module));
         }
         // Only cache this registry if all modules are loaded.
         if ($this->moduleHandler->isLoaded()) {
             $this->cache->set("theme_registry:build:modules", $cache, Cache::PERMANENT, array('theme_registry' => TRUE));
         }
     }
     // Process each base theme.
     foreach ($this->baseThemes as $base) {
         // If the base theme uses a theme engine, process its hooks.
         $base_path = $base->getPath();
         if ($this->engine) {
             $this->processExtension($cache, $this->engine, 'base_theme_engine', $base->getName(), $base_path);
         }
         $this->processExtension($cache, $base->getName(), 'base_theme', $base->getName(), $base_path);
     }
     // And then the same thing, but for the theme.
     if ($this->engine) {
         $this->processExtension($cache, $this->engine, 'theme_engine', $this->theme->getName(), $this->theme->getPath());
     }
     // Finally, hooks provided by the theme itself.
     $this->processExtension($cache, $this->theme->getName(), 'theme', $this->theme->getName(), $this->theme->getPath());
     // Let modules alter the registry.
     $this->moduleHandler->alter('theme_registry', $cache);
     // @todo Implement more reduction of the theme registry entry.
     // Optimize the registry to not have empty arrays for functions.
     foreach ($cache as $hook => $info) {
         if (empty($info['preprocess functions'])) {
             unset($cache[$hook]['preprocess functions']);
         }
     }
     $this->registry = $cache;
     return $this->registry;
 }
 /**
  * {@inheritdoc}
  */
 public function getJsAssets(AttachedAssetsInterface $assets, $optimize)
 {
     $theme_info = $this->themeManager->getActiveTheme();
     // Add the theme name to the cache key since themes may implement
     // hook_library_info_alter(). Additionally add the current language to
     // support translation of JavaScript files via hook_js_alter().
     $libraries_to_load = $this->getLibrariesToLoad($assets);
     $cid = 'js:' . $theme_info->getName() . ':' . $this->languageManager->getCurrentLanguage()->getId() . ':' . Crypt::hashBase64(serialize($libraries_to_load)) . (int) (count($assets->getSettings()) > 0) . (int) $optimize;
     if ($cached = $this->cache->get($cid)) {
         list($js_assets_header, $js_assets_footer, $settings, $settings_in_header) = $cached->data;
     } else {
         $javascript = [];
         $default_options = ['type' => 'file', 'group' => JS_DEFAULT, 'weight' => 0, 'cache' => TRUE, 'preprocess' => TRUE, 'attributes' => [], 'version' => NULL, 'browsers' => []];
         // Collect all libraries that contain JS assets and are in the header.
         $header_js_libraries = [];
         foreach ($libraries_to_load as $library) {
             list($extension, $name) = explode('/', $library, 2);
             $definition = $this->libraryDiscovery->getLibraryByName($extension, $name);
             if (isset($definition['js']) && !empty($definition['header'])) {
                 $header_js_libraries[] = $library;
             }
         }
         // The current list of header JS libraries are only those libraries that
         // are in the header, but their dependencies must also be loaded for them
         // to function correctly, so update the list with those.
         $header_js_libraries = $this->libraryDependencyResolver->getLibrariesWithDependencies($header_js_libraries);
         foreach ($libraries_to_load as $library) {
             list($extension, $name) = explode('/', $library, 2);
             $definition = $this->libraryDiscovery->getLibraryByName($extension, $name);
             if (isset($definition['js'])) {
                 foreach ($definition['js'] as $options) {
                     $options += $default_options;
                     // 'scope' is a calculated option, based on which libraries are
                     // marked to be loaded from the header (see above).
                     $options['scope'] = in_array($library, $header_js_libraries) ? 'header' : 'footer';
                     // Preprocess can only be set if caching is enabled and no
                     // attributes are set.
                     $options['preprocess'] = $options['cache'] && empty($options['attributes']) ? $options['preprocess'] : FALSE;
                     // Always add a tiny value to the weight, to conserve the insertion
                     // order.
                     $options['weight'] += count($javascript) / 1000;
                     // Local and external files must keep their name as the associative
                     // key so the same JavaScript file is not added twice.
                     $javascript[$options['data']] = $options;
                 }
             }
         }
         // Allow modules and themes to alter the JavaScript assets.
         $this->moduleHandler->alter('js', $javascript, $assets);
         $this->themeManager->alter('js', $javascript, $assets);
         // Sort JavaScript assets, so that they appear in the correct order.
         uasort($javascript, 'static::sort');
         // Prepare the return value: filter JavaScript assets per scope.
         $js_assets_header = [];
         $js_assets_footer = [];
         foreach ($javascript as $key => $item) {
             if ($item['scope'] == 'header') {
                 $js_assets_header[$key] = $item;
             } elseif ($item['scope'] == 'footer') {
                 $js_assets_footer[$key] = $item;
             }
         }
         if ($optimize) {
             $collection_optimizer = \Drupal::service('asset.js.collection_optimizer');
             $js_assets_header = $collection_optimizer->optimize($js_assets_header);
             $js_assets_footer = $collection_optimizer->optimize($js_assets_footer);
         }
         // If the core/drupalSettings library is being loaded or is already
         // loaded, get the JavaScript settings assets, and convert them into a
         // single "regular" JavaScript asset.
         $libraries_to_load = $this->getLibrariesToLoad($assets);
         $settings_required = in_array('core/drupalSettings', $libraries_to_load) || in_array('core/drupalSettings', $this->libraryDependencyResolver->getLibrariesWithDependencies($assets->getAlreadyLoadedLibraries()));
         $settings_have_changed = count($libraries_to_load) > 0 || count($assets->getSettings()) > 0;
         // Initialize settings to FALSE since they are not needed by default. This
         // distinguishes between an empty array which must still allow
         // hook_js_settings_alter() to be run.
         $settings = FALSE;
         if ($settings_required && $settings_have_changed) {
             $settings = $this->getJsSettingsAssets($assets);
             // Allow modules to add cached JavaScript settings.
             foreach ($this->moduleHandler->getImplementations('js_settings_build') as $module) {
                 $function = $module . '_' . 'js_settings_build';
                 $function($settings, $assets);
             }
         }
         $settings_in_header = in_array('core/drupalSettings', $header_js_libraries);
         $this->cache->set($cid, [$js_assets_header, $js_assets_footer, $settings, $settings_in_header], CacheBackendInterface::CACHE_PERMANENT, ['library_info']);
     }
     if ($settings !== FALSE) {
         // Attached settings override both library definitions and
         // hook_js_settings_build().
         $settings = NestedArray::mergeDeepArray([$settings, $assets->getSettings()], TRUE);
         // Allow modules and themes to alter the JavaScript settings.
         $this->moduleHandler->alter('js_settings', $settings, $assets);
         $this->themeManager->alter('js_settings', $settings, $assets);
         // Update the $assets object accordingly, so that it reflects the final
         // settings.
         $assets->setSettings($settings);
         $settings_as_inline_javascript = ['type' => 'setting', 'group' => JS_SETTING, 'weight' => 0, 'browsers' => [], 'data' => $settings];
         $settings_js_asset = ['drupalSettings' => $settings_as_inline_javascript];
         // Prepend to the list of JS assets, to render it first. Preferably in
         // the footer, but in the header if necessary.
         if ($settings_in_header) {
             $js_assets_header = $settings_js_asset + $js_assets_header;
         } else {
             $js_assets_footer = $settings_js_asset + $js_assets_footer;
         }
     }
     return [$js_assets_header, $js_assets_footer];
 }
Esempio n. 25
0
 /**
  * Builds a table row for the system modules page.
  *
  * @param array $modules
  *   The list existing modules.
  * @param \Drupal\Core\Extension\Extension $module
  *   The module for which to build the form row.
  * @param $distribution
  *
  * @return array
  *   The form row for the given module.
  */
 protected function buildRow(array $modules, Extension $module, $distribution)
 {
     // Set the basic properties.
     $row['#required'] = array();
     $row['#requires'] = array();
     $row['#required_by'] = array();
     $row['name']['#markup'] = $module->info['name'];
     $row['description']['#markup'] = $this->t($module->info['description']);
     $row['version']['#markup'] = $module->info['version'];
     // Generate link for module's help page, if there is one.
     $row['links']['help'] = array();
     if ($this->moduleHandler->moduleExists('help') && $module->status && in_array($module->getName(), $this->moduleHandler->getImplementations('help'))) {
         if ($this->moduleHandler->invoke($module->getName(), 'help', array('help.page.' . $module->getName(), $this->routeMatch))) {
             $row['links']['help'] = array('#type' => 'link', '#title' => $this->t('Help'), '#url' => Url::fromRoute('help.page', ['name' => $module->getName()]), '#options' => array('attributes' => array('class' => array('module-link', 'module-link-help'), 'title' => $this->t('Help'))));
         }
     }
     // Generate link for module's permission, if the user has access to it.
     $row['links']['permissions'] = array();
     if ($module->status && \Drupal::currentUser()->hasPermission('administer permissions') && in_array($module->getName(), $this->moduleHandler->getImplementations('permission'))) {
         $row['links']['permissions'] = array('#type' => 'link', '#title' => $this->t('Permissions'), '#url' => Url::fromRoute('user.admin_permissions'), '#options' => array('fragment' => 'module-' . $module->getName(), 'attributes' => array('class' => array('module-link', 'module-link-permissions'), 'title' => $this->t('Configure permissions'))));
     }
     // Generate link for module's configuration page, if it has one.
     $row['links']['configure'] = array();
     if ($module->status && isset($module->info['configure'])) {
         $route_parameters = isset($module->info['configure_parameters']) ? $module->info['configure_parameters'] : array();
         if ($this->accessManager->checkNamedRoute($module->info['configure'], $route_parameters, $this->currentUser)) {
             $links = $this->menuLinkManager->loadLinksByRoute($module->info['configure']);
             /** @var \Drupal\Core\Menu\MenuLinkInterface $link */
             $link = reset($links);
             // Most configure links have a corresponding menu link, though some just
             // have a route.
             if ($link) {
                 $description = $link->getDescription();
             } else {
                 $request = new Request();
                 $request->attributes->set('_route_name', $module->info['configure']);
                 $route_object = $this->routeProvider->getRouteByName($module->info['configure']);
                 $request->attributes->set('_route', $route_object);
                 $request->attributes->add($route_parameters);
                 $description = $this->titleResolver->getTitle($request, $route_object);
             }
             $row['links']['configure'] = array('#type' => 'link', '#title' => $this->t('Configure'), '#url' => Url::fromRoute($module->info['configure'], $route_parameters), '#options' => array('attributes' => array('class' => array('module-link', 'module-link-configure'), 'title' => $description)));
         }
     }
     // Present a checkbox for installing and indicating the status of a module.
     $row['enable'] = array('#type' => 'checkbox', '#title' => $this->t('Install'), '#default_value' => (bool) $module->status, '#disabled' => (bool) $module->status);
     // Disable the checkbox for required modules.
     if (!empty($module->info['required'])) {
         // Used when displaying modules that are required by the installation profile
         $row['enable']['#disabled'] = TRUE;
         $row['#required_by'][] = $distribution . (!empty($module->info['explanation']) ? ' (' . $module->info['explanation'] . ')' : '');
     }
     // Check the compatibilities.
     $compatible = TRUE;
     // Initialize an empty array of reasons why the module is incompatible. Add
     // each reason as a separate element of the array.
     $reasons = array();
     // Check the core compatibility.
     if ($module->info['core'] != \Drupal::CORE_COMPATIBILITY) {
         $compatible = FALSE;
         $reasons[] = $this->t('This version is not compatible with Drupal !core_version and should be replaced.', array('!core_version' => \Drupal::CORE_COMPATIBILITY));
     }
     // Ensure this module is compatible with the currently installed version of PHP.
     if (version_compare(phpversion(), $module->info['php']) < 0) {
         $compatible = FALSE;
         $required = $module->info['php'] . (substr_count($module->info['php'], '.') < 2 ? '.*' : '');
         $reasons[] = $this->t('This module requires PHP version @php_required and is incompatible with PHP version !php_version.', array('@php_required' => $required, '!php_version' => phpversion()));
     }
     // If this module is not compatible, disable the checkbox.
     if (!$compatible) {
         $status = implode(' ', $reasons);
         $row['enable']['#disabled'] = TRUE;
         $row['description']['#markup'] = $status;
         $row['#attributes']['class'][] = 'incompatible';
     }
     // If this module requires other modules, add them to the array.
     foreach ($module->requires as $dependency => $version) {
         if (!isset($modules[$dependency])) {
             $row['#requires'][$dependency] = $this->t('@module (<span class="admin-missing">missing</span>)', array('@module' => Unicode::ucfirst($dependency)));
             $row['enable']['#disabled'] = TRUE;
         } elseif (empty($modules[$dependency]->hidden)) {
             $name = $modules[$dependency]->info['name'];
             // Disable the module's checkbox if it is incompatible with the
             // dependency's version.
             if ($incompatible_version = drupal_check_incompatibility($version, str_replace(\Drupal::CORE_COMPATIBILITY . '-', '', $modules[$dependency]->info['version']))) {
                 $row['#requires'][$dependency] = $this->t('@module (<span class="admin-missing">incompatible with</span> version @version)', array('@module' => $name . $incompatible_version, '@version' => $modules[$dependency]->info['version']));
                 $row['enable']['#disabled'] = TRUE;
             } elseif ($modules[$dependency]->info['core'] != \Drupal::CORE_COMPATIBILITY) {
                 $row['#requires'][$dependency] = $this->t('@module (<span class="admin-missing">incompatible with</span> this version of Drupal core)', array('@module' => $name));
                 $row['enable']['#disabled'] = TRUE;
             } elseif ($modules[$dependency]->status) {
                 $row['#requires'][$dependency] = $this->t('@module', array('@module' => $name));
             } else {
                 $row['#requires'][$dependency] = $this->t('@module (<span class="admin-disabled">disabled</span>)', array('@module' => $name));
             }
         }
     }
     // If this module is required by other modules, list those, and then make it
     // impossible to disable this one.
     foreach ($module->required_by as $dependent => $version) {
         if (isset($modules[$dependent]) && empty($modules[$dependent]->info['hidden'])) {
             if ($modules[$dependent]->status == 1 && $module->status == 1) {
                 $row['#required_by'][$dependent] = $this->t('@module', array('@module' => $modules[$dependent]->info['name']));
                 $row['enable']['#disabled'] = TRUE;
             } else {
                 $row['#required_by'][$dependent] = $this->t('@module (<span class="admin-disabled">disabled</span>)', array('@module' => $modules[$dependent]->info['name']));
             }
         }
     }
     return $row;
 }