WHMCS升级8.5.1后cPanel登录钩子setUri()报错问题咨询
问题原因
- WHMCS 8.5版本调整了服务详情侧边栏cPanel、Webmail登录按钮的内部菜单项ID:旧版本使用
Login to cPanel、Login to Webmail作为菜单项的内部检索标识,8.5版本将标识修改为cpanel_login、webmail_login。旧代码传入旧ID调用getChild()时会返回null,后续对null值调用setUri()方法就触发了题中的致命错误。 - 旧代码仅校验了父级菜单
Service Details Actions存在,未对要修改的两个子菜单项做存在性判断,只要子项ID变更就会直接触发报错。 - 旧代码未判断当前页面是否存在
service上下文,在非服务详情页面触发钩子时,也可能出现取值错误。
适配WHMCS 8.5+的修复代码
将原钩子文件替换为以下代码即可,代码同时兼容8.4及更早版本,不会出现版本切换后失效的问题:
<?php use WHMCS\View\Menu\Item as MenuItem; use WHMCS\View\Menu\Menu; add_hook('ClientAreaPrimarySidebar', 1, function(MenuItem $primarySidebar) { $service = Menu::context('service'); // 非服务详情页直接终止逻辑 if (!$service) { return; } $domain = $service->domain; $servertype = $service->product->servertype; // 非cPanel类型服务不修改菜单 if ($servertype != "cpanel") { return; } $actionsMenu = $primarySidebar->getChild('Service Details Actions'); if (!is_null($actionsMenu)) { // 兼容新旧版本菜单项ID,做存在性校验后再修改链接 $cpanelItem = $actionsMenu->getChild('cpanel_login') ?? $actionsMenu->getChild('Login to cPanel'); if ($cpanelItem) { $cpanelItem->setUri('http://' . $domain . '/cpanel'); } $webmailItem = $actionsMenu->getChild('webmail_login') ?? $actionsMenu->getChild('Login to Webmail'); if ($webmailItem) { $webmailItem->setUri('http://' . $domain . '/webmail'); } } });
注意事项
- 如果你的站点已经启用HTTPS,将代码中跳转链接的
http://替换为https://即可,避免浏览器拦截不安全跳转。 - 代码增加了多层非空判断,即使后续WHMCS版本再次调整菜单项ID,也不会触发致命错误,只会跳过链接修改逻辑,不影响站点正常运行。
内容的提问来源于stack exchange,提问作者ThePolovsky
相关产品推荐
相关产品推荐

