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