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