Answers.Body: <p>The way in which <code>$mask</code> is used in combination with the <code>bit</code> value of each link (e.g. <code>$link['bit']</code>) to show or suppress links is defined in the <a href="https://github.com/civicrm/civicrm-core/blob/master/CRM/Core/Action.php#LC321" rel="nofollow noreferrer"><code>CRM_Core_Action::filterLinks()</code></a> function. Specifically, if the expression <code>(!$mask || !array_key_exists('bit', $link) || ($mask &amp; $link['bit']))</code> is true, then the link is included. Otherwise it is removed (<code>unset()</code>) from the <code>$links</code> array.</p>
  <p>In other words, the link is <strong>displayed</strong> if any of the following is true:</p>
  <ul>
  <li><code>$mask</code> is zero;</li>
  <li>the <code>$link</code> array does not contain a <code>'bit'</code> field;</li>
  <li>the <code>bitwise and</code> of <code>$mask</code> and <code>$link['bit']</code> is nonzero.</li>
  </ul>
  <p>Otherwise, the link is removed.</p>
  <p>What I have not figured out is where and how the <code>$mask</code> value is initialized, and where the existing <code>$link['bit']</code> values come from. For example, on the Contact Search Results page, the links include the following bit values. It's hard to see how a bitwise mask could be used to filter out the links with bit values of 7000 and greater. And it appears the bit values are sequentially assigned, so the link action for a given bit value may change depending on the user's permissions. It seems it would be safer to filter on, say, the <code>$link['url']</code> value to find and remove or alter particular links.</p>
  <pre><code>Decimal Hex     Binary                      Link Text
     4    00004   0000 0000 0000 0000 0100    View
     2    00002   0000 0000 0000 0000 0010    Edit
  7000    01B58   0000 0001 1011 0101 1000    Delete
  7001    01B59   0000 0001 1011 0101 1001    Add Donation
  7002    01B5A   0000 0001 1011 0101 1010    Add Pledge
  7003    01B5B   0000 0001 1011 0101 1011    Add Membership
  7004    01B5C   0000 0001 1011 0101 1100    Add Relationship
  7005    01B5D   0000 0001 1011 0101 1101    Record Activity
  7006    01B5E   0000 0001 1011 0101 1110    Add Note
  7007    01B5F   0000 0001 1011 0101 1111    Send an Email
  7008    01B60   0000 0001 1011 0110 0000    Add to Group
  7009    01B61   0000 0001 1011 0110 0001    Tag Contact
  7010    01B62   0000 0001 1011 0110 0010    Communication Preferences Link
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-03-05T08:38:50.457Z
Answers.LastActivityDate: 2021-03-05T08:38:50.457Z
Answers.UserDisplayName: Martin_W
Body: <p>I don't really understand what the point of the $mask variable that is passed to hook_civicrm_links is. Can anyone explain it to me?</p>
  <p>PS I understand how to use the other variables and I might not need to use $mask (the examples in the docs don't) but I feel like I might be missing out on something ingenious here.</p>
  <p><a href="https://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_links" rel="nofollow noreferrer">The docs</a> say:</p>
  <blockquote>
  <p>$links = the links array to modify in-place</p>
  <p>each item in the array may have:</p>
  <ul>
  <li><p>name: the link text</p>
  </li>
  <li><p>url: the link URL base path (like 'civicrm/contact/view', and fillable from $values)</p>
  </li>
  <li><p>qs: the link URL query parameters to be used by sprintf() with $values (like 'reset=1&amp;cid=%%id%%' when $values['id'] is the contact ID)</p>
  </li>
  <li><p>title (optional): the text that appears when hovering over the link</p>
  </li>
  <li><p>extra (optional): additional attributes for the  tag (fillable from $values)</p>
  </li>
  <li><p>bit (optional): a binary number that will be fitered by $mask (sending nothing as $links['bit'] means the link will always display)</p>
  </li>
  <li><p>ref (optional, recommended): a CSS class to apply to the  tag.</p>
  </li>
  <li><p>class (optional): Any other CSS classes to apply to the  tag (e.g. no-popup).</p>
  </li>
  </ul>
  <p>$mask = a bitmask that will fiter $links</p>
  </blockquote>
  <p>So I am guessing it is something to do with permissions.  A but of human friendly explanation with context and example would be much appreciated :)</p>
  
Tags: <hooks><links>
Title: How am I meant to use $mask in hook_civicrm_links?
ThreadText: # How am I meant to use $mask in hook_civicrm_links?
  
  (Asked by: username_0 on 2017-02-01)
  
  I don't really understand what the point of the $mask variable that is passed to hook\_civicrm\_links is. Can anyone explain it to me?
  
  PS I understand how to use the other variables and I might not need to use $mask (the examples in the docs don't) but I feel like I might be missing out on something ingenious here.
  
  [The docs](https://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_links) say:
  
  > $links = the links array to modify in-place
  >
  > each item in the array may have:
  >
  > * name: the link text
  > * url: the link URL base path (like 'civicrm/contact/view', and fillable from $values)
  > * qs: the link URL query parameters to be used by sprintf() with $values (like 'reset=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 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 tag.
  > * class (optional): Any other CSS classes to apply to the tag (e.g. no-popup).
  >
  > $mask = a bitmask that will fiter $links
  
  So I am guessing it is something to do with permissions. A but of human friendly explanation with context and example would be much appreciated :)
  
  **Tags:** hooks, links
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2021-03-05. Score: 0
  
  The way in which $mask is used in combination with the bit value of each link (e.g. $link['bit']) to show or suppress links is defined in the CRM_Core_Action::filterLinks() function. Specifically, if the expression (!$mask || !array_key_exists('bit', $link) || ($mask & $link['bit'])) is true, then the link is included. Otherwise it is removed (unset()) from the $links array.
  In other words, the link is displayed if any of the following is true:
  
  $mask is zero;
  the $link array does not contain a 'bit' field;
  the bitwise and of $mask and $link['bit'] is nonzero.
  
  Otherwise, the link is removed.
  What I have not figured out is where and how the $mask value is initialized, and where the existing $link['bit'] values come from. For example, on the Contact Search Results page, the links include the following bit values. It's hard to see how a bitwise mask could be used to filter out the links with bit values of 7000 and greater. And it appears the bit values are sequentially assigned, so the link action for a given bit value may change depending on the user's permissions. It seems it would be safer to filter on, say, the $link['url'] value to find and remove or alter particular links.
  Decimal Hex     Binary                      Link Text
     4    00004   0000 0000 0000 0000 0100    View
     2    00002   0000 0000 0000 0000 0010    Edit
  7000    01B58   0000 0001 1011 0101 1000    Delete
  7001    01B59   0000 0001 1011 0101 1001    Add Donation
  7002    01B5A   0000 0001 1011 0101 1010    Add Pledge
  7003    01B5B   0000 0001 1011 0101 1011    Add Membership
  7004    01B5C   0000 0001 1011 0101 1100    Add Relationship
  7005    01B5D   0000 0001 1011 0101 1101    Record Activity
  7006    01B5E   0000 0001 1011 0101 1110    Add Note
  7007    01B5F   0000 0001 1011 0101 1111    Send an Email
  7008    01B60   0000 0001 1011 0110 0000    Add to Group
  7009    01B61   0000 0001 1011 0110 0001    Tag Contact
  7010    01B62   0000 0001 1011 0110 0010    Communication Preferences Link
  
  
  ---
  
  