Merge pull request #7962 from eileenmcnaughton/CRM-18213
[civicrm-core.git] / CRM / Core / PseudoConstant.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
7e9e8871 4 | CiviCRM version 4.7 |
6a488035 5 +--------------------------------------------------------------------+
e7112fa7 6 | Copyright CiviCRM LLC (c) 2004-2015 |
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
e7112fa7 46 * @copyright CiviCRM LLC (c) 2004-2015
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 56 /**
c490a46a 57 * @deprecated Please use the buildOptions() method in the appropriate BAO object.
29494eef 58 *
6a488035
TO
59 * activity type
60 * @var array
6a488035
TO
61 */
62 private static $activityType;
63
6a488035 64 /**
100fef9d 65 * States, provinces
6a488035 66 * @var array
6a488035
TO
67 */
68 private static $stateProvince;
69
70 /**
d09edf64 71 * Counties.
6a488035 72 * @var array
6a488035
TO
73 */
74 private static $county;
75
76 /**
100fef9d 77 * States/provinces abbreviations
6a488035 78 * @var array
6a488035 79 */
05a8d245 80 private static $stateProvinceAbbreviation = array();
6a488035
TO
81
82 /**
d09edf64 83 * Country.
6a488035 84 * @var array
6a488035
TO
85 */
86 private static $country;
87
88 /**
d09edf64 89 * CountryIsoCode.
6a488035 90 * @var array
6a488035
TO
91 */
92 private static $countryIsoCode;
93
6a488035 94 /**
c490a46a 95 * @deprecated Please use the buildOptions() method in the appropriate BAO object.
29494eef 96 *
6a488035
TO
97 * group
98 * @var array
6a488035
TO
99 */
100 private static $group;
101
102 /**
100fef9d 103 * GroupIterator
6a488035 104 * @var mixed
6a488035
TO
105 */
106 private static $groupIterator;
107
108 /**
100fef9d 109 * RelationshipType
6a488035 110 * @var array
6a488035
TO
111 */
112 private static $relationshipType;
113
114 /**
100fef9d 115 * Civicrm groups that are not smart groups
6a488035 116 * @var array
6a488035
TO
117 */
118 private static $staticGroup;
119
6a488035 120 /**
100fef9d 121 * Currency codes
6a488035 122 * @var array
6a488035
TO
123 */
124 private static $currencyCode;
125
6a488035 126 /**
100fef9d 127 * Payment processor
6a488035 128 * @var array
6a488035
TO
129 */
130 private static $paymentProcessor;
131
132 /**
100fef9d 133 * Payment processor types
6a488035 134 * @var array
6a488035
TO
135 */
136 private static $paymentProcessorType;
137
138 /**
139 * World Region
140 * @var array
6a488035
TO
141 */
142 private static $worldRegions;
143
6a488035 144 /**
c490a46a 145 * @deprecated Please use the buildOptions() method in the appropriate BAO object.
29494eef 146 *
6a488035
TO
147 * activity status
148 * @var array
6a488035
TO
149 */
150 private static $activityStatus;
151
6a488035
TO
152 /**
153 * Visibility
154 * @var array
6a488035
TO
155 */
156 private static $visibility;
157
6a488035
TO
158 /**
159 * Greetings
160 * @var array
6a488035
TO
161 */
162 private static $greeting;
163
164 /**
165 * Default Greetings
166 * @var array
6a488035
TO
167 */
168 private static $greetingDefaults;
169
170 /**
171 * Extensions of type module
172 * @var array
6a488035
TO
173 */
174 private static $extensions;
175
f743a6eb
CW
176 /**
177 * Financial Account Type
178 * @var array
f743a6eb
CW
179 */
180 private static $accountOptionValues;
181
887a4028 182 /**
6d68a4cb
CW
183 * Low-level option getter, rarely accessed directly.
184 * NOTE: Rather than calling this function directly use CRM_*_BAO_*::buildOptions()
07c365da 185 * @see http://wiki.civicrm.org/confluence/display/CRMDOC/Pseudoconstant+%28option+list%29+Reference
6d68a4cb 186 *
76068c6a
TO
187 * NOTE: If someone undertakes a refactoring of this, please consider the use-case of
188 * the Setting.getoptions API. There is no DAO/field, but it would be nice to use the
189 * same 'pseudoconstant' struct in *.settings.php. This means loosening the coupling
190 * between $field lookup and the $pseudoconstant evaluation.
191 *
6a0b768e
TO
192 * @param string $daoName
193 * @param string $fieldName
194 * @param array $params
a42ef93c
CW
195 * - name string name of the option group
196 * - flip boolean results are return in id => label format if false
197 * if true, the results are reversed
198 * - grouping boolean if true, return the value in 'grouping' column (currently unsupported for tables other than option_value)
199 * - localize boolean if true, localize the results before returning
f743a6eb 200 * - condition string|array add condition(s) to the sql query - will be concatenated using 'AND'
091fe2a8
CW
201 * - keyColumn string the column to use for 'id'
202 * - labelColumn string the column to use for 'label'
6d68a4cb 203 * - orderColumn string the column to use for sorting, defaults to 'weight' column if one exists, else defaults to labelColumn
a42ef93c
CW
204 * - onlyActive boolean return only the action option values
205 * - fresh boolean ignore cache entries and go back to DB
353ffa53 206 * @param string $context : Context string
887a4028 207 *
8d7a9d07 208 * @return array|bool
72b3a70c 209 * array on success, FALSE on error.
a42ef93c 210 *
887a4028 211 */
786ad6e1
CW
212 public static function get($daoName, $fieldName, $params = array(), $context = NULL) {
213 CRM_Core_DAO::buildOptionsContext($context);
f2b53f26 214 $flip = !empty($params['flip']);
786ad6e1
CW
215 // Merge params with defaults
216 $params += array(
217 'grouping' => FALSE,
218 'localize' => FALSE,
c203a3d6 219 'onlyActive' => ($context == 'validate' || $context == 'get') ? FALSE : TRUE,
786ad6e1 220 'fresh' => FALSE,
33e61cb8 221 'context' => $context,
786ad6e1 222 );
33e61cb8 223 $entity = CRM_Core_DAO_AllCoreTables::getBriefName(CRM_Core_DAO_AllCoreTables::getCanonicalClassName($daoName));
f2b53f26
CW
224
225 // Custom fields are not in the schema
786ad6e1 226 if (strpos($fieldName, 'custom_') === 0 && is_numeric($fieldName[7])) {
2921fb78 227 $customField = new CRM_Core_BAO_CustomField();
a3d8b390 228 $customField->id = (int) substr($fieldName, 7);
2921fb78 229 $options = $customField->getOptions();
2fea9ed9
CW
230 if ($options && $flip) {
231 $options = array_flip($options);
a3d8b390
CW
232 }
233 $customField->free();
786ad6e1 234 return $options;
f2b53f26
CW
235 }
236
237 // Core field: load schema
8d7a9d07 238 $dao = new $daoName();
5fafc9b0 239 $fieldSpec = $dao->getFieldSpec($fieldName);
091fe2a8 240 $dao->free();
4268623e 241
33e61cb8
CW
242 // Ensure we have the canonical name for this field
243 $fieldName = CRM_Utils_Array::value('name', $fieldSpec, $fieldName);
4268623e 244
33e61cb8 245 // Return false if field doesn't exist.
5fafc9b0 246 if (empty($fieldSpec)) {
ecc63dd6
A
247 return FALSE;
248 }
887a4028 249
887a4028
A
250 elseif (!empty($fieldSpec['pseudoconstant'])) {
251 $pseudoconstant = $fieldSpec['pseudoconstant'];
cc6443c4 252
253 // if callback is specified..
22e263ad 254 if (!empty($pseudoconstant['callback'])) {
c8074a93 255 return call_user_func(Civi\Core\Resolver::singleton()->get($pseudoconstant['callback']));
cc6443c4 256 }
257
786ad6e1 258 // Merge params with schema defaults
091fe2a8 259 $params += array(
786ad6e1 260 'condition' => CRM_Utils_Array::value('condition', $pseudoconstant, array()),
091fe2a8
CW
261 'keyColumn' => CRM_Utils_Array::value('keyColumn', $pseudoconstant),
262 'labelColumn' => CRM_Utils_Array::value('labelColumn', $pseudoconstant),
091fe2a8
CW
263 );
264
f6635f33
AH
265 if ($context == 'abbreviate') {
266 switch ($fieldName) {
267 case 'state_province_id':
268 $params['labelColumn'] = 'abbreviation';
269 break;
2e1050f4 270
f6635f33
AH
271 case 'country_id':
272 $params['labelColumn'] = 'iso_code';
273 break;
2e1050f4 274
f6635f33
AH
275 default:
276 }
277 }
278
091fe2a8 279 // Fetch option group from option_value table
22e263ad 280 if (!empty($pseudoconstant['optionGroupName'])) {
786ad6e1
CW
281 if ($context == 'validate') {
282 $params['labelColumn'] = 'name';
283 }
b432ddaa
CW
284 if ($context == 'match') {
285 $params['keyColumn'] = 'name';
286 }
a42ef93c 287 // Call our generic fn for retrieving from the option_value table
33e61cb8 288 $options = CRM_Core_OptionGroup::values(
887a4028 289 $pseudoconstant['optionGroupName'],
a42ef93c
CW
290 $flip,
291 $params['grouping'],
292 $params['localize'],
f743a6eb 293 $params['condition'] ? ' AND ' . implode(' AND ', (array) $params['condition']) : NULL,
091fe2a8 294 $params['labelColumn'] ? $params['labelColumn'] : 'label',
a42ef93c 295 $params['onlyActive'],
c0c9cd82
CW
296 $params['fresh'],
297 $params['keyColumn'] ? $params['keyColumn'] : 'value'
887a4028 298 );
33e61cb8
CW
299 CRM_Utils_Hook::fieldOptions($entity, $fieldName, $options, $params);
300 return $options;
887a4028 301 }
091fe2a8
CW
302
303 // Fetch options from other tables
887a4028 304 if (!empty($pseudoconstant['table'])) {
a42ef93c
CW
305 // Normalize params so the serialized cache string will be consistent.
306 CRM_Utils_Array::remove($params, 'flip', 'fresh');
887a4028 307 ksort($params);
a1ef51e2 308 $cacheKey = $daoName . $fieldName . serialize($params);
887a4028 309
a1ef51e2 310 // Retrieve cached options
a42ef93c 311 if (isset(self::$cache[$cacheKey]) && empty($params['fresh'])) {
a1ef51e2 312 $output = self::$cache[$cacheKey];
887a4028 313 }
a1ef51e2 314 else {
4539198e 315 $daoName = CRM_Core_DAO_AllCoreTables::getClassForTable($pseudoconstant['table']);
2158332a
CW
316 if (!class_exists($daoName)) {
317 return FALSE;
318 }
319 // Get list of fields for the option table
8d7a9d07 320 $dao = new $daoName();
7ae0389f
CW
321 $availableFields = array_keys($dao->fieldKeys());
322 $dao->free();
887a4028 323
a1ef51e2
CW
324 $select = "SELECT %1 AS id, %2 AS label";
325 $from = "FROM %3";
326 $wheres = array();
327 $order = "ORDER BY %2";
786ad6e1 328
b432ddaa
CW
329 // Use machine name in certain contexts
330 if ($context == 'validate' || $context == 'match') {
331 $nameField = $context == 'validate' ? 'labelColumn' : 'keyColumn';
a38a89fc 332 if (!empty($pseudoconstant['nameColumn'])) {
b432ddaa 333 $params[$nameField] = $pseudoconstant['nameColumn'];
a38a89fc
CW
334 }
335 elseif (in_array('name', $availableFields)) {
b432ddaa 336 $params[$nameField] = 'name';
a38a89fc 337 }
786ad6e1 338 }
6d68a4cb 339 // Condition param can be passed as an sql clause string or an array of clauses
a1ef51e2 340 if (!empty($params['condition'])) {
6d68a4cb 341 $wheres[] = implode(' AND ', (array) $params['condition']);
a1ef51e2 342 }
6d68a4cb 343 // onlyActive param will automatically filter on common flags
a1ef51e2 344 if (!empty($params['onlyActive'])) {
21d4b9c1 345 foreach (array('is_active' => 1, 'is_deleted' => 0, 'is_test' => 0, 'is_hidden' => 0) as $flag => $val) {
6d68a4cb
CW
346 if (in_array($flag, $availableFields)) {
347 $wheres[] = "$flag = $val";
348 }
a1ef51e2
CW
349 }
350 }
6d68a4cb
CW
351 // Filter domain specific options
352 if (in_array('domain_id', $availableFields)) {
353 $wheres[] = 'domain_id = ' . CRM_Core_Config::domainID();
354 }
a1ef51e2 355 $queryParams = array(
353ffa53
TO
356 1 => array($params['keyColumn'], 'String', CRM_Core_DAO::QUERY_FORMAT_NO_QUOTES),
357 2 => array($params['labelColumn'], 'String', CRM_Core_DAO::QUERY_FORMAT_NO_QUOTES),
358 3 => array($pseudoconstant['table'], 'String', CRM_Core_DAO::QUERY_FORMAT_NO_QUOTES),
a1ef51e2
CW
359 );
360 // Add orderColumn param
361 if (!empty($params['orderColumn'])) {
362 $queryParams[4] = array($params['orderColumn'], 'String', CRM_Core_DAO::QUERY_FORMAT_NO_QUOTES);
363 $order = "ORDER BY %4";
364 }
365 // Support no sorting if $params[orderColumn] is FALSE
366 elseif (isset($params['orderColumn']) && $params['orderColumn'] === FALSE) {
367 $order = '';
368 }
369 // Default to 'weight' if that column exists
370 elseif (in_array('weight', $availableFields)) {
371 $order = "ORDER BY weight";
372 }
a42ef93c 373
a1ef51e2
CW
374 $output = array();
375 $query = "$select $from";
376 if ($wheres) {
377 $query .= " WHERE " . implode($wheres, ' AND ');
378 }
379 $query .= ' ' . $order;
380 $dao = CRM_Core_DAO::executeQuery($query, $queryParams);
381 while ($dao->fetch()) {
382 $output[$dao->id] = $dao->label;
383 }
384 $dao->free();
a3d8b390
CW
385 // Localize results
386 if (!empty($params['localize']) || $pseudoconstant['table'] == 'civicrm_country' || $pseudoconstant['table'] == 'civicrm_state_province') {
387 $I18nParams = array();
388 if ($pseudoconstant['table'] == 'civicrm_country') {
389 $I18nParams['context'] = 'country';
390 }
391 if ($pseudoconstant['table'] == 'civicrm_state_province') {
392 $I18nParams['context'] = 'province';
393 }
a1ef51e2 394 $i18n = CRM_Core_I18n::singleton();
a3d8b390 395 $i18n->localizeArray($output, $I18nParams);
a1ef51e2
CW
396 // Maintain sort by label
397 if ($order == "ORDER BY %2") {
398 CRM_Utils_Array::asort($output);
399 }
400 }
33e61cb8 401 CRM_Utils_Hook::fieldOptions($entity, $fieldName, $output, $params);
a1ef51e2
CW
402 self::$cache[$cacheKey] = $output;
403 }
404 return $flip ? array_flip($output) : $output;
887a4028
A
405 }
406 }
a3d8b390
CW
407
408 // Return "Yes" and "No" for boolean fields
409 elseif (CRM_Utils_Array::value('type', $fieldSpec) === CRM_Utils_Type::T_BOOLEAN) {
3b66f502 410 $output = $context == 'validate' ? array(0, 1) : CRM_Core_SelectValues::boolean();
33e61cb8 411 CRM_Utils_Hook::fieldOptions($entity, $fieldName, $output, $params);
a3d8b390
CW
412 return $flip ? array_flip($output) : $output;
413 }
887a4028
A
414 // If we're still here, it's an error. Return FALSE.
415 return FALSE;
416 }
417
6a488035 418 /**
d09edf64 419 * Fetch the translated label for a field given its key.
dcda1cd5 420 *
6a0b768e
TO
421 * @param string $baoName
422 * @param string $fieldName
423 * @param string|Int $key
a8c23526
CW
424 *
425 * TODO: Accept multivalued input?
dcda1cd5 426 *
2a3f958d
CW
427 * @return bool|null|string
428 * FALSE if the given field has no associated option list
429 * NULL if the given key has no corresponding option
430 * String if label is found
dcda1cd5 431 */
00be9182 432 public static function getLabel($baoName, $fieldName, $key) {
a8c23526
CW
433 $values = $baoName::buildOptions($fieldName, 'get');
434 if ($values === FALSE) {
435 return FALSE;
436 }
437 return CRM_Utils_Array::value($key, $values);
438 }
439
440 /**
d09edf64 441 * Fetch the machine name for a field given its key.
a8c23526 442 *
6a0b768e
TO
443 * @param string $baoName
444 * @param string $fieldName
445 * @param string|Int $key
a8c23526
CW
446 *
447 * @return bool|null|string
448 * FALSE if the given field has no associated option list
449 * NULL if the given key has no corresponding option
450 * String if label is found
451 */
00be9182 452 public static function getName($baoName, $fieldName, $key) {
a8c23526 453 $values = $baoName::buildOptions($fieldName, 'validate');
2a3f958d
CW
454 if ($values === FALSE) {
455 return FALSE;
456 }
457 return CRM_Utils_Array::value($key, $values);
458 }
dcda1cd5
CW
459
460 /**
d09edf64 461 * Fetch the key for a field option given its name.
dcda1cd5 462 *
6a0b768e
TO
463 * @param string $baoName
464 * @param string $fieldName
465 * @param string|Int $value
dcda1cd5 466 *
8d7a9d07 467 * @return bool|null|string|int
2a3f958d
CW
468 * FALSE if the given field has no associated option list
469 * NULL if the given key has no corresponding option
470 * String|Number if key is found
dcda1cd5 471 */
00be9182 472 public static function getKey($baoName, $fieldName, $value) {
a8c23526 473 $values = $baoName::buildOptions($fieldName, 'validate');
2a3f958d
CW
474 if ($values === FALSE) {
475 return FALSE;
476 }
477 return CRM_Utils_Array::key($value, $values);
478 }
dcda1cd5 479
e869b07d
CW
480 /**
481 * Lookup the admin page at which a field's option list can be edited
482 * @param $fieldSpec
483 * @return string|null
484 */
00be9182 485 public static function getOptionEditUrl($fieldSpec) {
e869b07d
CW
486 // If it's an option group, that's easy
487 if (!empty($fieldSpec['pseudoconstant']['optionGroupName'])) {
488 return 'civicrm/admin/options/' . $fieldSpec['pseudoconstant']['optionGroupName'];
489 }
490 // For everything else...
491 elseif (!empty($fieldSpec['pseudoconstant']['table'])) {
492 $daoName = CRM_Core_DAO_AllCoreTables::getClassForTable($fieldSpec['pseudoconstant']['table']);
493 if (!$daoName) {
494 return NULL;
495 }
496 // We don't have good mapping so have to do a bit of guesswork from the menu
e1462487 497 list(, $parent, , $child) = explode('_', $daoName);
e869b07d 498 $sql = "SELECT path FROM civicrm_menu
e1462487
CW
499 WHERE page_callback LIKE '%CRM_Admin_Page_$child%' OR page_callback LIKE '%CRM_{$parent}_Page_$child%'
500 ORDER BY page_callback
e869b07d
CW
501 LIMIT 1";
502 return CRM_Core_Dao::singleValueQuery($sql);
503 }
504 return NULL;
505 }
506
dcda1cd5 507 /**
d09edf64 508 * DEPRECATED generic populate method.
c490a46a 509 * All pseudoconstant functions that use this method are also @deprecated
6a488035
TO
510 *
511 * The static array $var is populated from the db
512 * using the <b>$name DAO</b>.
513 *
514 * Note: any database errors will be trapped by the DAO.
515 *
6a0b768e
TO
516 * @param array $var
517 * The associative array we will fill.
518 * @param string $name
519 * The name of the DAO.
520 * @param bool $all
521 * Get all objects. default is to get only active ones.
522 * @param string $retrieve
523 * The field that we are interested in (normally name, differs in some objects).
524 * @param string $filter
525 * The field that we want to filter the result set with.
526 * @param string $condition
527 * The condition that gets passed to the final query as the WHERE clause.
745b795a 528 *
8eedd10a 529 * @param bool $orderby
745b795a 530 * @param string $key
8eedd10a 531 * @param bool $force
6a488035 532 *
8eedd10a 533 * @return array
6a488035 534 */
8360b701
DL
535 public static function populate(
536 &$var,
537 $name,
538 $all = FALSE,
539 $retrieve = 'name',
540 $filter = 'is_active',
541 $condition = NULL,
542 $orderby = NULL,
543 $key = 'id',
544 $force = NULL
545 ) {
6a488035 546 $cacheKey = "CRM_PC_{$name}_{$all}_{$key}_{$retrieve}_{$filter}_{$condition}_{$orderby}";
353ffa53
TO
547 $cache = CRM_Utils_Cache::singleton();
548 $var = $cache->get($cacheKey);
6a488035
TO
549 if ($var && empty($force)) {
550 return $var;
551 }
552
8d7a9d07 553 $object = new $name();
6a488035
TO
554
555 $object->selectAdd();
556 $object->selectAdd("$key, $retrieve");
557 if ($condition) {
558 $object->whereAdd($condition);
559 }
560
561 if (!$orderby) {
562 $object->orderBy($retrieve);
563 }
564 else {
565 $object->orderBy($orderby);
566 }
567
568 if (!$all) {
569 $object->$filter = 1;
570 }
571
572 $object->find();
573 $var = array();
574 while ($object->fetch()) {
575 $var[$object->$key] = $object->$retrieve;
576 }
577
578 $cache->set($cacheKey, $var);
579 }
580
581 /**
d09edf64 582 * Flush given pseudoconstant so it can be reread from db.
6a488035
TO
583 * nex time it's requested.
584 *
6a488035 585 *
2a6da8d7 586 * @param bool|string $name pseudoconstant to be flushed
6a488035 587 */
2683ce94 588 public static function flush($name = 'cache') {
80085473 589 if (isset(self::$$name)) {
fa56270d
CW
590 self::$$name = NULL;
591 }
80085473
CW
592 if ($name == 'cache') {
593 CRM_Core_OptionGroup::flushAll();
594 }
6a488035
TO
595 }
596
6a488035 597 /**
c490a46a 598 * @deprecated Please use the buildOptions() method in the appropriate BAO object.
a19392e7 599 *
6a488035
TO
600 * Get all Activty types.
601 *
602 * The static array activityType is returned
603 *
6a488035 604 *
a6c01b45
CW
605 * @return array
606 * array reference of all activity types.
6a488035
TO
607 */
608 public static function &activityType() {
609 $args = func_get_args();
610 $all = CRM_Utils_Array::value(0, $args, TRUE);
611 $includeCaseActivities = CRM_Utils_Array::value(1, $args, FALSE);
612 $reset = CRM_Utils_Array::value(2, $args, FALSE);
613 $returnColumn = CRM_Utils_Array::value(3, $args, 'label');
614 $includeCampaignActivities = CRM_Utils_Array::value(4, $args, FALSE);
615 $onlyComponentActivities = CRM_Utils_Array::value(5, $args, FALSE);
616 $index = (int) $all . '_' . $returnColumn . '_' . (int) $includeCaseActivities;
617 $index .= '_' . (int) $includeCampaignActivities;
618 $index .= '_' . (int) $onlyComponentActivities;
619
620 if (NULL === self::$activityType) {
621 self::$activityType = array();
622 }
623
624 if (!isset(self::$activityType[$index]) || $reset) {
625 $condition = NULL;
626 if (!$all) {
627 $condition = 'AND filter = 0';
628 }
629 $componentClause = " v.component_id IS NULL";
630 if ($onlyComponentActivities) {
631 $componentClause = " v.component_id IS NOT NULL";
632 }
633
634 $componentIds = array();
635 $compInfo = CRM_Core_Component::getEnabledComponents();
636
637 // build filter for listing activity types only if their
638 // respective components are enabled
639 foreach ($compInfo as $compName => $compObj) {
640 if ($compName == 'CiviCase') {
641 if ($includeCaseActivities) {
642 $componentIds[] = $compObj->componentID;
643 }
644 }
645 elseif ($compName == 'CiviCampaign') {
646 if ($includeCampaignActivities) {
647 $componentIds[] = $compObj->componentID;
648 }
649 }
650 else {
651 $componentIds[] = $compObj->componentID;
652 }
653 }
654
655 if (count($componentIds)) {
656 $componentIds = implode(',', $componentIds);
657 $componentClause = " ($componentClause OR v.component_id IN ($componentIds))";
658 if ($onlyComponentActivities) {
659 $componentClause = " ( v.component_id IN ($componentIds ) )";
660 }
661 }
bdd7b275 662 $condition = $condition . ' AND ' . $componentClause;
6a488035
TO
663
664 self::$activityType[$index] = CRM_Core_OptionGroup::values('activity_type', FALSE, FALSE, FALSE, $condition, $returnColumn);
665 }
666 return self::$activityType[$index];
667 }
0e6e8724 668
6a488035
TO
669 /**
670 * Get all the State/Province from database.
671 *
672 * The static array stateProvince is returned, and if it's
673 * called the first time, the <b>State Province DAO</b> is used
674 * to get all the States.
675 *
676 * Note: any database errors will be trapped by the DAO.
677 *
6a488035 678 *
6a0b768e 679 * @param bool|int $id - Optional id to return
6a488035 680 *
2a6da8d7 681 * @param bool $limit
6a488035 682 *
a6c01b45
CW
683 * @return array
684 * array reference of all State/Provinces.
6a488035
TO
685 */
686 public static function &stateProvince($id = FALSE, $limit = TRUE) {
687 if (($id && !CRM_Utils_Array::value($id, self::$stateProvince)) || !self::$stateProvince || !$id) {
688 $whereClause = FALSE;
6a488035
TO
689 if ($limit) {
690 $countryIsoCodes = self::countryIsoCode();
0acb7f15 691 $limitCodes = CRM_Core_BAO_Country::provinceLimit();
353ffa53 692 $limitIds = array();
6a488035
TO
693 foreach ($limitCodes as $code) {
694 $limitIds = array_merge($limitIds, array_keys($countryIsoCodes, $code));
695 }
696 if (!empty($limitIds)) {
697 $whereClause = 'country_id IN (' . implode(', ', $limitIds) . ')';
698 }
699 else {
700 $whereClause = FALSE;
701 }
702 }
703 self::populate(self::$stateProvince, 'CRM_Core_DAO_StateProvince', TRUE, 'name', 'is_active', $whereClause);
704
705 // localise the province names if in an non-en_US locale
706 global $tsLocale;
707 if ($tsLocale != '' and $tsLocale != 'en_US') {
708 $i18n = CRM_Core_I18n::singleton();
709 $i18n->localizeArray(self::$stateProvince, array(
353ffa53
TO
710 'context' => 'province',
711 ));
6a488035
TO
712 self::$stateProvince = CRM_Utils_Array::asort(self::$stateProvince);
713 }
714 }
715 if ($id) {
716 if (array_key_exists($id, self::$stateProvince)) {
717 return self::$stateProvince[$id];
718 }
719 else {
720 $result = NULL;
721 return $result;
722 }
723 }
724 return self::$stateProvince;
725 }
726
727 /**
728 * Get all the State/Province abbreviations from the database.
729 *
730 * Same as above, except gets the abbreviations instead of the names.
731 *
6a488035 732 *
6a0b768e 733 * @param bool|int $id - Optional id to return
2a6da8d7
EM
734 *
735 * @param bool $limit
6a488035 736 *
a6c01b45
CW
737 * @return array
738 * array reference of all State/Province abbreviations.
6a488035 739 */
a8215a8d 740 public static function stateProvinceAbbreviation($id = FALSE, $limit = TRUE) {
05a8d245 741 if ($id && is_numeric($id)) {
742 if (!array_key_exists($id, (array) self::$stateProvinceAbbreviation)) {
743 $query = "SELECT abbreviation
6a488035
TO
744FROM civicrm_state_province
745WHERE id = %1";
05a8d245 746 $params = array(
747 1 => array(
748 $id,
749 'Integer',
750 ),
751 );
752 self::$stateProvinceAbbreviation[$id] = CRM_Core_DAO::singleValueQuery($query, $params);
753 }
754 return self::$stateProvinceAbbreviation[$id];
6a488035 755 }
05a8d245 756 else {
6a488035
TO
757 $whereClause = FALSE;
758
759 if ($limit) {
6a488035 760 $countryIsoCodes = self::countryIsoCode();
0acb7f15 761 $limitCodes = CRM_Core_BAO_Country::provinceLimit();
353ffa53 762 $limitIds = array();
6a488035
TO
763 foreach ($limitCodes as $code) {
764 $tmpArray = array_keys($countryIsoCodes, $code);
765
766 if (!empty($tmpArray)) {
767 $limitIds[] = array_shift($tmpArray);
768 }
769 }
770 if (!empty($limitIds)) {
771 $whereClause = 'country_id IN (' . implode(', ', $limitIds) . ')';
772 }
773 }
774 self::populate(self::$stateProvinceAbbreviation, 'CRM_Core_DAO_StateProvince', TRUE, 'abbreviation', 'is_active', $whereClause);
775 }
776
6a488035
TO
777 return self::$stateProvinceAbbreviation;
778 }
779
780 /**
781 * Get all the countries from database.
782 *
783 * The static array country is returned, and if it's
784 * called the first time, the <b>Country DAO</b> is used
785 * to get all the countries.
786 *
787 * Note: any database errors will be trapped by the DAO.
788 *
6a488035 789 *
dd244018 790 * @param bool|int $id - Optional id to return
6a488035 791 *
dd244018 792 * @param bool $applyLimit
6a488035 793 *
a6c01b45
CW
794 * @return array
795 * array reference of all countries.
6a488035
TO
796 */
797 public static function country($id = FALSE, $applyLimit = TRUE) {
798 if (($id && !CRM_Utils_Array::value($id, self::$country)) || !self::$country || !$id) {
799
800 $config = CRM_Core_Config::singleton();
801 $limitCodes = array();
802
803 if ($applyLimit) {
804 // limit the country list to the countries specified in CIVICRM_COUNTRY_LIMIT
805 // (ensuring it's a subset of the legal values)
806 // K/P: We need to fix this, i dont think it works with new setting files
0acb7f15 807 $limitCodes = CRM_Core_BAO_Country::countryLimit();
6a488035
TO
808 if (!is_array($limitCodes)) {
809 $limitCodes = array(
810 $config->countryLimit => 1,
811 );
812 }
813
814 $limitCodes = array_intersect(self::countryIsoCode(), $limitCodes);
815 }
816
817 if (count($limitCodes)) {
818 $whereClause = "iso_code IN ('" . implode("', '", $limitCodes) . "')";
819 }
820 else {
821 $whereClause = NULL;
822 }
823
824 self::populate(self::$country, 'CRM_Core_DAO_Country', TRUE, 'name', 'is_active', $whereClause);
825
826 // if default country is set, percolate it to the top
827 if ($config->defaultContactCountry()) {
828 $countryIsoCodes = self::countryIsoCode();
829 $defaultID = array_search($config->defaultContactCountry(), $countryIsoCodes);
830 if ($defaultID !== FALSE) {
831 $default[$defaultID] = CRM_Utils_Array::value($defaultID, self::$country);
832 self::$country = $default + self::$country;
833 }
834 }
835
836 // localise the country names if in an non-en_US locale
837 global $tsLocale;
838 if ($tsLocale != '' and $tsLocale != 'en_US') {
839 $i18n = CRM_Core_I18n::singleton();
840 $i18n->localizeArray(self::$country, array(
353ffa53
TO
841 'context' => 'country',
842 ));
6a488035
TO
843 self::$country = CRM_Utils_Array::asort(self::$country);
844 }
845 }
846 if ($id) {
847 if (array_key_exists($id, self::$country)) {
848 return self::$country[$id];
849 }
850 else {
7cdc9e9f 851 return CRM_Core_DAO::$_nullObject;
6a488035
TO
852 }
853 }
854 return self::$country;
855 }
856
857 /**
858 * Get all the country ISO Code abbreviations from the database.
859 *
860 * The static array countryIsoCode is returned, and if it's
861 * called the first time, the <b>Country DAO</b> is used
862 * to get all the countries' ISO codes.
863 *
864 * Note: any database errors will be trapped by the DAO.
865 *
6a488035 866 *
fd31fa4c 867 * @param bool $id
6a488035 868 *
a6c01b45
CW
869 * @return array
870 * array reference of all country ISO codes.
6a488035
TO
871 */
872 public static function &countryIsoCode($id = FALSE) {
873 if (!self::$countryIsoCode) {
874 self::populate(self::$countryIsoCode, 'CRM_Core_DAO_Country', TRUE, 'iso_code');
875 }
876 if ($id) {
877 if (array_key_exists($id, self::$countryIsoCode)) {
878 return self::$countryIsoCode[$id];
879 }
880 else {
7cdc9e9f 881 return CRM_Core_DAO::$_nullObject;
6a488035
TO
882 }
883 }
884 return self::$countryIsoCode;
885 }
886
6a488035 887 /**
c490a46a 888 * @deprecated Please use the buildOptions() method in the appropriate BAO object.
29494eef 889 *
6a488035
TO
890 * Get all groups from database
891 *
892 * The static array group is returned, and if it's
893 * called the first time, the <b>Group DAO</b> is used
894 * to get all the groups.
895 *
896 * Note: any database errors will be trapped by the DAO.
897 *
6a0b768e
TO
898 * @param string $groupType
899 * Type of group(Access/Mailing).
900 * @param bool $excludeHidden
901 * Exclude hidden groups.
6a488035 902 *
6a488035 903 *
a6c01b45
CW
904 * @return array
905 * array reference of all groups.
6a488035 906 */
addbec40 907 public static function allGroup($groupType = NULL, $excludeHidden = TRUE) {
6a488035
TO
908 $condition = CRM_Contact_BAO_Group::groupTypeCondition($groupType, $excludeHidden);
909
910 if (!self::$group) {
911 self::$group = array();
912 }
913
addbec40 914 $groupKey = ($groupType ? $groupType : 'null') . !empty($excludeHidden);
6a488035
TO
915
916 if (!isset(self::$group[$groupKey])) {
917 self::$group[$groupKey] = NULL;
918 self::populate(self::$group[$groupKey], 'CRM_Contact_DAO_Group', FALSE, 'title', 'is_active', $condition);
919 }
920 return self::$group[$groupKey];
921 }
922
923 /**
924 * Create or get groups iterator (iterates over nested groups in a
925 * logical fashion)
926 *
927 * The GroupNesting instance is returned; it's created if this is being
928 * called for the first time
929 *
930 *
6a488035 931 *
dd244018 932 * @param bool $styledLabels
6a488035 933 *
72b3a70c 934 * @return CRM_Contact_BAO_GroupNesting
6a488035
TO
935 */
936 public static function &groupIterator($styledLabels = FALSE) {
937 if (!self::$groupIterator) {
d424ffde
CW
938 // When used as an object, GroupNesting implements Iterator
939 // and iterates nested groups in a logical manner for us
6a488035
TO
940 self::$groupIterator = new CRM_Contact_BAO_GroupNesting($styledLabels);
941 }
942 return self::$groupIterator;
943 }
944
945 /**
d09edf64 946 * Get all permissioned groups from database.
6a488035
TO
947 *
948 * The static array group is returned, and if it's
949 * called the first time, the <b>Group DAO</b> is used
950 * to get all the groups.
951 *
952 * Note: any database errors will be trapped by the DAO.
953 *
6a0b768e
TO
954 * @param string $groupType
955 * Type of group(Access/Mailing).
956 * @param bool $excludeHidden
957 * Exclude hidden groups.
dd244018 958 *
6a488035 959 *
a6c01b45
CW
960 * @return array
961 * array reference of all groups.
6a488035
TO
962 */
963 public static function group($groupType = NULL, $excludeHidden = TRUE) {
964 return CRM_Core_Permission::group($groupType, $excludeHidden);
965 }
966
24431f7b 967 /**
d09edf64 968 * Fetch groups in a nested format suitable for use in select form element.
24431f7b
CW
969 * @param bool $checkPermissions
970 * @param string|null $groupType
971 * @param bool $excludeHidden
972 * @return array
973 */
974 public static function nestedGroup($checkPermissions = TRUE, $groupType = NULL, $excludeHidden = TRUE) {
975 $groups = $checkPermissions ? self::group($groupType, $excludeHidden) : self::allGroup($groupType, $excludeHidden);
976 return CRM_Contact_BAO_Group::getGroupsHierarchy($groups, NULL, '&nbsp;&nbsp;', TRUE);
977 }
978
6a488035 979 /**
d09edf64 980 * Get all permissioned groups from database.
6a488035
TO
981 *
982 * The static array group is returned, and if it's
983 * called the first time, the <b>Group DAO</b> is used
984 * to get all the groups.
985 *
986 * Note: any database errors will be trapped by the DAO.
987 *
6a488035 988 *
dd244018
EM
989 * @param bool $onlyPublic
990 * @param null $groupType
991 * @param bool $excludeHidden
6a488035 992 *
a6c01b45
CW
993 * @return array
994 * array reference of all groups.
6a488035
TO
995 */
996 public static function &staticGroup($onlyPublic = FALSE, $groupType = NULL, $excludeHidden = TRUE) {
997 if (!self::$staticGroup) {
998 $condition = 'saved_search_id = 0 OR saved_search_id IS NULL';
999 if ($onlyPublic) {
1000 $condition .= " AND visibility != 'User and User Admin Only'";
1001 }
1002
1003 if ($groupType) {
1004 $condition .= ' AND ' . CRM_Contact_BAO_Group::groupTypeCondition($groupType);
1005 }
1006
1007 if ($excludeHidden) {
1008 $condition .= ' AND is_hidden != 1 ';
1009 }
1010
1011 self::populate(self::$staticGroup, 'CRM_Contact_DAO_Group', FALSE, 'title', 'is_active', $condition, 'title');
1012 }
1013
1014 return self::$staticGroup;
1015 }
1016
6a488035
TO
1017 /**
1018 * Get all Relationship Types from database.
1019 *
1020 * The static array group is returned, and if it's
1021 * called the first time, the <b>RelationshipType DAO</b> is used
1022 * to get all the relationship types.
1023 *
1024 * Note: any database errors will be trapped by the DAO.
1025 *
6a0b768e
TO
1026 * @param string $valueColumnName
1027 * Db column name/label.
1028 * @param bool $reset
1029 * Reset relationship types if true.
fa8e67b8
TO
1030 * @param bool|NULL $isActive
1031 * Filter by is_active. NULL to disable.
6a488035 1032 *
a6c01b45
CW
1033 * @return array
1034 * array reference of all relationship types.
6a488035 1035 */
fa8e67b8
TO
1036 public static function &relationshipType($valueColumnName = 'label', $reset = FALSE, $isActive = 1) {
1037 $cacheKey = $valueColumnName . '::' . $isActive;
1038 if (!CRM_Utils_Array::value($cacheKey, self::$relationshipType) || $reset) {
1039 self::$relationshipType[$cacheKey] = array();
6a488035
TO
1040
1041 //now we have name/label columns CRM-3336
1042 $column_a_b = "{$valueColumnName}_a_b";
1043 $column_b_a = "{$valueColumnName}_b_a";
1044
1045 $relationshipTypeDAO = new CRM_Contact_DAO_RelationshipType();
1046 $relationshipTypeDAO->selectAdd();
1047 $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
1048 if ($isActive !== NULL) {
1049 $relationshipTypeDAO->is_active = $isActive;
1050 }
6a488035
TO
1051 $relationshipTypeDAO->find();
1052 while ($relationshipTypeDAO->fetch()) {
1053
fa8e67b8 1054 self::$relationshipType[$cacheKey][$relationshipTypeDAO->id] = array(
05802b8e 1055 'id' => $relationshipTypeDAO->id,
6a488035
TO
1056 $column_a_b => $relationshipTypeDAO->$column_a_b,
1057 $column_b_a => $relationshipTypeDAO->$column_b_a,
1058 'contact_type_a' => "$relationshipTypeDAO->contact_type_a",
1059 'contact_type_b' => "$relationshipTypeDAO->contact_type_b",
1060 'contact_sub_type_a' => "$relationshipTypeDAO->contact_sub_type_a",
1061 'contact_sub_type_b' => "$relationshipTypeDAO->contact_sub_type_b",
1062 );
1063 }
1064 }
1065
fa8e67b8 1066 return self::$relationshipType[$cacheKey];
6a488035
TO
1067 }
1068
6a488035 1069 /**
100fef9d 1070 * Get all the ISO 4217 currency codes
6a488035
TO
1071 *
1072 * so far, we use this for validation only, so there's no point of putting this into the database
1073 *
6a488035 1074 *
a6c01b45
CW
1075 * @return array
1076 * array reference of all currency codes
6a488035
TO
1077 */
1078 public static function &currencyCode() {
1079 if (!self::$currencyCode) {
1080 self::$currencyCode = array(
1081 'AFN',
1082 'ALL',
1083 'DZD',
1084 'USD',
1085 'EUR',
1086 'AOA',
1087 'XCD',
1088 'XCD',
1089 'ARS',
1090 'AMD',
1091 'AWG',
1092 'AUD',
1093 'EUR',
1094 'AZM',
1095 'BSD',
1096 'BHD',
1097 'BDT',
1098 'BBD',
1099 'BYR',
1100 'EUR',
1101 'BZD',
1102 'XOF',
1103 'BMD',
1104 'INR',
1105 'BTN',
1106 'BOB',
1107 'BOV',
1108 'BAM',
1109 'BWP',
1110 'NOK',
1111 'BRL',
1112 'USD',
1113 'BND',
1114 'BGN',
1115 'XOF',
1116 'BIF',
1117 'KHR',
1118 'XAF',
1119 'CAD',
1120 'CVE',
1121 'KYD',
1122 'XAF',
1123 'XAF',
1124 'CLP',
1125 'CLF',
1126 'CNY',
1127 'AUD',
1128 'AUD',
1129 'COP',
1130 'COU',
1131 'KMF',
1132 'XAF',
1133 'CDF',
1134 'NZD',
1135 'CRC',
1136 'XOF',
1137 'HRK',
1138 'CUP',
1139 'CYP',
1140 'CZK',
1141 'DKK',
1142 'DJF',
1143 'XCD',
1144 'DOP',
1145 'USD',
1146 'EGP',
1147 'SVC',
1148 'USD',
1149 'XAF',
1150 'ERN',
1151 'EEK',
1152 'ETB',
1153 'FKP',
1154 'DKK',
1155 'FJD',
1156 'EUR',
1157 'EUR',
1158 'EUR',
1159 'XPF',
1160 'EUR',
1161 'XAF',
1162 'GMD',
1163 'GEL',
1164 'EUR',
1165 'GHC',
1166 'GIP',
1167 'EUR',
1168 'DKK',
1169 'XCD',
1170 'EUR',
1171 'USD',
1172 'GTQ',
1173 'GNF',
1174 'GWP',
1175 'XOF',
1176 'GYD',
1177 'HTG',
1178 'USD',
1179 'AUD',
1180 'EUR',
1181 'HNL',
1182 'HKD',
1183 'HUF',
1184 'ISK',
1185 'INR',
1186 'IDR',
1187 'XDR',
1188 'IRR',
1189 'IQD',
1190 'EUR',
1191 'ILS',
1192 'EUR',
1193 'JMD',
1194 'JPY',
1195 'JOD',
1196 'KZT',
1197 'KES',
1198 'AUD',
1199 'KPW',
1200 'KRW',
1201 'KWD',
1202 'KGS',
1203 'LAK',
1204 'LVL',
1205 'LBP',
1206 'ZAR',
1207 'LSL',
1208 'LRD',
1209 'LYD',
1210 'CHF',
1211 'LTL',
1212 'EUR',
1213 'MOP',
1214 'MKD',
1215 'MGA',
1216 'MWK',
1217 'MYR',
1218 'MVR',
1219 'XOF',
1220 'MTL',
1221 'USD',
1222 'EUR',
1223 'MRO',
1224 'MUR',
1225 'EUR',
1226 'MXN',
1227 'MXV',
1228 'USD',
1229 'MDL',
1230 'EUR',
1231 'MNT',
1232 'XCD',
1233 'MAD',
1234 'MZM',
1235 'MMK',
1236 'ZAR',
1237 'NAD',
1238 'AUD',
1239 'NPR',
1240 'EUR',
1241 'ANG',
1242 'XPF',
1243 'NZD',
1244 'NIO',
1245 'XOF',
1246 'NGN',
1247 'NZD',
1248 'AUD',
1249 'USD',
1250 'NOK',
1251 'OMR',
1252 'PKR',
1253 'USD',
1254 'PAB',
1255 'USD',
1256 'PGK',
1257 'PYG',
1258 'PEN',
1259 'PHP',
1260 'NZD',
1261 'PLN',
1262 'EUR',
1263 'USD',
1264 'QAR',
1265 'EUR',
1266 'ROL',
1267 'RON',
1268 'RUB',
1269 'RWF',
1270 'SHP',
1271 'XCD',
1272 'XCD',
1273 'EUR',
1274 'XCD',
1275 'WST',
1276 'EUR',
1277 'STD',
1278 'SAR',
1279 'XOF',
1280 'CSD',
1281 'EUR',
1282 'SCR',
1283 'SLL',
1284 'SGD',
1285 'SKK',
1286 'SIT',
1287 'SBD',
1288 'SOS',
1289 'ZAR',
1290 'EUR',
1291 'LKR',
1292 'SDD',
1293 'SRD',
1294 'NOK',
1295 'SZL',
1296 'SEK',
1297 'CHF',
1298 'CHW',
1299 'CHE',
1300 'SYP',
1301 'TWD',
1302 'TJS',
1303 'TZS',
1304 'THB',
1305 'USD',
1306 'XOF',
1307 'NZD',
1308 'TOP',
1309 'TTD',
1310 'TND',
1311 'TRY',
1312 'TRL',
1313 'TMM',
1314 'USD',
1315 'AUD',
1316 'UGX',
1317 'UAH',
1318 'AED',
1319 'GBP',
1320 'USD',
1321 'USS',
1322 'USN',
1323 'USD',
1324 'UYU',
1325 'UZS',
1326 'VUV',
1327 'VEB',
1328 'VND',
1329 'USD',
1330 'USD',
1331 'XPF',
1332 'MAD',
1333 'YER',
1334 'ZMK',
1335 'ZWD',
1336 'XAU',
1337 'XBA',
1338 'XBB',
1339 'XBC',
1340 'XBD',
1341 'XPD',
1342 'XPT',
1343 'XAG',
1344 'XFU',
1345 'XFO',
1346 'XTS',
1347 'XXX',
1348 );
1349 }
1350 return self::$currencyCode;
1351 }
1352
1353 /**
1354 * Get all the County from database.
1355 *
1356 * The static array county is returned, and if it's
1357 * called the first time, the <b>County DAO</b> is used
1358 * to get all the Counties.
1359 *
1360 * Note: any database errors will be trapped by the DAO.
1361 *
6a488035 1362 *
6a0b768e 1363 * @param bool|int $id - Optional id to return
6a488035 1364 *
a6c01b45
CW
1365 * @return array
1366 * array reference of all Counties
6a488035
TO
1367 */
1368 public static function &county($id = FALSE) {
1369 if (!self::$county) {
1370
1371 $config = CRM_Core_Config::singleton();
1372 // order by id so users who populate civicrm_county can have more control over sort by the order they load the counties
1373 self::populate(self::$county, 'CRM_Core_DAO_County', TRUE, 'name', NULL, NULL, 'id');
1374 }
1375 if ($id) {
1376 if (array_key_exists($id, self::$county)) {
1377 return self::$county[$id];
1378 }
1379 else {
7cdc9e9f 1380 return CRM_Core_DAO::$_nullObject;
6a488035
TO
1381 }
1382 }
1383 return self::$county;
1384 }
1385
6a488035 1386 /**
c490a46a 1387 * @deprecated Please use the buildOptions() method in the appropriate BAO object.
6a488035
TO
1388 * Get all active payment processors
1389 *
1390 * The static array paymentProcessor is returned
1391 *
6a488035 1392 *
6a0b768e
TO
1393 * @param bool $all
1394 * Get payment processors - default is to get only active ones.
1395 * @param bool $test
1396 * Get test payment processors.
6a488035 1397 *
77b97be7 1398 * @param null $additionalCond
6a488035 1399 *
a6c01b45
CW
1400 * @return array
1401 * array of all payment processors
6a488035 1402 */
d6944518 1403 public static function paymentProcessor($all = FALSE, $test = FALSE, $additionalCond = NULL) {
6a488035
TO
1404 $condition = "is_test = ";
1405 $condition .= ($test) ? '1' : '0';
1406
1407 if ($additionalCond) {
1408 $condition .= " AND ( $additionalCond ) ";
1409 }
1410
b44e3f84 1411 // CRM-7178. Make sure we only include payment processors valid in this
6a488035
TO
1412 // domain
1413 $condition .= " AND domain_id = " . CRM_Core_Config::domainID();
1414
1415 $cacheKey = $condition . '_' . (int) $all;
1416 if (!isset(self::$paymentProcessor[$cacheKey])) {
1417 self::populate(self::$paymentProcessor[$cacheKey], 'CRM_Financial_DAO_PaymentProcessor', $all, 'name', 'is_active', $condition, 'is_default desc, name');
1418 }
1419
1420 return self::$paymentProcessor[$cacheKey];
1421 }
1422
1423 /**
c490a46a 1424 * @deprecated Please use the buildOptions() method in the appropriate BAO object.
6a488035
TO
1425 *
1426 * The static array paymentProcessorType is returned
1427 *
6a488035 1428 *
6a0b768e
TO
1429 * @param bool $all
1430 * Get payment processors - default is to get only active ones.
6a488035 1431 *
100fef9d 1432 * @param int $id
77b97be7 1433 * @param string $return
6a488035 1434 *
a6c01b45
CW
1435 * @return array
1436 * array of all payment processor types
6a488035
TO
1437 */
1438 public static function &paymentProcessorType($all = FALSE, $id = NULL, $return = 'title') {
86bfa4f6 1439 $cacheKey = $id . '_' . $return;
6a488035
TO
1440 if (empty(self::$paymentProcessorType[$cacheKey])) {
1441 self::populate(self::$paymentProcessorType[$cacheKey], 'CRM_Financial_DAO_PaymentProcessorType', $all, $return, 'is_active', NULL, "is_default, $return", 'id');
1442 }
1443 if ($id && CRM_Utils_Array::value($id, self::$paymentProcessorType[$cacheKey])) {
1444 return self::$paymentProcessorType[$cacheKey][$id];
1445 }
1446 return self::$paymentProcessorType[$cacheKey];
1447 }
1448
1449 /**
d09edf64 1450 * Get all the World Regions from Database.
6a488035 1451 *
6a488035 1452 *
77b97be7
EM
1453 * @param bool $id
1454 *
a6c01b45
CW
1455 * @return array
1456 * array reference of all World Regions
6a488035
TO
1457 */
1458 public static function &worldRegion($id = FALSE) {
1459 if (!self::$worldRegions) {
1460 self::populate(self::$worldRegions, 'CRM_Core_DAO_Worldregion', TRUE, 'name', NULL, NULL, 'id');
1461 }
1462
1463 if ($id) {
1464 if (array_key_exists($id, self::$worldRegions)) {
1465 return self::$worldRegions[$id];
1466 }
1467 else {
7cdc9e9f 1468 return CRM_Core_DAO::$_nullObject;
6a488035
TO
1469 }
1470 }
1471
1472 return self::$worldRegions;
1473 }
1474
6a488035 1475 /**
c490a46a 1476 * @deprecated Please use the buildOptions() method in the appropriate BAO object.
29494eef 1477 *
6a488035
TO
1478 * Get all Activity Statuses.
1479 *
1480 * The static array activityStatus is returned
1481 *
6a488035 1482 *
77b97be7
EM
1483 * @param string $column
1484 *
a6c01b45
CW
1485 * @return array
1486 * array reference of all activity statuses
6a488035
TO
1487 */
1488 public static function &activityStatus($column = 'label') {
1489 if (NULL === self::$activityStatus) {
1490 self::$activityStatus = array();
1491 }
1492 if (!array_key_exists($column, self::$activityStatus)) {
1493 self::$activityStatus[$column] = array();
1494
1495 self::$activityStatus[$column] = CRM_Core_OptionGroup::values('activity_status', FALSE, FALSE, FALSE, NULL, $column);
1496 }
1497
1498 return self::$activityStatus[$column];
1499 }
1500
6a488035 1501 /**
c490a46a 1502 * @deprecated Please use the buildOptions() method in the appropriate BAO object.
a19392e7 1503 *
6a488035
TO
1504 * Get all Visibility levels.
1505 *
1506 * The static array visibility is returned
1507 *
6a488035 1508 *
77b97be7 1509 * @param string $column
6a488035 1510 *
a6c01b45
CW
1511 * @return array
1512 * array reference of all Visibility levels.
6a488035
TO
1513 */
1514 public static function &visibility($column = 'label') {
1515 if (!isset(self::$visibility)) {
2aa397bc 1516 self::$visibility = array();
6a488035
TO
1517 }
1518
1519 if (!isset(self::$visibility[$column])) {
1520 self::$visibility[$column] = CRM_Core_OptionGroup::values('visibility', FALSE, FALSE, FALSE, NULL, $column);
2aa397bc 1521 }
6a488035
TO
1522
1523 return self::$visibility[$column];
1524 }
1525
a0ee3941 1526 /**
100fef9d 1527 * @param int $countryID
a0ee3941
EM
1528 * @param string $field
1529 *
1530 * @return array
1531 */
6a488035
TO
1532 public static function &stateProvinceForCountry($countryID, $field = 'name') {
1533 static $_cache = NULL;
1534
1535 $cacheKey = "{$countryID}_{$field}";
1536 if (!$_cache) {
1537 $_cache = array();
1538 }
1539
1540 if (!empty($_cache[$cacheKey])) {
1541 return $_cache[$cacheKey];
1542 }
1543
1544 $query = "
1545SELECT civicrm_state_province.{$field} name, civicrm_state_province.id id
1546 FROM civicrm_state_province
1547WHERE country_id = %1
1548ORDER BY name";
1549 $params = array(
1550 1 => array(
1551 $countryID,
1552 'Integer',
1553 ),
1554 );
1555
1556 $dao = CRM_Core_DAO::executeQuery($query, $params);
1557
1558 $result = array();
1559 while ($dao->fetch()) {
1560 $result[$dao->id] = $dao->name;
1561 }
1562
1563 // localise the stateProvince names if in an non-en_US locale
1564 $config = CRM_Core_Config::singleton();
1565 global $tsLocale;
1566 if ($tsLocale != '' and $tsLocale != 'en_US') {
1567 $i18n = CRM_Core_I18n::singleton();
1568 $i18n->localizeArray($result, array(
1569 'context' => 'province',
1570 ));
1571 $result = CRM_Utils_Array::asort($result);
1572 }
1573
1574 $_cache[$cacheKey] = $result;
1575
1576 CRM_Utils_Hook::buildStateProvinceForCountry($countryID, $result);
1577
1578 return $result;
1579 }
1580
a0ee3941 1581 /**
100fef9d 1582 * @param int $stateID
a0ee3941
EM
1583 *
1584 * @return array
1585 */
6a488035
TO
1586 public static function &countyForState($stateID) {
1587 if (is_array($stateID)) {
1588 $states = implode(", ", $stateID);
1589 $query = "
1590 SELECT civicrm_county.name name, civicrm_county.id id, civicrm_state_province.abbreviation abbreviation
1591 FROM civicrm_county
1592 LEFT JOIN civicrm_state_province ON civicrm_county.state_province_id = civicrm_state_province.id
1593 WHERE civicrm_county.state_province_id in ( $states )
1594 ORDER BY civicrm_state_province.abbreviation, civicrm_county.name";
1595
1596 $dao = CRM_Core_DAO::executeQuery($query);
1597
1598 $result = array();
1599 while ($dao->fetch()) {
1600 $result[$dao->id] = $dao->abbreviation . ': ' . $dao->name;
1601 }
1602 }
1603 else {
1604
1605 static $_cache = NULL;
1606
1607 $cacheKey = "{$stateID}_name";
1608 if (!$_cache) {
1609 $_cache = array();
1610 }
1611
1612 if (!empty($_cache[$cacheKey])) {
1613 return $_cache[$cacheKey];
1614 }
1615
1616 $query = "
1617 SELECT civicrm_county.name name, civicrm_county.id id
1618 FROM civicrm_county
1619 WHERE state_province_id = %1
1620 ORDER BY name";
1621 $params = array(
1622 1 => array(
1623 $stateID,
1624 'Integer',
1625 ),
1626 );
1627
1628 $dao = CRM_Core_DAO::executeQuery($query, $params);
1629
1630 $result = array();
1631 while ($dao->fetch()) {
1632 $result[$dao->id] = $dao->name;
1633 }
1634 }
1635
1636 return $result;
1637 }
1638
b05e28de
DL
1639 /**
1640 * Given a state ID return the country ID, this allows
1641 * us to populate forms and values for downstream code
1642 *
5a4f6742 1643 * @param int $stateID
b05e28de 1644 *
a6c01b45
CW
1645 * @return int
1646 * the country id that the state belongs to
b05e28de 1647 */
00be9182 1648 public static function countryIDForStateID($stateID) {
b05e28de 1649 if (empty($stateID)) {
7cdc9e9f 1650 return CRM_Core_DAO::$_nullObject;
b05e28de
DL
1651 }
1652
1653 $query = "
1654SELECT country_id
1655FROM civicrm_state_province
1656WHERE id = %1
1657";
1658 $params = array(1 => array($stateID, 'Integer'));
1659
1660 return CRM_Core_DAO::singleValueQuery($query, $params);
1661 }
1662
6a488035
TO
1663 /**
1664 * Get all types of Greetings.
1665 *
1666 * The static array of greeting is returned
1667 *
6a488035 1668 *
6a0b768e
TO
1669 * @param $filter
1670 * Get All Email Greetings - default is to get only active ones.
6a488035 1671 *
77b97be7 1672 * @param string $columnName
6a488035 1673 *
a6c01b45
CW
1674 * @return array
1675 * array reference of all greetings.
6a488035
TO
1676 */
1677 public static function greeting($filter, $columnName = 'label') {
1678 $index = $filter['greeting_type'] . '_' . $columnName;
1679
1680 // also add contactType to the array
1681 $contactType = CRM_Utils_Array::value('contact_type', $filter);
1682 if ($contactType) {
1683 $index .= '_' . $contactType;
1684 }
1685
1686 if (NULL === self::$greeting) {
1687 self::$greeting = array();
1688 }
1689
1690 if (!CRM_Utils_Array::value($index, self::$greeting)) {
1691 $filterCondition = NULL;
1692 if ($contactType) {
1693 $filterVal = 'v.filter =';
1694 switch ($contactType) {
1695 case 'Individual':
1696 $filterVal .= "1";
1697 break;
1698
1699 case 'Household':
1700 $filterVal .= "2";
1701 break;
1702
1703 case 'Organization':
1704 $filterVal .= "3";
1705 break;
1706 }
1707 $filterCondition .= "AND (v.filter = 0 OR {$filterVal}) ";
1708 }
1709
1710 self::$greeting[$index] = CRM_Core_OptionGroup::values($filter['greeting_type'], NULL, NULL, NULL, $filterCondition, $columnName);
1711 }
1712
1713 return self::$greeting[$index];
1714 }
1715
1716 /**
d09edf64 1717 * Construct array of default greeting values for contact type.
6a488035 1718 *
6a488035 1719 *
a6c01b45
CW
1720 * @return array
1721 * array reference of default greetings.
6a488035
TO
1722 */
1723 public static function &greetingDefaults() {
1724 if (!self::$greetingDefaults) {
1725 $defaultGreetings = array();
353ffa53
TO
1726 $contactTypes = self::get('CRM_Contact_DAO_Contact', 'contact_type', array(
1727 'keyColumn' => 'id',
8d7a9d07 1728 'labelColumn' => 'name',
353ffa53 1729 ));
6a488035 1730
091fe2a8 1731 foreach ($contactTypes as $filter => $contactType) {
6a488035
TO
1732 $filterCondition = " AND (v.filter = 0 OR v.filter = $filter) AND v.is_default = 1 ";
1733
1734 foreach (CRM_Contact_BAO_Contact::$_greetingTypes as $greeting) {
1735 $tokenVal = CRM_Core_OptionGroup::values($greeting, NULL, NULL, NULL, $filterCondition, 'label');
1736 $defaultGreetings[$contactType][$greeting] = $tokenVal;
1737 }
1738 }
1739
1740 self::$greetingDefaults = $defaultGreetings;
1741 }
1742
1743 return self::$greetingDefaults;
1744 }
1745
6a488035 1746 /**
d09edf64 1747 * Get all extensions.
6a488035
TO
1748 *
1749 * The static array extensions
1750 *
1751 * FIXME: This is called by civix but not by any core code. We
1752 * should provide an API call which civix can use instead.
1753 *
6a488035 1754 *
a6c01b45
CW
1755 * @return array
1756 * array($fullyQualifiedName => $label) list of extensions
6a488035
TO
1757 */
1758 public static function &getExtensions() {
1759 if (!self::$extensions) {
1760 self::$extensions = array();
1761 $sql = '
1762 SELECT full_name, label
1763 FROM civicrm_extension
1764 WHERE is_active = 1
1765 ';
1766 $dao = CRM_Core_DAO::executeQuery($sql);
1767 while ($dao->fetch()) {
1768 self::$extensions[$dao->full_name] = $dao->label;
1769 }
1770 }
1771
1772 return self::$extensions;
1773 }
1774
f743a6eb 1775 /**
d09edf64 1776 * Get all options values.
f743a6eb
CW
1777 *
1778 * The static array option values is returned
1779 *
f743a6eb 1780 *
6a0b768e
TO
1781 * @param bool $optionGroupName
1782 * Get All Option Group values- default is to get only active ones.
f743a6eb 1783 *
100fef9d 1784 * @param int $id
77b97be7 1785 * @param null $condition
f743a6eb 1786 *
a6c01b45
CW
1787 * @return array
1788 * array reference of all Option Group Name
f743a6eb 1789 */
2aa397bc 1790 public static function accountOptionValues($optionGroupName, $id = NULL, $condition = NULL) {
f743a6eb
CW
1791 $cacheKey = $optionGroupName . '_' . $condition;
1792 if (empty(self::$accountOptionValues[$cacheKey])) {
2aa397bc 1793 self::$accountOptionValues[$cacheKey] = CRM_Core_OptionGroup::values($optionGroupName, FALSE, FALSE, FALSE, $condition);
f743a6eb
CW
1794 }
1795 if ($id) {
1796 return CRM_Utils_Array::value($id, self::$accountOptionValues[$cacheKey]);
1797 }
1798
1799 return self::$accountOptionValues[$cacheKey];
1800 }
1801
6a488035
TO
1802 /**
1803 * Fetch the list of active extensions of type 'module'
1804 *
5a4f6742
CW
1805 * @param bool $fresh
1806 * Whether to forcibly reload extensions list from canonical store.
6a488035 1807 *
a6c01b45
CW
1808 * @return array
1809 * array(array('prefix' => $, 'file' => $))
6a488035
TO
1810 */
1811 public static function getModuleExtensions($fresh = FALSE) {
1812 return CRM_Extension_System::singleton()->getMapper()->getActiveModuleFiles($fresh);
1813 }
dc428161 1814
1815
1816 /**
d09edf64 1817 * Get all tax rates.
dc428161 1818 *
1819 * The static array tax rates is returned
1820 *
a6c01b45
CW
1821 * @return array
1822 * array list of tax rates with the financial type
dc428161 1823 */
1824 public static function getTaxRates() {
27864d8a 1825 if (!isset(Civi::$statics[__CLASS__]['taxRates'])) {
1826 Civi::$statics[__CLASS__]['taxRates'] = array();
dc428161 1827 $sql = "
1828 SELECT fa.tax_rate, efa.entity_id
1829 FROM civicrm_entity_financial_account efa
1830 INNER JOIN civicrm_financial_account fa ON fa.id = efa.financial_account_id
1831 INNER JOIN civicrm_option_value cov ON cov.value = efa.account_relationship
1832 INNER JOIN civicrm_option_group cog ON cog.id = cov.option_group_id
1833 WHERE efa.entity_table = 'civicrm_financial_type'
1834 AND cov.name = 'Sales Tax Account is'
1835 AND cog.name = 'account_relationship'
1836 AND fa.is_active = 1";
1837 $dao = CRM_Core_DAO::executeQuery($sql);
1838 while ($dao->fetch()) {
27864d8a 1839 Civi::$statics[__CLASS__]['taxRates'][$dao->entity_id] = $dao->tax_rate;
dc428161 1840 }
1841 }
1842
27864d8a 1843 return Civi::$statics[__CLASS__]['taxRates'];
dc428161 1844 }
96025800 1845
6a488035 1846}