Files
WebForm-mw/civi-extension/webform-mw/webform_mw.php
T
Joel Brock 4d194176b1 Civi extension: register xml/Menu via hook_civicrm_xmlMenu
The Engagement Report tab on Organization contact pages was loading the
contact-view summary recursively inside its own tab pane. Root cause:
Civi's menu router was not picking up the extension's xml/Menu file, so
`civicrm/contact/view/engagement-report` fell back to the parent
`civicrm/contact/view` route. Adding an explicit hook_civicrm_xmlMenu
implementation forces the menu file to register, after which the route
resolves to CRM_WebformMw_Page_Tab and the iframe renders as intended.

Deploy: replace the extension files on the Civi server, then in
Administer → System Settings → Extensions Disable + re-Enable webform-mw
(or run `cv flush` on the server) so the menu cache is rebuilt.
2026-06-09 13:32:24 -07:00

96 lines
2.7 KiB
PHP

<?php
/**
* WebForm-mw CiviCRM extension.
*
* Adds an "Engagement Report" tab to Organization contact-view pages that
* embeds the WebForm-mw Next.js staff report via an iframe.
*
* Configuration (in civicrm.settings.php or as env vars on the Civi server):
*
* define('WEBFORM_MW_APP_URL', 'https://survey.fci.coop');
* define('WEBFORM_MW_STAFF_KEY', '<the STAFF_REPORT_KEY shared with the app>');
*
* Both values must be set or the tab renders a help banner explaining what
* to configure. See README.md.
*/
/**
* Resolve the app URL from constant or env. Empty string when unset.
*/
function _webform_mw_app_url(): string {
if (defined('WEBFORM_MW_APP_URL')) {
return rtrim((string) constant('WEBFORM_MW_APP_URL'), '/');
}
$env = getenv('WEBFORM_MW_APP_URL');
return is_string($env) && $env !== '' ? rtrim($env, '/') : '';
}
/**
* Resolve the staff secret from constant or env. Empty string when unset.
*/
function _webform_mw_staff_key(): string {
if (defined('WEBFORM_MW_STAFF_KEY')) {
return (string) constant('WEBFORM_MW_STAFF_KEY');
}
$env = getenv('WEBFORM_MW_STAFF_KEY');
return is_string($env) ? $env : '';
}
/**
* Implements hook_civicrm_xmlMenu().
*
* Registers this extension's menu file. Civi 5.50+ usually auto-discovers
* `xml/Menu/*.xml` from extensions, but some installations only pick the
* file up when an explicit hook returns it. Without this the new path
* `civicrm/contact/view/engagement-report` falls back to the parent
* `civicrm/contact/view` route and the tab pane recursively embeds the
* contact-view summary instead of our iframe.
*/
function webform_mw_civicrm_xmlMenu(&$files) {
$files[] = __DIR__ . '/xml/Menu/webform_mw.xml';
}
/**
* Implements hook_civicrm_tabset().
*
* Adds the Engagement Report tab to the Organization contact summary tabset.
* Other contact types (Individual, Household) get no tab.
*/
function webform_mw_civicrm_tabset($tabsetName, &$tabs, $context) {
if ($tabsetName !== 'civicrm/contact/view') {
return;
}
$cid = $context['contact_id'] ?? NULL;
if (!$cid) {
return;
}
// Restrict to Organization contacts.
$contactType = NULL;
try {
$contactType = civicrm_api3('Contact', 'getvalue', [
'id' => (int) $cid,
'return' => 'contact_type',
]);
}
catch (\Throwable $e) {
// Quietly skip — failing here should not break the contact page.
return;
}
if ($contactType !== 'Organization') {
return;
}
$tabs[] = [
'id' => 'engagement_report',
'title' => ts('Engagement Report'),
'weight' => 200,
'count' => NULL,
'icon' => 'crm-i fa-line-chart',
'url' => CRM_Utils_System::url(
'civicrm/contact/view/engagement-report',
"reset=1&cid={$cid}&snippet=1"
),
];
}