module_instructions-2.0.x-dev/module_instructions.module
module_instructions.module
<?php /** * @file * Contains module_instructions.module. */ use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Url; /** * Implements hook_help(). */ function module_instructions_help($route_name, RouteMatchInterface $route_match) { switch ($route_name) { case 'help.page.module_instructions': $output = ''; $output .= '<h3>' . t('About') . '</h3>'; $output .= '<p>' . t('Module Instructions module shows the content of README.txt, CHANGELOG.txt and LICENSE.txt files for contrib modules.') . '</p>'; return $output; } } /** * Implements hook_module_instructions_info(). */ function module_instructions_module_instructions_info() { return [ 'readme' => [ 'label' => t('Readme'), ], 'license' => [ 'label' => t('License'), ], 'changelog' => [ 'label' => t('Changelog'), ], ]; } /** * Implements hook_form_FORM_ID_alter(). */ function module_instructions_form_system_modules_alter(&$form, FormStateInterface $form_state, $form_id) { if (!\Drupal::currentUser()->hasPermission('access module instruction files')) { return; } /** @var \Drupal\Core\Extension\ModuleHandlerInterface $module_handler */ $module_handler = \Drupal::service('module_handler'); $files = $module_handler->invokeAll('module_instructions_info'); /** @var \Drupal\Core\Config\ImmutableConfig $config */ $config = \Drupal::config('module_instructions.settings'); $types = $config->get('types'); $collection = \Drupal::state()->get('module_instructions_collection'); foreach ($form['modules'] as $name => $group) { if (is_array($group)) { foreach ($group as $module => $item) { if (is_array($item) && !empty($item['name']) && !empty($collection[$module])) { foreach ($collection[$module] as $type => $file) { if ($collection[$module][$type] && isset($types[$type])) { $label = !empty($files[$type]['label']) ? $files[$type]['label'] : ucfirst($type); $form['modules'][$name][$module]['links'][$type] = _module_instructions_create_link_array($module, $label, $file); } } } } } } } /** * Creates a link to the instruction route. * * @param string $module * Module name. * @param string $label * Label to display on the page. * @param string $file * Actual file name. * * @return array * Link to the file. */ function _module_instructions_create_link_array($module, $label, $file) { return [ '#type' => 'link', '#title' => $label, '#url' => Url::fromRoute('module_instructions.instruction', ['module' => $module, 'file' => $file]), '#options' => [ 'attributes' => [ 'class' => [ 'module-link', 'module-link-' . strtolower($label), 'action-link', 'action-link--small', ], 'title' => $label, ], ], ]; } /** * Implements hook_theme_registry_alter(). */ function module_instructions_theme_registry_alter(&$theme_registry) { if (!empty($theme_registry['system_modules_details']) && \Drupal::currentUser()->hasPermission('access module instruction files') ) { $path = \Drupal::service('extension.path.resolver')->getPath('module', 'module_instructions') . '/templates'; $theme_registry['system_modules_details']['path'] = $path; } } /** * Implements hook_preprocess_HOOK(). */ function module_instructions_preprocess_system_modules_details(&$variables) { /** @var \Drupal\Core\Extension\ModuleHandlerInterface $module_handler */ $module_handler = \Drupal::service('module_handler'); $files = $module_handler->invokeAll('module_instructions_info'); $variables['module_links'] = array_merge(['help', 'permissions', 'configure'], array_keys($files)); } /** * Implements hook_cron(). */ function module_instructions_cron() { /** @var \Drupal\Core\Extension\ModuleHandlerInterface $module_handler */ $module_handler = \Drupal::service('module_handler'); $modules = $module_handler->getModuleList(); // Get all files. $files = $module_handler->invokeAll('module_instructions_info'); $collection = []; foreach ($modules as $module => $info) { $collection[$module] = []; foreach ($files as $file => $data) { $collection[$module][strtolower($file)] = module_instructions_file_exists($module, $file); } } \Drupal::state()->set('module_instructions_collection', $collection); } /** * Implements hook_modules_installed(). */ function module_instructions_modules_installed($modules, $is_syncing) { $collection = \Drupal::state()->get('module_instructions_collection'); /** @var \Drupal\Core\Extension\ModuleHandlerInterface $module_handler */ $module_handler = \Drupal::service('module_handler'); $files = $module_handler->invokeAll('module_instructions_info'); foreach ($modules as $module) { $collection[$module] = []; foreach ($files as $file => $data) { $collection[$module][strtolower($file)] = module_instructions_file_exists($module, $file); } } \Drupal::state()->set('module_instructions_collection', $collection); } /** * Implements hook_modules_uninstalled(). */ function module_instructions_modules_uninstalled($modules, $is_syncing) { $collection = \Drupal::state()->get('module_instructions_collection'); foreach ($modules as $module) { if (isset($collection[$module])) { unset($collection[$module]); } } \Drupal::state()->set('module_instructions_collection', $collection); } /** * Check if the module has a required file. * * @param string $module * Module name. * @param string $file * File to check. * * @return string|bool * Path to the file. */ function module_instructions_file_exists($module, $file) { $fullpath = \Drupal::service('extension.path.resolver')->getPath('module', $module); $names = [ strtoupper($file), strtoupper($file) . '.txt', strtoupper($file) . '.md', strtolower($file) . '.txt', strtolower($file) . '.md', ]; foreach ($names as $name) { if (file_exists("{$fullpath}/{$name}")) { return $name; } } return FALSE; }