Answers.Body: <p>Finally, I solved the problem like this:</p>
  <ol>
  <li>sites/all/modules/civicrm/templates/CRM/Case/Form/ActivityTab.tpl -&gt; add another cell to the activity table:
  <code>&lt;th data-data=&quot;document_links&quot; data-orderable=&quot;false&quot; class=&quot;crm-case-activities-status&quot;&gt;&amp;nbsp;Dokumente &lt;/th&gt;</code></li>
  <li>sites/all/modules/civicrm/CRM/Case/Selector/Search.php -&gt; add the function <code>addDocumentLinks()</code> that is basically only the document-link part of the original function <code>addCaseActivityLinks()</code>:</li>
  </ol>
  <pre><code>public static function addDocumentLinks($caseID, $contactID, $userID, $context, $dao, $allowView = TRUE) {
  $caseDeleted = CRM_Core_DAO::getFieldValue('CRM_Case_DAO_Case', $caseID, 'is_deleted');
  $actionLinks = self::actionLinks();
  // Check logged in user for permission.
  if (CRM_Case_BAO_Case::checkPermission($dao-&gt;id, 'view', $dao-&gt;activity_type_id, $userID)) {
  $permissions[] = CRM_Core_Permission::VIEW;
    }
  if (!$allowView) {
  unset($actionLinks[CRM_Core_Action::VIEW]);
    }
  $linksMarkup = &quot;&quot;;
  // if there are file attachments we will return how many and, if only one, add a link to it
  if (!empty($dao-&gt;attachment_ids)) {
  $linksMarkup .= implode(' ', CRM_Core_BAO_File::paperIconAttachment('civicrm_activity', $dao-&gt;id));
    }
  return $linksMarkup;
  }
  </code></pre>
  <ol start="3">
  <li>sites/all/modules/civicrm/CRM/Case/Selector/Search.php -&gt; delete the document-link part from the original function <code>addCaseActivityLinks()</code>:</li>
  </ol>
  <pre><code>public static function addCaseActivityLinks($caseID, $contactID, $userID, $context, $dao, $allowView = TRUE) {
  $caseDeleted = CRM_Core_DAO::getFieldValue('CRM_Case_DAO_Case', $caseID, 'is_deleted');
  $actionLinks = self::actionLinks();
  // Check logged in user for permission.
  if (CRM_Case_BAO_Case::checkPermission($dao-&gt;id, 'view', $dao-&gt;activity_type_id, $userID)) {
  $permissions[] = CRM_Core_Permission::VIEW;
    }
  if (!$allowView) {
  unset($actionLinks[CRM_Core_Action::VIEW]);
    }
  if (!$dao-&gt;deleted) {
  // Activity is not deleted, allow user to edit/delete if they have permission
      // hide Edit link if:
      // 1. User does not have edit permission.
      // 2. Activity type is NOT editable (special case activities).CRM-5871
  if (CRM_Case_BAO_Case::checkPermission($dao-&gt;id, 'edit', $dao-&gt;activity_type_id, $userID)) {
  $permissions[] = CRM_Core_Permission::EDIT;
      }
  if (in_array($dao-&gt;activity_type_id, CRM_Activity_BAO_Activity::getViewOnlyActivityTypeIDs())) {
  unset($actionLinks[CRM_Core_Action::UPDATE]);
      }
  if (CRM_Case_BAO_Case::checkPermission($dao-&gt;id, 'delete', $dao-&gt;activity_type_id, $userID)) {
  $permissions[] = CRM_Core_Permission::DELETE;
      }
  unset($actionLinks[CRM_Core_Action::RENEW]);
    }
  $extraMask = 0;
  if ($dao-&gt;deleted &amp;&amp; !$caseDeleted
  &amp;&amp; (CRM_Case_BAO_Case::checkPermission($dao-&gt;id, 'delete', $dao-&gt;activity_type_id, $userID))) {
  // Case is not deleted but activity is.
      // Allow user to restore activity if they have delete permissions
  unset($actionLinks[CRM_Core_Action::DELETE]);
  $extraMask = CRM_Core_Action::RENEW;
    }
  if (!CRM_Case_BAO_Case::checkPermission($dao-&gt;id, 'Move To Case', $dao-&gt;activity_type_id)) {
  unset($actionLinks[CRM_Core_Action::DETACH]);
    }
  if (!CRM_Case_BAO_Case::checkPermission($dao-&gt;id, 'Copy To Case', $dao-&gt;activity_type_id)) {
  unset($actionLinks[CRM_Core_Action::COPY]);
    }
  $actionMask = CRM_Core_Action::mask($permissions) | $extraMask;
  $values = [
  'aid' =&gt; $dao-&gt;id,
  'cid' =&gt; $contactID,
  'cxt' =&gt; empty($context) ? '' : &quot;&amp;context={$context}&quot;,
  'caseid' =&gt; $caseID,
    ];
  $linksMarkup = CRM_Core_Action::formLink($actionLinks,
  $actionMask,
  $values,
  ts('more'),
  FALSE,
  'case.tab.row',
  'Activity',
  $dao-&gt;id
  );
  
  // deleted part
  
  return $linksMarkup;
  }
  </code></pre>
  <ol start="4">
  <li>sites/all/modules/civicrm/CRM/Case/BAO/Case.php -&gt; add the function call for <code>addDocumentLinks()</code> inside the function <code>getCaseActivity()</code> inside the while loop <code>while($dao-&gt;fetch()) { }</code> (approx. line 1091):</li>
  </ol>
  <pre><code>$caseActivities[$caseActivityId]['document_links']
          = CRM_Case_Selector_Search::addDocumentLinks($caseID, $contactID, $userID, $context, $dao);
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-10-21T12:36:55.800Z
Answers.LastActivityDate: 2020-10-21T12:42:57.757Z
Answers.LastEditDate: 2020-10-21T12:42:57.757Z
Answers.UserDisplayName: emma
Answers.Body: <p>It's in <a href="https://github.com/civicrm/civicrm-core/blob/7dc9cb422d359515633c466ad1d1526db9c25bfc/CRM/Case/Selector/Search.php#L541" rel="nofollow noreferrer">CRM/Case/Selector/Search.php</a> in addCaseActivityLinks().</p>
  <p>But on a more general note, between this and your other questions there's a lot of customizing going on and it may make upgrading difficult. At some point you might want to consider something like <a href="https://www.drupal.org/project/webform_civicrm/" rel="nofollow noreferrer">webform</a> to customize forms or even going full custom and making your own pages/forms in an extension and using the api to pull in just the data you need.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-10-21T07:53:18.207Z
Answers.Text: We are already using Drupal webform, but only for some menue pages. I'll take a closer look into that. The reason I am working in this nonperfect way right now is that the customized software should go into the next test phase with an NGO in a while. So I'd put all my changes in an extension (or similar solution) after that.
Answers.UserDisplayName: emma
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-10-21T08:19:30.313Z
Answers.Text: What about the Custom Template Dir and the Custom PHP Dir in /civicrm/admin/setting/path?reset=1 ? Would you recommend using them?
Answers.UserDisplayName: emma
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-10-21T17:34:34.620Z
Answers.Text: Only for small stuff that's easy to reapply after each upgrade, since you'll still need to merge in any core changes into your overridden file after every upgrade. (I haven't used this extension but see also https://github.com/artfulrobot/patchwork)
Answers.UserDisplayName: Demerit
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-10-20T13:18:56.440Z
Answers.LastActivityDate: 2020-10-20T13:18:56.440Z
Answers.UserDisplayName: Demerit
Body: <p>In the CiviCRM Case View, I want to add another column to the Activities table. Right now, the last column contains some links (&quot;View&quot;, &quot;Edit&quot;, &quot;Delete&quot;) and one link to an attached document if existent.
  I want to split this last column in two, so the link to attachments and the other links are in two different columns.</p>
  <p>Therefore, I doubled the last column inside the sites/all/modules/civicrm/templates/CRM/Case/Form/ActivityTab.tpl template:</p>
  <pre><code>&lt;th data-data=&quot;links&quot; data-orderable=&quot;false&quot; class=&quot;crm-case-activities-status&quot;&gt;&amp;nbsp;&lt;/th&gt;
  &lt;th data-data=&quot;links&quot; data-orderable=&quot;false&quot; class=&quot;crm-case-activities-status&quot;&gt;&amp;nbsp;&lt;/th&gt;
  </code></pre>
  <p>Then, I adapted the first column like this:</p>
  <pre><code>&lt;th data-data=&quot;links&quot; class=&quot;crm-case-activities-status&quot;&gt;&amp;nbsp;Dokumente &lt;/th&gt;
  &lt;th data-data=&quot;links&quot; data-orderable=&quot;false&quot; class=&quot;crm-case-activities-status&quot;&gt;&amp;nbsp;&lt;/th&gt;
  </code></pre>
  <p>Now, I am stuck at the content part. Does anyone know from which location &quot;links&quot; is called or created? I read that the html &quot;data&quot; attribute can be used by a JavaScript script. As I need only the links to any attached documents, but not the others, I would need to alter that script.</p>
  <p>Edit: Alternatively, it would be helpful to know where the Activity table is created (<code>&lt;table id=&quot;case_id_{$caseid}&quot;  class=&quot;nestedActivitySelector crm-ajax-table&quot; data-page-length=&quot;100&quot;&gt;</code>).</p>
  <p>Edit: Reading Demerit's answer, I have checked the addCaseActivityLinks() function. To adapt it for my documents column, I thought about copying the function, renaming it, adapting it, and make the ActivityTab.tpl call it inside my document  tag.
  Another solution would be to use an existing param of the addCaseActivityLinks() function in order to determine with which value of data-data the function has been called (<code>data-data=&quot;links&quot;</code> or <code>data-data=&quot;documents&quot;</code>). These existing params are: <code>$caseID, $contactID, $userID, $context, $dao, $allowView = TRUE</code></p>
  <p>I think I am still missing understanding of how/where the addCaseActivityLinks() function is called, so I would be able to implement one of the abovementioned solutions. I searched the whole project for a fucntion call, but couldn't find one. Any hint anyone?</p>
  
Tags: <civicase>
Title: Adding a column for Document Links to the Activity table in CaseView
ThreadText: # Adding a column for Document Links to the Activity table in CaseView
  
  (Asked by: username_0 on 2020-10-20)
  
  In the CiviCRM Case View, I want to add another column to the Activities table. Right now, the last column contains some links ("View", "Edit", "Delete") and one link to an attached document if existent.
  I want to split this last column in two, so the link to attachments and the other links are in two different columns.
  Therefore, I doubled the last column inside the sites/all/modules/civicrm/templates/CRM/Case/Form/ActivityTab.tpl template:
   
   
  
  Then, I adapted the first column like this:
   Dokumente 
   
  
  Now, I am stuck at the content part. Does anyone know from which location "links" is called or created? I read that the html "data" attribute can be used by a JavaScript script. As I need only the links to any attached documents, but not the others, I would need to alter that script.
  Edit: Alternatively, it would be helpful to know where the Activity table is created ().
  Edit: Reading username_1's answer, I have checked the addCaseActivityLinks() function. To adapt it for my documents column, I thought about copying the function, renaming it, adapting it, and make the ActivityTab.tpl call it inside my document  tag.
  Another solution would be to use an existing param of the addCaseActivityLinks() function in order to determine with which value of data-data the function has been called (data-data="links" or data-data="documents"). These existing params are: $caseID, $contactID, $userID, $context, $dao, $allowView = TRUE
  I think I am still missing understanding of how/where the addCaseActivityLinks() function is called, so I would be able to implement one of the abovementioned solutions. I searched the whole project for a fucntion call, but couldn't find one. Any hint anyone?
  
  **Tags:** civicase
  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_0 on 2020-10-21. Score: 2 | Accepted answer
  
  Finally, I solved the problem like this:
  
  sites/all/modules/civicrm/templates/CRM/Case/Form/ActivityTab.tpl -> add another cell to the activity table:
   Dokumente 
  sites/all/modules/civicrm/CRM/Case/Selector/Search.php -> add the function addDocumentLinks() that is basically only the document-link part of the original function addCaseActivityLinks():
  
  public static function addDocumentLinks($caseID, $contactID, $userID, $context, $dao, $allowView = TRUE) {
  $caseDeleted = CRM_Core_DAO::getFieldValue('CRM_Case_DAO_Case', $caseID, 'is_deleted');
  $actionLinks = self::actionLinks();
  // Check logged in user for permission.
  if (CRM_Case_BAO_Case::checkPermission($dao->id, 'view', $dao->activity_type_id, $userID)) {
  $permissions[] = CRM_Core_Permission::VIEW;
    }
  if (!$allowView) {
  unset($actionLinks[CRM_Core_Action::VIEW]);
    }
  $linksMarkup = "";
  // if there are file attachments we will return how many and, if only one, add a link to it
  if (!empty($dao->attachment_ids)) {
  $linksMarkup .= implode(' ', CRM_Core_BAO_File::paperIconAttachment('civicrm_activity', $dao->id));
    }
  return $linksMarkup;
  }
  
  
  sites/all/modules/civicrm/CRM/Case/Selector/Search.php -> delete the document-link part from the original function addCaseActivityLinks():
  
  public static function addCaseActivityLinks($caseID, $contactID, $userID, $context, $dao, $allowView = TRUE) {
  $caseDeleted = CRM_Core_DAO::getFieldValue('CRM_Case_DAO_Case', $caseID, 'is_deleted');
  $actionLinks = self::actionLinks();
  // Check logged in user for permission.
  if (CRM_Case_BAO_Case::checkPermission($dao->id, 'view', $dao->activity_type_id, $userID)) {
  $permissions[] = CRM_Core_Permission::VIEW;
    }
  if (!$allowView) {
  unset($actionLinks[CRM_Core_Action::VIEW]);
    }
  if (!$dao->deleted) {
  // Activity is not deleted, allow user to edit/delete if they have permission
      // hide Edit link if:
      // 1. User does not have edit permission.
      // 2. Activity type is NOT editable (special case activities).CRM-5871
  if (CRM_Case_BAO_Case::checkPermission($dao->id, 'edit', $dao->activity_type_id, $userID)) {
  $permissions[] = CRM_Core_Permission::EDIT;
      }
  if (in_array($dao->activity_type_id, CRM_Activity_BAO_Activity::getViewOnlyActivityTypeIDs())) {
  unset($actionLinks[CRM_Core_Action::UPDATE]);
      }
  if (CRM_Case_BAO_Case::checkPermission($dao->id, 'delete', $dao->activity_type_id, $userID)) {
  $permissions[] = CRM_Core_Permission::DELETE;
      }
  unset($actionLinks[CRM_Core_Action::RENEW]);
    }
  $extraMask = 0;
  if ($dao->deleted && !$caseDeleted
  && (CRM_Case_BAO_Case::checkPermission($dao->id, 'delete', $dao->activity_type_id, $userID))) {
  // Case is not deleted but activity is.
      // Allow user to restore activity if they have delete permissions
  unset($actionLinks[CRM_Core_Action::DELETE]);
  $extraMask = CRM_Core_Action::RENEW;
    }
  if (!CRM_Case_BAO_Case::checkPermission($dao->id, 'Move To Case', $dao->activity_type_id)) {
  unset($actionLinks[CRM_Core_Action::DETACH]);
    }
  if (!CRM_Case_BAO_Case::checkPermission($dao->id, 'Copy To Case', $dao->activity_type_id)) {
  unset($actionLinks[CRM_Core_Action::COPY]);
    }
  $actionMask = CRM_Core_Action::mask($permissions) | $extraMask;
  $values = [
  'aid' => $dao->id,
  'cid' => $contactID,
  'cxt' => empty($context) ? '' : "&context={$context}",
  'caseid' => $caseID,
    ];
  $linksMarkup = CRM_Core_Action::formLink($actionLinks,
  $actionMask,
  $values,
  ts('more'),
  FALSE,
  'case.tab.row',
  'Activity',
  $dao->id
  );
  
  // deleted part
  
  return $linksMarkup;
  }
  
  
  sites/all/modules/civicrm/CRM/Case/BAO/Case.php -> add the function call for addDocumentLinks() inside the function getCaseActivity() inside the while loop while($dao->fetch()) { } (approx. line 1091):
  
  $caseActivities[$caseActivityId]['document_links']
          = CRM_Case_Selector_Search::addDocumentLinks($caseID, $contactID, $userID, $context, $dao);
  
  
  ---
  
  ### Answer by username_1 on 2020-10-20. Score: 1
  
  It's in [CRM/Case/Selector/Search.php](https://github.com/civicrm/civicrm-core/blob/7dc9cb422d359515633c466ad1d1526db9c25bfc/CRM/Case/Selector/Search.php#L541) in addCaseActivityLinks().
  
  But on a more general note, between this and your other questions there's a lot of customizing going on and it may make upgrading difficult. At some point you might want to consider something like [webform](https://www.drupal.org/project/webform_civicrm/) to customize forms or even going full custom and making your own pages/forms in an extension and using the api to pull in just the data you need.
  
  > **Comments:**
  > **username_0**: We are already using Drupal webform, but only for some menue pages. I'll take a closer look into that. The reason I am working in this nonperfect way right now is that the customized software should go into the next test phase with an NGO in a while. So I'd put all my changes in an extension (or similar solution) after that.  
  > **username_0**: What about the Custom Template Dir and the Custom PHP Dir in /civicrm/admin/setting/path?reset=1 ? Would you recommend using them?  
  > **username_1**: Only for small stuff that's easy to reapply after each upgrade, since you'll still need to merge in any core changes into your overridden file after every upgrade. (I haven't used this extension but see also https://github.com/artfulrobot/patchwork)  
  
  ---
  
  