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