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