From 0f8c6e5846791d886139a66ee88259e84f0d5b4b Mon Sep 17 00:00:00 2001 From: eileenmcnaugton Date: Wed, 30 Sep 2015 20:11:19 +1300 Subject: [PATCH] CRM-17310 Add my reports functionality This includes a new my reports menu & the ability to save reports as 'my report' to show on there --- CRM/Core/BAO/Navigation.php | 7 +++ CRM/Report/BAO/ReportInstance.php | 52 +++++++++++++++++++++ CRM/Report/Form.php | 5 +- CRM/Report/Form/Instance.php | 21 +++++++++ CRM/Report/Info.php | 15 +++--- CRM/Report/Page/InstanceList.php | 37 ++++++++++++--- templates/CRM/Report/Form/Tabs/Instance.tpl | 6 +++ templates/CRM/Report/Form/Tabs/Settings.hlp | 10 +++- templates/CRM/Report/Page/InstanceList.tpl | 14 ++++-- 9 files changed, 146 insertions(+), 21 deletions(-) diff --git a/CRM/Core/BAO/Navigation.php b/CRM/Core/BAO/Navigation.php index 08c345ef25..ed189576a2 100644 --- a/CRM/Core/BAO/Navigation.php +++ b/CRM/Core/BAO/Navigation.php @@ -604,6 +604,13 @@ ORDER BY parent_id, weight"; return $showItem; } } + // CRM-17310 my reports allow people with access own reports to see the report if it is theirs. + elseif ($key == 'access own private reports') { + // Special permission processing for private reports. + $report_url = parse_url(ltrim($url, '/')); + $instance_id = CRM_Report_Utils_Report::getInstanceID($report_url['path']); + $hasPermission = $showItem = CRM_Report_BAO_ReportInstance::contactIsOwner($instance_id); + } else { $hasPermission = TRUE; } diff --git a/CRM/Report/BAO/ReportInstance.php b/CRM/Report/BAO/ReportInstance.php index 2971b7bff0..9fe13ebaf6 100644 --- a/CRM/Report/BAO/ReportInstance.php +++ b/CRM/Report/BAO/ReportInstance.php @@ -264,4 +264,56 @@ class CRM_Report_BAO_ReportInstance extends CRM_Report_DAO_ReportInstance { return NULL; } + /** + * Check if report is private. + * + * @param int $instance_id + * + * @return bool + */ + public static function reportIsPrivate($instance_id) { + $owner_id = CRM_Core_DAO::getFieldValue('CRM_Report_DAO_ReportInstance', $instance_id, 'owner_id', 'id'); + if ($owner_id) { + return TRUE; + } + return FALSE; + } + + /** + * Check if the logged in user is the owner. + * + * @param int $instance_id + * + * @return TRUE if contact owns the report, FALSE if not + */ + public static function contactIsOwner($instance_id) { + $session = CRM_Core_Session::singleton(); + $contact_id = $session->get('userID'); + $owner_id = CRM_Core_DAO::getFieldValue('CRM_Report_DAO_ReportInstance', $instance_id, 'owner_id', 'id'); + if ($contact_id === $owner_id) { + return TRUE; + } + return FALSE; + } + + /** + * Check if the logged in contact can administer the report. + * + * @param int $instance_id + * + * @return bool + * True if contact can edit the private report, FALSE if not. + */ + public static function contactCanAdministerReport($instance_id) { + if (self::reportIsPrivate($instance_id)) { + if (self::contactIsOwner($instance_id) || CRM_Core_Permission::check('access all private reports')) { + return TRUE; + } + } + elseif (CRM_Core_Permission::check('administer Reports')) { + return TRUE; + } + return FALSE; + } + } diff --git a/CRM/Report/Form.php b/CRM/Report/Form.php index d1ba8f6bd3..aeb5720d2d 100644 --- a/CRM/Report/Form.php +++ b/CRM/Report/Form.php @@ -1331,7 +1331,10 @@ class CRM_Report_Form extends CRM_Core_Form { } } } - if (!empty($this->_options)) { + if (!empty($this->_options) && + (!$this->_id + || ($this->_id && CRM_Report_BAO_ReportInstance::contactCanAdministerReport($this->_id))) + ) { $this->tabs['ReportOptions'] = array( 'title' => ts('Display Options'), 'tpl' => 'ReportOptions', diff --git a/CRM/Report/Form/Instance.php b/CRM/Report/Form/Instance.php index 814511450b..2c14372e95 100644 --- a/CRM/Report/Form/Instance.php +++ b/CRM/Report/Form/Instance.php @@ -114,6 +114,8 @@ class CRM_Report_Form_Instance { $form->addElement('checkbox', 'addToDashboard', ts('Available for Dashboard?'), NULL, array('onclick' => "return showHideByValue('addToDashboard','','limit_result','table-row','radio',false);")); + $form->addElement('checkbox', 'add_to_my_reports', ts('Add to My Reports?'), NULL); + $form->addElement('checkbox', 'is_reserved', ts('Reserved Report?')); if (!CRM_Core_Permission::check('administer reserved reports')) { $form->freeze('is_reserved'); @@ -271,6 +273,12 @@ class CRM_Report_Form_Instance { $defaults['report_footer'] = $defaults['footer']; } + // CRM-17310 private reports option. + $defaults['add_to_my_reports'] = 0; + if (CRM_Utils_Array::value('owner_id', $defaults) != NULL) { + $defaults['add_to_my_reports'] = 1; + } + if (!empty($defaults['navigation_id'])) { // Get the default navigation parent id. $params = array('id' => $defaults['navigation_id']); @@ -355,6 +363,19 @@ class CRM_Report_Form_Instance { unset($formValues[$field]); } $view_mode = $formValues['view_mode']; + + // CRM-17310 my reports functionality - we should set owner if the checkbox is 1, + // it seems to be not set at all if unchecked. + if (!empty($formValues['add_to_my_reports'])) { + $params['owner_id'] = CRM_Core_Session::singleton()->getLoggedInContactID(); + $params['permission'] = 'access own private reports'; + $params['grouprole'] = array(); + } + else { + $params['owner_id'] = 'null'; + } + unset($formValues['add_to_my_reports']); + // pass form_values as string $params['form_values'] = serialize($formValues); diff --git a/CRM/Report/Info.php b/CRM/Report/Info.php index adb81363d6..6f4ee789c4 100644 --- a/CRM/Report/Info.php +++ b/CRM/Report/Info.php @@ -30,7 +30,6 @@ * information about it. It needs to extend CRM_Core_Component_Info * abstract class. * - * @package CRM * @copyright CiviCRM LLC (c) 2004-2016 * $Id$ * @@ -51,9 +50,6 @@ class CRM_Report_Info extends CRM_Core_Component_Info { * @return array * collection of required component settings */ - /** - * @return array - */ public function getInfo() { return array( 'name' => 'CiviReport', @@ -91,6 +87,14 @@ class CRM_Report_Info extends CRM_Core_Component_Info { ts('access Report Criteria'), ts('Change report search criteria'), ), + 'access own private reports' => array( + ts('access own private reports'), + ts('Access reports owned by the contact'), + ), + 'access all private reports' => array( + ts('access all private reports'), + ts('Access all private reports'), + ), 'administer reserved reports' => array( ts('administer reserved reports'), ts('Edit all reports that have been marked as reserved'), @@ -124,9 +128,6 @@ class CRM_Report_Info extends CRM_Core_Component_Info { * collection of required dashboard settings, * null if no element offered */ - /** - * @return array|null - */ public function getUserDashboardElement() { // no dashboard element for this component return NULL; diff --git a/CRM/Report/Page/InstanceList.php b/CRM/Report/Page/InstanceList.php index 3051a4b156..143c48ef77 100644 --- a/CRM/Report/Page/InstanceList.php +++ b/CRM/Report/Page/InstanceList.php @@ -108,9 +108,12 @@ class CRM_Report_Page_InstanceList extends CRM_Core_Page { elseif ($this->grouping) { $report .= " AND v.grouping = '{$this->grouping}' "; } + elseif ($this->myReports) { + $report .= " AND inst.owner_id = " . CRM_Core_Session::getLoggedInContactID(); + } $sql = " - SELECT inst.id, inst.title, inst.report_id, inst.description, v.label, v.grouping, v.name as class_name, + SELECT inst.id, inst.title, inst.report_id, inst.description, inst.owner_id, v.label, v.grouping, v.name as class_name, CASE WHEN comp.name IS NOT NULL THEN SUBSTRING(comp.name, 5) WHEN v.grouping IS NOT NULL THEN v.grouping @@ -136,6 +139,7 @@ class CRM_Report_Page_InstanceList extends CRM_Core_Page { $config = CRM_Core_Config::singleton(); $rows = array(); $url = 'civicrm/report/instance'; + $my_reports_grouping = 'My'; while ($dao->fetch()) { if (in_array($dao->report_id, self::$_exceptions)) { continue; @@ -145,6 +149,12 @@ class CRM_Report_Page_InstanceList extends CRM_Core_Page { if ($dao->compName == 'Contact' || $dao->compName == $dao->grouping) { $enabled = TRUE; } + + // filter report listings for private reports + if (!empty($dao->owner_id) && CRM_Core_Session::getLoggedInContactID() != $dao->owner_id) { + continue; + } + //filter report listings by permissions if (!($enabled && CRM_Report_Utils_Report::isInstancePermissioned($dao->id))) { continue; @@ -158,14 +168,25 @@ class CRM_Report_Page_InstanceList extends CRM_Core_Page { if ($this->ovID) { $this->title = ts("Report(s) created from the template: %1", array(1 => $dao->label)); } - $rows[$dao->compName][$dao->id]['title'] = $dao->title; - $rows[$dao->compName][$dao->id]['label'] = $dao->label; - $rows[$dao->compName][$dao->id]['description'] = $dao->description; - $rows[$dao->compName][$dao->id]['url'] = CRM_Utils_System::url("{$url}/{$dao->id}", "reset=1&output=criteria"); - $rows[$dao->compName][$dao->id]['viewUrl'] = CRM_Utils_System::url("{$url}/{$dao->id}", 'force=1&reset=1'); - $rows[$dao->compName][$dao->id]['actions'] = $this->getActionLinks($dao->id, $dao->class_name); + + $report_grouping = $dao->compName; + if ($dao->owner_id != NULL) { + $report_grouping = $my_reports_grouping; + } + $rows[$report_grouping][$dao->id]['title'] = $dao->title; + $rows[$report_grouping][$dao->id]['label'] = $dao->label; + $rows[$report_grouping][$dao->id]['description'] = $dao->description; + $rows[$report_grouping][$dao->id]['url'] = CRM_Utils_System::url("{$url}/{$dao->id}", "reset=1&output=criteria"); + $rows[$report_grouping][$dao->id]['viewUrl'] = CRM_Utils_System::url("{$url}/{$dao->id}", 'force=1&reset=1'); + $rows[$report_grouping][$dao->id]['actions'] = $this->getActionLinks($dao->id, $dao->class_name); } } + // Move My Reports to the beginning of the reports list + if (isset($rows[$my_reports_grouping])) { + $my_reports = $rows[$my_reports_grouping]; + unset($rows[$my_reports_grouping]); + $rows = array($my_reports_grouping => $my_reports) + $rows; + } return $rows; } @@ -175,6 +196,7 @@ class CRM_Report_Page_InstanceList extends CRM_Core_Page { public function run() { //Filters by source report template or by component $this->ovID = CRM_Utils_Request::retrieve('ovid', 'Positive', $this); + $this->myReports = CRM_Utils_Request::retrieve('myreports', 'String', $this); $this->compID = CRM_Utils_Request::retrieve('compid', 'Positive', $this); $this->grouping = CRM_Utils_Request::retrieve('grp', 'String', $this); @@ -205,6 +227,7 @@ class CRM_Report_Page_InstanceList extends CRM_Core_Page { $this->assign('newButton', $newButton); $this->assign('templateUrl', $templateUrl); $this->assign('compName', $this->_compName); + $this->assign('myReports', $this->myReports); } return parent::run(); } diff --git a/templates/CRM/Report/Form/Tabs/Instance.tpl b/templates/CRM/Report/Form/Tabs/Instance.tpl index eda7ed50f3..17e5eec343 100644 --- a/templates/CRM/Report/Form/Tabs/Instance.tpl +++ b/templates/CRM/Report/Form/Tabs/Instance.tpl @@ -88,6 +88,12 @@ {$form.grouprole.html|crmAddClass:huge} {/if} + + {$form.add_to_my_reports.label} {help id="id-add_to_my_reports" file="CRM/Report/Form/Tabs/Settings.hlp"} + {$form.add_to_my_reports.html} + {ts}If set to Yes, this report will appear in the My Reports section of the reports listing page and will only be visible by you.{/ts} + + {$form.is_reserved.label} {help id="id-is_reserved" file="CRM/Report/Form/Tabs/Settings.hlp"} {$form.is_reserved.html} diff --git a/templates/CRM/Report/Form/Tabs/Settings.hlp b/templates/CRM/Report/Form/Tabs/Settings.hlp index 2a0d8da6e0..6c85a44ff4 100644 --- a/templates/CRM/Report/Form/Tabs/Settings.hlp +++ b/templates/CRM/Report/Form/Tabs/Settings.hlp @@ -55,7 +55,7 @@ {/htxt} {htxt id="id-report_perms"} {ts}You can control access to this report by selecting a 'Permission' from the list, or selecting one or more Roles. For example, you might select access CiviContribute for contribution reports (e.g. the same people who can see contribution data would also have access to the report). You can also prevent users from modifying the default report criteria and filters for reports by NOT giving them access Report Criteria permission. Those users will be able to run the report - but only with the criteria and filters that you've established for them.{/ts} -{/htxt} +{/htxt} {htxt id="id-dash_avail-title"} {ts}Dashboard{/ts} @@ -81,3 +81,11 @@ {ts}Users with 'administer reserved reports' permission can mark a report instance as reserved, which prevents other users from accessing or modifying Report Criteria and Report Settings. This is particularly useful for report instances whose criteria affect the data available on non-report screens. For example, the display columns configured for the Contact Logging Summary affect the columns shown under each contact's Change Log tab.{/ts} {/htxt} +{htxt id="id-add_to_my_reports-title"} +{ts}Add to My Reports{/ts} +{/htxt} +{htxt id="id-add_to_my_reports"} +{ts}Selecting Yes will set the report to be visible only to the user + that clicked this option and saved the report settings form. If this is + enabled, the permissions configuration for this report will be disabled.{/ts} +{/htxt} diff --git a/templates/CRM/Report/Page/InstanceList.tpl b/templates/CRM/Report/Page/InstanceList.tpl index f9341c2a98..bf64c4c0af 100644 --- a/templates/CRM/Report/Page/InstanceList.tpl +++ b/templates/CRM/Report/Page/InstanceList.tpl @@ -38,7 +38,7 @@ {foreach from=$list item=rows key=report}
- {if $title}{$title}{elseif $report EQ 'Contribute'}{ts}Contribution Reports{/ts}{else}{$report} {ts}Reports{/ts}{/if} + {if $title}{$title}{elseif $report EQ 'Contribute'}{ts}Contribution Reports{/ts}{else}{ts}{$report} Reports{/ts}{/if}
@@ -81,11 +81,15 @@
  - {ts 1=$compName}No %1 reports have been created.{/ts}   - {if $templateUrl} - {ts 1=$templateUrl}You can create reports by selecting from the list of report templates here.{/ts} + {if $myReports} + {ts}You do not have any private reports. To add a report to this section, edit the Report Settings for a report and set 'Add to My Reports' to Yes.{/ts}   {else} - {ts}Contact your site administrator for help creating reports.{/ts} + {ts 1=$compName}No %1 reports have been created.{/ts}   + {if $templateUrl} + {ts 1=$templateUrl}You can create reports by selecting from the list of report templates here.{/ts} + {else} + {ts}Contact your site administrator for help creating reports.{/ts} + {/if} {/if}
-- 2.25.1