3 namespace Drupal\advanced_help;
5 use Drupal\Core\Cache\CacheBackendInterface;
6 use Drupal\Core\Extension\ModuleHandlerInterface;
7 use Drupal\Core\Extension\ThemeHandlerInterface;
8 use Drupal\Core\StringTranslation\TranslationInterface;
9 use Drupal\Core\Plugin\DefaultPluginManager;
10 use Drupal\Core\StringTranslation\StringTranslationTrait;
11 use Drupal\Component\Serialization\Yaml;
14 * AdvancedHelp plugin manager.
16 class AdvancedHelpManager extends DefaultPluginManager {
17 use StringTranslationTrait;
20 * Constructs an AdvancedHelpManager instance.
22 * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
23 * Cache backend instance to use.
24 * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
25 * The module handler to invoke the alter hook with.
26 * @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler
28 * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
29 * The string translation service.
31 public function __construct(ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler, CacheBackendInterface $cache_backend, TranslationInterface $string_translation) {
32 $this->module_handler = $module_handler;
33 $this->theme_handler = $theme_handler;
34 $this->setStringTranslation($string_translation);
35 $this->alterInfo('advanced_help');
36 $this->setCacheBackend($cache_backend, 'advanced_help', ['advanced_help']);
40 * Get the modules/theme list.
43 public function getModuleList() {
44 $modules = $this->module_handler->getModuleList();
45 $themes = $this->theme_handler->listInfo();
48 foreach ($modules as $name => $data) {
49 $result[$name] = $this->module_handler->getName($name);
52 foreach ($themes as $name => $data) {
53 $result[$name] = $this->theme_handler->getName($name);
60 * Get the information for a single help topic.
65 function getTopic($module, $topic) {
66 $topics = $this->getTopics();
67 if (!empty($topics[$module][$topic])) {
68 return $topics[$module][$topic];
74 * Return the name of the module.
75 * @param string $module
78 function getModuleName($module) {
79 return $this->module_handler->getName($module);
83 * Search the system for all available help topics.
84 * @todo check visibility of the method.
86 public function getTopics() {
87 $ini = $this->parseHelp();
88 return $ini['topics'];
92 * Returns advanced help settings.
93 * @todo check visibility of the method.
95 public function getSettings() {
96 $ini = $this->parseHelp();
97 return $ini['settings'];
102 * Function to parse yml / txt files.
104 * @todo implement cache
105 * @todo check visibility of the method.
107 public function parseHelp() {
108 $language = \Drupal::languageManager()->getCurrentLanguage()->getId();
111 $cache = $this->cacheGet('advanced_help_ini_' . $language);
117 $ini = ['topics' => [], 'settings' => []];
119 foreach ($this->module_handler->getModuleList() + $this->theme_handler->listInfo() as $plugin_name => $extension) {
120 $module = $plugin_name;
121 $module_path = $extension->getPath();
124 if (file_exists("$module_path/help/$module.help.yml")) {
125 $path = "$module_path/help";
126 $info = Yaml::decode(file_get_contents("$module_path/help/$module.help.yml"));
128 elseif (!file_exists("$module_path/help")) {
129 // Look for one or more README files.
130 $files = file_scan_directory("./$module_path",
131 '/^(readme).*\.(txt|md)$/i', ['recurse' => FALSE]);
132 $path = "./$module_path";
133 foreach ($files as $name => $fileinfo) {
134 $info[$fileinfo->filename] = [
135 'line break' => TRUE,
136 'readme file' => TRUE,
137 'file' => $fileinfo->filename,
138 'title' => $fileinfo->name,
144 // Get translated titles:
146 if (file_exists("$module_path/translations/help/$language/$module.help.yml")) {
147 $translation = Yaml::decode(file_get_contents("$module_path/translations/help/$language/$module.help.yml"));
150 $ini['settings'][$module] = [];
151 if (!empty($info['advanced help settings'])) {
152 $ini['settings'][$module] = $info['advanced help settings'];
153 unset($info['advanced help settings']);
155 // Check translated strings for translatable global settings.
156 if (isset($translation['advanced help settings']['name'])) {
157 $ini['settings']['name'] = $translation['advanced help settings']['name'];
159 if (isset($translation['advanced help settings']['index name'])) {
160 $ini['settings']['index name'] = $translation['advanced help settings']['index name'];
165 foreach ($info as $name => $topic) {
166 // Each topic should have a name, a title, a file and path.
167 $file = !empty($topic['file']) ? $topic['file'] : $name;
168 $ini['topics'][$module][$name] = [
172 'title' => !empty($translation[$name]['title']) ? $translation[$name]['title'] : $topic['title'],
173 'weight' => isset($topic['weight']) ? $topic['weight'] : 0,
174 'parent' => isset($topic['parent']) ? $topic['parent'] : 0,
175 'popup width' => isset($topic['popup width']) ? $topic['popup width'] : 500,
176 'popup height' => isset($topic['popup height']) ? $topic['popup height'] : 500,
177 // Require extension.
178 'file' => isset($topic['readme file']) ? $file : $file . '.html',
181 'line break' => isset($topic['line break']) ? $topic['line break'] : (isset($ini['settings'][$module]['line break']) ? $ini['settings'][$module]['line break'] : FALSE),
182 'navigation' => isset($topic['navigation']) ? $topic['navigation'] : (isset($ini['settings'][$module]['navigation']) ? $ini['settings'][$module]['navigation'] : TRUE),
183 'css' => isset($topic['css']) ? $topic['css'] : (isset($ini['settings'][$module]['css']) ? $ini['settings'][$module]['css'] : NULL),
184 'readme file' => isset($topic['readme file']) ? $topic['readme file'] : FALSE,
189 // drupal_alter('advanced_help_topic_info', $ini);
190 $this->cacheSet('advanced_help_ini_' . $language, $ini);
196 * Load and render a help topic.
198 * @todo allow the theme override the help.
203 public function getTopicFileInfo($module, $topic) {
204 $language = \Drupal::languageManager()->getCurrentLanguage()->getId();
206 $info = $this->getTopic($module, $topic);
211 $path_type = (preg_match('/themes/', $info['path'])) ? 'theme' : 'module';
214 // // Allow theme override.
215 // path_to_theme() . '/help',
217 drupal_get_path($path_type, $module) . "/translations/help/$language",
218 // In same directory as .inc file.
222 foreach ($paths as $path) {
223 if (file_exists("$path/$info[file]")) {
224 return ['path' => $path, 'file' => $info['file']];
231 public function getTopicFileName($module, $topic) {
232 $info = $this->getTopicFileInfo($module, $topic);
234 return "./{$info['path']}/{$info['file']}";