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;
}
