hook_civicrm_links¶
Summary¶
Programmatically alter a list of links.
This hook is called from various screens that display lists of links, including:
- Action links at the end of a search result row
- Action links on a tabular admin screen
- Action links on a tabular contact summary tab
- The "Create New" dropdown
- The Actions dropdown at the top of a contact record
Notes¶
Conversions impacting this hook
Many screens that display tabular results are in the process of being converted to SearchKit displays, including admin pages, dashboards, contact summary tabs, component searches, and reports. SearchKit displays do not call this hook as their links can be modified via the GUI. If you need to modify links on such a screen, consider replacing it with a SearchDisplay instead of using this hook, or try enabling the CiviCRM Admin UI extension which may already contain a replacement.
Definition¶
hook_civicrm_links(string $op, string $objectName, $objectID, array &$links, int &$mask, array &$values)
Parameters¶
-
string
$op
- the context in which the links appear such asview.contact.activity
,survey.dashboard.row
,pcp.user.actions
orpdfFormat.manage.action
. This should be lowercase but there are some inconsistencies in CiviCRM core (eg.view.contact.userDashBoard
). In many cases$objectName
is enough to filter on but you can filter on context as well. -
string
$objectName
- the entity the links relate to (orNULL
if$op
iscreate.new.shortcuts
) -
int|string
$objectID
- the CiviCRM internal ID of the entity or string of the extension name for list of extensions. (orNULL
if$op
iscreate.new.shortcuts
) -
array
$links
- the links to modify in placeeach item in the array may have:
-
name
: the link text -
url
: the link URL base path (likecivicrm/contact/view
, and fillable from$values
) -
qs
: the link URL query parameters to be used by sprintf() with $values (likereset=1&cid=%%id%%
when$values['id']
is the contact ID) -
title
(optional): the text that appears when hovering over the link -
extra
(optional): additional attributes for the<a>
tag (fillable from$values
) -
bit
(optional): a binary number that will be fitered by $mask (sending nothing as$links['bit']
means the link will always display) -
ref
(optional, recommended): a CSS class to apply to the<a>
tag. -
class
(optional): Any other CSS classes to apply to the<a>
tag (e.g. no-popup). -
int
weight
(recommended): Weight is used to order the links. If not set 0 will be used but e-notices could occur. This was introduced in CiviCRM 5.63 so it will not have any impact on earlier versions of CiviCRM. There are some conventions for core weights: -CRM_Core_Action::VIEW
-20 -CRM_Core_Action::UPDATE
-10 -CRM_Core_Action::ENABLE
40 -CRM_Core_Action::DISABLE
40 -CRM_Core_Action::DELETE
100 -
int|null
$mask
- a bitmask that will filter$links
-
array
$values
- values to fill$links['url']
,$links['qs']
, and/or$links['extra']
usingsprintf()
-style percent signs
-
Link interactions with pop-ups
On many screens, links will open a pop-up when clicked.
To prevent this, for example if the link initiates a file download, add class => 'no-popup'
.
Also note that inside pop-ups, many links are turned into buttons, and some attributes (including class
) will be lost or transformed.
Tip
If you omit the qs
parameter, Civi will interpret the url
as a regular URL rather than as a Civi admin page.
This is useful if you want to link to a non-Civi page.
If needed, you can add query string parameters to the url
by obtaining the needed values from &$values
.
(Works for Civi Profile search results.)
Returns¶
NULL
Examples¶
function MODULENAME_civicrm_links(string $op, ?string $objectName, $objectID, array &$links, ?int &$mask, array &$values): void {
$myLinks = [];
if ($objectName !== 'Contact') {
return;
}
switch ($op) {
case 'view.contact.activity':
// Adds a link to the main tab.
$links[] = [
'name' => E::ts('My Module Actions'),
'url' => 'mymodule/civicrm/actions/%%myObjectID%%',
'title' => 'New Thing',
'class' => 'no-popup',
'weight' => 25,
];
$values['myObjectID'] = $objectID;
break;
case 'contact.selector.row':
// Add a similar thing when a contact appears in a row
$links[] = [
'name' => E::ts('My Module'),
'url' => 'mymodule/civicrm/actions/%%myObjectID%%',
'title' => 'New Thing',
'qs' => 'reset=1&tid=%%thingID%%',
'class' => 'no-popup',
'weight' => 30,
];
$values['myObjectID'] = $objectID;
$values['thingID'] = 'my_thing';
break;
case 'create.new.shortcuts':
// add link to create new profile
$links[] = [
'url' => '/civicrm/admin/uf/group?action=add&reset=1',
'name' => E::ts('New Profile'),
'weight' => 45,
// Old extensions using 'title' will still work.
];
break;
case 'view.report.links':
// Disable copy & delete links.
unset($links['copy']);
unset($links['delete']);
}
}
Adding contextual links to the rows of a contact's Events tab and Find Participants search result
function mymodule_civicrm_links(string $op, string $objectName, ?int $objectID, array &$links, ?int &$mask, array &$values): void {
// Create a Send Invoice link with the context of the participant's order ID (a custom participant field).
if ($objectName !== 'Participant' || $op !== 'participant.selector.row') {
return;
}
$contactID = $values['cid'];
$orderID = mymodule_myCustomFunction($objectID);
//check if this participant is a student with a parent, for saving the email.
//if not, fall back to current contact record
$contactID = \Civi\Api4\Relationship::get(FALSE)
->addWhere('relationship_type_id', '=', 1)
->addWhere('contact_id_a', '=', $contactID)
->addSelect('contact_id_b')
->execute()->first()['contact_id_b'] ?: $contactID;
$links[] = [
'name' => E::ts('Send Invoice'),
'title' => E::ts('Send Invoice'),
'url' => 'civicrm/activity/email/add',
'qs' => "action=add&reset=1&cid=$contactID&selectedChild=activity&atype=3&order_id=$orderID",
'weight' => 25,
];
}