CRM_Core_BAO_Preferences - Remove unused file/class/functions
[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 $config = CRM_Core_Config::singleton();
711 if ($limit) {
712 $countryIsoCodes = self::countryIsoCode();
713 $limitCodes = $config->provinceLimit();
714 $limitIds = array();
715 foreach ($limitCodes as $code) {
716 $limitIds = array_merge($limitIds, array_keys($countryIsoCodes, $code));
717 }
718 if (!empty($limitIds)) {
719 $whereClause = 'country_id IN (' . implode(', ', $limitIds) . ')';
720 }
721 else {
722 $whereClause = FALSE;
723 }
724 }
725 self::populate(self::$stateProvince, 'CRM_Core_DAO_StateProvince', TRUE, 'name', 'is_active', $whereClause);
726
727 // localise the province names if in an non-en_US locale
728 global $tsLocale;
729 if ($tsLocale != '' and $tsLocale != 'en_US') {
730 $i18n = CRM_Core_I18n::singleton();
731 $i18n->localizeArray(self::$stateProvince, array(
732 'context' => 'province',
733 ));
734 self::$stateProvince = CRM_Utils_Array::asort(self::$stateProvince);
735 }
736 }
737 if ($id) {
738 if (array_key_exists($id, self::$stateProvince)) {
739 return self::$stateProvince[$id];
740 }
741 else {
742 $result = NULL;
743 return $result;
744 }
745 }
746 return self::$stateProvince;
747 }
748
749 /**
750 * Get all the State/Province abbreviations from the database.
751 *
752 * Same as above, except gets the abbreviations instead of the names.
753 *
754 *
755 * @param bool|int $id - Optional id to return
756 *
757 * @param bool $limit
758 *
759 * @return array
760 * array reference of all State/Province abbreviations.
761 */
762 public static function stateProvinceAbbreviation($id = FALSE, $limit = TRUE) {
763 if ($id > 1) {
764 $query = "
765 SELECT abbreviation
766 FROM civicrm_state_province
767 WHERE id = %1";
768 $params = array(
769 1 => array(
770 $id,
771 'Integer',
772 ),
773 );
774 return CRM_Core_DAO::singleValueQuery($query, $params);
775 }
776
777 if (!self::$stateProvinceAbbreviation || !$id) {
778
779 $whereClause = FALSE;
780
781 if ($limit) {
782 $config = CRM_Core_Config::singleton();
783 $countryIsoCodes = self::countryIsoCode();
784 $limitCodes = $config->provinceLimit();
785 $limitIds = array();
786 foreach ($limitCodes as $code) {
787 $tmpArray = array_keys($countryIsoCodes, $code);
788
789 if (!empty($tmpArray)) {
790 $limitIds[] = array_shift($tmpArray);
791 }
792 }
793 if (!empty($limitIds)) {
794 $whereClause = 'country_id IN (' . implode(', ', $limitIds) . ')';
795 }
796 }
797 self::populate(self::$stateProvinceAbbreviation, 'CRM_Core_DAO_StateProvince', TRUE, 'abbreviation', 'is_active', $whereClause);
798 }
799
800 if ($id) {
801 if (array_key_exists($id, self::$stateProvinceAbbreviation)) {
802 return self::$stateProvinceAbbreviation[$id];
803 }
804 else {
805 $result = NULL;
806 return $result;
807 }
808 }
809 return self::$stateProvinceAbbreviation;
810 }
811
812 /**
813 * Get all the countries from database.
814 *
815 * The static array country is returned, and if it's
816 * called the first time, the <b>Country DAO</b> is used
817 * to get all the countries.
818 *
819 * Note: any database errors will be trapped by the DAO.
820 *
821 *
822 * @param bool|int $id - Optional id to return
823 *
824 * @param bool $applyLimit
825 *
826 * @return array
827 * array reference of all countries.
828 */
829 public static function country($id = FALSE, $applyLimit = TRUE) {
830 if (($id && !CRM_Utils_Array::value($id, self::$country)) || !self::$country || !$id) {
831
832 $config = CRM_Core_Config::singleton();
833 $limitCodes = array();
834
835 if ($applyLimit) {
836 // limit the country list to the countries specified in CIVICRM_COUNTRY_LIMIT
837 // (ensuring it's a subset of the legal values)
838 // K/P: We need to fix this, i dont think it works with new setting files
839 $limitCodes = $config->countryLimit();
840 if (!is_array($limitCodes)) {
841 $limitCodes = array(
842 $config->countryLimit => 1,
843 );
844 }
845
846 $limitCodes = array_intersect(self::countryIsoCode(), $limitCodes);
847 }
848
849 if (count($limitCodes)) {
850 $whereClause = "iso_code IN ('" . implode("', '", $limitCodes) . "')";
851 }
852 else {
853 $whereClause = NULL;
854 }
855
856 self::populate(self::$country, 'CRM_Core_DAO_Country', TRUE, 'name', 'is_active', $whereClause);
857
858 // if default country is set, percolate it to the top
859 if ($config->defaultContactCountry()) {
860 $countryIsoCodes = self::countryIsoCode();
861 $defaultID = array_search($config->defaultContactCountry(), $countryIsoCodes);
862 if ($defaultID !== FALSE) {
863 $default[$defaultID] = CRM_Utils_Array::value($defaultID, self::$country);
864 self::$country = $default + self::$country;
865 }
866 }
867
868 // localise the country names if in an non-en_US locale
869 global $tsLocale;
870 if ($tsLocale != '' and $tsLocale != 'en_US') {
871 $i18n = CRM_Core_I18n::singleton();
872 $i18n->localizeArray(self::$country, array(
873 'context' => 'country',
874 ));
875 self::$country = CRM_Utils_Array::asort(self::$country);
876 }
877 }
878 if ($id) {
879 if (array_key_exists($id, self::$country)) {
880 return self::$country[$id];
881 }
882 else {
883 return CRM_Core_DAO::$_nullObject;
884 }
885 }
886 return self::$country;
887 }
888
889 /**
890 * Get all the country ISO Code abbreviations from the database.
891 *
892 * The static array countryIsoCode is returned, and if it's
893 * called the first time, the <b>Country DAO</b> is used
894 * to get all the countries' ISO codes.
895 *
896 * Note: any database errors will be trapped by the DAO.
897 *
898 *
899 * @param bool $id
900 *
901 * @return array
902 * array reference of all country ISO codes.
903 */
904 public static function &countryIsoCode($id = FALSE) {
905 if (!self::$countryIsoCode) {
906 self::populate(self::$countryIsoCode, 'CRM_Core_DAO_Country', TRUE, 'iso_code');
907 }
908 if ($id) {
909 if (array_key_exists($id, self::$countryIsoCode)) {
910 return self::$countryIsoCode[$id];
911 }
912 else {
913 return CRM_Core_DAO::$_nullObject;
914 }
915 }
916 return self::$countryIsoCode;
917 }
918
919 /**
920 * @deprecated Please use the buildOptions() method in the appropriate BAO object.
921 *
922 * Get all groups from database
923 *
924 * The static array group is returned, and if it's
925 * called the first time, the <b>Group DAO</b> is used
926 * to get all the groups.
927 *
928 * Note: any database errors will be trapped by the DAO.
929 *
930 * @param string $groupType
931 * Type of group(Access/Mailing).
932 * @param bool $excludeHidden
933 * Exclude hidden groups.
934 *
935 *
936 * @return array
937 * array reference of all groups.
938 */
939 public static function &allGroup($groupType = NULL, $excludeHidden = TRUE) {
940 $condition = CRM_Contact_BAO_Group::groupTypeCondition($groupType, $excludeHidden);
941
942 if (!self::$group) {
943 self::$group = array();
944 }
945
946 $groupKey = $groupType ? $groupType : 'null';
947
948 if (!isset(self::$group[$groupKey])) {
949 self::$group[$groupKey] = NULL;
950 self::populate(self::$group[$groupKey], 'CRM_Contact_DAO_Group', FALSE, 'title', 'is_active', $condition);
951 }
952 return self::$group[$groupKey];
953 }
954
955 /**
956 * Create or get groups iterator (iterates over nested groups in a
957 * logical fashion)
958 *
959 * The GroupNesting instance is returned; it's created if this is being
960 * called for the first time
961 *
962 *
963 *
964 * @param bool $styledLabels
965 *
966 * @return CRM_Contact_BAO_GroupNesting
967 */
968 public static function &groupIterator($styledLabels = FALSE) {
969 if (!self::$groupIterator) {
970 // When used as an object, GroupNesting implements Iterator
971 // and iterates nested groups in a logical manner for us
972 self::$groupIterator = new CRM_Contact_BAO_GroupNesting($styledLabels);
973 }
974 return self::$groupIterator;
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 * @param string $groupType
987 * Type of group(Access/Mailing).
988 * @param bool $excludeHidden
989 * Exclude hidden groups.
990 *
991 *
992 * @return array
993 * array reference of all groups.
994 */
995 public static function group($groupType = NULL, $excludeHidden = TRUE) {
996 return CRM_Core_Permission::group($groupType, $excludeHidden);
997 }
998
999 /**
1000 * Fetch groups in a nested format suitable for use in select form element.
1001 * @param bool $checkPermissions
1002 * @param string|null $groupType
1003 * @param bool $excludeHidden
1004 * @return array
1005 */
1006 public static function nestedGroup($checkPermissions = TRUE, $groupType = NULL, $excludeHidden = TRUE) {
1007 $groups = $checkPermissions ? self::group($groupType, $excludeHidden) : self::allGroup($groupType, $excludeHidden);
1008 return CRM_Contact_BAO_Group::getGroupsHierarchy($groups, NULL, '&nbsp;&nbsp;', TRUE);
1009 }
1010
1011 /**
1012 * Get all permissioned groups from database.
1013 *
1014 * The static array group is returned, and if it's
1015 * called the first time, the <b>Group DAO</b> is used
1016 * to get all the groups.
1017 *
1018 * Note: any database errors will be trapped by the DAO.
1019 *
1020 *
1021 * @param bool $onlyPublic
1022 * @param null $groupType
1023 * @param bool $excludeHidden
1024 *
1025 * @return array
1026 * array reference of all groups.
1027 */
1028 public static function &staticGroup($onlyPublic = FALSE, $groupType = NULL, $excludeHidden = TRUE) {
1029 if (!self::$staticGroup) {
1030 $condition = 'saved_search_id = 0 OR saved_search_id IS NULL';
1031 if ($onlyPublic) {
1032 $condition .= " AND visibility != 'User and User Admin Only'";
1033 }
1034
1035 if ($groupType) {
1036 $condition .= ' AND ' . CRM_Contact_BAO_Group::groupTypeCondition($groupType);
1037 }
1038
1039 if ($excludeHidden) {
1040 $condition .= ' AND is_hidden != 1 ';
1041 }
1042
1043 self::populate(self::$staticGroup, 'CRM_Contact_DAO_Group', FALSE, 'title', 'is_active', $condition, 'title');
1044 }
1045
1046 return self::$staticGroup;
1047 }
1048
1049 /**
1050 * Get all Relationship Types from database.
1051 *
1052 * The static array group is returned, and if it's
1053 * called the first time, the <b>RelationshipType DAO</b> is used
1054 * to get all the relationship types.
1055 *
1056 * Note: any database errors will be trapped by the DAO.
1057 *
1058 * @param string $valueColumnName
1059 * Db column name/label.
1060 * @param bool $reset
1061 * Reset relationship types if true.
1062 *
1063 *
1064 * @return array
1065 * array reference of all relationship types.
1066 */
1067 public static function &relationshipType($valueColumnName = 'label', $reset = FALSE) {
1068 if (!CRM_Utils_Array::value($valueColumnName, self::$relationshipType) || $reset) {
1069 self::$relationshipType[$valueColumnName] = array();
1070
1071 //now we have name/label columns CRM-3336
1072 $column_a_b = "{$valueColumnName}_a_b";
1073 $column_b_a = "{$valueColumnName}_b_a";
1074
1075 $relationshipTypeDAO = new CRM_Contact_DAO_RelationshipType();
1076 $relationshipTypeDAO->selectAdd();
1077 $relationshipTypeDAO->selectAdd("id, {$column_a_b}, {$column_b_a}, contact_type_a, contact_type_b, contact_sub_type_a, contact_sub_type_b");
1078 $relationshipTypeDAO->is_active = 1;
1079 $relationshipTypeDAO->find();
1080 while ($relationshipTypeDAO->fetch()) {
1081
1082 self::$relationshipType[$valueColumnName][$relationshipTypeDAO->id] = array(
1083 'id' => $relationshipTypeDAO->id,
1084 $column_a_b => $relationshipTypeDAO->$column_a_b,
1085 $column_b_a => $relationshipTypeDAO->$column_b_a,
1086 'contact_type_a' => "$relationshipTypeDAO->contact_type_a",
1087 'contact_type_b' => "$relationshipTypeDAO->contact_type_b",
1088 'contact_sub_type_a' => "$relationshipTypeDAO->contact_sub_type_a",
1089 'contact_sub_type_b' => "$relationshipTypeDAO->contact_sub_type_b",
1090 );
1091 }
1092 }
1093
1094 return self::$relationshipType[$valueColumnName];
1095 }
1096
1097 /**
1098 * Get all the ISO 4217 currency codes
1099 *
1100 * so far, we use this for validation only, so there's no point of putting this into the database
1101 *
1102 *
1103 * @return array
1104 * array reference of all currency codes
1105 */
1106 public static function &currencyCode() {
1107 if (!self::$currencyCode) {
1108 self::$currencyCode = array(
1109 'AFN',
1110 'ALL',
1111 'DZD',
1112 'USD',
1113 'EUR',
1114 'AOA',
1115 'XCD',
1116 'XCD',
1117 'ARS',
1118 'AMD',
1119 'AWG',
1120 'AUD',
1121 'EUR',
1122 'AZM',
1123 'BSD',
1124 'BHD',
1125 'BDT',
1126 'BBD',
1127 'BYR',
1128 'EUR',
1129 'BZD',
1130 'XOF',
1131 'BMD',
1132 'INR',
1133 'BTN',
1134 'BOB',
1135 'BOV',
1136 'BAM',
1137 'BWP',
1138 'NOK',
1139 'BRL',
1140 'USD',
1141 'BND',
1142 'BGN',
1143 'XOF',
1144 'BIF',
1145 'KHR',
1146 'XAF',
1147 'CAD',
1148 'CVE',
1149 'KYD',
1150 'XAF',
1151 'XAF',
1152 'CLP',
1153 'CLF',
1154 'CNY',
1155 'AUD',
1156 'AUD',
1157 'COP',
1158 'COU',
1159 'KMF',
1160 'XAF',
1161 'CDF',
1162 'NZD',
1163 'CRC',
1164 'XOF',
1165 'HRK',
1166 'CUP',
1167 'CYP',
1168 'CZK',
1169 'DKK',
1170 'DJF',
1171 'XCD',
1172 'DOP',
1173 'USD',
1174 'EGP',
1175 'SVC',
1176 'USD',
1177 'XAF',
1178 'ERN',
1179 'EEK',
1180 'ETB',
1181 'FKP',
1182 'DKK',
1183 'FJD',
1184 'EUR',
1185 'EUR',
1186 'EUR',
1187 'XPF',
1188 'EUR',
1189 'XAF',
1190 'GMD',
1191 'GEL',
1192 'EUR',
1193 'GHC',
1194 'GIP',
1195 'EUR',
1196 'DKK',
1197 'XCD',
1198 'EUR',
1199 'USD',
1200 'GTQ',
1201 'GNF',
1202 'GWP',
1203 'XOF',
1204 'GYD',
1205 'HTG',
1206 'USD',
1207 'AUD',
1208 'EUR',
1209 'HNL',
1210 'HKD',
1211 'HUF',
1212 'ISK',
1213 'INR',
1214 'IDR',
1215 'XDR',
1216 'IRR',
1217 'IQD',
1218 'EUR',
1219 'ILS',
1220 'EUR',
1221 'JMD',
1222 'JPY',
1223 'JOD',
1224 'KZT',
1225 'KES',
1226 'AUD',
1227 'KPW',
1228 'KRW',
1229 'KWD',
1230 'KGS',
1231 'LAK',
1232 'LVL',
1233 'LBP',
1234 'ZAR',
1235 'LSL',
1236 'LRD',
1237 'LYD',
1238 'CHF',
1239 'LTL',
1240 'EUR',
1241 'MOP',
1242 'MKD',
1243 'MGA',
1244 'MWK',
1245 'MYR',
1246 'MVR',
1247 'XOF',
1248 'MTL',
1249 'USD',
1250 'EUR',
1251 'MRO',
1252 'MUR',
1253 'EUR',
1254 'MXN',
1255 'MXV',
1256 'USD',
1257 'MDL',
1258 'EUR',
1259 'MNT',
1260 'XCD',
1261 'MAD',
1262 'MZM',
1263 'MMK',
1264 'ZAR',
1265 'NAD',
1266 'AUD',
1267 'NPR',
1268 'EUR',
1269 'ANG',
1270 'XPF',
1271 'NZD',
1272 'NIO',
1273 'XOF',
1274 'NGN',
1275 'NZD',
1276 'AUD',
1277 'USD',
1278 'NOK',
1279 'OMR',
1280 'PKR',
1281 'USD',
1282 'PAB',
1283 'USD',
1284 'PGK',
1285 'PYG',
1286 'PEN',
1287 'PHP',
1288 'NZD',
1289 'PLN',
1290 'EUR',
1291 'USD',
1292 'QAR',
1293 'EUR',
1294 'ROL',
1295 'RON',
1296 'RUB',
1297 'RWF',
1298 'SHP',
1299 'XCD',
1300 'XCD',
1301 'EUR',
1302 'XCD',
1303 'WST',
1304 'EUR',
1305 'STD',
1306 'SAR',
1307 'XOF',
1308 'CSD',
1309 'EUR',
1310 'SCR',
1311 'SLL',
1312 'SGD',
1313 'SKK',
1314 'SIT',
1315 'SBD',
1316 'SOS',
1317 'ZAR',
1318 'EUR',
1319 'LKR',
1320 'SDD',
1321 'SRD',
1322 'NOK',
1323 'SZL',
1324 'SEK',
1325 'CHF',
1326 'CHW',
1327 'CHE',
1328 'SYP',
1329 'TWD',
1330 'TJS',
1331 'TZS',
1332 'THB',
1333 'USD',
1334 'XOF',
1335 'NZD',
1336 'TOP',
1337 'TTD',
1338 'TND',
1339 'TRY',
1340 'TRL',
1341 'TMM',
1342 'USD',
1343 'AUD',
1344 'UGX',
1345 'UAH',
1346 'AED',
1347 'GBP',
1348 'USD',
1349 'USS',
1350 'USN',
1351 'USD',
1352 'UYU',
1353 'UZS',
1354 'VUV',
1355 'VEB',
1356 'VND',
1357 'USD',
1358 'USD',
1359 'XPF',
1360 'MAD',
1361 'YER',
1362 'ZMK',
1363 'ZWD',
1364 'XAU',
1365 'XBA',
1366 'XBB',
1367 'XBC',
1368 'XBD',
1369 'XPD',
1370 'XPT',
1371 'XAG',
1372 'XFU',
1373 'XFO',
1374 'XTS',
1375 'XXX',
1376 );
1377 }
1378 return self::$currencyCode;
1379 }
1380
1381 /**
1382 * Get all the County from database.
1383 *
1384 * The static array county is returned, and if it's
1385 * called the first time, the <b>County DAO</b> is used
1386 * to get all the Counties.
1387 *
1388 * Note: any database errors will be trapped by the DAO.
1389 *
1390 *
1391 * @param bool|int $id - Optional id to return
1392 *
1393 * @return array
1394 * array reference of all Counties
1395 */
1396 public static function &county($id = FALSE) {
1397 if (!self::$county) {
1398
1399 $config = CRM_Core_Config::singleton();
1400 // order by id so users who populate civicrm_county can have more control over sort by the order they load the counties
1401 self::populate(self::$county, 'CRM_Core_DAO_County', TRUE, 'name', NULL, NULL, 'id');
1402 }
1403 if ($id) {
1404 if (array_key_exists($id, self::$county)) {
1405 return self::$county[$id];
1406 }
1407 else {
1408 return CRM_Core_DAO::$_nullObject;
1409 }
1410 }
1411 return self::$county;
1412 }
1413
1414 /**
1415 * @deprecated Please use the buildOptions() method in the appropriate BAO object.
1416 * Get all active payment processors
1417 *
1418 * The static array paymentProcessor is returned
1419 *
1420 *
1421 * @param bool $all
1422 * Get payment processors - default is to get only active ones.
1423 * @param bool $test
1424 * Get test payment processors.
1425 *
1426 * @param null $additionalCond
1427 *
1428 * @return array
1429 * array of all payment processors
1430 */
1431 public static function paymentProcessor($all = FALSE, $test = FALSE, $additionalCond = NULL) {
1432 $condition = "is_test = ";
1433 $condition .= ($test) ? '1' : '0';
1434
1435 if ($additionalCond) {
1436 $condition .= " AND ( $additionalCond ) ";
1437 }
1438
1439 // CRM-7178. Make sure we only include payment processors valid in this
1440 // domain
1441 $condition .= " AND domain_id = " . CRM_Core_Config::domainID();
1442
1443 $cacheKey = $condition . '_' . (int) $all;
1444 if (!isset(self::$paymentProcessor[$cacheKey])) {
1445 self::populate(self::$paymentProcessor[$cacheKey], 'CRM_Financial_DAO_PaymentProcessor', $all, 'name', 'is_active', $condition, 'is_default desc, name');
1446 }
1447
1448 return self::$paymentProcessor[$cacheKey];
1449 }
1450
1451 /**
1452 * @deprecated Please use the buildOptions() method in the appropriate BAO object.
1453 *
1454 * The static array paymentProcessorType is returned
1455 *
1456 *
1457 * @param bool $all
1458 * Get payment processors - default is to get only active ones.
1459 *
1460 * @param int $id
1461 * @param string $return
1462 *
1463 * @return array
1464 * array of all payment processor types
1465 */
1466 public static function &paymentProcessorType($all = FALSE, $id = NULL, $return = 'title') {
1467 $cacheKey = $id . '_' . $return;
1468 if (empty(self::$paymentProcessorType[$cacheKey])) {
1469 self::populate(self::$paymentProcessorType[$cacheKey], 'CRM_Financial_DAO_PaymentProcessorType', $all, $return, 'is_active', NULL, "is_default, $return", 'id');
1470 }
1471 if ($id && CRM_Utils_Array::value($id, self::$paymentProcessorType[$cacheKey])) {
1472 return self::$paymentProcessorType[$cacheKey][$id];
1473 }
1474 return self::$paymentProcessorType[$cacheKey];
1475 }
1476
1477 /**
1478 * Get all the World Regions from Database.
1479 *
1480 *
1481 * @param bool $id
1482 *
1483 * @return array
1484 * array reference of all World Regions
1485 */
1486 public static function &worldRegion($id = FALSE) {
1487 if (!self::$worldRegions) {
1488 self::populate(self::$worldRegions, 'CRM_Core_DAO_Worldregion', TRUE, 'name', NULL, NULL, 'id');
1489 }
1490
1491 if ($id) {
1492 if (array_key_exists($id, self::$worldRegions)) {
1493 return self::$worldRegions[$id];
1494 }
1495 else {
1496 return CRM_Core_DAO::$_nullObject;
1497 }
1498 }
1499
1500 return self::$worldRegions;
1501 }
1502
1503 /**
1504 * @deprecated Please use the buildOptions() method in the appropriate BAO object.
1505 *
1506 * Get all Activity Statuses.
1507 *
1508 * The static array activityStatus is returned
1509 *
1510 *
1511 * @param string $column
1512 *
1513 * @return array
1514 * array reference of all activity statuses
1515 */
1516 public static function &activityStatus($column = 'label') {
1517 if (NULL === self::$activityStatus) {
1518 self::$activityStatus = array();
1519 }
1520 if (!array_key_exists($column, self::$activityStatus)) {
1521 self::$activityStatus[$column] = array();
1522
1523 self::$activityStatus[$column] = CRM_Core_OptionGroup::values('activity_status', FALSE, FALSE, FALSE, NULL, $column);
1524 }
1525
1526 return self::$activityStatus[$column];
1527 }
1528
1529 /**
1530 * @deprecated Please use the buildOptions() method in the appropriate BAO object.
1531 *
1532 * Get all Visibility levels.
1533 *
1534 * The static array visibility is returned
1535 *
1536 *
1537 * @param string $column
1538 *
1539 * @return array
1540 * array reference of all Visibility levels.
1541 */
1542 public static function &visibility($column = 'label') {
1543 if (!isset(self::$visibility)) {
1544 self::$visibility = array();
1545 }
1546
1547 if (!isset(self::$visibility[$column])) {
1548 self::$visibility[$column] = CRM_Core_OptionGroup::values('visibility', FALSE, FALSE, FALSE, NULL, $column);
1549 }
1550
1551 return self::$visibility[$column];
1552 }
1553
1554 /**
1555 * @param int $countryID
1556 * @param string $field
1557 *
1558 * @return array
1559 */
1560 public static function &stateProvinceForCountry($countryID, $field = 'name') {
1561 static $_cache = NULL;
1562
1563 $cacheKey = "{$countryID}_{$field}";
1564 if (!$_cache) {
1565 $_cache = array();
1566 }
1567
1568 if (!empty($_cache[$cacheKey])) {
1569 return $_cache[$cacheKey];
1570 }
1571
1572 $query = "
1573 SELECT civicrm_state_province.{$field} name, civicrm_state_province.id id
1574 FROM civicrm_state_province
1575 WHERE country_id = %1
1576 ORDER BY name";
1577 $params = array(
1578 1 => array(
1579 $countryID,
1580 'Integer',
1581 ),
1582 );
1583
1584 $dao = CRM_Core_DAO::executeQuery($query, $params);
1585
1586 $result = array();
1587 while ($dao->fetch()) {
1588 $result[$dao->id] = $dao->name;
1589 }
1590
1591 // localise the stateProvince names if in an non-en_US locale
1592 $config = CRM_Core_Config::singleton();
1593 global $tsLocale;
1594 if ($tsLocale != '' and $tsLocale != 'en_US') {
1595 $i18n = CRM_Core_I18n::singleton();
1596 $i18n->localizeArray($result, array(
1597 'context' => 'province',
1598 ));
1599 $result = CRM_Utils_Array::asort($result);
1600 }
1601
1602 $_cache[$cacheKey] = $result;
1603
1604 CRM_Utils_Hook::buildStateProvinceForCountry($countryID, $result);
1605
1606 return $result;
1607 }
1608
1609 /**
1610 * @param int $stateID
1611 *
1612 * @return array
1613 */
1614 public static function &countyForState($stateID) {
1615 if (is_array($stateID)) {
1616 $states = implode(", ", $stateID);
1617 $query = "
1618 SELECT civicrm_county.name name, civicrm_county.id id, civicrm_state_province.abbreviation abbreviation
1619 FROM civicrm_county
1620 LEFT JOIN civicrm_state_province ON civicrm_county.state_province_id = civicrm_state_province.id
1621 WHERE civicrm_county.state_province_id in ( $states )
1622 ORDER BY civicrm_state_province.abbreviation, civicrm_county.name";
1623
1624 $dao = CRM_Core_DAO::executeQuery($query);
1625
1626 $result = array();
1627 while ($dao->fetch()) {
1628 $result[$dao->id] = $dao->abbreviation . ': ' . $dao->name;
1629 }
1630 }
1631 else {
1632
1633 static $_cache = NULL;
1634
1635 $cacheKey = "{$stateID}_name";
1636 if (!$_cache) {
1637 $_cache = array();
1638 }
1639
1640 if (!empty($_cache[$cacheKey])) {
1641 return $_cache[$cacheKey];
1642 }
1643
1644 $query = "
1645 SELECT civicrm_county.name name, civicrm_county.id id
1646 FROM civicrm_county
1647 WHERE state_province_id = %1
1648 ORDER BY name";
1649 $params = array(
1650 1 => array(
1651 $stateID,
1652 'Integer',
1653 ),
1654 );
1655
1656 $dao = CRM_Core_DAO::executeQuery($query, $params);
1657
1658 $result = array();
1659 while ($dao->fetch()) {
1660 $result[$dao->id] = $dao->name;
1661 }
1662 }
1663
1664 return $result;
1665 }
1666
1667 /**
1668 * Given a state ID return the country ID, this allows
1669 * us to populate forms and values for downstream code
1670 *
1671 * @param int $stateID
1672 *
1673 * @return int
1674 * the country id that the state belongs to
1675 */
1676 public static function countryIDForStateID($stateID) {
1677 if (empty($stateID)) {
1678 return CRM_Core_DAO::$_nullObject;
1679 }
1680
1681 $query = "
1682 SELECT country_id
1683 FROM civicrm_state_province
1684 WHERE id = %1
1685 ";
1686 $params = array(1 => array($stateID, 'Integer'));
1687
1688 return CRM_Core_DAO::singleValueQuery($query, $params);
1689 }
1690
1691 /**
1692 * Get all types of Greetings.
1693 *
1694 * The static array of greeting is returned
1695 *
1696 *
1697 * @param $filter
1698 * Get All Email Greetings - default is to get only active ones.
1699 *
1700 * @param string $columnName
1701 *
1702 * @return array
1703 * array reference of all greetings.
1704 */
1705 public static function greeting($filter, $columnName = 'label') {
1706 $index = $filter['greeting_type'] . '_' . $columnName;
1707
1708 // also add contactType to the array
1709 $contactType = CRM_Utils_Array::value('contact_type', $filter);
1710 if ($contactType) {
1711 $index .= '_' . $contactType;
1712 }
1713
1714 if (NULL === self::$greeting) {
1715 self::$greeting = array();
1716 }
1717
1718 if (!CRM_Utils_Array::value($index, self::$greeting)) {
1719 $filterCondition = NULL;
1720 if ($contactType) {
1721 $filterVal = 'v.filter =';
1722 switch ($contactType) {
1723 case 'Individual':
1724 $filterVal .= "1";
1725 break;
1726
1727 case 'Household':
1728 $filterVal .= "2";
1729 break;
1730
1731 case 'Organization':
1732 $filterVal .= "3";
1733 break;
1734 }
1735 $filterCondition .= "AND (v.filter = 0 OR {$filterVal}) ";
1736 }
1737
1738 self::$greeting[$index] = CRM_Core_OptionGroup::values($filter['greeting_type'], NULL, NULL, NULL, $filterCondition, $columnName);
1739 }
1740
1741 return self::$greeting[$index];
1742 }
1743
1744 /**
1745 * Construct array of default greeting values for contact type.
1746 *
1747 *
1748 * @return array
1749 * array reference of default greetings.
1750 */
1751 public static function &greetingDefaults() {
1752 if (!self::$greetingDefaults) {
1753 $defaultGreetings = array();
1754 $contactTypes = self::get('CRM_Contact_DAO_Contact', 'contact_type', array(
1755 'keyColumn' => 'id',
1756 'labelColumn' => 'name',
1757 ));
1758
1759 foreach ($contactTypes as $filter => $contactType) {
1760 $filterCondition = " AND (v.filter = 0 OR v.filter = $filter) AND v.is_default = 1 ";
1761
1762 foreach (CRM_Contact_BAO_Contact::$_greetingTypes as $greeting) {
1763 $tokenVal = CRM_Core_OptionGroup::values($greeting, NULL, NULL, NULL, $filterCondition, 'label');
1764 $defaultGreetings[$contactType][$greeting] = $tokenVal;
1765 }
1766 }
1767
1768 self::$greetingDefaults = $defaultGreetings;
1769 }
1770
1771 return self::$greetingDefaults;
1772 }
1773
1774 /**
1775 * Get all extensions.
1776 *
1777 * The static array extensions
1778 *
1779 * FIXME: This is called by civix but not by any core code. We
1780 * should provide an API call which civix can use instead.
1781 *
1782 *
1783 * @return array
1784 * array($fullyQualifiedName => $label) list of extensions
1785 */
1786 public static function &getExtensions() {
1787 if (!self::$extensions) {
1788 self::$extensions = array();
1789 $sql = '
1790 SELECT full_name, label
1791 FROM civicrm_extension
1792 WHERE is_active = 1
1793 ';
1794 $dao = CRM_Core_DAO::executeQuery($sql);
1795 while ($dao->fetch()) {
1796 self::$extensions[$dao->full_name] = $dao->label;
1797 }
1798 }
1799
1800 return self::$extensions;
1801 }
1802
1803 /**
1804 * Get all options values.
1805 *
1806 * The static array option values is returned
1807 *
1808 *
1809 * @param bool $optionGroupName
1810 * Get All Option Group values- default is to get only active ones.
1811 *
1812 * @param int $id
1813 * @param null $condition
1814 *
1815 * @return array
1816 * array reference of all Option Group Name
1817 */
1818 public static function accountOptionValues($optionGroupName, $id = NULL, $condition = NULL) {
1819 $cacheKey = $optionGroupName . '_' . $condition;
1820 if (empty(self::$accountOptionValues[$cacheKey])) {
1821 self::$accountOptionValues[$cacheKey] = CRM_Core_OptionGroup::values($optionGroupName, FALSE, FALSE, FALSE, $condition);
1822 }
1823 if ($id) {
1824 return CRM_Utils_Array::value($id, self::$accountOptionValues[$cacheKey]);
1825 }
1826
1827 return self::$accountOptionValues[$cacheKey];
1828 }
1829
1830 /**
1831 * Fetch the list of active extensions of type 'module'
1832 *
1833 * @param bool $fresh
1834 * Whether to forcibly reload extensions list from canonical store.
1835 *
1836 * @return array
1837 * array(array('prefix' => $, 'file' => $))
1838 */
1839 public static function getModuleExtensions($fresh = FALSE) {
1840 return CRM_Extension_System::singleton()->getMapper()->getActiveModuleFiles($fresh);
1841 }
1842
1843
1844 /**
1845 * Get all tax rates.
1846 *
1847 * The static array tax rates is returned
1848 *
1849 * @return array
1850 * array list of tax rates with the financial type
1851 */
1852 public static function getTaxRates() {
1853 if (!self::$taxRates) {
1854 self::$taxRates = array();
1855 $sql = "
1856 SELECT fa.tax_rate, efa.entity_id
1857 FROM civicrm_entity_financial_account efa
1858 INNER JOIN civicrm_financial_account fa ON fa.id = efa.financial_account_id
1859 INNER JOIN civicrm_option_value cov ON cov.value = efa.account_relationship
1860 INNER JOIN civicrm_option_group cog ON cog.id = cov.option_group_id
1861 WHERE efa.entity_table = 'civicrm_financial_type'
1862 AND cov.name = 'Sales Tax Account is'
1863 AND cog.name = 'account_relationship'
1864 AND fa.is_active = 1";
1865 $dao = CRM_Core_DAO::executeQuery($sql);
1866 while ($dao->fetch()) {
1867 self::$taxRates[$dao->entity_id] = $dao->tax_rate;
1868 }
1869 }
1870
1871 return self::$taxRates;
1872 }
1873
1874 }