Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert case activity links to 'actionLinks' #14349

Merged
merged 2 commits into from
Nov 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions CRM/Activity/BAO/Activity.php
Original file line number Diff line number Diff line change
Expand Up @@ -2482,6 +2482,21 @@ public static function checkEditInboundEmailsPermissions() {
return FALSE;
}

/**
* Get the list of view only activities
*
* @return array
*/
public static function getViewOnlyActivityTypeIDs() {
$viewOnlyActivities = [
'Email' => CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'activity_type_id', 'Email'),
];
if (self::checkEditInboundEmailsPermissions()) {
$viewOnlyActivities['Inbound Email'] = CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'activity_type_id', 'Inbound Email');
}
return $viewOnlyActivities;
}

/**
* Wrapper for ajax activity selector.
*
Expand Down
3 changes: 2 additions & 1 deletion CRM/Case/BAO/Case.php
Original file line number Diff line number Diff line change
Expand Up @@ -1094,7 +1094,8 @@ public static function getCaseActivity($caseID, &$params, $contactID, $context =
$caseActivity['no_attachments'] = count($attachmentIDs);
}

$caseActivities[$caseActivityId]['links'] = CRM_Case_Selector_Search::addCaseActivityLinks($caseID, $contactID, $userID, $context, $dao);
$caseActivities[$caseActivityId]['links']
= CRM_Case_Selector_Search::addCaseActivityLinks($caseID, $contactID, $userID, $context, $dao);
}

$caseActivitiesDT = [];
Expand Down
11 changes: 11 additions & 0 deletions CRM/Case/Form/ActivityView.php
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,17 @@ public function preProcess() {
],
];
CRM_Utils_System::appendBreadCrumb($breadcrumb);

$this->addButtons([
[
'type' => 'cancel',
'name' => ts('Done'),
],
]);
// Add additional action links
$activityDeleted = CRM_Core_DAO::getFieldValue('CRM_Activity_DAO_Activity', $activityID, 'is_deleted');
$actionLinks = CRM_Case_Selector_Search::permissionedActionLinks($caseID, $contactID, CRM_Core_Session::getLoggedInContactID(), NULL, $activityTypeID, $activityDeleted, $activityID, FALSE);
$this->assign('actionLinks', $actionLinks);
}

}
227 changes: 178 additions & 49 deletions CRM/Case/Selector/Search.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ class CRM_Case_Selector_Search extends CRM_Core_Selector_Base {
*/
public static $_links = NULL;

/**
* The action links that we need to display for the browse screen.
*
* @var array
*/
private static $_actionLinks;

/**
* We use desc to remind us what that column is, name is used in the tpl
*
Expand Down Expand Up @@ -486,70 +493,192 @@ public function getExportFileName($output = 'csv') {
* @param int $contactID
* @param int $userID
* @param string $context
* @param \CRM_Core_DAO $dao
* @param \CRM_Activity_BAO_Activity $dao
* @param bool $allowView
*
* @return string
* HTML formatted Link
* @return string $linksMarkup
*/
public static function addCaseActivityLinks($caseID, $contactID, $userID, $context, $dao) {
// FIXME: Why are we not using CRM_Core_Action for these links? This is too much manual work and likely to get out-of-sync with core markup.
$caseActivityId = $dao->id;
$allowView = CRM_Case_BAO_Case::checkPermission($caseActivityId, 'view', $dao->activity_type_id, $userID);
$allowEdit = CRM_Case_BAO_Case::checkPermission($caseActivityId, 'edit', $dao->activity_type_id, $userID);
$allowDelete = CRM_Case_BAO_Case::checkPermission($caseActivityId, 'delete', $dao->activity_type_id, $userID);
$emailActivityTypeIDs = [
'Email' => CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'activity_type_id', 'Email'),
'Inbound Email' => CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'activity_type_id', 'Inbound Email'),
];
$url = CRM_Utils_System::url("civicrm/case/activity",
"reset=1&cid={$contactID}&caseid={$caseID}", FALSE, NULL, FALSE
);
$contextUrl = '';
if ($context == 'fulltext') {
$contextUrl = "&context={$context}";
}
$editUrl = "{$url}&action=update{$contextUrl}";
$deleteUrl = "{$url}&action=delete{$contextUrl}";
$restoreUrl = "{$url}&action=renew{$contextUrl}";
$viewTitle = ts('View activity');
public static function addCaseActivityLinks($caseID, $contactID, $userID, $context, $dao, $allowView = TRUE) {
$caseDeleted = CRM_Core_DAO::getFieldValue('CRM_Case_DAO_Case', $caseID, 'is_deleted');

$url = "";
$css = 'class="action-item crm-hover-button"';
if ($allowView) {
$viewUrl = CRM_Utils_System::url('civicrm/case/activity/view', array('cid' => $contactID, 'aid' => $caseActivityId));
$url = '<a ' . str_replace('action-item', 'action-item medium-pop-up', $css) . 'href="' . $viewUrl . '" title="' . $viewTitle . '">' . ts('View') . '</a>';
$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]);
}
$additionalUrl = "&id={$caseActivityId}";
if (!$dao->deleted) {
//hide edit link of activity type email.CRM-4530.
if (!in_array($dao->type, $emailActivityTypeIDs)) {
//hide Edit link if activity type is NOT editable (special case activities).CRM-5871
if ($allowEdit) {
$url .= '<a ' . $css . ' href="' . $editUrl . $additionalUrl . '">' . ts('Edit') . '</a> ';
}
// 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 ($allowDelete) {
$url .= ' <a ' . str_replace('action-item', 'action-item small-popup', $css) . ' href="' . $deleteUrl . $additionalUrl . '">' . ts('Delete') . '</a>';
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]);
}
elseif (!$caseDeleted) {
$url = ' <a ' . $css . ' href="' . $restoreUrl . $additionalUrl . '">' . ts('Restore') . '</a>';
$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;
}

//check for operations.
if (CRM_Case_BAO_Case::checkPermission($caseActivityId, 'Move To Case', $dao->activity_type_id)) {
$url .= ' <a ' . $css . ' href="#" onClick="Javascript:fileOnCase( \'move\',' . $caseActivityId . ', ' . $caseID . ', this ); return false;">' . ts('Move To Case') . '</a> ';
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($caseActivityId, 'Copy To Case', $dao->activity_type_id)) {
$url .= ' <a ' . $css . ' href="#" onClick="Javascript:fileOnCase( \'copy\',' . $caseActivityId . ',' . $caseID . ', this ); return false;">' . ts('Copy To Case') . '</a> ';
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
);
// if there are file attachments we will return how many and, if only one, add a link to it
if (!empty($dao->attachment_ids)) {
$url .= implode(' ', CRM_Core_BAO_File::paperIconAttachment('civicrm_activity', $caseActivityId));
$linksMarkup .= implode(' ', CRM_Core_BAO_File::paperIconAttachment('civicrm_activity', $dao->id));
}
return $linksMarkup;
}

/**
* @param int $caseID
* @param int $contactID
* @param int $userID
* @param string $context
* @param int $activityTypeID
* @param int $activityDeleted
* @param int $activityID
* @param bool $allowView
*
* @return array|null
*/
public static function permissionedActionLinks($caseID, $contactID, $userID, $context, $activityTypeID, $activityDeleted, $activityID, $allowView = TRUE) {
$caseDeleted = CRM_Core_DAO::getFieldValue('CRM_Case_DAO_Case', $caseID, 'is_deleted');
$values = [
'aid' => $activityID,
'cid' => $contactID,
'cxt' => empty($context) ? '' : "&context={$context}",
'caseid' => $caseID,
];
$actionLinks = self::actionLinks();

// Check logged in user for permission.
if (CRM_Case_BAO_Case::checkPermission($activityID, 'view', $activityTypeID, $userID)) {
$permissions[] = CRM_Core_Permission::VIEW;
}
if (!$allowView) {
unset($actionLinks[CRM_Core_Action::VIEW]);
}
if (!$activityDeleted) {
// 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($activityID, 'edit', $activityTypeID, $userID)) {
$permissions[] = CRM_Core_Permission::EDIT;
}
if (in_array($activityTypeID, CRM_Activity_BAO_Activity::getViewOnlyActivityTypeIDs())) {
unset($actionLinks[CRM_Core_Action::UPDATE]);
}
if (CRM_Case_BAO_Case::checkPermission($activityID, 'delete', $activityTypeID, $userID)) {
$permissions[] = CRM_Core_Permission::DELETE;
}
unset($actionLinks[CRM_Core_Action::RENEW]);
}
$extraMask = 0;
if ($activityDeleted && !$caseDeleted
&& (CRM_Case_BAO_Case::checkPermission($activityID, 'delete', $activityTypeID, $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($activityID, 'Move To Case', $activityTypeID)) {
unset($actionLinks[CRM_Core_Action::DETACH]);
}
if (!CRM_Case_BAO_Case::checkPermission($activityID, 'Copy To Case', $activityTypeID)) {
unset($actionLinks[CRM_Core_Action::COPY]);
}

$actionMask = CRM_Core_Action::mask($permissions) | $extraMask;
return CRM_Core_Action::filterLinks($actionLinks, $actionMask, $values, 'case.activity', 'Activity', $activityID);
}

return $url;
/**
* Get the action links for this page.
*
* @return array
*/
public static function actionLinks() {
// check if variable _actionsLinks is populated
if (!isset(self::$_actionLinks)) {
self::$_actionLinks = [
CRM_Core_Action::VIEW => [
'name' => ts('View'),
'url' => 'civicrm/case/activity/view',
'qs' => 'reset=1&cid=%%cid%%&caseid=%%caseid%%&aid=%%aid%%',
'title' => ts('View'),
],
CRM_Core_Action::UPDATE => [
'name' => ts('Edit'),
'url' => 'civicrm/case/activity',
'qs' => 'reset=1&cid=%%cid%%&caseid=%%caseid%%&id=%%aid%%&action=update%%cxt%%',
'title' => ts('Edit'),
'icon' => 'fa-pencil',
],
CRM_Core_Action::DELETE => [
'name' => ts('Delete'),
'url' => 'civicrm/case/activity',
'qs' => 'reset=1&cid=%%cid%%&caseid=%%caseid%%&id=%%aid%%&action=delete%%cxt%%',
'title' => ts('Delete'),
'icon' => 'fa-trash',
],
CRM_Core_Action::RENEW => [
'name' => ts('Restore'),
'url' => 'civicrm/case/activity',
'qs' => 'reset=1&cid=%%cid%%&caseid=%%caseid%%&id=%%aid%%&action=renew%%cxt%%',
'title' => ts('Restore'),
mattwire marked this conversation as resolved.
Show resolved Hide resolved
'icon' => 'fa-undo',
],
CRM_Core_Action::DETACH => [
'name' => ts('Move To Case'),
'ref' => 'move_to_case_action',
'title' => ts('Move To Case'),
'extra' => 'onclick = "Javascript:fileOnCase( \'move\', %%aid%%, %%caseid%%, this ); return false;"',
'icon' => 'fa-clipboard',
],
CRM_Core_Action::COPY => [
'name' => ts('Copy To Case'),
'ref' => 'copy_to_case_action',
'title' => ts('Copy To Case'),
'extra' => 'onclick = "Javascript:fileOnCase( \'copy\', %%aid%%, %%caseid%%, this ); return false;"',
'icon' => 'fa-files-o',
],
];
}
return self::$_actionLinks;
}

}
7 changes: 4 additions & 3 deletions templates/CRM/Case/Form/ActivityView.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
*}
{* View Case Activities *}
<div class="crm-block crm-content-block crm-case-activity-view-block">
<div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location="top" linkButtons=$actionLinks}</div>
{if $revs}
{strip}
<table class="crm-info-panel">
Expand Down Expand Up @@ -77,7 +78,7 @@
</table>
{/if}
{/if}
<div class="crm-submit-buttons">
{crmButton p='civicrm/case' q="reset=1" class='cancel' icon='times'}{ts}Done{/ts}{/crmButton}
</div>
<div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location="bottom" linkButtons=$actionLinks}</div>
</div>

{include file="CRM/Case/Form/ActivityToCase.tpl"}
25 changes: 22 additions & 3 deletions templates/CRM/common/formButtons.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,29 @@
+--------------------------------------------------------------------+
*}

{* Loops through $form.buttons.html array and assigns separate spans with classes to allow theming
by button and name. crmBtnType grabs type keyword from button name (e.g. 'upload', 'next', 'back', 'cancel') so
types of buttons can be styled differently via css. *}
{crmRegion name='form-buttons'}
{* Loops through $linkButtons and assigns html "a" (link) buttons to the template. Used for additional entity functions such as "Move to Case" or "Renew Membership" *}
{if $linkButtons}
{foreach from=$linkButtons item=linkButton}
{if $linkButton.accesskey}
{capture assign=accessKey}accesskey="{$linkButton.accessKey}"{/capture}
{else}{assign var="accessKey" value=""}
{/if}
{if $linkButton.icon}
{capture assign=icon}<i class="crm-i {$linkButton.icon}"></i> {/capture}
{else}{assign var="icon" value=""}
{/if}
{if $linkButton.ref}
{capture assign=linkname}name="{$linkButton.ref}"{/capture}
{else}{capture assign=linkname}name="{$linkButton.name}"{/capture}
{/if}
<a class="button" {$linkname} href="{crmURL p=$linkButton.url q=$linkButton.qs}" {$accessKey} {$linkButton.extra}><span>{$icon}{$linkButton.title}</span></a>
{/foreach}
{/if}

{* Loops through $form.buttons.html array and assigns separate spans with classes to allow theming by button and name.
* crmBtnType grabs type keyword from button name (e.g. 'upload', 'next', 'back', 'cancel') so types of buttons can be styled differently via css.
*}
{foreach from=$form.buttons item=button key=key name=btns}
{if $key|substring:0:4 EQ '_qf_'}
{if $location}
Expand Down