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