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