Commit | Line | Data |
---|---|---|
6a488035 TO |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
06b69b18 | 4 | | CiviCRM version 4.5 | |
6a488035 | 5 | +--------------------------------------------------------------------+ |
06b69b18 | 6 | | Copyright CiviCRM LLC (c) 2004-2014 | |
6a488035 TO |
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 | * @package CRM | |
06b69b18 | 31 | * @copyright CiviCRM LLC (c) 2004-2014 |
6a488035 TO |
32 | * $Id$ |
33 | * | |
34 | */ | |
35 | class CRM_Contact_BAO_ContactType extends CRM_Contact_DAO_ContactType { | |
36 | ||
37 | /** | |
c490a46a | 38 | * Fetch object based on array of properties |
6a488035 TO |
39 | * |
40 | * @param array $params (reference ) an assoc array of name/value pairs | |
41 | * @param array $defaults (reference ) an assoc array to hold the flattened values | |
42 | * | |
c490a46a | 43 | * @return CRM_Contact_BAO_ContactType object on success, null otherwise |
6a488035 TO |
44 | * @access public |
45 | * @static | |
46 | */ | |
47 | static function retrieve(&$params, &$defaults) { | |
48 | $contactType = new CRM_Contact_DAO_ContactType(); | |
49 | $contactType->copyValues($params); | |
50 | if ($contactType->find(TRUE)) { | |
51 | CRM_Core_DAO::storeValues($contactType, $defaults); | |
52 | return $contactType; | |
53 | } | |
54 | return NULL; | |
55 | } | |
56 | ||
86538308 EM |
57 | /** |
58 | * @param $contactType | |
59 | * | |
60 | * @return bool | |
61 | */ | |
6a488035 TO |
62 | static function isActive($contactType) { |
63 | $contact = self::contactTypeInfo(FALSE); | |
64 | $active = array_key_exists($contactType, $contact) ? TRUE : FALSE; | |
65 | return $active; | |
66 | } | |
67 | ||
68 | /** | |
c490a46a | 69 | * Retrieve basic contact type information. |
6a488035 | 70 | * |
dd244018 | 71 | * @param bool $all |
6a488035 | 72 | * |
dd244018 EM |
73 | * @return array of basic contact types information. |
74 | * @static | |
6a488035 TO |
75 | */ |
76 | static function &basicTypeInfo($all = FALSE) { | |
77 | static $_cache = NULL; | |
78 | ||
79 | if ($_cache === NULL) { | |
80 | $_cache = array(); | |
81 | } | |
82 | ||
83 | $argString = $all ? 'CRM_CT_BTI_1' : 'CRM_CT_BTI_0'; | |
84 | if (!array_key_exists($argString, $_cache)) { | |
85 | $cache = CRM_Utils_Cache::singleton(); | |
86 | $_cache[$argString] = $cache->get($argString); | |
87 | if (!$_cache[$argString]) { | |
88 | $sql = " | |
89 | SELECT * | |
90 | FROM civicrm_contact_type | |
91 | WHERE parent_id IS NULL | |
92 | "; | |
93 | if ($all === FALSE) { | |
94 | $sql .= " AND is_active = 1"; | |
95 | } | |
96 | ||
97 | $dao = CRM_Core_DAO::executeQuery($sql, | |
98 | CRM_Core_DAO::$_nullArray, | |
99 | FALSE, | |
100 | 'CRM_Contact_DAO_ContactType' | |
101 | ); | |
102 | while ($dao->fetch()) { | |
103 | $value = array(); | |
104 | CRM_Core_DAO::storeValues($dao, $value); | |
105 | $_cache[$argString][$dao->name] = $value; | |
106 | } | |
107 | ||
108 | $cache->set($argString, $_cache[$argString]); | |
109 | } | |
110 | } | |
111 | return $_cache[$argString]; | |
112 | } | |
113 | ||
114 | /** | |
c490a46a | 115 | * Retrieve all basic contact types. |
6a488035 | 116 | * |
da6b46f4 | 117 | * @param bool $all |
6a488035 | 118 | * |
da6b46f4 EM |
119 | * @return array of basic contact types |
120 | * @static | |
6a488035 TO |
121 | */ |
122 | static function basicTypes($all = FALSE) { | |
123 | return array_keys(self::basicTypeInfo($all)); | |
124 | } | |
125 | ||
86538308 EM |
126 | /** |
127 | * @param bool $all | |
128 | * @param string $key | |
129 | * | |
130 | * @return array | |
131 | */ | |
6a488035 TO |
132 | static function basicTypePairs($all = FALSE, $key = 'name') { |
133 | $subtypes = self::basicTypeInfo($all); | |
134 | ||
135 | $pairs = array(); | |
136 | foreach ($subtypes as $name => $info) { | |
137 | $index = ($key == 'name') ? $name : $info[$key]; | |
138 | $pairs[$index] = $info['label']; | |
139 | } | |
140 | return $pairs; | |
141 | } | |
142 | ||
143 | /** | |
c490a46a | 144 | * Retrieve all subtypes Information. |
6a488035 | 145 | * |
fd31fa4c EM |
146 | * @param array $contactType . |
147 | * @param bool $all | |
148 | * @param bool $ignoreCache | |
149 | * @param bool $reset | |
6a488035 | 150 | * |
fd31fa4c EM |
151 | * @return array of sub type information |
152 | * @static | |
6a488035 TO |
153 | */ |
154 | static function &subTypeInfo($contactType = NULL, $all = FALSE, $ignoreCache = FALSE, $reset = FALSE) { | |
155 | static $_cache = NULL; | |
156 | ||
157 | if ($reset === TRUE) { | |
158 | $_cache = NULL; | |
159 | } | |
160 | ||
161 | if ($_cache === NULL) { | |
162 | $_cache = array(); | |
163 | } | |
164 | if ($contactType && !is_array($contactType)) { | |
165 | $contactType = array($contactType); | |
166 | } | |
167 | ||
168 | $argString = $all ? 'CRM_CT_STI_1_' : 'CRM_CT_STI_0_'; | |
169 | if (!empty($contactType)) { | |
170 | $argString .= implode('_', $contactType); | |
171 | } | |
172 | ||
173 | if ((!array_key_exists($argString, $_cache)) || $ignoreCache) { | |
174 | $cache = CRM_Utils_Cache::singleton(); | |
175 | $_cache[$argString] = $cache->get($argString); | |
176 | if (!$_cache[$argString] || $ignoreCache) { | |
177 | $_cache[$argString] = array(); | |
178 | ||
179 | $ctWHERE = ''; | |
180 | if (!empty($contactType)) { | |
181 | $ctWHERE = " AND parent.name IN ('" . implode("','", $contactType) . "')"; | |
182 | } | |
183 | ||
184 | $sql = " | |
185 | SELECT subtype.*, parent.name as parent, parent.label as parent_label | |
186 | FROM civicrm_contact_type subtype | |
187 | INNER JOIN civicrm_contact_type parent ON subtype.parent_id = parent.id | |
188 | WHERE subtype.name IS NOT NULL AND subtype.parent_id IS NOT NULL {$ctWHERE} | |
189 | "; | |
190 | if ($all === FALSE) { | |
191 | $sql .= " AND subtype.is_active = 1 AND parent.is_active = 1 ORDER BY parent.id"; | |
192 | } | |
193 | $dao = CRM_Core_DAO::executeQuery($sql, array(), | |
194 | FALSE, 'CRM_Contact_DAO_ContactType' | |
195 | ); | |
196 | while ($dao->fetch()) { | |
197 | $value = array(); | |
198 | CRM_Core_DAO::storeValues($dao, $value); | |
199 | $value['parent'] = $dao->parent; | |
200 | $value['parent_label'] = $dao->parent_label; | |
201 | $_cache[$argString][$dao->name] = $value; | |
202 | } | |
203 | ||
204 | $cache->set($argString, $_cache[$argString]); | |
205 | } | |
206 | } | |
207 | return $_cache[$argString]; | |
208 | } | |
209 | ||
210 | /** | |
211 | * | |
c490a46a | 212 | * retrieve all subtypes |
6a488035 | 213 | * |
f4aaa82a EM |
214 | * @param array $contactType . |
215 | * @param bool $all | |
216 | * @param string $columnName | |
217 | * @param bool $ignoreCache | |
6a488035 | 218 | * |
f4aaa82a EM |
219 | * @return array of all subtypes OR list of subtypes associated to |
220 | *a given basic contact type | |
221 | * @static | |
6a488035 TO |
222 | */ |
223 | static function subTypes($contactType = NULL, $all = FALSE, $columnName = 'name', $ignoreCache = FALSE) { | |
224 | if ($columnName == 'name') { | |
225 | return array_keys(self::subTypeInfo($contactType, $all, $ignoreCache)); | |
226 | } | |
227 | else { | |
228 | return array_values(self::subTypePairs($contactType, FALSE, NULL, $ignoreCache)); | |
229 | } | |
230 | } | |
231 | ||
232 | /** | |
233 | * | |
c490a46a | 234 | * retrieve subtype pairs with name as 'subtype-name' and 'label' as value |
6a488035 | 235 | * |
f4aaa82a EM |
236 | * @param array $contactType . |
237 | * @param bool $all | |
238 | * @param string $labelPrefix | |
239 | * @param bool $ignoreCache | |
6a488035 | 240 | * |
f4aaa82a EM |
241 | * @return list of subtypes with name as 'subtype-name' and 'label' as value |
242 | * @static | |
6a488035 TO |
243 | */ |
244 | static function subTypePairs($contactType = NULL, $all = FALSE, $labelPrefix = '- ', $ignoreCache = FALSE) { | |
245 | $subtypes = self::subTypeInfo($contactType, $all, $ignoreCache); | |
246 | ||
247 | $pairs = array(); | |
248 | foreach ($subtypes as $name => $info) { | |
249 | $pairs[$name] = $labelPrefix . $info['label']; | |
250 | } | |
251 | return $pairs; | |
252 | } | |
253 | ||
254 | /** | |
255 | * | |
c490a46a | 256 | * retrieve list of all types i.e basic + subtypes. |
6a488035 | 257 | * |
f4aaa82a | 258 | * @param bool $all |
6a488035 | 259 | * |
f4aaa82a EM |
260 | * @return array of basic types + all subtypes. |
261 | * @static | |
6a488035 TO |
262 | */ |
263 | static function contactTypes($all = FALSE) { | |
264 | return array_keys(self::contactTypeInfo($all)); | |
265 | } | |
266 | ||
267 | /** | |
268 | * | |
c490a46a | 269 | * retrieve info array about all types i.e basic + subtypes. |
6a488035 | 270 | * |
f4aaa82a EM |
271 | * @param bool $all |
272 | * @param bool $reset | |
6a488035 | 273 | * |
f4aaa82a EM |
274 | * @return array of basic types + all subtypes. |
275 | * @static | |
6a488035 TO |
276 | */ |
277 | static function contactTypeInfo($all = FALSE, $reset = FALSE) { | |
278 | static $_cache = NULL; | |
279 | ||
280 | if ($reset === TRUE) { | |
281 | $_cache = NULL; | |
282 | } | |
283 | ||
284 | if ($_cache === NULL) { | |
285 | $_cache = array(); | |
286 | } | |
287 | ||
288 | $argString = $all ? 'CRM_CT_CTI_1' : 'CRM_CT_CTI_0'; | |
289 | if (!array_key_exists($argString, $_cache)) { | |
290 | $cache = CRM_Utils_Cache::singleton(); | |
291 | $_cache[$argString] = $cache->get($argString); | |
292 | if (!$_cache[$argString]) { | |
293 | $_cache[$argString] = array(); | |
294 | ||
295 | $sql = " | |
296 | SELECT type.*, parent.name as parent, parent.label as parent_label | |
297 | FROM civicrm_contact_type type | |
298 | LEFT JOIN civicrm_contact_type parent ON type.parent_id = parent.id | |
299 | WHERE type.name IS NOT NULL | |
300 | "; | |
301 | if ($all === FALSE) { | |
302 | $sql .= " AND type.is_active = 1"; | |
303 | } | |
304 | ||
305 | $dao = CRM_Core_DAO::executeQuery($sql, | |
306 | CRM_Core_DAO::$_nullArray, | |
307 | FALSE, | |
308 | 'CRM_Contact_DAO_ContactType' | |
309 | ); | |
310 | while ($dao->fetch()) { | |
311 | $value = array(); | |
312 | CRM_Core_DAO::storeValues($dao, $value); | |
313 | if (array_key_exists('parent_id', $value)) { | |
314 | $value['parent'] = $dao->parent; | |
315 | $value['parent_label'] = $dao->parent_label; | |
316 | } | |
317 | $_cache[$argString][$dao->name] = $value; | |
318 | } | |
319 | ||
320 | $cache->set($argString, $_cache[$argString]); | |
321 | } | |
322 | } | |
323 | ||
324 | return $_cache[$argString]; | |
325 | } | |
326 | ||
327 | /** | |
c490a46a | 328 | * Retrieve basic type pairs with name as 'built-in name' and 'label' as value |
6a488035 | 329 | * |
f4aaa82a EM |
330 | * @param bool $all |
331 | * @param null $typeName | |
332 | * @param null $delimiter | |
6a488035 | 333 | * |
c490a46a | 334 | * @return array of basictypes with name as 'built-in name' and 'label' as value |
f4aaa82a | 335 | * @static |
6a488035 TO |
336 | */ |
337 | static function contactTypePairs($all = FALSE, $typeName = NULL, $delimiter = NULL) { | |
338 | $types = self::contactTypeInfo($all); | |
339 | ||
340 | if ($typeName && !is_array($typeName)) { | |
341 | $typeName = explode(CRM_Core_DAO::VALUE_SEPARATOR, trim($typeName, CRM_Core_DAO::VALUE_SEPARATOR)); | |
342 | } | |
343 | ||
344 | $pairs = array(); | |
345 | if ($typeName) { | |
346 | foreach ($typeName as $type) { | |
347 | if (array_key_exists($type, $types)) { | |
348 | $pairs[$type] = $types[$type]['label']; | |
349 | } | |
350 | } | |
351 | } | |
352 | else { | |
353 | foreach ($types as $name => $info) { | |
354 | $pairs[$name] = $info['label']; | |
355 | } | |
356 | } | |
357 | ||
358 | return !$delimiter ? $pairs : implode($delimiter, $pairs); | |
359 | } | |
360 | ||
b500fbea EM |
361 | /** |
362 | * Get a list of elements for select box | |
363 | * Note that this used to default to using the hex(01) character - which results in an invalid character being used in form fields | |
364 | * which was not handled well be anything that loaded & resaved the html (outside core) | |
365 | * The use of this separator is now explicit in the calling functions as a step towards it's removal | |
366 | * | |
367 | * @param bool $all | |
368 | * @param bool $isSeparator | |
369 | * @param string $separator | |
370 | * | |
371 | * @return mixed | |
372 | */ | |
373 | static function getSelectElements($all = FALSE, | |
374 | $isSeparator = TRUE, | |
375 | $separator = '__' | |
6a488035 TO |
376 | ) { |
377 | static $_cache = NULL; | |
378 | ||
379 | if ($_cache === NULL) { | |
380 | $_cache = array(); | |
381 | } | |
382 | ||
383 | $argString = $all ? 'CRM_CT_GSE_1' : 'CRM_CT_GSE_0'; | |
b500fbea | 384 | $argString .= $isSeparator ? '_1' : '_0'; |
6a488035 TO |
385 | if (!array_key_exists($argString, $_cache)) { |
386 | $cache = CRM_Utils_Cache::singleton(); | |
387 | $_cache[$argString] = $cache->get($argString); | |
388 | ||
389 | if (!$_cache[$argString]) { | |
390 | $_cache[$argString] = array(); | |
391 | ||
392 | $sql = " | |
393 | SELECT c.name as child_name , c.label as child_label , c.id as child_id, | |
394 | p.name as parent_name, p.label as parent_label, p.id as parent_id | |
395 | FROM civicrm_contact_type c | |
396 | LEFT JOIN civicrm_contact_type p ON ( c.parent_id = p.id ) | |
397 | WHERE ( c.name IS NOT NULL ) | |
398 | "; | |
399 | ||
400 | if ($all === FALSE) { | |
401 | $sql .= " | |
402 | AND c.is_active = 1 | |
403 | AND ( p.is_active = 1 OR p.id IS NULL ) | |
404 | "; | |
405 | } | |
406 | $sql .= " ORDER BY c.id"; | |
407 | ||
408 | $values = array(); | |
409 | $dao = CRM_Core_DAO::executeQuery($sql); | |
410 | while ($dao->fetch()) { | |
411 | if (!empty($dao->parent_id)) { | |
b500fbea | 412 | $key = $isSeparator ? $dao->parent_name . $separator . $dao->child_name : $dao->child_name; |
6a488035 TO |
413 | $label = "- {$dao->child_label}"; |
414 | $pName = $dao->parent_name; | |
415 | } | |
416 | else { | |
417 | $key = $dao->child_name; | |
418 | $label = $dao->child_label; | |
419 | $pName = $dao->child_name; | |
420 | } | |
421 | ||
422 | if (!isset($values[$pName])) { | |
423 | $values[$pName] = array(); | |
424 | } | |
425 | $values[$pName][] = array('key' => $key, 'label' => $label); | |
426 | } | |
427 | ||
428 | $selectElements = array(); | |
429 | foreach ($values as $pName => $elements) { | |
430 | foreach ($elements as $element) { | |
431 | $selectElements[$element['key']] = $element['label']; | |
432 | } | |
433 | } | |
434 | $_cache[$argString] = $selectElements; | |
435 | ||
436 | $cache->set($argString, $_cache[$argString]); | |
437 | } | |
438 | } | |
439 | return $_cache[$argString]; | |
440 | } | |
441 | ||
442 | /** | |
100fef9d | 443 | * Check if a given type is a subtype |
6a488035 | 444 | * |
f4aaa82a EM |
445 | * @param string $subType contact subType. |
446 | * @param bool $ignoreCache | |
6a488035 | 447 | * |
f4aaa82a EM |
448 | * @return boolean true if subType, false otherwise. |
449 | * @static | |
6a488035 TO |
450 | */ |
451 | static function isaSubType($subType, $ignoreCache = FALSE) { | |
452 | return in_array($subType, self::subTypes(NULL, TRUE, 'name', $ignoreCache)); | |
453 | } | |
454 | ||
455 | /** | |
100fef9d | 456 | * Retrieve the basic contact type associated with given subType. |
6a488035 TO |
457 | * |
458 | *@param array/string $subType contact subType. | |
459 | *@return array/string of basicTypes. | |
460 | *@static | |
461 | * | |
462 | */ | |
463 | static function getBasicType($subType) { | |
464 | static $_cache = NULL; | |
465 | if ($_cache === NULL) { | |
466 | $_cache = array(); | |
467 | } | |
468 | ||
469 | $isArray = TRUE; | |
470 | if ($subType && !is_array($subType)) { | |
471 | $subType = array($subType); | |
472 | $isArray = FALSE; | |
473 | } | |
474 | $argString = implode('_', $subType); | |
475 | ||
476 | if (!array_key_exists($argString, $_cache)) { | |
477 | $_cache[$argString] = array(); | |
478 | ||
479 | $sql = " | |
480 | SELECT subtype.name as contact_subtype, type.name as contact_type | |
481 | FROM civicrm_contact_type subtype | |
482 | INNER JOIN civicrm_contact_type type ON ( subtype.parent_id = type.id ) | |
483 | WHERE subtype.name IN ('" . implode("','", $subType) . "' )"; | |
484 | $dao = CRM_Core_DAO::executeQuery($sql); | |
485 | while ($dao->fetch()) { | |
486 | if (!$isArray) { | |
487 | $_cache[$argString] = $dao->contact_type; | |
488 | break; | |
489 | } | |
490 | $_cache[$argString][$dao->contact_subtype] = $dao->contact_type; | |
491 | } | |
492 | } | |
493 | return $_cache[$argString]; | |
494 | } | |
495 | ||
496 | /** | |
c490a46a | 497 | * Suppress all subtypes present in given array. |
6a488035 | 498 | * |
c490a46a | 499 | * @param array $subTypes contact subTypes |
f4aaa82a | 500 | * @param bool $ignoreCache |
6a488035 | 501 | * |
c490a46a | 502 | * @return array of suppressed subTypes. |
f4aaa82a | 503 | * @static |
6a488035 TO |
504 | */ |
505 | static function suppressSubTypes(&$subTypes, $ignoreCache = FALSE) { | |
506 | $subTypes = array_diff($subTypes, self::subTypes(NULL, TRUE, 'name', $ignoreCache)); | |
507 | return $subTypes; | |
508 | } | |
509 | ||
510 | /** | |
100fef9d | 511 | * Verify if a given subtype is associated with a given basic contact type. |
6a488035 | 512 | * |
f4aaa82a EM |
513 | * @param string $subType contact subType |
514 | * @param string $contactType contact Type | |
515 | * @param bool $ignoreCache | |
516 | * @param string $columnName | |
6a488035 | 517 | * |
f4aaa82a EM |
518 | * @return boolean true if contact extends, false otherwise. |
519 | * @static | |
6a488035 TO |
520 | */ |
521 | static function isExtendsContactType($subType, $contactType, $ignoreCache = FALSE, $columnName = 'name') { | |
522 | if (!is_array($subType)) { | |
523 | $subType = explode(CRM_Core_DAO::VALUE_SEPARATOR, trim($subType, CRM_Core_DAO::VALUE_SEPARATOR)); | |
524 | } | |
525 | $subtypeList = self::subTypes($contactType, TRUE, $columnName, $ignoreCache); | |
526 | $intersection = array_intersect($subType, $subtypeList); | |
527 | return $subType == $intersection; | |
528 | } | |
529 | ||
530 | /** | |
100fef9d | 531 | * Create shortcuts menu for contactTypes |
6a488035 | 532 | * |
c490a46a CW |
533 | * @return array of contactTypes |
534 | * @static | |
6a488035 TO |
535 | */ |
536 | static function getCreateNewList() { | |
537 | $shortCuts = array(); | |
b500fbea EM |
538 | //@todo FIXME - using the CRM_Core_DAO::VALUE_SEPARATOR creates invalid html - if you can find the form |
539 | // this is loaded onto then replace with something like '__' & test | |
540 | $separator = CRM_Core_DAO::VALUE_SEPARATOR; | |
541 | $contactTypes = self::getSelectElements(FALSE, TRUE, $separator); | |
6a488035 TO |
542 | foreach ($contactTypes as $key => $value) { |
543 | if ($key) { | |
544 | $typeValue = explode(CRM_Core_DAO::VALUE_SEPARATOR, $key); | |
7926b999 | 545 | $cType = CRM_Utils_Array::value('0', $typeValue); |
546 | $typeUrl = 'ct=' . $cType; | |
6a488035 TO |
547 | if ($csType = CRM_Utils_Array::value('1', $typeValue)) { |
548 | $typeUrl .= "&cst=$csType"; | |
549 | } | |
7926b999 | 550 | $shortCut = array( |
6a488035 TO |
551 | 'path' => 'civicrm/contact/add', |
552 | 'query' => "$typeUrl&reset=1", | |
553 | 'ref' => "new-$value", | |
554 | 'title' => $value, | |
555 | ); | |
7926b999 | 556 | if ($csType = CRM_Utils_Array::value('1', $typeValue)) { |
557 | $shortCuts[$cType]['shortCuts'][] = $shortCut; | |
558 | } | |
559 | else { | |
560 | $shortCuts[$cType] = $shortCut; | |
561 | } | |
6a488035 TO |
562 | } |
563 | } | |
564 | return $shortCuts; | |
565 | } | |
566 | ||
567 | /** | |
100fef9d | 568 | * Delete Contact SubTypes |
6a488035 | 569 | * |
f4aaa82a | 570 | * @param int $contactTypeId ID of the Contact Subtype to be deleted. |
6a488035 | 571 | * |
f4aaa82a | 572 | * @return bool |
6a488035 TO |
573 | * @access public |
574 | * @static | |
575 | */ | |
576 | static function del($contactTypeId) { | |
577 | ||
578 | if (!$contactTypeId) { | |
579 | return FALSE; | |
580 | } | |
581 | ||
582 | $params = array('id' => $contactTypeId); | |
583 | self::retrieve($params, $typeInfo); | |
584 | $name = $typeInfo['name']; | |
585 | // check if any custom group | |
586 | $custom = new CRM_Core_DAO_CustomGroup(); | |
587 | $custom->whereAdd("extends_entity_column_value LIKE '%" . | |
588 | CRM_Core_DAO::VALUE_SEPARATOR . | |
589 | $name . | |
590 | CRM_Core_DAO::VALUE_SEPARATOR . "%'" | |
591 | ); | |
592 | if ($custom->find()) { | |
593 | return FALSE; | |
594 | } | |
595 | ||
596 | // remove subtype for existing contacts | |
597 | $sql = " | |
598 | UPDATE civicrm_contact SET contact_sub_type = NULL | |
599 | WHERE contact_sub_type = '$name'"; | |
600 | CRM_Core_DAO::executeQuery($sql); | |
601 | ||
602 | // remove subtype from contact type table | |
603 | $contactType = new CRM_Contact_DAO_ContactType(); | |
604 | $contactType->id = $contactTypeId; | |
605 | $contactType->delete(); | |
606 | ||
607 | // remove navigation entry if any | |
608 | if ($name) { | |
609 | $sql = " | |
610 | DELETE | |
611 | FROM civicrm_navigation | |
612 | WHERE name = %1"; | |
613 | $params = array(1 => array("New $name", 'String')); | |
614 | $dao = CRM_Core_DAO::executeQuery($sql, $params); | |
615 | CRM_Core_BAO_Navigation::resetNavigation(); | |
616 | } | |
617 | return TRUE; | |
618 | } | |
619 | ||
620 | /** | |
100fef9d | 621 | * Add or update Contact SubTypes |
6a488035 TO |
622 | * |
623 | * @param array $params an assoc array of name/value pairs | |
624 | * | |
625 | * @return object | |
626 | * @access public | |
627 | * @static | |
628 | */ | |
0f77a625 | 629 | static function add(&$params) { |
6a488035 TO |
630 | |
631 | // label or name | |
0f77a625 | 632 | if (empty($params['id']) && empty($params['label'])) { |
6a488035 TO |
633 | return; |
634 | } | |
a7488080 | 635 | if (!empty($params['parent_id']) && |
6a488035 TO |
636 | !CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_ContactType', $params['parent_id']) |
637 | ) { | |
638 | return; | |
639 | } | |
640 | ||
641 | $contactType = new CRM_Contact_DAO_ContactType(); | |
642 | $contactType->copyValues($params); | |
643 | $contactType->id = CRM_Utils_Array::value('id', $params); | |
644 | $contactType->is_active = CRM_Utils_Array::value('is_active', $params, 0); | |
645 | ||
6a488035 TO |
646 | $contactType->save(); |
647 | if ($contactType->find(TRUE)) { | |
648 | $contactName = $contactType->name; | |
649 | $contact = ucfirst($contactType->label); | |
650 | $active = $contactType->is_active; | |
651 | } | |
652 | ||
a7488080 | 653 | if (!empty($params['id'])) { |
6a488035 TO |
654 | $params = array('name' => "New $contactName"); |
655 | $newParams = array( | |
656 | 'label' => "New $contact", | |
657 | 'is_active' => $active, | |
658 | ); | |
659 | CRM_Core_BAO_Navigation::processUpdate($params, $newParams); | |
660 | } | |
661 | else { | |
662 | $name = self::getBasicType($contactName); | |
663 | if (!$name) { | |
664 | return; | |
665 | } | |
666 | $value = array('name' => "New $name"); | |
667 | CRM_Core_BAO_Navigation::retrieve($value, $navinfo); | |
668 | $navigation = array( | |
669 | 'label' => "New $contact", | |
670 | 'name' => "New $contactName", | |
15a7ea79 | 671 | 'url' => "civicrm/contact/add?ct=$name&cst=$contactName&reset=1", |
6a488035 TO |
672 | 'permission' => 'add contacts', |
673 | 'parent_id' => $navinfo['id'], | |
674 | 'is_active' => $active, | |
675 | ); | |
676 | CRM_Core_BAO_Navigation::add($navigation); | |
677 | } | |
678 | CRM_Core_BAO_Navigation::resetNavigation(); | |
679 | ||
680 | // reset the cache after adding | |
681 | self::subTypeInfo(NULL, FALSE, FALSE, TRUE); | |
682 | ||
683 | return $contactType; | |
684 | } | |
685 | ||
686 | /** | |
100fef9d | 687 | * Update the is_active flag in the db |
6a488035 TO |
688 | * |
689 | * @param int $id id of the database record | |
690 | * @param boolean $is_active value we want to set the is_active field | |
691 | * | |
692 | * @return Object DAO object on success, null otherwise | |
693 | * @static | |
694 | */ | |
695 | static function setIsActive($id, $is_active) { | |
696 | $params = array('id' => $id); | |
697 | self::retrieve($params, $contactinfo); | |
698 | $params = array('name' => "New $contactinfo[name]"); | |
699 | $newParams = array('is_active' => $is_active); | |
700 | CRM_Core_BAO_Navigation::processUpdate($params, $newParams); | |
701 | CRM_Core_BAO_Navigation::resetNavigation(); | |
702 | return CRM_Core_DAO::setFieldValue('CRM_Contact_DAO_ContactType', $id, | |
703 | 'is_active', $is_active | |
704 | ); | |
705 | } | |
706 | ||
86538308 | 707 | /** |
100fef9d | 708 | * @param string $typeName |
86538308 EM |
709 | * |
710 | * @return mixed | |
711 | */ | |
6a488035 TO |
712 | static function getLabel($typeName) { |
713 | $types = self::contactTypeInfo(TRUE); | |
714 | ||
715 | if (array_key_exists($typeName, $types)) { | |
716 | return $types[$typeName]['label']; | |
717 | } | |
718 | return $typeName; | |
719 | } | |
720 | ||
721 | /** | |
100fef9d | 722 | * Check whether allow to change any contact's subtype |
6a488035 TO |
723 | * on the basis of custom data and relationship of specific subtype |
724 | * currently used in contact/edit form amd in import validation | |
725 | * | |
726 | * @param int $contactId contact id. | |
727 | * @param string $subType subtype. | |
728 | * | |
729 | * @return boolean true/false. | |
730 | * @static | |
731 | */ | |
732 | static function isAllowEdit($contactId, $subType = NULL) { | |
733 | ||
734 | if (!$contactId) { | |
735 | return TRUE; | |
736 | } | |
737 | ||
738 | if (empty($subType)) { | |
739 | $subType = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', | |
740 | $contactId, | |
741 | 'contact_sub_type' | |
742 | ); | |
743 | } | |
744 | ||
745 | if (self::hasCustomData($subType, $contactId) || self::hasRelationships($contactId, $subType)) { | |
746 | return FALSE; | |
747 | } | |
748 | ||
749 | return TRUE; | |
750 | } | |
751 | ||
86538308 EM |
752 | /** |
753 | * @param $contactType | |
100fef9d | 754 | * @param int $contactId |
86538308 EM |
755 | * |
756 | * @return bool | |
757 | */ | |
6a488035 TO |
758 | static function hasCustomData($contactType, $contactId = NULL) { |
759 | $subTypeClause = ''; | |
760 | ||
761 | if (self::isaSubType($contactType)) { | |
762 | $subType = $contactType; | |
763 | $contactType = self::getBasicType($subType); | |
764 | ||
765 | // check for empty custom data which extends subtype | |
766 | $subTypeValue = CRM_Core_DAO::VALUE_SEPARATOR . $subType . CRM_Core_DAO::VALUE_SEPARATOR; | |
767 | $subTypeClause = " AND extends_entity_column_value LIKE '%{$subTypeValue}%' "; | |
768 | } | |
769 | $query = "SELECT table_name FROM civicrm_custom_group WHERE extends = '{$contactType}' {$subTypeClause}"; | |
770 | ||
771 | $dao = CRM_Core_DAO::executeQuery($query); | |
772 | while ($dao->fetch()) { | |
773 | $sql = "SELECT count(id) FROM {$dao->table_name}"; | |
774 | if ($contactId) { | |
775 | $sql .= " WHERE entity_id = {$contactId}"; | |
776 | } | |
777 | $sql .= " LIMIT 1"; | |
778 | ||
779 | $customDataCount = CRM_Core_DAO::singleValueQuery($sql); | |
780 | if (!empty($customDataCount)) { | |
781 | $dao->free(); | |
782 | return TRUE; | |
783 | } | |
784 | } | |
785 | return FALSE; | |
786 | } | |
787 | ||
f4aaa82a EM |
788 | /** |
789 | * @todo what does this function do? | |
100fef9d | 790 | * @param int $contactId |
f4aaa82a EM |
791 | * @param $contactType |
792 | * | |
793 | * @return bool | |
794 | */ | |
6a488035 TO |
795 | static function hasRelationships($contactId, $contactType) { |
796 | $subTypeClause = NULL; | |
797 | if (self::isaSubType($contactType)) { | |
798 | $subType = $contactType; | |
799 | $contactType = self::getBasicType($subType); | |
800 | $subTypeClause = " AND ( ( crt.contact_type_a = '{$contactType}' AND crt.contact_sub_type_a = '{$subType}') OR | |
801 | ( crt.contact_type_b = '{$contactType}' AND crt.contact_sub_type_b = '{$subType}') ) "; | |
802 | } | |
803 | else { | |
804 | $subTypeClause = " AND ( crt.contact_type_a = '{$contactType}' OR crt.contact_type_b = '{$contactType}' ) "; | |
805 | } | |
806 | ||
807 | // check relationships for | |
808 | $relationshipQuery = " | |
809 | SELECT count(cr.id) FROM civicrm_relationship cr | |
810 | INNER JOIN civicrm_relationship_type crt ON | |
811 | ( cr.relationship_type_id = crt.id {$subTypeClause} ) | |
812 | WHERE ( cr.contact_id_a = {$contactId} OR cr.contact_id_b = {$contactId} ) | |
813 | LIMIT 1"; | |
814 | ||
815 | $relationshipCount = CRM_Core_DAO::singleValueQuery($relationshipQuery); | |
816 | ||
817 | if (!empty($relationshipCount)) { | |
818 | return TRUE; | |
819 | } | |
820 | ||
821 | return FALSE; | |
822 | } | |
823 | ||
f4aaa82a EM |
824 | /** |
825 | * @todo what does this function do? | |
826 | * @param $contactType | |
827 | * @param array $subtypeSet | |
828 | * | |
829 | * @return array | |
830 | */ | |
c490a46a | 831 | static function getSubtypeCustomPair($contactType, $subtypeSet = array()) { |
6a488035 TO |
832 | if (empty($subtypeSet)) { |
833 | return $subtypeSet; | |
834 | } | |
835 | ||
836 | $customSet = $subTypeClause = array(); | |
837 | foreach ($subtypeSet as $subtype) { | |
838 | $subtype = CRM_Utils_Type::escape($subtype, 'String'); | |
839 | $subType = CRM_Core_DAO::VALUE_SEPARATOR . $subtype . CRM_Core_DAO::VALUE_SEPARATOR; | |
840 | $subTypeClause[] = "extends_entity_column_value LIKE '%{$subtype}%' "; | |
841 | } | |
842 | $query = "SELECT table_name | |
843 | FROM civicrm_custom_group | |
844 | WHERE extends = %1 AND " . implode(" OR ", $subTypeClause); | |
845 | $dao = CRM_Core_DAO::executeQuery($query, array(1 => array($contactType, 'String'))); | |
846 | while ($dao->fetch()) { | |
847 | $customSet[] = $dao->table_name; | |
848 | } | |
849 | return array_unique($customSet); | |
850 | } | |
851 | ||
f4aaa82a EM |
852 | /** |
853 | * Function that does something | |
854 | * @todo what does this function do? | |
855 | * | |
100fef9d | 856 | * @param int $contactID |
f4aaa82a EM |
857 | * @param $contactType |
858 | * @param array $oldSubtypeSet | |
859 | * @param array $newSubtypeSet | |
860 | * | |
861 | * @return bool | |
862 | */ | |
6a488035 TO |
863 | static function deleteCustomSetForSubtypeMigration($contactID, |
864 | $contactType, | |
865 | $oldSubtypeSet = array(), | |
866 | $newSubtypeSet = array() | |
867 | ) { | |
868 | $oldCustomSet = self::getSubtypeCustomPair($contactType, $oldSubtypeSet); | |
869 | $newCustomSet = self::getSubtypeCustomPair($contactType, $newSubtypeSet); | |
870 | ||
871 | $customToBeRemoved = array_diff($oldCustomSet, $newCustomSet); | |
872 | foreach ($customToBeRemoved as $customTable) { | |
873 | self::deleteCustomRowsForEntityID($customTable, $contactID); | |
874 | } | |
875 | return TRUE; | |
876 | } | |
877 | ||
878 | /** | |
879 | * Delete content / rows of a custom table specific to a subtype for a given custom-group. | |
880 | * This function currently works for contact subtypes only and could be later improved / genralized | |
881 | * to work for other subtypes as well. | |
882 | * | |
883 | * @param int $gID - custom group id. | |
884 | * @param array $subtypes - list of subtypes related to which entry is to be removed. | |
885 | * | |
886 | * @return void | |
887 | * @access public | |
888 | */ | |
66ed0bee | 889 | public static function deleteCustomRowsOfSubtype($gID, $subtypes = array()) { |
6a488035 TO |
890 | if (!$gID or empty($subtypes)) { |
891 | return FALSE; | |
892 | } | |
893 | ||
894 | $tableName = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomGroup', $gID, 'table_name'); | |
895 | ||
66ed0bee | 896 | // drop triggers CRM-13587 |
897 | CRM_Core_DAO::dropTriggers($tableName); | |
898 | ||
6a488035 TO |
899 | $subtypeClause = array(); |
900 | foreach ($subtypes as $subtype) { | |
901 | $subtype = CRM_Utils_Type::escape($subtype, 'String'); | |
902 | $subtypeClause[] = "civicrm_contact.contact_sub_type LIKE '%" . CRM_Core_DAO::VALUE_SEPARATOR . $subtype . CRM_Core_DAO::VALUE_SEPARATOR . "%'"; | |
903 | } | |
904 | $subtypeClause = implode(' OR ', $subtypeClause); | |
905 | ||
906 | $query = "DELETE custom.* | |
907 | FROM {$tableName} custom | |
908 | INNER JOIN civicrm_contact ON civicrm_contact.id = custom.entity_id | |
909 | WHERE ($subtypeClause)"; | |
66ed0bee | 910 | |
911 | CRM_Core_DAO::singleValueQuery($query); | |
912 | ||
913 | // rebuild triggers CRM-13587 | |
914 | CRM_Core_DAO::triggerRebuild($tableName); | |
6a488035 TO |
915 | } |
916 | ||
917 | /** | |
918 | * Delete content / rows of a custom table specific entity-id for a given custom-group table. | |
919 | * | |
920 | * @param int $customTable - custom table name. | |
921 | * @param int $entityID - entity id. | |
922 | * | |
923 | * @return void | |
924 | * @access public | |
925 | */ | |
926 | function deleteCustomRowsForEntityID($customTable, $entityID) { | |
927 | $customTable = CRM_Utils_Type::escape($customTable, 'String'); | |
928 | $query = "DELETE FROM {$customTable} WHERE entity_id = %1"; | |
929 | return CRM_Core_DAO::singleValueQuery($query, array(1 => array($entityID, 'Integer'))); | |
930 | } | |
931 | } | |
932 |