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