From 15d9b3ae22fdaa680a96725516334c693f4d9618 Mon Sep 17 00:00:00 2001 From: Nileema Date: Tue, 31 Dec 2013 12:22:30 +0530 Subject: [PATCH] -- CRM-13889 APIs for Dashboard, DashboardContact and new hook hook_civicrm_dashboard_defaults ---------------------------------------- * CRM-13889: Add APIs for Dashboard and DashboardContact http://issues.civicrm.org/jira/browse/CRM-13889 --- CRM/Core/BAO/Dashboard.php | 91 +++++++++++---- CRM/Utils/Hook.php | 10 ++ api/v3/Dashboard.php | 107 ++++++++++++++++++ api/v3/DashboardContact.php | 98 ++++++++++++++++ sql/civicrm_generated.mysql | 2 +- tests/phpunit/api/v3/DashboardContactTest.php | 91 +++++++++++++++ tests/phpunit/api/v3/DashboardTest.php | 93 +++++++++++++++ .../phpunit/api/v3/SyntaxConformanceTest.php | 3 +- 8 files changed, 471 insertions(+), 24 deletions(-) create mode 100644 api/v3/Dashboard.php create mode 100644 api/v3/DashboardContact.php create mode 100644 tests/phpunit/api/v3/DashboardContactTest.php create mode 100644 tests/phpunit/api/v3/DashboardTest.php diff --git a/CRM/Core/BAO/Dashboard.php b/CRM/Core/BAO/Dashboard.php index c421f9f810..3e6f4b11c8 100644 --- a/CRM/Core/BAO/Dashboard.php +++ b/CRM/Core/BAO/Dashboard.php @@ -82,10 +82,12 @@ class CRM_Core_BAO_Dashboard extends CRM_Core_DAO_Dashboard { * @access public * @static */ - static function getContactDashlets($flatFormat = FALSE) { + static function getContactDashlets($flatFormat = FALSE, $contactID = NULL) { $dashlets = array(); - $contactID = CRM_Core_Session::singleton()->get('userID'); + if (!$contactID) { + $contactID = CRM_Core_Session::singleton()->get('userID'); + } // get contact dashboard dashlets $hasDashlets = FALSE; @@ -111,23 +113,42 @@ class CRM_Core_BAO_Dashboard extends CRM_Core_DAO_Dashboard { } // If empty then initialize contact dashboard for this user - if (!$hasDashlets) { - $defaultDashlets = self::getDashlets(); - if ($defaultDashlets) { - // Add dashlet entries for logged in contact - // TODO: need to optimize this sql - $items = ''; - foreach ($defaultDashlets as $key => $values) { - // Set civicrm blog as default enabled - $default = $values['url'] == 'civicrm/dashlet/blog&reset=1&snippet=5' ? 1 : 0; - $items .= ($items ? ', ' : '') . "($key, $contactID, $default, $default)"; + $defaultDashlet = self::initializeDashlets($hasDashlets); + return $defaultDashlet ? $defaultDashlet : $dashlets; + } + + static function initializeDashlets($hasDashlets) { + $getDashlets = civicrm_api3("Dashboard", "get", array('domain_id' => CRM_Core_Config::domainID())); + $contactID = CRM_Core_Session::singleton()->get('userID'); + + $allDashlets = CRM_Utils_Array::index(array('name'), $getDashlets['values']); + $defaultDashlets = array(); + if (!$hasDashlets && CRM_Utils_Array::value('blog', $allDashlets)) { + $defaultDashlets['blog'] = array( + 'dashboard_id' => $allDashlets['blog']['id'], + 'is_active' => 1, + 'column_no' => 1, + 'contact_id' => $contactID, + 'domain_id' => CRM_Core_Config::domainID(), + ); + } + CRM_Utils_Hook::dashboard_defaults($allDashlets, $defaultDashlets); + if (is_array($defaultDashlets) && !empty($defaultDashlets)) { + foreach ($defaultDashlets as $defaultDashlet) { + if (!self::checkPermission($getDashlets['values'][$defaultDashlet['dashboard_id']]['permission'], + $getDashlets['values'][$defaultDashlet['dashboard_id']]['permission_operator'])) { + unset($defaultDashlets[$defaultDashlet]); + continue; + } + else { + $assignDashlets = civicrm_api3("dashboard_contact", "create", $defaultDashlet); + $dashlets[$defaultDashlet['dashboard_id']] = $defaultDashlet['dashboard_id']; } - $query = "INSERT INTO civicrm_dashboard_contact (dashboard_id, contact_id, column_no, is_active) VALUES $items"; - CRM_Core_DAO::executeQuery($query); } + return $dashlets; } - return $dashlets; + return FALSE; } /** @@ -216,7 +237,7 @@ class CRM_Core_BAO_Dashboard extends CRM_Core_DAO_Dashboard { $dashletInfo = array(); $params = array(1 => array($dashletID, 'Integer')); - $query = "SELECT label, url, fullscreen_url, is_fullscreen FROM civicrm_dashboard WHERE id = %1"; + $query = "SELECT name, label, url, fullscreen_url, is_fullscreen FROM civicrm_dashboard WHERE id = %1"; $dashboadDAO = CRM_Core_DAO::executeQuery($query, $params); $dashboadDAO->fetch(); @@ -257,6 +278,7 @@ class CRM_Core_BAO_Dashboard extends CRM_Core_DAO_Dashboard { $dashletInfo = array( 'title' => $dashboadDAO->label, + 'name' => $dashboadDAO->name, 'content' => $dao->content, ); @@ -280,12 +302,17 @@ class CRM_Core_BAO_Dashboard extends CRM_Core_DAO_Dashboard { * @access public * @static */ - static function saveDashletChanges($columns) { + static function saveDashletChanges($columns, $contactID=NULL) { + $session = CRM_Core_Session::singleton(); + if (!$contactID) { + $contactID = $session->get('userID'); + } + $session = CRM_Core_Session::singleton(); $contactID = $session->get('userID'); //we need to get existing dashletes, so we know when to update or insert - $contactDashlets = self::getContactDashlets(TRUE); + $contactDashlets = self::getContactDashlets(TRUE, $contactID); $dashletIDs = array(); if (is_array($columns)) { @@ -343,7 +370,8 @@ class CRM_Core_BAO_Dashboard extends CRM_Core_DAO_Dashboard { static function addDashlet(&$params) { // special case to handle duplicate entires for report instances - $dashboardID = NULL; + $dashboardID = CRM_Utils_Array::value('id', $params); + if (CRM_Utils_Array::value('instanceURL', $params)) { $query = "SELECT id FROM `civicrm_dashboard` @@ -355,9 +383,14 @@ class CRM_Core_BAO_Dashboard extends CRM_Core_DAO_Dashboard { if (!$dashboardID) { // check url is same as exiting entries, if yes just update existing - $dashlet->url = CRM_Utils_Array::value('url', $params); - $dashlet->find(TRUE); - $dashlet->name = self::getDashletName(CRM_Utils_Array::value('instanceURL', $params)); + if (CRM_Utils_Array::value('name', $params)) { + $dashlet->name = CRM_Utils_Array::value('name', $params); + $dashlet->find(TRUE); + } + else { + $dashlet->url = CRM_Utils_Array::value('url', $params); + $dashlet->find(TRUE); + } } else { $dashlet->id = $dashboardID; @@ -435,6 +468,19 @@ class CRM_Core_BAO_Dashboard extends CRM_Core_DAO_Dashboard { } } + static function addContactDashletToDashboard(&$params) { + $valuesString = NULL; + $columns = array(); + foreach ($params as $dashboardIDs) { + $contactID = CRM_Utils_Array::value('contact_id', $dashboardIDs); + $dashboardID = CRM_Utils_Array::value('dashboard_id', $dashboardIDs); + $column = CRM_Utils_Array::value('column_no', $dashboardIDs, 0); + $columns[$column][$dashboardID] = 0; + } + self::saveDashletChanges($columns, $contactID); + return TRUE; + } + /** * Function to reset dashlet cache * @@ -464,6 +510,7 @@ class CRM_Core_BAO_Dashboard extends CRM_Core_DAO_Dashboard { $dashlet = new CRM_Core_DAO_Dashboard(); $dashlet->id = $dashletID; $dashlet->delete(); + return TRUE; } } diff --git a/CRM/Utils/Hook.php b/CRM/Utils/Hook.php index fbb789ce36..bed5f0dfcd 100644 --- a/CRM/Utils/Hook.php +++ b/CRM/Utils/Hook.php @@ -1388,4 +1388,14 @@ abstract class CRM_Utils_Hook { static function queryObjects(&$queryObjects, $type = 'Contact') { return self::singleton()->invoke(2, $queryObjects, $type, self::$_nullObject, self::$_nullObject, self::$_nullObject, 'civicrm_queryObjects'); } + + /** + * This hook is called while viewing contact dashboard + * + * @param array $availableDashlets list of dashlets; each is formatted per api/v3/Dashboard + * @param array $activeDashlets list of dashlets; each is formatted per api/v3/DashboardContact + */ + static function dashboard_defaults($availableDashlets, &$defaultDashlets) { + return self::singleton()->invoke(2, $availableDashlets, $defaultDashlets, self::$_nullObject, self::$_nullObject, self::$_nullObject, 'civicrm_dashboard_defaults'); + } } diff --git a/api/v3/Dashboard.php b/api/v3/Dashboard.php new file mode 100644 index 0000000000..ae42779036 --- /dev/null +++ b/api/v3/Dashboard.php @@ -0,0 +1,107 @@ +id)) { + _civicrm_api3_object_to_array($dashboardBAO, $dashboardArray[$dashboardBAO->id]); + return civicrm_api3_create_success($dashboardArray, $params, 'dashboard', 'create', $dashboardBAO); + } +} + +/** + * Specify Meta data for create. Note that this data is retrievable via the getfields function + * and is used for pre-filling defaults and ensuring mandatory requirements are met. + * @param array $params (reference) array of parameters determined by getfields + */ +function _civicrm_api3_dashboard_create_spec(&$params) { + unset($params['version']); +} + +/** + * Gets a CiviCRM Dashlets according to parameters + * + * @param array $params Associative array of property name/value + * pairs for the activity. + * + * @return array + * + */ +function civicrm_api3_dashboard_get($params) { + $bao = new CRM_Core_BAO_Dashboard(); + _civicrm_api3_dao_set_filter($bao, $params, true, 'Dashboard'); + $dashlets = _civicrm_api3_dao_to_array($bao, $params, true,'Dashboard'); + return civicrm_api3_create_success($dashlets, $params, 'dashboard', 'get', $bao); +} + +/** + * Delete a specified Dashlet. + * + * @param array $params array holding 'id' OR 'name' of dashlet to be deleted + * + * @return void|CRM_Core_Error An error if 'name or ID' is invalid, + * + */ +function civicrm_api3_dashboard_delete($params) { + if (CRM_Core_BAO_Dashboard::deleteDashlet($params['id'])) { + return civicrm_api3_create_success(1, $params, 'dashboard', 'delete'); + } + else { + return civicrm_api3_create_error('Could not delete dashlet'); + } +} \ No newline at end of file diff --git a/api/v3/DashboardContact.php b/api/v3/DashboardContact.php new file mode 100644 index 0000000000..280420f702 --- /dev/null +++ b/api/v3/DashboardContact.php @@ -0,0 +1,98 @@ +. + */ + +/** + * Include class definitions + */ +require_once 'CiviTest/CiviUnitTestCase.php'; + +/** + * Test APIv3 civicrm_action_schedule functions + * + * @package CiviCRM_APIv3 + * @subpackage API_ActionSchedule + */ + +class api_v3_DashboardContactTest extends CiviUnitTestCase { + protected $_params; + protected $_params2; + protected $_entity = 'dashborad_contact'; + protected $_apiversion = 3; + + public $_eNoticeCompliant = TRUE; + /** + * Test setup for every test + * + * Connect to the database, truncate the tables that will be used + * and redirect stdin to a temporary file + */ + public function setUp() { + // Connect to the database + parent::setUp(); + } + + /** + * Tears down the fixture, for example, closes a network connection. + * This method is called after a test is executed. + * + * @access protected + */ + function tearDown() { + $tablesToTruncate = array( + 'civicrm_dashboard', + 'civicrm_dashboard_contact', + ); + $this->quickCleanup($tablesToTruncate, TRUE); + } + + function testDashboardContactCreate() { + $dashParams = array( + 'version' => 3, + 'label' => 'New Dashlet element', + 'name' => 'New Dashlet element', + 'url' => 'civicrm/report/list&compid=99&reset=1&snippet=5', + 'fullscreen_url' => 'civicrm/report/list&compid=99&reset=1&snippet=5&context=dashletFullscreen', + ); + $dashresult = $this->callAPISuccess('dashboard', 'create', $dashParams); + $contact = $this->callAPISuccess('contact', 'create', array( 'first_name' => 'abc1', + 'contact_type' => 'Individual', + 'last_name' => 'xyz1', + 'email' => 'abc@abc.com') + ); + $oldCount = CRM_Core_DAO::singleValueQuery("select count(*) from civicrm_dashboard_contact where contact_id = {$contact['id']} AND is_active = 1 AND dashboard_id = {$dashresult['id']}"); + $params = array( + 'version' => 3, + 'contact_id' => $contact['id'], + 'dashboard_id' => $dashresult['id'], + 'is_active' => 1, + ); + $dashboradContact = $this->callAPISuccess('dashboard_contact', 'create', $params); + $newCount = CRM_Core_DAO::singleValueQuery("select count(*) from civicrm_dashboard_contact where contact_id = {$contact['id']} AND is_active = 1 AND dashboard_id = {$dashresult['id']}"); + $this->assertEquals($oldCount+1, $newCount); + } +} \ No newline at end of file diff --git a/tests/phpunit/api/v3/DashboardTest.php b/tests/phpunit/api/v3/DashboardTest.php new file mode 100644 index 0000000000..baba27c2b1 --- /dev/null +++ b/tests/phpunit/api/v3/DashboardTest.php @@ -0,0 +1,93 @@ +. + */ + +/** + * Include class definitions + */ +require_once 'CiviTest/CiviUnitTestCase.php'; + +/** + * Test APIv3 civicrm_action_schedule functions + * + * @package CiviCRM_APIv3 + * @subpackage API_ActionSchedule + */ + +class api_v3_DashboardTest extends CiviUnitTestCase { + protected $_params; + protected $_params2; + protected $_entity = 'dashboard'; + protected $_apiversion = 3; + + public $_eNoticeCompliant = TRUE; + /** + * Test setup for every test + * + * Connect to the database, truncate the tables that will be used + * and redirect stdin to a temporary file + */ + public function setUp() { + // Connect to the database + parent::setUp(); + } + + /** + * Tears down the fixture, for example, closes a network connection. + * This method is called after a test is executed. + * + * @access protected + */ + function tearDown() { + $tablesToTruncate = array( + 'civicrm_dashboard', + ); + $this->quickCleanup($tablesToTruncate, TRUE); + } + + function testDashboardCreate() { + $oldCount = CRM_Core_DAO::singleValueQuery('select count(*) from civicrm_dashboard'); + $params = array( + 'version' => 3, + 'label' => 'New Dashlet element', + 'name' => 'New Dashlet element', + 'url' => 'civicrm/report/list&reset=1&compid=99&snippet=5', + 'fullscreen_url' => 'civicrm/report/list&compid=99&reset=1&snippet=5&context=dashletFullscreen', + ); + $dashboard = $this->callAPISuccess('dashboard', 'create', $params); + $this->assertTrue(is_numeric($dashboard['id']), "In line " . __LINE__); + $this->assertTrue($dashboard['id'] > 0, "In line " . __LINE__); + $newCount = CRM_Core_DAO::singleValueQuery('select count(*) from civicrm_dashboard'); + $this->assertEquals($oldCount+1, $newCount); + $this->DashboardDelete($dashboard['id'],$oldCount); + } + + function DashboardDelete($id, $oldCount) { + $params = array( + 'version' => 3, + 'id' => $id, + ); + $dashboardget = $this->callAPISuccess('dashboard', 'get', $params); + $this->assertEquals($id, $dashboardget['id']); + $dashboard = $this->callAPISuccess('dashboard', 'delete', $params); + $newCount = CRM_Core_DAO::singleValueQuery('select count(*) from civicrm_dashboard'); + $this->assertEquals($oldCount, $newCount); + } +} \ No newline at end of file diff --git a/tests/phpunit/api/v3/SyntaxConformanceTest.php b/tests/phpunit/api/v3/SyntaxConformanceTest.php index c7631f63f0..38ac526470 100644 --- a/tests/phpunit/api/v3/SyntaxConformanceTest.php +++ b/tests/phpunit/api/v3/SyntaxConformanceTest.php @@ -156,7 +156,7 @@ class api_v3_SyntaxConformanceTest extends CiviUnitTestCase { * @return multitype:string |multitype:multitype:string */ public static function toBeSkipped_automock($sequential = FALSE) { - $entitiesWithoutGet = array('MailingContact', 'EntityTag', 'Participant', 'ParticipantPayment', 'Setting', 'SurveyRespondant', 'MailingRecipients', 'CustomSearch', 'Extension', 'ReportTemplate', 'System'); + $entitiesWithoutGet = array('MailingContact', 'EntityTag', 'Participant', 'ParticipantPayment', 'Setting', 'SurveyRespondant', 'MailingRecipients', 'CustomSearch', 'Extension', 'ReportTemplate', 'System', 'DashboardContact'); if ($sequential === TRUE) { return $entitiesWithoutGet; } @@ -235,6 +235,7 @@ class api_v3_SyntaxConformanceTest extends CiviUnitTestCase { 'MailSettings', 'Setting', 'MailingContact', + 'DashboardContact', ); if ($sequential === TRUE) { return $entitiesWithout; -- 2.25.1