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