88use Consolidation \AnnotatedCommand \Hooks \HookManager ;
99use Consolidation \OutputFormatters \StructuredData \RowsOfFields ;
1010use Drupal \Core \Config \ConfigFactoryInterface ;
11+ use Drupal \Core \Extension \Extension ;
1112use Drupal \Core \Extension \MissingDependencyException ;
1213use Drupal \Core \Extension \ModuleExtensionList ;
1314use Drupal \Core \Extension \ModuleHandlerInterface ;
1415use Drupal \Core \Extension \ModuleInstallerInterface ;
1516use Drupal \Core \Extension \ThemeHandlerInterface ;
17+ use Drupal \Core \Link ;
18+ use Drupal \Core \Url ;
19+ use Drupal \user \PermissionHandlerInterface ;
1620use Drush \Attributes as CLI ;
1721use Drush \Commands \AutowireTrait ;
1822use Drush \Commands \DrushCommands ;
@@ -33,7 +37,8 @@ public function __construct(
3337 protected ModuleInstallerInterface $ moduleInstaller ,
3438 protected ModuleHandlerInterface $ moduleHandler ,
3539 protected ThemeHandlerInterface $ themeHandler ,
36- protected ModuleExtensionList $ extensionListModule
40+ protected ModuleExtensionList $ extensionListModule ,
41+ protected PermissionHandlerInterface $ permissionHandler
3742 ) {
3843 parent ::__construct ();
3944 }
@@ -63,6 +68,11 @@ public function getExtensionListModule(): ModuleExtensionList
6368 return $ this ->extensionListModule ;
6469 }
6570
71+ public function getPermissionHandler (): PermissionHandlerInterface
72+ {
73+ return $ this ->permissionHandler ;
74+ }
75+
6676 /**
6777 * Enable one or more modules.
6878 */
@@ -93,7 +103,20 @@ public function install(array $modules): void
93103 if (batch_get ()) {
94104 drush_backend_batch_process ();
95105 }
96- $ this ->logger ()->success (dt ('Successfully installed: !list ' , $ todo_str ));
106+
107+ $ moduleData = $ this ->getExtensionListModule ()->getList ();
108+ foreach ($ todo as $ moduleName ) {
109+ $ links = $ this ->getModuleLinks ($ moduleData [$ moduleName ]);
110+ $ links = array_map (function ($ link ) {
111+ return sprintf ('<href=%s>%s</> ' , $ link ->getUrl ()->setAbsolute ()->toString (), $ link ->getText ());
112+ }, $ links );
113+
114+ if ($ links === []) {
115+ $ this ->logger ()->success (dt ('Module %name has been installed. ' , ['%name ' => $ moduleName ]));
116+ } else {
117+ $ this ->logger ()->success (dt ('Module %name has been installed. (%links) ' , ['%name ' => $ moduleName , '%links ' => implode (' - ' , $ links )]));
118+ }
119+ }
97120 }
98121
99122 /**
@@ -371,4 +394,29 @@ public function addUninstallDependencies($modules)
371394 }
372395 return $ module_list ;
373396 }
397+
398+ protected function getModuleLinks (Extension $ module ): array
399+ {
400+ $ links = [];
401+
402+ // Generate link for module's help page. Assume that if a hook_help()
403+ // implementation exists then the module provides an overview page, rather
404+ // than checking to see if the page exists, which is costly.
405+ if ($ this ->getModuleHandler ()->moduleExists ('help ' ) && $ module ->status && $ this ->getModuleHandler ()->hasImplementations ('help ' , $ module ->getName ())) {
406+ $ links [] = Link::fromTextAndUrl (dt ('Help ' ), Url::fromRoute ('help.page ' , ['name ' => $ module ->getName ()]));
407+ }
408+
409+ // Generate link for module's permissions page.
410+ if ($ module ->status && $ this ->getPermissionHandler ()->moduleProvidesPermissions ($ module ->getName ())) {
411+ $ links [] = Link::fromTextAndUrl (dt ('Permissions ' ), Url::fromRoute ('user.admin_permissions.module ' , ['modules ' => $ module ->getName ()]));
412+ }
413+
414+ // Generate link for module's configuration page, if it has one.
415+ if ($ module ->status && isset ($ module ->info ['configure ' ])) {
416+ $ route_parameters = $ module ->info ['configure_parameters ' ] ?? [];
417+ $ links [] = Link::fromTextAndUrl (dt ('Configure ' ), Url::fromRoute ($ module ->info ['configure ' ], $ route_parameters ));
418+ }
419+
420+ return $ links ;
421+ }
374422}
0 commit comments