3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.7 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2015 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
34 * Read and write settings for a given domain (or contact).
36 * If the target entity does not already have a value for the setting, then
37 * the defaults will be used. If mandatory values are provided, they will
38 * override any defaults or custom settings.
40 * It's expected that the SettingsBag will have O(50-250) settings -- and that
41 * we'll load the full bag on many page requests. Consequently, we don't
42 * want the full metadata (help text and version history and HTML widgets)
43 * for all 250 settings, but we do need the default values.
45 * This class is not usually instantiated directly. Instead, use SettingsManager
46 * or Civi::settings().
48 * @see \Civi::settings()
49 * @see SettingsManagerTest
59 * Array(string $settingName => mixed $value).
65 * Array(string $settingName => mixed $value).
70 * The result of combining default values, mandatory
71 * values, and user values.
74 * Array(string $settingName => mixed $value).
83 protected $filteredValues;
86 * @param int $domainId
87 * The domain for which we want settings.
88 * @param int|NULL $contactId
89 * The contact for which we want settings. Use NULL for domain settings.
91 public function __construct($domainId, $contactId) {
92 $this->domainId
= $domainId;
93 $this->contactId
= $contactId;
94 $this->values
= array();
95 $this->filteredValues
= array();
96 $this->combined
= NULL;
100 * Set/replace the default values.
102 * @param array $defaults
103 * Array(string $settingName => mixed $value).
106 public function loadDefaults($defaults) {
107 $this->defaults
= $defaults;
108 $this->filteredValues
= array();
109 $this->combined
= NULL;
114 * Set/replace the mandatory values.
116 * @param array $mandatory
117 * Array(string $settingName => mixed $value).
120 public function loadMandatory($mandatory) {
121 $this->mandatory
= $mandatory;
122 $this->filteredValues
= array();
123 $this->combined
= NULL;
128 * Load all explicit settings that apply to this domain or contact.
132 public function loadValues() {
133 $this->values
= array();
134 // Note: Don't use Setting DAO. It requires fields() which requires
135 // translations -- which are keyed off settings!
136 $dao = \CRM_Core_DAO
::executeQuery($this->createQuery()->toSQL());
137 while ($dao->fetch()) {
138 $this->values
[$dao->name
] = ($dao->value
!== NULL) ?
unserialize($dao->value
) : NULL;
140 $this->combined
= NULL;
145 * Add a batch of settings. Save them.
147 * @param array $settings
148 * Array(string $settingName => mixed $settingValue).
151 public function add(array $settings) {
152 foreach ($settings as $key => $value) {
153 $this->set($key, $value);
159 * Get a list of all effective settings.
162 * Array(string $settingName => mixed $settingValue).
164 public function all() {
165 if ($this->combined
=== NULL) {
166 $this->combined
= $this->combine(
167 array($this->defaults
, $this->values
, $this->mandatory
)
170 return $this->combined
;
174 * Determine the effective value.
179 public function get($key) {
181 return isset($all[$key]) ?
$all[$key] : NULL;
185 * Determine the default value of a setting.
188 * The simple name of the setting.
191 public function getDefault($key) {
192 return isset($this->defaults
[$key]) ?
$this->defaults
[$key] : NULL;
196 * Determine the explicitly designated value, regardless of
197 * any default or mandatory values.
200 * The simple name of the setting.
203 public function getExplicit($key) {
204 return (isset($this->values
[$key]) ?
$this->values
[$key] : NULL);
208 * Determine the mandatory value of a setting.
211 * The simple name of the setting.
214 public function getMandatory($key) {
215 return isset($this->mandatory
[$key]) ?
$this->mandatory
[$key] : NULL;
219 * Determine if the entity has explicitly designated a value.
221 * Note that get() may still return other values based on
222 * mandatory values or defaults.
225 * The simple name of the setting.
228 public function hasExplict($key) {
229 // NULL means no designated value.
230 return isset($this->values
[$key]);
234 * Removes any explicit settings. This restores the default.
237 * The simple name of the setting.
240 public function revert($key) {
241 // It might be better to DELETE (to avoid long-term leaks),
242 // but setting NULL is simpler for now.
243 return $this->set($key, NULL);
247 * Add a single setting. Save it.
250 * The simple name of the setting.
251 * @param mixed $value
252 * The new, explicit value of the setting.
255 public function set($key, $value) {
256 $this->setDb($key, $value);
257 $this->values
[$key] = $value;
258 unset($this->filteredValues
[$key]);
259 $this->combined
= NULL;
264 * @return \CRM_Utils_SQL_Select
266 protected function createQuery() {
267 $select = \CRM_Utils_SQL_Select
::from('civicrm_setting')
268 ->select('id, group_name, name, value, domain_id, contact_id, is_domain, component_id, created_date, created_id')
269 ->where('domain_id = #id', array(
270 'id' => $this->domainId
,
272 if ($this->contactId
=== NULL) {
273 $select->where('is_domain = 1');
276 $select->where('contact_id = #id', array(
277 'id' => $this->contactId
,
279 $select->where('is_domain = 0');
285 * Combine a series of arrays, excluding any
286 * null values. Later values override earlier
289 * @param array $arrays
290 * List of arrays to combine.
293 protected function combine($arrays) {
295 foreach ($arrays as $array) {
296 foreach ($array as $k => $v) {
306 * Update the DB record for this setting.
308 * @param string $name
309 * The simple name of the setting.
310 * @param mixed $value
311 * The new value of the setting.
313 protected function setDb($name, $value) {
314 if (\CRM_Core_BAO_Setting
::isUpgradeFromPreFourOneAlpha1()) {
315 // civicrm_setting table is not going to be present.
320 $fieldsToSet = \CRM_Core_BAO_Setting
::validateSettingsInput(array($name => $value), $fields);
321 //We haven't traditionally validated inputs to setItem, so this breaks things.
322 //foreach ($fieldsToSet as $settingField => &$settingValue) {
323 // self::validateSetting($settingValue, $fields['values'][$settingField]);
326 $metadata = $fields['values'][$name];
328 $dao = new \
CRM_Core_DAO_Setting();
330 $dao->domain_id
= $this->domainId
;
331 if ($this->contactId
) {
332 $dao->contact_id
= $this->contactId
;
339 $dao->group_name
= '';
341 if (isset($metadata['on_change'])) {
342 foreach ($metadata['on_change'] as $callback) {
344 \Civi\Core\Resolver
::singleton()->get($callback),
345 unserialize($dao->value
),
353 if (\CRM_Utils_System
::isNull($value)) {
354 $dao->value
= 'null';
357 $dao->value
= serialize($value);
360 $dao->created_date
= \CRM_Utils_Time
::getTime('Ymdhis');
362 $session = \CRM_Core_Session
::singleton();
363 if (\CRM_Contact_BAO_Contact_Utils
::isContactId($session->get('userID'))) {
364 $dao->created_id
= $session->get('userID');