From 01d70c562c189135c1d0012646ca1dde1112af9d Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Thu, 27 Sep 2018 17:05:06 -0400 Subject: [PATCH] (DX) Civi::contactSettings - Add a facade for working with the logged-in user's settings Before ------ To read/write a setting for the logged-in user, you need a snippet like this: ```php $cid = CRM_Core_Session::getLoggedInContactID(); $myFilter = Civi::service('settings_manager') ->getBagByContact(NULL, $cid) ->get('activity_tab_filter'); ``` After ----- To read/write a setting for the logged-in user, you can use a snippet like this: ```php $myFilter = Civi::contactSettings()->get('activity_tab_filter'); ``` Technical Details ----------------- * A convenience function like this is liable to be used in lazy circumstances where the developer is unlikely to check their conditions carefully. Therefore, the errors are reported as exceptions so that mistakes are easiliy revealed. * This is technically a small contract change to `SettingsManager::getBagByContact()` because it now interprets `$contactId===NULL` as meaning "the logged-in user". However, I don't think NULL was a sensible value before, and this interface isn't widely known/used. --- Civi.php | 16 +++++++ Civi/Core/SettingsManager.php | 11 +++++ tests/phpunit/Civi/Core/CiviFacadeTest.php | 50 ++++++++++++++++++++++ 3 files changed, 77 insertions(+) create mode 100644 tests/phpunit/Civi/Core/CiviFacadeTest.php diff --git a/Civi.php b/Civi.php index 8acfdba768..90aebee174 100644 --- a/Civi.php +++ b/Civi.php @@ -108,6 +108,22 @@ class Civi { return CRM_Core_Resources::singleton(); } + /** + * Obtain the contact's personal settings. + * + * @param NULL|int $contactID + * For the default/active user's contact, leave $domainID as NULL. + * @param NULL|int $domainID + * For the default domain, leave $domainID as NULL. + * @return \Civi\Core\SettingsBag + * @throws CRM_Core_Exception + * If there is no contact, then there's no SettingsBag, and we'll throw + * an exception. + */ + public static function contactSettings($contactID = NULL, $domainID = NULL) { + return \Civi\Core\Container::getBootService('settings_manager')->getBagByContact($domainID, $contactID); + } + /** * Obtain the domain settings. * diff --git a/Civi/Core/SettingsManager.php b/Civi/Core/SettingsManager.php index e56d723b2f..cca82f79de 100644 --- a/Civi/Core/SettingsManager.php +++ b/Civi/Core/SettingsManager.php @@ -171,13 +171,24 @@ class SettingsManager { /** * @param int|NULL $domainId + * For the default domain, leave $domainID as NULL. * @param int|NULL $contactId + * For the default/active user's contact, leave $domainID as NULL. * @return SettingsBag + * @throws \CRM_Core_Exception + * If there is no contact, then there's no SettingsBag, and we'll throw + * an exception. */ public function getBagByContact($domainId, $contactId) { if ($domainId === NULL) { $domainId = \CRM_Core_Config::domainID(); } + if ($contactId === NULL) { + $contactId = \CRM_Core_Session::getLoggedInContactID(); + if (!$contactId) { + throw new \CRM_Core_Exception("Cannot access settings subsystem - user or domain is unavailable"); + } + } $key = "$domainId:$contactId"; if (!isset($this->bagsByContact[$key])) { diff --git a/tests/phpunit/Civi/Core/CiviFacadeTest.php b/tests/phpunit/Civi/Core/CiviFacadeTest.php new file mode 100644 index 0000000000..0f678eac5d --- /dev/null +++ b/tests/phpunit/Civi/Core/CiviFacadeTest.php @@ -0,0 +1,50 @@ +origSetting = $GLOBALS['civicrm_setting']; + + parent::setUp(); + $this->useTransaction(TRUE); + + $this->mandates = array(); + } + + public function tearDown() { + $GLOBALS['civicrm_setting'] = $this->origSetting; + parent::tearDown(); + } + + /** + * Get the the settingsbag for a logged-in user. + */ + public function testContactSettings_loggedIn() { + $this->createLoggedInUser(); + $settingsBag = \Civi::contactSettings(); + $settingsBag->set('foo', 'bar'); + $this->assertEquals('bar', $settingsBag->get('foo')); + } + + /** + * Anonymous users don't have a SettingsBag. + * @expectedException \CRM_Core_Exception + */ + public function testContactSettings_anonFail() { + \Civi::contactSettings(); + } + + /** + * Get the SettingsBag for a specific user. + */ + public function testContactSettings_byId() { + $cid = \CRM_Core_DAO::singleValueQuery('SELECT MIN(id) FROM civicrm_contact'); + $settingsBag = \Civi::contactSettings($cid); + $settingsBag->set('foo', 'bar'); + $this->assertEquals('bar', $settingsBag->get('foo')); + } + +} -- 2.25.1