Commit 01d70c56 authored by totten's avatar totten

(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.
parent 56afc088
......@@ -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.
*
......
......@@ -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])) {
......
<?php
namespace Civi\Core;
class CiviFacadeTest extends \CiviUnitTestCase {
protected $origSetting;
protected function setUp() {
$this->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'));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment