Add select2 to input field of datepicker
[civicrm-core.git] / CRM / Core / PseudoConstant.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
fee14197 4 | CiviCRM version 5 |
6a488035 5 +--------------------------------------------------------------------+
6b83d5bd 6 | Copyright CiviCRM LLC (c) 2004-2019 |
6a488035
TO
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
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. |
13 | |
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. |
18 | |
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 +--------------------------------------------------------------------+
d25dd0ee 26 */
6a488035
TO
27
28/**
29 *
30 * Stores all constants and pseudo constants for CRM application.
31 *
32 * examples of constants are "Contact Type" which will always be either
33 * 'Individual', 'Household', 'Organization'.
34 *
35 * pseudo constants are entities from the database whose values rarely
36 * change. examples are list of countries, states, location types,
37 * relationship types.
38 *
39 * currently we're getting the data from the underlying database. this
40 * will be reworked to use caching.
41 *
42 * Note: All pseudoconstants should be uninitialized or default to NULL.
43 * This provides greater consistency/predictability after flushing.
44 *
45 * @package CRM
6b83d5bd 46 * @copyright CiviCRM LLC (c) 2004-2019
6a488035
TO
47 */
48class CRM_Core_PseudoConstant {
49
887a4028 50 /**
d09edf64 51 * Static cache for pseudoconstant arrays.
887a4028 52 * @var array
887a4028
A
53 */
54 private static $cache;
55
6a488035
TO
56 /**
57 * activity type
58 * @var array
518fa0ee 59 * @deprecated Please use the buildOptions() method in the appropriate BAO object.
6a488035
TO
60 */
61 private static $activityType;
62
6a488035 63 /**
100fef9d 64 * States, provinces
6a488035 65 * @var array
6a488035
TO
66 */
67 private static $stateProvince;
68
69 /**
d09edf64 70 * Counties.
6a488035 71 * @var array
6a488035
TO
72 */
73 private static $county;
74
75 /**
100fef9d 76 * States/provinces abbreviations
6a488035 77 * @var array
6a488035 78 */
be2fb01f 79 private static $stateProvinceAbbreviation = [];
6a488035
TO
80
81 /**
d09edf64 82 * Country.
6a488035 83 * @var array
6a488035
TO
84 */
85 private static $country;
86
87 /**
d09edf64 88 * CountryIsoCode.
6a488035 89 * @var array
6a488035
TO
90 */
91 private static $countryIsoCode;
92
6a488035
TO
93 /**
94 * group
95 * @var array
518fa0ee 96 * @deprecated Please use the buildOptions() method in the appropriate BAO object.
6a488035
TO
97 */
98 private static $group;
99
6a488035 100 /**
100fef9d 101 * RelationshipType
6a488035 102 * @var array
6a488035
TO
103 */
104 private static $relationshipType;
105
106 /**
100fef9d 107 * Civicrm groups that are not smart groups
6a488035 108 * @var array
6a488035
TO
109 */
110 private static $staticGroup;
111
6a488035 112 /**
100fef9d 113 * Currency codes
6a488035 114 * @var array
6a488035
TO
115 */
116 private static $currencyCode;
117
6a488035 118 /**
100fef9d 119 * Payment processor
6a488035 120 * @var array
6a488035
TO
121 */
122 private static $paymentProcessor;
123
124 /**
100fef9d 125 * Payment processor types
6a488035 126 * @var array
6a488035
TO
127 */
128 private static $paymentProcessorType;
129
130 /**
131 * World Region
132 * @var array
6a488035
TO
133 */
134 private static $worldRegions;
135
6a488035
TO
136 /**
137 * activity status
138 * @var array
518fa0ee 139 * @deprecated Please use the buildOptions() method in the appropriate BAO object.
6a488035
TO
140 */
141 private static $activityStatus;
142
6a488035
TO
143 /**
144 * Visibility
145 * @var array
6a488035
TO
146 */
147 private static $visibility;
148
6a488035
TO
149 /**
150 * Greetings
151 * @var array
6a488035
TO
152 */
153 private static $greeting;
154
6a488035
TO
155 /**
156 * Extensions of type module
157 * @var array
6a488035
TO
158 */
159 private static $extensions;
160
f743a6eb
CW
161 /**
162 * Financial Account Type
163 * @var array
f743a6eb
CW
164 */
165 private static $accountOptionValues;
166
887a4028 167 /**
6d68a4cb
CW
168 * Low-level option getter, rarely accessed directly.
169 * NOTE: Rather than calling this function directly use CRM_*_BAO_*::buildOptions()
7eaff122 170 * @see https://docs.civicrm.org/dev/en/latest/framework/pseudoconstant/
6d68a4cb 171 *
76068c6a
TO
172 * NOTE: If someone undertakes a refactoring of this, please consider the use-case of
173 * the Setting.getoptions API. There is no DAO/field, but it would be nice to use the
174 * same 'pseudoconstant' struct in *.settings.php. This means loosening the coupling
175 * between $field lookup and the $pseudoconstant evaluation.
176 *
6a0b768e
TO
177 * @param string $daoName
178 * @param string $fieldName
179 * @param array $params
a42ef93c
CW
180 * - name string name of the option group
181 * - flip boolean results are return in id => label format if false
182 * if true, the results are reversed
183 * - grouping boolean if true, return the value in 'grouping' column (currently unsupported for tables other than option_value)
184 * - localize boolean if true, localize the results before returning
f743a6eb 185 * - condition string|array add condition(s) to the sql query - will be concatenated using 'AND'
091fe2a8
CW
186 * - keyColumn string the column to use for 'id'
187 * - labelColumn string the column to use for 'label'
6d68a4cb 188 * - orderColumn string the column to use for sorting, defaults to 'weight' column if one exists, else defaults to labelColumn
a42ef93c
CW
189 * - onlyActive boolean return only the action option values
190 * - fresh boolean ignore cache entries and go back to DB
353ffa53 191 * @param string $context : Context string
5b22d1b8 192 * @see CRM_Core_DAO::buildOptionsContext
887a4028 193 *
8d7a9d07 194 * @return array|bool
72b3a70c 195 * array on success, FALSE on error.
a42ef93c 196 *
887a4028 197 */
be2fb01f 198 public static function get($daoName, $fieldName, $params = [], $context = NULL) {
786ad6e1 199 CRM_Core_DAO::buildOptionsContext($context);
f2b53f26 200 $flip = !empty($params['flip']);
65c86f7d 201 // Historically this was 'false' but according to the notes in
202 // CRM_Core_DAO::buildOptionsContext it should be context dependent.
203 // timidly changing for 'search' only to fix world_region in search options.
204 $localizeDefault = in_array($context, ['search']) ? TRUE : FALSE;
786ad6e1 205 // Merge params with defaults
be2fb01f 206 $params += [
786ad6e1 207 'grouping' => FALSE,
65c86f7d 208 'localize' => $localizeDefault,
c203a3d6 209 'onlyActive' => ($context == 'validate' || $context == 'get') ? FALSE : TRUE,
786ad6e1 210 'fresh' => FALSE,
33e61cb8 211 'context' => $context,
be2fb01f 212 ];
33e61cb8 213 $entity = CRM_Core_DAO_AllCoreTables::getBriefName(CRM_Core_DAO_AllCoreTables::getCanonicalClassName($daoName));
f2b53f26
CW
214
215 // Custom fields are not in the schema
786ad6e1 216 if (strpos($fieldName, 'custom_') === 0 && is_numeric($fieldName[7])) {
2921fb78 217 $customField = new CRM_Core_BAO_CustomField();
a3d8b390 218 $customField->id = (int) substr($fieldName, 7);
832d5c06 219 $options = $customField->getOptions($context);
2fea9ed9
CW
220 if ($options && $flip) {
221 $options = array_flip($options);
a3d8b390
CW
222 }
223 $customField->free();
786ad6e1 224 return $options;
f2b53f26
CW
225 }
226
227 // Core field: load schema
8d7a9d07 228 $dao = new $daoName();
5fafc9b0 229 $fieldSpec = $dao->getFieldSpec($fieldName);
091fe2a8 230 $dao->free();
4268623e 231
33e61cb8
CW
232 // Ensure we have the canonical name for this field
233 $fieldName = CRM_Utils_Array::value('name', $fieldSpec, $fieldName);
4268623e 234
33e61cb8 235 // Return false if field doesn't exist.
5fafc9b0 236 if (empty($fieldSpec)) {
ecc63dd6
A
237 return FALSE;
238 }
887a4028 239
887a4028
A
240 elseif (!empty($fieldSpec['pseudoconstant'])) {
241 $pseudoconstant = $fieldSpec['pseudoconstant'];
cc6443c4 242
243 // if callback is specified..
22e263ad 244 if (!empty($pseudoconstant['callback'])) {
466fce54 245 $fieldOptions = call_user_func(Civi\Core\Resolver::singleton()->get($pseudoconstant['callback']), $context);
ca0f1c4b
TL
246 //CRM-18223: Allow additions to field options via hook.
247 CRM_Utils_Hook::fieldOptions($entity, $fieldName, $fieldOptions, $params);
248 return $fieldOptions;
cc6443c4 249 }
250
786ad6e1 251 // Merge params with schema defaults
be2fb01f
CW
252 $params += [
253 'condition' => CRM_Utils_Array::value('condition', $pseudoconstant, []),
091fe2a8
CW
254 'keyColumn' => CRM_Utils_Array::value('keyColumn', $pseudoconstant),
255 'labelColumn' => CRM_Utils_Array::value('labelColumn', $pseudoconstant),
be2fb01f 256 ];
091fe2a8 257
f6635f33
AH
258 if ($context == 'abbreviate') {
259 switch ($fieldName) {
260 case 'state_province_id':
261 $params['labelColumn'] = 'abbreviation';
262 break;
2e1050f4 263
f6635f33
AH
264 case 'country_id':
265 $params['labelColumn'] = 'iso_code';
266 break;
2e1050f4 267
f6635f33
AH
268 default:
269 }
270 }
271
091fe2a8 272 // Fetch option group from option_value table
22e263ad 273 if (!empty($pseudoconstant['optionGroupName'])) {
786ad6e1
CW
274 if ($context == 'validate') {
275 $params['labelColumn'] = 'name';
276 }
b432ddaa
CW
277 if ($context == 'match') {
278 $params['keyColumn'] = 'name';
279 }
a42ef93c 280 // Call our generic fn for retrieving from the option_value table
33e61cb8 281 $options = CRM_Core_OptionGroup::values(
887a4028 282 $pseudoconstant['optionGroupName'],
a42ef93c
CW
283 $flip,
284 $params['grouping'],
285 $params['localize'],
f743a6eb 286 $params['condition'] ? ' AND ' . implode(' AND ', (array) $params['condition']) : NULL,
091fe2a8 287 $params['labelColumn'] ? $params['labelColumn'] : 'label',
a42ef93c 288 $params['onlyActive'],
c0c9cd82 289 $params['fresh'],
fb011779
PN
290 $params['keyColumn'] ? $params['keyColumn'] : 'value',
291 !empty($params['orderColumn']) ? $params['orderColumn'] : 'weight'
887a4028 292 );
33e61cb8
CW
293 CRM_Utils_Hook::fieldOptions($entity, $fieldName, $options, $params);
294 return $options;
887a4028 295 }
091fe2a8
CW
296
297 // Fetch options from other tables
887a4028 298 if (!empty($pseudoconstant['table'])) {
a42ef93c
CW
299 // Normalize params so the serialized cache string will be consistent.
300 CRM_Utils_Array::remove($params, 'flip', 'fresh');
887a4028 301 ksort($params);
a1ef51e2 302 $cacheKey = $daoName . $fieldName . serialize($params);
887a4028 303
a1ef51e2 304 // Retrieve cached options
a42ef93c 305 if (isset(self::$cache[$cacheKey]) && empty($params['fresh'])) {
a1ef51e2 306 $output = self::$cache[$cacheKey];
887a4028 307 }
a1ef51e2 308 else {
4539198e 309 $daoName = CRM_Core_DAO_AllCoreTables::getClassForTable($pseudoconstant['table']);
2158332a
CW
310 if (!class_exists($daoName)) {
311 return FALSE;
312 }
313 // Get list of fields for the option table
8d7a9d07 314 $dao = new $daoName();
7ae0389f
CW
315 $availableFields = array_keys($dao->fieldKeys());
316 $dao->free();
887a4028 317
a1ef51e2
CW
318 $select = "SELECT %1 AS id, %2 AS label";
319 $from = "FROM %3";
be2fb01f 320 $wheres = [];
a1ef51e2 321 $order = "ORDER BY %2";
786ad6e1 322
b432ddaa
CW
323 // Use machine name in certain contexts
324 if ($context == 'validate' || $context == 'match') {
325 $nameField = $context == 'validate' ? 'labelColumn' : 'keyColumn';
a38a89fc 326 if (!empty($pseudoconstant['nameColumn'])) {
b432ddaa 327 $params[$nameField] = $pseudoconstant['nameColumn'];
a38a89fc
CW
328 }
329 elseif (in_array('name', $availableFields)) {
b432ddaa 330 $params[$nameField] = 'name';
a38a89fc 331 }
786ad6e1 332 }
6d68a4cb 333 // Condition param can be passed as an sql clause string or an array of clauses
a1ef51e2 334 if (!empty($params['condition'])) {
6d68a4cb 335 $wheres[] = implode(' AND ', (array) $params['condition']);
a1ef51e2 336 }
6d68a4cb 337 // onlyActive param will automatically filter on common flags
a1ef51e2 338 if (!empty($params['onlyActive'])) {
be2fb01f 339 foreach (['is_active' => 1, 'is_deleted' => 0, 'is_test' => 0, 'is_hidden' => 0] as $flag => $val) {
6d68a4cb
CW
340 if (in_array($flag, $availableFields)) {
341 $wheres[] = "$flag = $val";
342 }
a1ef51e2
CW
343 }
344 }
6d68a4cb
CW
345 // Filter domain specific options
346 if (in_array('domain_id', $availableFields)) {
347 $wheres[] = 'domain_id = ' . CRM_Core_Config::domainID();
348 }
be2fb01f
CW
349 $queryParams = [
350 1 => [$params['keyColumn'], 'String', CRM_Core_DAO::QUERY_FORMAT_NO_QUOTES],
351 2 => [$params['labelColumn'], 'String', CRM_Core_DAO::QUERY_FORMAT_NO_QUOTES],
352 3 => [$pseudoconstant['table'], 'String', CRM_Core_DAO::QUERY_FORMAT_NO_QUOTES],
353 ];
a1ef51e2
CW
354 // Add orderColumn param
355 if (!empty($params['orderColumn'])) {
be2fb01f 356 $queryParams[4] = [$params['orderColumn'], 'String', CRM_Core_DAO::QUERY_FORMAT_NO_QUOTES];
a1ef51e2
CW
357 $order = "ORDER BY %4";
358 }
359 // Support no sorting if $params[orderColumn] is FALSE
360 elseif (isset($params['orderColumn']) && $params['orderColumn'] === FALSE) {
361 $order = '';
362 }
363 // Default to 'weight' if that column exists
364 elseif (in_array('weight', $availableFields)) {
365 $order = "ORDER BY weight";
366 }
a42ef93c 367
be2fb01f 368 $output = [];
a1ef51e2
CW
369 $query = "$select $from";
370 if ($wheres) {
371 $query .= " WHERE " . implode($wheres, ' AND ');
372 }
373 $query .= ' ' . $order;
374 $dao = CRM_Core_DAO::executeQuery($query, $queryParams);
375 while ($dao->fetch()) {
376 $output[$dao->id] = $dao->label;
377 }
378 $dao->free();
a3d8b390
CW
379 // Localize results
380 if (!empty($params['localize']) || $pseudoconstant['table'] == 'civicrm_country' || $pseudoconstant['table'] == 'civicrm_state_province') {
be2fb01f 381 $I18nParams = [];
65c86f7d 382 if (isset($fieldSpec['localize_context'])) {
383 $I18nParams['context'] = $fieldSpec['localize_context'];
a3d8b390 384 }
a1ef51e2 385 $i18n = CRM_Core_I18n::singleton();
a3d8b390 386 $i18n->localizeArray($output, $I18nParams);
a1ef51e2
CW
387 // Maintain sort by label
388 if ($order == "ORDER BY %2") {
389 CRM_Utils_Array::asort($output);
390 }
391 }
33e61cb8 392 CRM_Utils_Hook::fieldOptions($entity, $fieldName, $output, $params);
a1ef51e2
CW
393 self::$cache[$cacheKey] = $output;
394 }
395 return $flip ? array_flip($output) : $output;
887a4028
A
396 }
397 }
a3d8b390
CW
398
399 // Return "Yes" and "No" for boolean fields
400 elseif (CRM_Utils_Array::value('type', $fieldSpec) === CRM_Utils_Type::T_BOOLEAN) {
be2fb01f 401 $output = $context == 'validate' ? [0, 1] : CRM_Core_SelectValues::boolean();
33e61cb8 402 CRM_Utils_Hook::fieldOptions($entity, $fieldName, $output, $params);
a3d8b390
CW
403 return $flip ? array_flip($output) : $output;
404 }
887a4028
A
405 // If we're still here, it's an error. Return FALSE.
406 return FALSE;
407 }
408
6a488035 409 /**
d09edf64 410 * Fetch the translated label for a field given its key.
dcda1cd5 411 *
6a0b768e
TO
412 * @param string $baoName
413 * @param string $fieldName
414 * @param string|Int $key
a8c23526
CW
415 *
416 * TODO: Accept multivalued input?
dcda1cd5 417 *
2a3f958d
CW
418 * @return bool|null|string
419 * FALSE if the given field has no associated option list
420 * NULL if the given key has no corresponding option
421 * String if label is found
dcda1cd5 422 */
00be9182 423 public static function getLabel($baoName, $fieldName, $key) {
a8c23526
CW
424 $values = $baoName::buildOptions($fieldName, 'get');
425 if ($values === FALSE) {
426 return FALSE;
427 }
428 return CRM_Utils_Array::value($key, $values);
429 }
430
431 /**
d09edf64 432 * Fetch the machine name for a field given its key.
a8c23526 433 *
6a0b768e
TO
434 * @param string $baoName
435 * @param string $fieldName
436 * @param string|Int $key
a8c23526
CW
437 *
438 * @return bool|null|string
439 * FALSE if the given field has no associated option list
440 * NULL if the given key has no corresponding option
441 * String if label is found
442 */
00be9182 443 public static function getName($baoName, $fieldName, $key) {
a8c23526 444 $values = $baoName::buildOptions($fieldName, 'validate');
2a3f958d
CW
445 if ($values === FALSE) {
446 return FALSE;
447 }
448 return CRM_Utils_Array::value($key, $values);
449 }
dcda1cd5
CW
450
451 /**
d09edf64 452 * Fetch the key for a field option given its name.
dcda1cd5 453 *
6a0b768e
TO
454 * @param string $baoName
455 * @param string $fieldName
456 * @param string|Int $value
dcda1cd5 457 *
8d7a9d07 458 * @return bool|null|string|int
2a3f958d
CW
459 * FALSE if the given field has no associated option list
460 * NULL if the given key has no corresponding option
461 * String|Number if key is found
dcda1cd5 462 */
00be9182 463 public static function getKey($baoName, $fieldName, $value) {
a8c23526 464 $values = $baoName::buildOptions($fieldName, 'validate');
2a3f958d
CW
465 if ($values === FALSE) {
466 return FALSE;
467 }
468 return CRM_Utils_Array::key($value, $values);
469 }
dcda1cd5 470
e869b07d
CW
471 /**
472 * Lookup the admin page at which a field's option list can be edited
473 * @param $fieldSpec
474 * @return string|null
475 */
00be9182 476 public static function getOptionEditUrl($fieldSpec) {
e869b07d
CW
477 // If it's an option group, that's easy
478 if (!empty($fieldSpec['pseudoconstant']['optionGroupName'])) {
479 return 'civicrm/admin/options/' . $fieldSpec['pseudoconstant']['optionGroupName'];
480 }
481 // For everything else...
482 elseif (!empty($fieldSpec['pseudoconstant']['table'])) {
483 $daoName = CRM_Core_DAO_AllCoreTables::getClassForTable($fieldSpec['pseudoconstant']['table']);
484 if (!$daoName) {
485 return NULL;
486 }
487 // We don't have good mapping so have to do a bit of guesswork from the menu
e1462487 488 list(, $parent, , $child) = explode('_', $daoName);
e869b07d 489 $sql = "SELECT path FROM civicrm_menu
e1462487
CW
490 WHERE page_callback LIKE '%CRM_Admin_Page_$child%' OR page_callback LIKE '%CRM_{$parent}_Page_$child%'
491 ORDER BY page_callback
e869b07d
CW
492 LIMIT 1";
493 return CRM_Core_Dao::singleValueQuery($sql);
494 }
495 return NULL;
496 }
497
dcda1cd5 498 /**
887688b9 499 * @deprecated generic populate method.
c490a46a 500 * All pseudoconstant functions that use this method are also @deprecated
6a488035
TO
501 *
502 * The static array $var is populated from the db
503 * using the <b>$name DAO</b>.
504 *
505 * Note: any database errors will be trapped by the DAO.
506 *
6a0b768e
TO
507 * @param array $var
508 * The associative array we will fill.
509 * @param string $name
510 * The name of the DAO.
511 * @param bool $all
512 * Get all objects. default is to get only active ones.
513 * @param string $retrieve
514 * The field that we are interested in (normally name, differs in some objects).
515 * @param string $filter
516 * The field that we want to filter the result set with.
517 * @param string $condition
518 * The condition that gets passed to the final query as the WHERE clause.
745b795a 519 *
8eedd10a 520 * @param bool $orderby
745b795a 521 * @param string $key
8eedd10a 522 * @param bool $force
6a488035 523 *
8eedd10a 524 * @return array
6a488035 525 */
8360b701
DL
526 public static function populate(
527 &$var,
528 $name,
529 $all = FALSE,
530 $retrieve = 'name',
531 $filter = 'is_active',
532 $condition = NULL,
533 $orderby = NULL,
534 $key = 'id',
535 $force = NULL
536 ) {
ec87a877 537 $cacheKey = CRM_Core_BAO_Cache::cleanKey("CRM_PC_{$name}_{$all}_{$key}_{$retrieve}_{$filter}_{$condition}_{$orderby}");
353ffa53
TO
538 $cache = CRM_Utils_Cache::singleton();
539 $var = $cache->get($cacheKey);
4f468a50 540 if ($var !== NULL && empty($force)) {
6a488035
TO
541 return $var;
542 }
543
5836c35a 544 /* @var CRM_Core_DAO $object */
8d7a9d07 545 $object = new $name();
6a488035
TO
546
547 $object->selectAdd();
548 $object->selectAdd("$key, $retrieve");
549 if ($condition) {
550 $object->whereAdd($condition);
551 }
552
553 if (!$orderby) {
554 $object->orderBy($retrieve);
555 }
556 else {
557 $object->orderBy($orderby);
558 }
559
560 if (!$all) {
561 $object->$filter = 1;
5836c35a
CW
562 $aclClauses = array_filter($name::getSelectWhereClause());
563 foreach ($aclClauses as $clause) {
564 $object->whereAdd($clause);
565 }
6a488035
TO
566 }
567
568 $object->find();
be2fb01f 569 $var = [];
6a488035
TO
570 while ($object->fetch()) {
571 $var[$object->$key] = $object->$retrieve;
572 }
573
574 $cache->set($cacheKey, $var);
575 }
576
577 /**
d09edf64 578 * Flush given pseudoconstant so it can be reread from db.
6a488035
TO
579 * nex time it's requested.
580 *
2a6da8d7 581 * @param bool|string $name pseudoconstant to be flushed
6a488035 582 */
2683ce94 583 public static function flush($name = 'cache') {
80085473 584 if (isset(self::$$name)) {
fa56270d
CW
585 self::$$name = NULL;
586 }
80085473
CW
587 if ($name == 'cache') {
588 CRM_Core_OptionGroup::flushAll();
7c990617 589 if (isset(\Civi::$statics[__CLASS__])) {
590 unset(\Civi::$statics[__CLASS__]);
591 }
80085473 592 }
6a488035
TO
593 }
594
6a488035 595 /**
c490a46a 596 * @deprecated Please use the buildOptions() method in the appropriate BAO object.
a19392e7 597 *
6a488035
TO
598 * Get all Activty types.
599 *
600 * The static array activityType is returned
601 *
6a488035 602 *
a6c01b45
CW
603 * @return array
604 * array reference of all activity types.
6a488035
TO
605 */
606 public static function &activityType() {
607 $args = func_get_args();
608 $all = CRM_Utils_Array::value(0, $args, TRUE);
609 $includeCaseActivities = CRM_Utils_Array::value(1, $args, FALSE);
610 $reset = CRM_Utils_Array::value(2, $args, FALSE);
611 $returnColumn = CRM_Utils_Array::value(3, $args, 'label');
612 $includeCampaignActivities = CRM_Utils_Array::value(4, $args, FALSE);
613 $onlyComponentActivities = CRM_Utils_Array::value(5, $args, FALSE);
614 $index = (int) $all . '_' . $returnColumn . '_' . (int) $includeCaseActivities;
615 $index .= '_' . (int) $includeCampaignActivities;
616 $index .= '_' . (int) $onlyComponentActivities;
617
618 if (NULL === self::$activityType) {
be2fb01f 619 self::$activityType = [];
6a488035
TO
620 }
621
622 if (!isset(self::$activityType[$index]) || $reset) {
623 $condition = NULL;
624 if (!$all) {
625 $condition = 'AND filter = 0';
626 }
627 $componentClause = " v.component_id IS NULL";
628 if ($onlyComponentActivities) {
629 $componentClause = " v.component_id IS NOT NULL";
630 }
631
be2fb01f 632 $componentIds = [];
6a488035
TO
633 $compInfo = CRM_Core_Component::getEnabledComponents();
634
635 // build filter for listing activity types only if their
636 // respective components are enabled
637 foreach ($compInfo as $compName => $compObj) {
638 if ($compName == 'CiviCase') {
639 if ($includeCaseActivities) {
640 $componentIds[] = $compObj->componentID;
641 }
642 }
643 elseif ($compName == 'CiviCampaign') {
644 if ($includeCampaignActivities) {
645 $componentIds[] = $compObj->componentID;
646 }
647 }
648 else {
649 $componentIds[] = $compObj->componentID;
650 }
651 }
652
653 if (count($componentIds)) {
654 $componentIds = implode(',', $componentIds);
655 $componentClause = " ($componentClause OR v.component_id IN ($componentIds))";
656 if ($onlyComponentActivities) {
657 $componentClause = " ( v.component_id IN ($componentIds ) )";
658 }
659 }
bdd7b275 660 $condition = $condition . ' AND ' . $componentClause;
6a488035
TO
661
662 self::$activityType[$index] = CRM_Core_OptionGroup::values('activity_type', FALSE, FALSE, FALSE, $condition, $returnColumn);
663 }
664 return self::$activityType[$index];
665 }
0e6e8724 666
6a488035
TO
667 /**
668 * Get all the State/Province from database.
669 *
670 * The static array stateProvince is returned, and if it's
671 * called the first time, the <b>State Province DAO</b> is used
672 * to get all the States.
673 *
674 * Note: any database errors will be trapped by the DAO.
675 *
6a488035 676 *
6a0b768e 677 * @param bool|int $id - Optional id to return
6a488035 678 *
2a6da8d7 679 * @param bool $limit
6a488035 680 *
a6c01b45
CW
681 * @return array
682 * array reference of all State/Provinces.
6a488035
TO
683 */
684 public static function &stateProvince($id = FALSE, $limit = TRUE) {
685 if (($id && !CRM_Utils_Array::value($id, self::$stateProvince)) || !self::$stateProvince || !$id) {
686 $whereClause = FALSE;
6a488035
TO
687 if ($limit) {
688 $countryIsoCodes = self::countryIsoCode();
0acb7f15 689 $limitCodes = CRM_Core_BAO_Country::provinceLimit();
be2fb01f 690 $limitIds = [];
6a488035
TO
691 foreach ($limitCodes as $code) {
692 $limitIds = array_merge($limitIds, array_keys($countryIsoCodes, $code));
693 }
694 if (!empty($limitIds)) {
695 $whereClause = 'country_id IN (' . implode(', ', $limitIds) . ')';
696 }
697 else {
698 $whereClause = FALSE;
699 }
700 }
701 self::populate(self::$stateProvince, 'CRM_Core_DAO_StateProvince', TRUE, 'name', 'is_active', $whereClause);
702
703 // localise the province names if in an non-en_US locale
98466ff9 704 $tsLocale = CRM_Core_I18n::getLocale();
6a488035
TO
705 if ($tsLocale != '' and $tsLocale != 'en_US') {
706 $i18n = CRM_Core_I18n::singleton();
be2fb01f 707 $i18n->localizeArray(self::$stateProvince, [
353ffa53 708 'context' => 'province',
be2fb01f 709 ]);
6a488035
TO
710 self::$stateProvince = CRM_Utils_Array::asort(self::$stateProvince);
711 }
712 }
713 if ($id) {
714 if (array_key_exists($id, self::$stateProvince)) {
715 return self::$stateProvince[$id];
716 }
717 else {
718 $result = NULL;
719 return $result;
720 }
721 }
722 return self::$stateProvince;
723 }
724
725 /**
726 * Get all the State/Province abbreviations from the database.
727 *
728 * Same as above, except gets the abbreviations instead of the names.
729 *
6a488035 730 *
6a0b768e 731 * @param bool|int $id - Optional id to return
2a6da8d7
EM
732 *
733 * @param bool $limit
6a488035 734 *
a6c01b45
CW
735 * @return array
736 * array reference of all State/Province abbreviations.
6a488035 737 */
a8215a8d 738 public static function stateProvinceAbbreviation($id = FALSE, $limit = TRUE) {
05a8d245 739 if ($id && is_numeric($id)) {
740 if (!array_key_exists($id, (array) self::$stateProvinceAbbreviation)) {
741 $query = "SELECT abbreviation
6a488035
TO
742FROM civicrm_state_province
743WHERE id = %1";
be2fb01f
CW
744 $params = [
745 1 => [
05a8d245 746 $id,
747 'Integer',
be2fb01f
CW
748 ],
749 ];
05a8d245 750 self::$stateProvinceAbbreviation[$id] = CRM_Core_DAO::singleValueQuery($query, $params);
751 }
752 return self::$stateProvinceAbbreviation[$id];
6a488035 753 }
05a8d245 754 else {
6a488035
TO
755 $whereClause = FALSE;
756
757 if ($limit) {
6a488035 758 $countryIsoCodes = self::countryIsoCode();
0acb7f15 759 $limitCodes = CRM_Core_BAO_Country::provinceLimit();
be2fb01f 760 $limitIds = [];
6a488035
TO
761 foreach ($limitCodes as $code) {
762 $tmpArray = array_keys($countryIsoCodes, $code);
763
764 if (!empty($tmpArray)) {
765 $limitIds[] = array_shift($tmpArray);
766 }
767 }
768 if (!empty($limitIds)) {
769 $whereClause = 'country_id IN (' . implode(', ', $limitIds) . ')';
770 }
771 }
772 self::populate(self::$stateProvinceAbbreviation, 'CRM_Core_DAO_StateProvince', TRUE, 'abbreviation', 'is_active', $whereClause);
773 }
774
6a488035
TO
775 return self::$stateProvinceAbbreviation;
776 }
777
4352bd72 778 /**
779 * Get all the State/Province abbreviations from the database for the specified country.
780 *
781 * @param int $countryID
782 *
783 * @return array
784 * array of all State/Province abbreviations for the given country.
785 */
786 public static function stateProvinceAbbreviationForCountry($countryID) {
787 if (!isset(\Civi::$statics[__CLASS__]['stateProvinceAbbreviationForCountry'][$countryID])) {
be2fb01f 788 \Civi::$statics[__CLASS__]['stateProvinceAbbreviationForCountry'][$countryID] = [];
4352bd72 789 }
790 self::populate(\Civi::$statics[__CLASS__]['stateProvinceAbbreviationForCountry'][$countryID], 'CRM_Core_DAO_StateProvince', TRUE, 'abbreviation', 'is_active', "country_id = " . (int) $countryID, 'abbreviation');
791 return \Civi::$statics[__CLASS__]['stateProvinceAbbreviationForCountry'][$countryID];
792 }
793
794 /**
795 * Get all the State/Province abbreviations from the database for the default country.
796 *
797 * @return array
798 * array of all State/Province abbreviations for the given country.
799 */
800 public static function stateProvinceAbbreviationForDefaultCountry() {
801 return CRM_Core_PseudoConstant::stateProvinceAbbreviationForCountry(Civi::settings()->get('defaultContactCountry'));
802 }
803
6a488035
TO
804 /**
805 * Get all the countries from database.
806 *
807 * The static array country is returned, and if it's
808 * called the first time, the <b>Country DAO</b> is used
809 * to get all the countries.
810 *
811 * Note: any database errors will be trapped by the DAO.
812 *
6a488035 813 *
dd244018 814 * @param bool|int $id - Optional id to return
6a488035 815 *
dd244018 816 * @param bool $applyLimit
6a488035 817 *
1273d77c 818 * @return array|null
a6c01b45 819 * array reference of all countries.
6a488035
TO
820 */
821 public static function country($id = FALSE, $applyLimit = TRUE) {
822 if (($id && !CRM_Utils_Array::value($id, self::$country)) || !self::$country || !$id) {
823
824 $config = CRM_Core_Config::singleton();
be2fb01f 825 $limitCodes = [];
6a488035
TO
826
827 if ($applyLimit) {
828 // limit the country list to the countries specified in CIVICRM_COUNTRY_LIMIT
829 // (ensuring it's a subset of the legal values)
830 // K/P: We need to fix this, i dont think it works with new setting files
0acb7f15 831 $limitCodes = CRM_Core_BAO_Country::countryLimit();
6a488035 832 if (!is_array($limitCodes)) {
be2fb01f 833 $limitCodes = [
6a488035 834 $config->countryLimit => 1,
be2fb01f 835 ];
6a488035
TO
836 }
837
838 $limitCodes = array_intersect(self::countryIsoCode(), $limitCodes);
839 }
840
841 if (count($limitCodes)) {
842 $whereClause = "iso_code IN ('" . implode("', '", $limitCodes) . "')";
843 }
844 else {
845 $whereClause = NULL;
846 }
847
848 self::populate(self::$country, 'CRM_Core_DAO_Country', TRUE, 'name', 'is_active', $whereClause);
849
850 // if default country is set, percolate it to the top
851 if ($config->defaultContactCountry()) {
852 $countryIsoCodes = self::countryIsoCode();
853 $defaultID = array_search($config->defaultContactCountry(), $countryIsoCodes);
854 if ($defaultID !== FALSE) {
855 $default[$defaultID] = CRM_Utils_Array::value($defaultID, self::$country);
856 self::$country = $default + self::$country;
857 }
858 }
859
860 // localise the country names if in an non-en_US locale
98466ff9 861 $tsLocale = CRM_Core_I18n::getLocale();
6a488035
TO
862 if ($tsLocale != '' and $tsLocale != 'en_US') {
863 $i18n = CRM_Core_I18n::singleton();
be2fb01f 864 $i18n->localizeArray(self::$country, [
353ffa53 865 'context' => 'country',
be2fb01f 866 ]);
6a488035
TO
867 self::$country = CRM_Utils_Array::asort(self::$country);
868 }
869 }
870 if ($id) {
871 if (array_key_exists($id, self::$country)) {
872 return self::$country[$id];
873 }
874 else {
1273d77c 875 return NULL;
6a488035
TO
876 }
877 }
878 return self::$country;
879 }
880
881 /**
882 * Get all the country ISO Code abbreviations from the database.
883 *
884 * The static array countryIsoCode is returned, and if it's
885 * called the first time, the <b>Country DAO</b> is used
886 * to get all the countries' ISO codes.
887 *
888 * Note: any database errors will be trapped by the DAO.
889 *
6a488035 890 *
fd31fa4c 891 * @param bool $id
6a488035 892 *
a6c01b45
CW
893 * @return array
894 * array reference of all country ISO codes.
6a488035
TO
895 */
896 public static function &countryIsoCode($id = FALSE) {
897 if (!self::$countryIsoCode) {
898 self::populate(self::$countryIsoCode, 'CRM_Core_DAO_Country', TRUE, 'iso_code');
899 }
900 if ($id) {
901 if (array_key_exists($id, self::$countryIsoCode)) {
902 return self::$countryIsoCode[$id];
903 }
904 else {
7cdc9e9f 905 return CRM_Core_DAO::$_nullObject;
6a488035
TO
906 }
907 }
908 return self::$countryIsoCode;
909 }
910
6a488035 911 /**
c490a46a 912 * @deprecated Please use the buildOptions() method in the appropriate BAO object.
29494eef 913 *
6a488035
TO
914 * Get all groups from database
915 *
916 * The static array group is returned, and if it's
917 * called the first time, the <b>Group DAO</b> is used
918 * to get all the groups.
919 *
920 * Note: any database errors will be trapped by the DAO.
921 *
6a0b768e
TO
922 * @param string $groupType
923 * Type of group(Access/Mailing).
924 * @param bool $excludeHidden
925 * Exclude hidden groups.
6a488035 926 *
6a488035 927 *
a6c01b45
CW
928 * @return array
929 * array reference of all groups.
6a488035 930 */
addbec40 931 public static function allGroup($groupType = NULL, $excludeHidden = TRUE) {
1678a63b 932 if ($groupType === 'validate') {
933 // validate gets passed through from getoptions. Handle in the deprecated
934 // fn rather than change the new pattern.
935 $groupType = NULL;
936 }
6a488035 937 $condition = CRM_Contact_BAO_Group::groupTypeCondition($groupType, $excludeHidden);
addbec40 938 $groupKey = ($groupType ? $groupType : 'null') . !empty($excludeHidden);
6a488035 939
6d054a8e 940 if (!isset(Civi::$statics[__CLASS__]['groups']['allGroup'][$groupKey])) {
941 self::populate(Civi::$statics[__CLASS__]['groups']['allGroup'][$groupKey], 'CRM_Contact_DAO_Group', FALSE, 'title', 'is_active', $condition);
6a488035 942 }
6d054a8e 943 return Civi::$statics[__CLASS__]['groups']['allGroup'][$groupKey];
6a488035
TO
944 }
945
6a488035 946 /**
d09edf64 947 * Get all permissioned groups from database.
6a488035
TO
948 *
949 * The static array group is returned, and if it's
950 * called the first time, the <b>Group DAO</b> is used
951 * to get all the groups.
952 *
953 * Note: any database errors will be trapped by the DAO.
954 *
6a0b768e
TO
955 * @param string $groupType
956 * Type of group(Access/Mailing).
957 * @param bool $excludeHidden
958 * Exclude hidden groups.
dd244018 959 *
6a488035 960 *
a6c01b45
CW
961 * @return array
962 * array reference of all groups.
6a488035
TO
963 */
964 public static function group($groupType = NULL, $excludeHidden = TRUE) {
965 return CRM_Core_Permission::group($groupType, $excludeHidden);
966 }
967
24431f7b 968 /**
d09edf64 969 * Fetch groups in a nested format suitable for use in select form element.
24431f7b
CW
970 * @param bool $checkPermissions
971 * @param string|null $groupType
972 * @param bool $excludeHidden
973 * @return array
974 */
975 public static function nestedGroup($checkPermissions = TRUE, $groupType = NULL, $excludeHidden = TRUE) {
976 $groups = $checkPermissions ? self::group($groupType, $excludeHidden) : self::allGroup($groupType, $excludeHidden);
977 return CRM_Contact_BAO_Group::getGroupsHierarchy($groups, NULL, '&nbsp;&nbsp;', TRUE);
978 }
979
6a488035 980 /**
d09edf64 981 * Get all permissioned groups from database.
6a488035
TO
982 *
983 * The static array group is returned, and if it's
984 * called the first time, the <b>Group DAO</b> is used
985 * to get all the groups.
986 *
987 * Note: any database errors will be trapped by the DAO.
988 *
6a488035 989 *
dd244018
EM
990 * @param bool $onlyPublic
991 * @param null $groupType
992 * @param bool $excludeHidden
6a488035 993 *
a6c01b45
CW
994 * @return array
995 * array reference of all groups.
6a488035
TO
996 */
997 public static function &staticGroup($onlyPublic = FALSE, $groupType = NULL, $excludeHidden = TRUE) {
998 if (!self::$staticGroup) {
999 $condition = 'saved_search_id = 0 OR saved_search_id IS NULL';
1000 if ($onlyPublic) {
1001 $condition .= " AND visibility != 'User and User Admin Only'";
1002 }
1003
1004 if ($groupType) {
1005 $condition .= ' AND ' . CRM_Contact_BAO_Group::groupTypeCondition($groupType);
1006 }
1007
1008 if ($excludeHidden) {
1009 $condition .= ' AND is_hidden != 1 ';
1010 }
1011
1012 self::populate(self::$staticGroup, 'CRM_Contact_DAO_Group', FALSE, 'title', 'is_active', $condition, 'title');
1013 }
1014
1015 return self::$staticGroup;
1016 }
1017
6a488035
TO
1018 /**
1019 * Get all Relationship Types from database.
1020 *
1021 * The static array group is returned, and if it's
1022 * called the first time, the <b>RelationshipType DAO</b> is used
1023 * to get all the relationship types.
1024 *
1025 * Note: any database errors will be trapped by the DAO.
1026 *
6a0b768e
TO
1027 * @param string $valueColumnName
1028 * Db column name/label.
1029 * @param bool $reset
1030 * Reset relationship types if true.
bf48aa29 1031 * @param bool $isActive
fa8e67b8 1032 * Filter by is_active. NULL to disable.
6a488035 1033 *
a6c01b45
CW
1034 * @return array
1035 * array reference of all relationship types.
6a488035 1036 */
fa8e67b8
TO
1037 public static function &relationshipType($valueColumnName = 'label', $reset = FALSE, $isActive = 1) {
1038 $cacheKey = $valueColumnName . '::' . $isActive;
1039 if (!CRM_Utils_Array::value($cacheKey, self::$relationshipType) || $reset) {
be2fb01f 1040 self::$relationshipType[$cacheKey] = [];
6a488035
TO
1041
1042 //now we have name/label columns CRM-3336
1043 $column_a_b = "{$valueColumnName}_a_b";
1044 $column_b_a = "{$valueColumnName}_b_a";
1045
1046 $relationshipTypeDAO = new CRM_Contact_DAO_RelationshipType();
1047 $relationshipTypeDAO->selectAdd();
1048 $relationshipTypeDAO->selectAdd("id, {$column_a_b}, {$column_b_a}, contact_type_a, contact_type_b, contact_sub_type_a, contact_sub_type_b");
fa8e67b8
TO
1049 if ($isActive !== NULL) {
1050 $relationshipTypeDAO->is_active = $isActive;
1051 }
6a488035
TO
1052 $relationshipTypeDAO->find();
1053 while ($relationshipTypeDAO->fetch()) {
1054
be2fb01f 1055 self::$relationshipType[$cacheKey][$relationshipTypeDAO->id] = [
05802b8e 1056 'id' => $relationshipTypeDAO->id,
6a488035
TO
1057 $column_a_b => $relationshipTypeDAO->$column_a_b,
1058 $column_b_a => $relationshipTypeDAO->$column_b_a,
1059 'contact_type_a' => "$relationshipTypeDAO->contact_type_a",
1060 'contact_type_b' => "$relationshipTypeDAO->contact_type_b",
1061 'contact_sub_type_a' => "$relationshipTypeDAO->contact_sub_type_a",
1062 'contact_sub_type_b' => "$relationshipTypeDAO->contact_sub_type_b",
be2fb01f 1063 ];
6a488035
TO
1064 }
1065 }
1066
fa8e67b8 1067 return self::$relationshipType[$cacheKey];
6a488035
TO
1068 }
1069
6a488035 1070 /**
100fef9d 1071 * Get all the ISO 4217 currency codes
6a488035
TO
1072 *
1073 * so far, we use this for validation only, so there's no point of putting this into the database
1074 *
6a488035 1075 *
a6c01b45
CW
1076 * @return array
1077 * array reference of all currency codes
6a488035
TO
1078 */
1079 public static function &currencyCode() {
1080 if (!self::$currencyCode) {
3b5223ee
HF
1081
1082 $query = "SELECT name FROM civicrm_currency";
1083 $dao = CRM_Core_DAO::executeQuery($query);
be2fb01f 1084 $currencyCode = [];
3b5223ee
HF
1085 while ($dao->fetch()) {
1086 self::$currencyCode[] = $dao->name;
1087 }
6a488035
TO
1088 }
1089 return self::$currencyCode;
1090 }
1091
1092 /**
1093 * Get all the County from database.
1094 *
1095 * The static array county is returned, and if it's
1096 * called the first time, the <b>County DAO</b> is used
1097 * to get all the Counties.
1098 *
1099 * Note: any database errors will be trapped by the DAO.
1100 *
6a488035 1101 *
6a0b768e 1102 * @param bool|int $id - Optional id to return
6a488035 1103 *
a6c01b45
CW
1104 * @return array
1105 * array reference of all Counties
6a488035
TO
1106 */
1107 public static function &county($id = FALSE) {
1108 if (!self::$county) {
1109
1110 $config = CRM_Core_Config::singleton();
1111 // order by id so users who populate civicrm_county can have more control over sort by the order they load the counties
1112 self::populate(self::$county, 'CRM_Core_DAO_County', TRUE, 'name', NULL, NULL, 'id');
1113 }
1114 if ($id) {
1115 if (array_key_exists($id, self::$county)) {
1116 return self::$county[$id];
1117 }
1118 else {
7cdc9e9f 1119 return CRM_Core_DAO::$_nullObject;
6a488035
TO
1120 }
1121 }
1122 return self::$county;
1123 }
1124
6a488035 1125 /**
c490a46a 1126 * @deprecated Please use the buildOptions() method in the appropriate BAO object.
6a488035
TO
1127 * Get all active payment processors
1128 *
1129 * The static array paymentProcessor is returned
1130 *
6a488035 1131 *
6a0b768e
TO
1132 * @param bool $all
1133 * Get payment processors - default is to get only active ones.
1134 * @param bool $test
1135 * Get test payment processors.
6a488035 1136 *
77b97be7 1137 * @param null $additionalCond
6a488035 1138 *
a6c01b45
CW
1139 * @return array
1140 * array of all payment processors
6a488035 1141 */
d6944518 1142 public static function paymentProcessor($all = FALSE, $test = FALSE, $additionalCond = NULL) {
6a488035
TO
1143 $condition = "is_test = ";
1144 $condition .= ($test) ? '1' : '0';
1145
1146 if ($additionalCond) {
1147 $condition .= " AND ( $additionalCond ) ";
1148 }
1149
b44e3f84 1150 // CRM-7178. Make sure we only include payment processors valid in this
6a488035
TO
1151 // domain
1152 $condition .= " AND domain_id = " . CRM_Core_Config::domainID();
1153
1154 $cacheKey = $condition . '_' . (int) $all;
1155 if (!isset(self::$paymentProcessor[$cacheKey])) {
1156 self::populate(self::$paymentProcessor[$cacheKey], 'CRM_Financial_DAO_PaymentProcessor', $all, 'name', 'is_active', $condition, 'is_default desc, name');
1157 }
1158
1159 return self::$paymentProcessor[$cacheKey];
1160 }
1161
1162 /**
c490a46a 1163 * @deprecated Please use the buildOptions() method in the appropriate BAO object.
6a488035
TO
1164 *
1165 * The static array paymentProcessorType is returned
1166 *
6a488035 1167 *
6a0b768e
TO
1168 * @param bool $all
1169 * Get payment processors - default is to get only active ones.
6a488035 1170 *
100fef9d 1171 * @param int $id
77b97be7 1172 * @param string $return
6a488035 1173 *
a6c01b45
CW
1174 * @return array
1175 * array of all payment processor types
6a488035
TO
1176 */
1177 public static function &paymentProcessorType($all = FALSE, $id = NULL, $return = 'title') {
86bfa4f6 1178 $cacheKey = $id . '_' . $return;
6a488035
TO
1179 if (empty(self::$paymentProcessorType[$cacheKey])) {
1180 self::populate(self::$paymentProcessorType[$cacheKey], 'CRM_Financial_DAO_PaymentProcessorType', $all, $return, 'is_active', NULL, "is_default, $return", 'id');
1181 }
1182 if ($id && CRM_Utils_Array::value($id, self::$paymentProcessorType[$cacheKey])) {
1183 return self::$paymentProcessorType[$cacheKey][$id];
1184 }
1185 return self::$paymentProcessorType[$cacheKey];
1186 }
1187
1188 /**
d09edf64 1189 * Get all the World Regions from Database.
6a488035 1190 *
6a488035 1191 *
77b97be7
EM
1192 * @param bool $id
1193 *
a6c01b45
CW
1194 * @return array
1195 * array reference of all World Regions
6a488035
TO
1196 */
1197 public static function &worldRegion($id = FALSE) {
1198 if (!self::$worldRegions) {
1199 self::populate(self::$worldRegions, 'CRM_Core_DAO_Worldregion', TRUE, 'name', NULL, NULL, 'id');
1200 }
1201
1202 if ($id) {
1203 if (array_key_exists($id, self::$worldRegions)) {
1204 return self::$worldRegions[$id];
1205 }
1206 else {
7cdc9e9f 1207 return CRM_Core_DAO::$_nullObject;
6a488035
TO
1208 }
1209 }
1210
1211 return self::$worldRegions;
1212 }
1213
6a488035 1214 /**
c490a46a 1215 * @deprecated Please use the buildOptions() method in the appropriate BAO object.
29494eef 1216 *
6a488035
TO
1217 * Get all Activity Statuses.
1218 *
1219 * The static array activityStatus is returned
1220 *
6a488035 1221 *
77b97be7
EM
1222 * @param string $column
1223 *
a6c01b45
CW
1224 * @return array
1225 * array reference of all activity statuses
6a488035
TO
1226 */
1227 public static function &activityStatus($column = 'label') {
1228 if (NULL === self::$activityStatus) {
be2fb01f 1229 self::$activityStatus = [];
6a488035
TO
1230 }
1231 if (!array_key_exists($column, self::$activityStatus)) {
be2fb01f 1232 self::$activityStatus[$column] = [];
6a488035
TO
1233
1234 self::$activityStatus[$column] = CRM_Core_OptionGroup::values('activity_status', FALSE, FALSE, FALSE, NULL, $column);
1235 }
1236
1237 return self::$activityStatus[$column];
1238 }
1239
6a488035 1240 /**
c490a46a 1241 * @deprecated Please use the buildOptions() method in the appropriate BAO object.
a19392e7 1242 *
6a488035
TO
1243 * Get all Visibility levels.
1244 *
1245 * The static array visibility is returned
1246 *
6a488035 1247 *
77b97be7 1248 * @param string $column
6a488035 1249 *
a6c01b45
CW
1250 * @return array
1251 * array reference of all Visibility levels.
6a488035
TO
1252 */
1253 public static function &visibility($column = 'label') {
1254 if (!isset(self::$visibility)) {
be2fb01f 1255 self::$visibility = [];
6a488035
TO
1256 }
1257
1258 if (!isset(self::$visibility[$column])) {
1259 self::$visibility[$column] = CRM_Core_OptionGroup::values('visibility', FALSE, FALSE, FALSE, NULL, $column);
2aa397bc 1260 }
6a488035
TO
1261
1262 return self::$visibility[$column];
1263 }
1264
a0ee3941 1265 /**
100fef9d 1266 * @param int $countryID
a0ee3941
EM
1267 * @param string $field
1268 *
1269 * @return array
1270 */
6a488035
TO
1271 public static function &stateProvinceForCountry($countryID, $field = 'name') {
1272 static $_cache = NULL;
1273
1274 $cacheKey = "{$countryID}_{$field}";
1275 if (!$_cache) {
be2fb01f 1276 $_cache = [];
6a488035
TO
1277 }
1278
1279 if (!empty($_cache[$cacheKey])) {
1280 return $_cache[$cacheKey];
1281 }
1282
1283 $query = "
1284SELECT civicrm_state_province.{$field} name, civicrm_state_province.id id
1285 FROM civicrm_state_province
1286WHERE country_id = %1
1287ORDER BY name";
be2fb01f
CW
1288 $params = [
1289 1 => [
6a488035
TO
1290 $countryID,
1291 'Integer',
be2fb01f
CW
1292 ],
1293 ];
6a488035
TO
1294
1295 $dao = CRM_Core_DAO::executeQuery($query, $params);
1296
be2fb01f 1297 $result = [];
6a488035
TO
1298 while ($dao->fetch()) {
1299 $result[$dao->id] = $dao->name;
1300 }
1301
1302 // localise the stateProvince names if in an non-en_US locale
1303 $config = CRM_Core_Config::singleton();
98466ff9 1304 $tsLocale = CRM_Core_I18n::getLocale();
6a488035
TO
1305 if ($tsLocale != '' and $tsLocale != 'en_US') {
1306 $i18n = CRM_Core_I18n::singleton();
be2fb01f 1307 $i18n->localizeArray($result, [
6a488035 1308 'context' => 'province',
be2fb01f 1309 ]);
6a488035
TO
1310 $result = CRM_Utils_Array::asort($result);
1311 }
1312
1313 $_cache[$cacheKey] = $result;
1314
1315 CRM_Utils_Hook::buildStateProvinceForCountry($countryID, $result);
1316
1317 return $result;
1318 }
1319
a0ee3941 1320 /**
100fef9d 1321 * @param int $stateID
a0ee3941
EM
1322 *
1323 * @return array
1324 */
6a488035
TO
1325 public static function &countyForState($stateID) {
1326 if (is_array($stateID)) {
1327 $states = implode(", ", $stateID);
1328 $query = "
1329 SELECT civicrm_county.name name, civicrm_county.id id, civicrm_state_province.abbreviation abbreviation
1330 FROM civicrm_county
1331 LEFT JOIN civicrm_state_province ON civicrm_county.state_province_id = civicrm_state_province.id
1332 WHERE civicrm_county.state_province_id in ( $states )
1333 ORDER BY civicrm_state_province.abbreviation, civicrm_county.name";
1334
1335 $dao = CRM_Core_DAO::executeQuery($query);
1336
be2fb01f 1337 $result = [];
6a488035
TO
1338 while ($dao->fetch()) {
1339 $result[$dao->id] = $dao->abbreviation . ': ' . $dao->name;
1340 }
1341 }
1342 else {
1343
1344 static $_cache = NULL;
1345
1346 $cacheKey = "{$stateID}_name";
1347 if (!$_cache) {
be2fb01f 1348 $_cache = [];
6a488035
TO
1349 }
1350
1351 if (!empty($_cache[$cacheKey])) {
1352 return $_cache[$cacheKey];
1353 }
1354
1355 $query = "
1356 SELECT civicrm_county.name name, civicrm_county.id id
1357 FROM civicrm_county
1358 WHERE state_province_id = %1
1359 ORDER BY name";
be2fb01f
CW
1360 $params = [
1361 1 => [
6a488035
TO
1362 $stateID,
1363 'Integer',
be2fb01f
CW
1364 ],
1365 ];
6a488035
TO
1366
1367 $dao = CRM_Core_DAO::executeQuery($query, $params);
1368
be2fb01f 1369 $result = [];
6a488035
TO
1370 while ($dao->fetch()) {
1371 $result[$dao->id] = $dao->name;
1372 }
1373 }
1374
1375 return $result;
1376 }
1377
b05e28de
DL
1378 /**
1379 * Given a state ID return the country ID, this allows
1380 * us to populate forms and values for downstream code
1381 *
5a4f6742 1382 * @param int $stateID
b05e28de 1383 *
1273d77c 1384 * @return int|null
a6c01b45 1385 * the country id that the state belongs to
b05e28de 1386 */
00be9182 1387 public static function countryIDForStateID($stateID) {
b05e28de 1388 if (empty($stateID)) {
1273d77c 1389 return NULL;
b05e28de
DL
1390 }
1391
1392 $query = "
1393SELECT country_id
1394FROM civicrm_state_province
1395WHERE id = %1
1396";
be2fb01f 1397 $params = [1 => [$stateID, 'Integer']];
b05e28de
DL
1398
1399 return CRM_Core_DAO::singleValueQuery($query, $params);
1400 }
1401
6a488035
TO
1402 /**
1403 * Get all types of Greetings.
1404 *
1405 * The static array of greeting is returned
1406 *
6a488035 1407 *
6a0b768e
TO
1408 * @param $filter
1409 * Get All Email Greetings - default is to get only active ones.
6a488035 1410 *
77b97be7 1411 * @param string $columnName
6a488035 1412 *
a6c01b45
CW
1413 * @return array
1414 * array reference of all greetings.
6a488035
TO
1415 */
1416 public static function greeting($filter, $columnName = 'label') {
5f35a2d9 1417 if (!isset(Civi::$statics[__CLASS__]['greeting'])) {
be2fb01f 1418 Civi::$statics[__CLASS__]['greeting'] = [];
5f35a2d9 1419 }
1420
6a488035
TO
1421 $index = $filter['greeting_type'] . '_' . $columnName;
1422
1423 // also add contactType to the array
1424 $contactType = CRM_Utils_Array::value('contact_type', $filter);
1425 if ($contactType) {
1426 $index .= '_' . $contactType;
1427 }
1428
5f35a2d9 1429 if (!CRM_Utils_Array::value($index, Civi::$statics[__CLASS__]['greeting'])) {
6a488035
TO
1430 $filterCondition = NULL;
1431 if ($contactType) {
1432 $filterVal = 'v.filter =';
1433 switch ($contactType) {
1434 case 'Individual':
1435 $filterVal .= "1";
1436 break;
1437
1438 case 'Household':
1439 $filterVal .= "2";
1440 break;
1441
1442 case 'Organization':
1443 $filterVal .= "3";
1444 break;
1445 }
1446 $filterCondition .= "AND (v.filter = 0 OR {$filterVal}) ";
1447 }
1448
5f35a2d9 1449 Civi::$statics[__CLASS__]['greeting'][$index] = CRM_Core_OptionGroup::values($filter['greeting_type'], NULL, NULL, NULL, $filterCondition, $columnName);
6a488035
TO
1450 }
1451
5f35a2d9 1452 return Civi::$statics[__CLASS__]['greeting'][$index];
6a488035
TO
1453 }
1454
6a488035 1455 /**
d09edf64 1456 * Get all extensions.
6a488035
TO
1457 *
1458 * The static array extensions
1459 *
1460 * FIXME: This is called by civix but not by any core code. We
1461 * should provide an API call which civix can use instead.
1462 *
6a488035 1463 *
a6c01b45
CW
1464 * @return array
1465 * array($fullyQualifiedName => $label) list of extensions
6a488035
TO
1466 */
1467 public static function &getExtensions() {
1468 if (!self::$extensions) {
be2fb01f 1469 self::$extensions = [];
6a488035
TO
1470 $sql = '
1471 SELECT full_name, label
1472 FROM civicrm_extension
1473 WHERE is_active = 1
1474 ';
1475 $dao = CRM_Core_DAO::executeQuery($sql);
1476 while ($dao->fetch()) {
1477 self::$extensions[$dao->full_name] = $dao->label;
1478 }
1479 }
1480
1481 return self::$extensions;
1482 }
1483
f743a6eb 1484 /**
d09edf64 1485 * Get all options values.
f743a6eb
CW
1486 *
1487 * The static array option values is returned
1488 *
f743a6eb 1489 *
6a0b768e
TO
1490 * @param bool $optionGroupName
1491 * Get All Option Group values- default is to get only active ones.
f743a6eb 1492 *
100fef9d 1493 * @param int $id
77b97be7 1494 * @param null $condition
f743a6eb 1495 *
a6c01b45
CW
1496 * @return array
1497 * array reference of all Option Group Name
f743a6eb 1498 */
2aa397bc 1499 public static function accountOptionValues($optionGroupName, $id = NULL, $condition = NULL) {
f743a6eb
CW
1500 $cacheKey = $optionGroupName . '_' . $condition;
1501 if (empty(self::$accountOptionValues[$cacheKey])) {
2aa397bc 1502 self::$accountOptionValues[$cacheKey] = CRM_Core_OptionGroup::values($optionGroupName, FALSE, FALSE, FALSE, $condition);
f743a6eb
CW
1503 }
1504 if ($id) {
1505 return CRM_Utils_Array::value($id, self::$accountOptionValues[$cacheKey]);
1506 }
1507
1508 return self::$accountOptionValues[$cacheKey];
1509 }
1510
6a488035
TO
1511 /**
1512 * Fetch the list of active extensions of type 'module'
1513 *
5a4f6742
CW
1514 * @param bool $fresh
1515 * Whether to forcibly reload extensions list from canonical store.
6a488035 1516 *
a6c01b45
CW
1517 * @return array
1518 * array(array('prefix' => $, 'file' => $))
6a488035
TO
1519 */
1520 public static function getModuleExtensions($fresh = FALSE) {
1521 return CRM_Extension_System::singleton()->getMapper()->getActiveModuleFiles($fresh);
1522 }
dc428161 1523
dc428161 1524 /**
d09edf64 1525 * Get all tax rates.
dc428161 1526 *
1527 * The static array tax rates is returned
1528 *
a6c01b45
CW
1529 * @return array
1530 * array list of tax rates with the financial type
dc428161 1531 */
1532 public static function getTaxRates() {
27864d8a 1533 if (!isset(Civi::$statics[__CLASS__]['taxRates'])) {
be2fb01f
CW
1534 Civi::$statics[__CLASS__]['taxRates'] = [];
1535 $option = civicrm_api3('option_value', 'get', [
a38ebe6a
SL
1536 'sequential' => 1,
1537 'option_group_id' => 'account_relationship',
1538 'name' => 'Sales Tax Account is',
be2fb01f
CW
1539 ]);
1540 $value = [];
a38ebe6a 1541 if ($option['count'] !== 0) {
02b2d071
SL
1542 if ($option['count'] > 1) {
1543 foreach ($option['values'] as $opt) {
1544 $value[] = $opt['value'];
1545 }
1546 }
1547 else {
1548 $value[] = $option['values'][0]['value'];
1549 }
518fa0ee 1550 $where = 'AND efa.account_relationship IN (' . implode(', ', $value) . ' )';
a38ebe6a
SL
1551 }
1552 else {
1553 $where = '';
1554 }
dc428161 1555 $sql = "
1556 SELECT fa.tax_rate, efa.entity_id
1557 FROM civicrm_entity_financial_account efa
1558 INNER JOIN civicrm_financial_account fa ON fa.id = efa.financial_account_id
dc428161 1559 WHERE efa.entity_table = 'civicrm_financial_type'
a38ebe6a 1560 {$where}
dc428161 1561 AND fa.is_active = 1";
1562 $dao = CRM_Core_DAO::executeQuery($sql);
1563 while ($dao->fetch()) {
27864d8a 1564 Civi::$statics[__CLASS__]['taxRates'][$dao->entity_id] = $dao->tax_rate;
dc428161 1565 }
1566 }
1567
27864d8a 1568 return Civi::$statics[__CLASS__]['taxRates'];
dc428161 1569 }
96025800 1570
f61d1b83
AS
1571 /**
1572 * Get participant status class options.
1573 *
1574 * @return array
1575 */
1576 public static function emailOnHoldOptions() {
be2fb01f 1577 return [
f61d1b83
AS
1578 '0' => ts('No'),
1579 '1' => ts('On Hold Bounce'),
1580 '2' => ts('On Hold Opt Out'),
be2fb01f 1581 ];
f61d1b83
AS
1582 }
1583
6a488035 1584}