3 +--------------------------------------------------------------------+
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2019 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
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. |
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. |
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 +--------------------------------------------------------------------+
31 * @copyright CiviCRM LLC (c) 2004-2019
33 class CRM_Contact_BAO_ContactType
extends CRM_Contact_DAO_ContactType
{
36 * Fetch object based on array of properties.
38 * @param array $params
39 * (reference ) an assoc array of name/value pairs.
40 * @param array $defaults
41 * (reference ) an assoc array to hold the flattened values.
43 * @return CRM_Contact_BAO_ContactType|null
44 * object on success, null otherwise
46 public static function retrieve(&$params, &$defaults) {
47 $contactType = new CRM_Contact_DAO_ContactType();
48 $contactType->copyValues($params);
49 if ($contactType->find(TRUE)) {
50 CRM_Core_DAO
::storeValues($contactType, $defaults);
57 * Is this contact type active.
59 * @param string $contactType
63 public static function isActive($contactType) {
64 $contact = self
::contactTypeInfo(FALSE);
65 $active = array_key_exists($contactType, $contact) ?
TRUE : FALSE;
70 * Retrieve basic contact type information.
75 * Array of basic contact types information.
77 public static function basicTypeInfo($all = FALSE) {
78 static $_cache = NULL;
80 if ($_cache === NULL) {
84 $argString = $all ?
'CRM_CT_BTI_1' : 'CRM_CT_BTI_0';
85 if (!array_key_exists($argString, $_cache)) {
86 $cache = CRM_Utils_Cache
::singleton();
87 $_cache[$argString] = $cache->get($argString);
88 if (!$_cache[$argString]) {
91 FROM civicrm_contact_type
92 WHERE parent_id IS NULL
95 $sql .= " AND is_active = 1";
99 $dao = CRM_Core_DAO
::executeQuery($sql,
102 'CRM_Contact_DAO_ContactType'
104 while ($dao->fetch()) {
106 CRM_Core_DAO
::storeValues($dao, $value);
107 $_cache[$argString][$dao->name
] = $value;
110 $cache->set($argString, $_cache[$argString]);
113 return $_cache[$argString];
117 * Retrieve all basic contact types.
122 * Array of basic contact types
124 public static function basicTypes($all = FALSE) {
125 return array_keys(self
::basicTypeInfo($all));
134 public static function basicTypePairs($all = FALSE, $key = 'name') {
135 $subtypes = self
::basicTypeInfo($all);
138 foreach ($subtypes as $name => $info) {
139 $index = ($key == 'name') ?
$name : $info[$key];
140 $pairs[$index] = $info['label'];
146 * Retrieve all subtypes Information.
148 * @param array $contactType
151 * @param bool $ignoreCache
155 * Array of sub type information
157 public static function subTypeInfo($contactType = NULL, $all = FALSE, $ignoreCache = FALSE, $reset = FALSE) {
158 static $_cache = NULL;
160 if ($reset === TRUE) {
164 if ($_cache === NULL) {
167 if ($contactType && !is_array($contactType)) {
168 $contactType = [$contactType];
171 $argString = $all ?
'CRM_CT_STI_1_' : 'CRM_CT_STI_0_';
172 if (!empty($contactType)) {
173 $argString .= implode('_', $contactType);
176 if ((!array_key_exists($argString, $_cache)) ||
$ignoreCache) {
177 $cache = CRM_Utils_Cache
::singleton();
178 $_cache[$argString] = $cache->get($argString);
179 if (!$_cache[$argString] ||
$ignoreCache) {
180 $_cache[$argString] = [];
183 if (!empty($contactType)) {
184 $ctWHERE = " AND parent.name IN ('" . implode("','", $contactType) . "')";
188 SELECT subtype.*, parent.name as parent, parent.label as parent_label
189 FROM civicrm_contact_type subtype
190 INNER JOIN civicrm_contact_type parent ON subtype.parent_id = parent.id
191 WHERE subtype.name IS NOT NULL AND subtype.parent_id IS NOT NULL {$ctWHERE}
193 if ($all === FALSE) {
194 $sql .= " AND subtype.is_active = 1 AND parent.is_active = 1 ORDER BY parent.id";
196 $dao = CRM_Core_DAO
::executeQuery($sql, [],
197 FALSE, 'CRM_Contact_DAO_ContactType'
199 while ($dao->fetch()) {
201 CRM_Core_DAO
::storeValues($dao, $value);
202 $value['parent'] = $dao->parent
;
203 $value['parent_label'] = $dao->parent_label
;
204 $_cache[$argString][$dao->name
] = $value;
207 $cache->set($argString, $_cache[$argString]);
210 return $_cache[$argString];
215 * retrieve all subtypes
217 * @param array $contactType
220 * @param string $columnName
221 * @param bool $ignoreCache
224 * all subtypes OR list of subtypes associated to
225 * a given basic contact type
227 public static function subTypes($contactType = NULL, $all = FALSE, $columnName = 'name', $ignoreCache = FALSE) {
228 if ($columnName == 'name') {
229 return array_keys(self
::subTypeInfo($contactType, $all, $ignoreCache));
232 return array_values(self
::subTypePairs($contactType, FALSE, NULL, $ignoreCache));
238 * retrieve subtype pairs with name as 'subtype-name' and 'label' as value
240 * @param array $contactType
242 * @param string $labelPrefix
243 * @param bool $ignoreCache
246 * list of subtypes with name as 'subtype-name' and 'label' as value
248 public static function subTypePairs($contactType = NULL, $all = FALSE, $labelPrefix = '- ', $ignoreCache = FALSE) {
249 $subtypes = self
::subTypeInfo($contactType, $all, $ignoreCache);
252 foreach ($subtypes as $name => $info) {
253 $pairs[$name] = $labelPrefix . $info['label'];
260 * retrieve list of all types i.e basic + subtypes.
265 * Array of basic types + all subtypes.
267 public static function contactTypes($all = FALSE) {
268 return array_keys(self
::contactTypeInfo($all));
272 * Retrieve info array about all types i.e basic + subtypes.
278 * Array of basic types + all subtypes.
280 public static function contactTypeInfo($all = FALSE, $reset = FALSE) {
281 static $_cache = NULL;
283 if ($reset === TRUE) {
287 if ($_cache === NULL) {
291 $argString = $all ?
'CRM_CT_CTI_1' : 'CRM_CT_CTI_0';
292 if (!array_key_exists($argString, $_cache)) {
293 $cache = CRM_Utils_Cache
::singleton();
294 $_cache[$argString] = $cache->get($argString);
295 if (!$_cache[$argString]) {
296 $_cache[$argString] = [];
299 SELECT type.*, parent.name as parent, parent.label as parent_label
300 FROM civicrm_contact_type type
301 LEFT JOIN civicrm_contact_type parent ON type.parent_id = parent.id
302 WHERE type.name IS NOT NULL
304 if ($all === FALSE) {
305 $sql .= " AND type.is_active = 1";
308 $dao = CRM_Core_DAO
::executeQuery($sql,
311 'CRM_Contact_DAO_ContactType'
313 while ($dao->fetch()) {
315 CRM_Core_DAO
::storeValues($dao, $value);
316 if (array_key_exists('parent_id', $value)) {
317 $value['parent'] = $dao->parent
;
318 $value['parent_label'] = $dao->parent_label
;
320 $_cache[$argString][$dao->name
] = $value;
323 $cache->set($argString, $_cache[$argString]);
327 return $_cache[$argString];
331 * Retrieve basic type pairs with name as 'built-in name' and 'label' as value.
334 * @param null $typeName
335 * @param null $delimiter
338 * Array of basictypes with name as 'built-in name' and 'label' as value
340 public static function contactTypePairs($all = FALSE, $typeName = NULL, $delimiter = NULL) {
341 $types = self
::contactTypeInfo($all);
343 if ($typeName && !is_array($typeName)) {
344 $typeName = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, trim($typeName, CRM_Core_DAO
::VALUE_SEPARATOR
));
349 foreach ($typeName as $type) {
350 if (array_key_exists($type, $types)) {
351 $pairs[$type] = $types[$type]['label'];
356 foreach ($types as $name => $info) {
357 $pairs[$name] = $info['label'];
361 return !$delimiter ?
$pairs : implode($delimiter, $pairs);
365 * Get a list of elements for select box.
366 * Note that this used to default to using the hex(01) character - which results in an invalid character being used in form fields
367 * which was not handled well be anything that loaded & resaved the html (outside core)
368 * The use of this separator is now explicit in the calling functions as a step towards it's removal
371 * @param bool $isSeparator
372 * @param string $separator
376 public static function getSelectElements(
381 static $_cache = NULL;
383 if ($_cache === NULL) {
387 $argString = $all ?
'CRM_CT_GSE_1' : 'CRM_CT_GSE_0';
388 $argString .= $isSeparator ?
'_1' : '_0';
389 $argString .= $separator;
390 $argString = CRM_Utils_Cache
::cleanKey($argString);
391 if (!array_key_exists($argString, $_cache)) {
392 $cache = CRM_Utils_Cache
::singleton();
393 $_cache[$argString] = $cache->get($argString);
395 if (!$_cache[$argString]) {
396 $_cache[$argString] = [];
399 SELECT c.name as child_name , c.label as child_label , c.id as child_id,
400 p.name as parent_name, p.label as parent_label, p.id as parent_id
401 FROM civicrm_contact_type c
402 LEFT JOIN civicrm_contact_type p ON ( c.parent_id = p.id )
403 WHERE ( c.name IS NOT NULL )
406 if ($all === FALSE) {
409 AND ( p.is_active = 1 OR p.id IS NULL )
412 $sql .= " ORDER BY c.id";
415 $dao = CRM_Core_DAO
::executeQuery($sql);
416 while ($dao->fetch()) {
417 if (!empty($dao->parent_id
)) {
418 $key = $isSeparator ?
$dao->parent_name
. $separator . $dao->child_name
: $dao->child_name
;
419 $label = "- {$dao->child_label}";
420 $pName = $dao->parent_name
;
423 $key = $dao->child_name
;
424 $label = $dao->child_label
;
425 $pName = $dao->child_name
;
428 if (!isset($values[$pName])) {
429 $values[$pName] = [];
431 $values[$pName][] = ['key' => $key, 'label' => $label];
434 $selectElements = [];
435 foreach ($values as $pName => $elements) {
436 foreach ($elements as $element) {
437 $selectElements[$element['key']] = $element['label'];
440 $_cache[$argString] = $selectElements;
442 $cache->set($argString, $_cache[$argString]);
445 return $_cache[$argString];
449 * Check if a given type is a subtype.
451 * @param string $subType
453 * @param bool $ignoreCache
456 * true if subType, false otherwise.
458 public static function isaSubType($subType, $ignoreCache = FALSE) {
459 return in_array($subType, self
::subTypes(NULL, TRUE, 'name', $ignoreCache));
463 * Retrieve the basic contact type associated with given subType.
465 * @param array|string $subType contact subType.
466 * @return array|string
469 public static function getBasicType($subType) {
470 static $_cache = NULL;
471 if ($_cache === NULL) {
476 if ($subType && !is_array($subType)) {
477 $subType = [$subType];
480 $argString = implode('_', $subType);
482 if (!array_key_exists($argString, $_cache)) {
483 $_cache[$argString] = [];
486 SELECT subtype.name as contact_subtype, type.name as contact_type
487 FROM civicrm_contact_type subtype
488 INNER JOIN civicrm_contact_type type ON ( subtype.parent_id = type.id )
489 WHERE subtype.name IN ('" . implode("','", $subType) . "' )";
490 $dao = CRM_Core_DAO
::executeQuery($sql);
491 while ($dao->fetch()) {
493 $_cache[$argString] = $dao->contact_type
;
496 $_cache[$argString][$dao->contact_subtype
] = $dao->contact_type
;
499 return $_cache[$argString];
503 * Suppress all subtypes present in given array.
505 * @param array $subTypes
507 * @param bool $ignoreCache
510 * Array of suppressed subTypes.
512 public static function suppressSubTypes(&$subTypes, $ignoreCache = FALSE) {
513 $subTypes = array_diff($subTypes, self
::subTypes(NULL, TRUE, 'name', $ignoreCache));
518 * Verify if a given subtype is associated with a given basic contact type.
520 * @param string $subType
522 * @param string $contactType
524 * @param bool $ignoreCache
525 * @param string $columnName
528 * true if contact extends, false otherwise.
530 public static function isExtendsContactType($subType, $contactType, $ignoreCache = FALSE, $columnName = 'name') {
531 $subType = (array) CRM_Utils_Array
::explodePadded($subType);
532 $subtypeList = self
::subTypes($contactType, TRUE, $columnName, $ignoreCache);
533 $intersection = array_intersect($subType, $subtypeList);
534 return $subType == $intersection;
538 * Create shortcuts menu for contactTypes.
543 public static function getCreateNewList() {
545 //@todo FIXME - using the CRM_Core_DAO::VALUE_SEPARATOR creates invalid html - if you can find the form
546 // this is loaded onto then replace with something like '__' & test
547 $separator = CRM_Core_DAO
::VALUE_SEPARATOR
;
548 $contactTypes = self
::getSelectElements(FALSE, TRUE, $separator);
549 foreach ($contactTypes as $key => $value) {
551 $typeValue = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $key);
552 $cType = CRM_Utils_Array
::value('0', $typeValue);
553 $typeUrl = 'ct=' . $cType;
554 if ($csType = CRM_Utils_Array
::value('1', $typeValue)) {
555 $typeUrl .= "&cst=$csType";
558 'path' => 'civicrm/contact/add',
559 'query' => "$typeUrl&reset=1",
560 'ref' => "new-$value",
563 if ($csType = CRM_Utils_Array
::value('1', $typeValue)) {
564 $shortCuts[$cType]['shortCuts'][] = $shortCut;
567 $shortCuts[$cType] = $shortCut;
575 * Delete Contact SubTypes.
577 * @param int $contactTypeId
578 * ID of the Contact Subtype to be deleted.
582 public static function del($contactTypeId) {
584 if (!$contactTypeId) {
588 $params = ['id' => $contactTypeId];
589 self
::retrieve($params, $typeInfo);
590 $name = $typeInfo['name'];
591 // check if any custom group
592 $custom = new CRM_Core_DAO_CustomGroup();
593 $custom->whereAdd("extends_entity_column_value LIKE '%" .
594 CRM_Core_DAO
::VALUE_SEPARATOR
.
596 CRM_Core_DAO
::VALUE_SEPARATOR
. "%'"
598 if ($custom->find()) {
602 // remove subtype for existing contacts
604 UPDATE civicrm_contact SET contact_sub_type = NULL
605 WHERE contact_sub_type = '$name'";
606 CRM_Core_DAO
::executeQuery($sql);
608 // remove subtype from contact type table
609 $contactType = new CRM_Contact_DAO_ContactType();
610 $contactType->id
= $contactTypeId;
611 $contactType->delete();
613 // remove navigation entry if any
617 FROM civicrm_navigation
619 $params = [1 => ["New $name", 'String']];
620 $dao = CRM_Core_DAO
::executeQuery($sql, $params);
621 CRM_Core_BAO_Navigation
::resetNavigation();
627 * Add or update Contact SubTypes.
629 * @param array $params
630 * An assoc array of name/value pairs.
632 * @return object|void
634 public static function add(&$params) {
637 if (empty($params['id']) && empty($params['label'])) {
640 if (!empty($params['parent_id']) &&
641 !CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_ContactType', $params['parent_id'])
646 $contactType = new CRM_Contact_DAO_ContactType();
647 $contactType->copyValues($params);
648 $contactType->id
= CRM_Utils_Array
::value('id', $params);
649 $contactType->is_active
= CRM_Utils_Array
::value('is_active', $params, 0);
651 $contactType->save();
652 if ($contactType->find(TRUE)) {
653 $contactName = $contactType->name
;
654 $contact = ucfirst($contactType->label
);
655 $active = $contactType->is_active
;
658 if (!empty($params['id'])) {
660 'label' => "New $contact",
661 'is_active' => $active,
663 CRM_Core_BAO_Navigation
::processUpdate(['name' => "New $contactName"], $newParams);
666 $name = self
::getBasicType($contactName);
670 $value = ['name' => "New $name"];
671 CRM_Core_BAO_Navigation
::retrieve($value, $navinfo);
673 'label' => "New $contact",
674 'name' => "New $contactName",
675 'url' => "civicrm/contact/add?ct=$name&cst=$contactName&reset=1",
676 'permission' => 'add contacts',
677 'parent_id' => $navinfo['id'],
678 'is_active' => $active,
680 CRM_Core_BAO_Navigation
::add($navigation);
682 CRM_Core_BAO_Navigation
::resetNavigation();
684 // reset the cache after adding
685 self
::subTypeInfo(NULL, FALSE, FALSE, TRUE);
691 * Update the is_active flag in the db.
694 * Id of the database record.
695 * @param bool $is_active
696 * Value we want to set the is_active field.
699 * true if we found and updated the object, else false
701 public static function setIsActive($id, $is_active) {
702 $params = ['id' => $id];
703 self
::retrieve($params, $contactinfo);
704 $params = ['name' => "New $contactinfo[name]"];
705 $newParams = ['is_active' => $is_active];
706 CRM_Core_BAO_Navigation
::processUpdate($params, $newParams);
707 CRM_Core_BAO_Navigation
::resetNavigation();
708 return CRM_Core_DAO
::setFieldValue('CRM_Contact_DAO_ContactType', $id,
709 'is_active', $is_active
714 * @param string $typeName
718 public static function getLabel($typeName) {
719 $types = self
::contactTypeInfo(TRUE);
721 if (array_key_exists($typeName, $types)) {
722 return $types[$typeName]['label'];
728 * Check whether allow to change any contact's subtype
729 * on the basis of custom data and relationship of specific subtype
730 * currently used in contact/edit form amd in import validation
732 * @param int $contactId
734 * @param string $subType
739 public static function isAllowEdit($contactId, $subType = NULL) {
745 if (empty($subType)) {
746 $subType = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Contact',
752 if (self
::hasCustomData($subType, $contactId) || self
::hasRelationships($contactId, $subType)) {
760 * @param $contactType
761 * @param int $contactId
765 public static function hasCustomData($contactType, $contactId = NULL) {
768 if (self
::isaSubType($contactType)) {
769 $subType = $contactType;
770 $contactType = self
::getBasicType($subType);
772 // check for empty custom data which extends subtype
773 $subTypeValue = CRM_Core_DAO
::VALUE_SEPARATOR
. $subType . CRM_Core_DAO
::VALUE_SEPARATOR
;
774 $subTypeClause = " AND extends_entity_column_value LIKE '%{$subTypeValue}%' ";
776 $query = "SELECT table_name FROM civicrm_custom_group WHERE extends = '{$contactType}' {$subTypeClause}";
778 $dao = CRM_Core_DAO
::executeQuery($query);
779 while ($dao->fetch()) {
780 $sql = "SELECT count(id) FROM {$dao->table_name}";
782 $sql .= " WHERE entity_id = {$contactId}";
786 $customDataCount = CRM_Core_DAO
::singleValueQuery($sql);
787 if (!empty($customDataCount)) {
795 * @todo what does this function do?
796 * @param int $contactId
797 * @param $contactType
801 public static function hasRelationships($contactId, $contactType) {
802 $subTypeClause = NULL;
803 if (self
::isaSubType($contactType)) {
804 $subType = $contactType;
805 $contactType = self
::getBasicType($subType);
806 $subTypeClause = " AND ( ( crt.contact_type_a = '{$contactType}' AND crt.contact_sub_type_a = '{$subType}') OR
807 ( crt.contact_type_b = '{$contactType}' AND crt.contact_sub_type_b = '{$subType}') ) ";
810 $subTypeClause = " AND ( crt.contact_type_a = '{$contactType}' OR crt.contact_type_b = '{$contactType}' ) ";
813 // check relationships for
814 $relationshipQuery = "
815 SELECT count(cr.id) FROM civicrm_relationship cr
816 INNER JOIN civicrm_relationship_type crt ON
817 ( cr.relationship_type_id = crt.id {$subTypeClause} )
818 WHERE ( cr.contact_id_a = {$contactId} OR cr.contact_id_b = {$contactId} )
821 $relationshipCount = CRM_Core_DAO
::singleValueQuery($relationshipQuery);
823 if (!empty($relationshipCount)) {
831 * @todo what does this function do?
832 * @param $contactType
833 * @param array $subtypeSet
837 public static function getSubtypeCustomPair($contactType, $subtypeSet = []) {
838 if (empty($subtypeSet)) {
842 $customSet = $subTypeClause = [];
843 foreach ($subtypeSet as $subtype) {
844 $subtype = CRM_Utils_Type
::escape($subtype, 'String');
845 $subtype = CRM_Core_DAO
::VALUE_SEPARATOR
. $subtype . CRM_Core_DAO
::VALUE_SEPARATOR
;
846 $subTypeClause[] = "extends_entity_column_value LIKE '%{$subtype}%' ";
848 $query = "SELECT table_name
849 FROM civicrm_custom_group
850 WHERE extends = %1 AND " . implode(" OR ", $subTypeClause);
851 $dao = CRM_Core_DAO
::executeQuery($query, [1 => [$contactType, 'String']]);
852 while ($dao->fetch()) {
853 $customSet[] = $dao->table_name
;
855 return array_unique($customSet);
859 * Function that does something.
860 * @todo what does this function do?
862 * @param int $contactID
863 * @param $contactType
864 * @param array $oldSubtypeSet
865 * @param array $newSubtypeSet
869 public static function deleteCustomSetForSubtypeMigration(
875 $oldCustomSet = self
::getSubtypeCustomPair($contactType, $oldSubtypeSet);
876 $newCustomSet = self
::getSubtypeCustomPair($contactType, $newSubtypeSet);
878 $customToBeRemoved = array_diff($oldCustomSet, $newCustomSet);
879 foreach ($customToBeRemoved as $customTable) {
880 self
::deleteCustomRowsForEntityID($customTable, $contactID);
886 * Delete content / rows of a custom table specific to a subtype for a given custom-group.
887 * This function currently works for contact subtypes only and could be later improved / genralized
888 * to work for other subtypes as well.
892 * @param array $subtypes
893 * List of subtypes related to which entry is to be removed.
894 * @param array $subtypesToPreserve
898 public static function deleteCustomRowsOfSubtype($gID, $subtypes = [], $subtypesToPreserve = []) {
899 if (!$gID or empty($subtypes)) {
903 $tableName = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_CustomGroup', $gID, 'table_name');
905 // drop triggers CRM-13587
906 CRM_Core_DAO
::dropTriggers($tableName);
908 foreach ($subtypesToPreserve as $subtypeToPreserve) {
909 $subtypeToPreserve = CRM_Utils_Type
::escape($subtypeToPreserve, 'String');
910 $subtypesToPreserveClause[] = "(civicrm_contact.contact_sub_type NOT LIKE '%" . CRM_Core_DAO
::VALUE_SEPARATOR
. $subtypeToPreserve . CRM_Core_DAO
::VALUE_SEPARATOR
. "%')";
912 $subtypesToPreserveClause = implode(' AND ', $subtypesToPreserveClause);
915 foreach ($subtypes as $subtype) {
916 $subtype = CRM_Utils_Type
::escape($subtype, 'String');
917 $subtypeClause[] = "( civicrm_contact.contact_sub_type LIKE '%" . CRM_Core_DAO
::VALUE_SEPARATOR
. $subtype . CRM_Core_DAO
::VALUE_SEPARATOR
. "%'"
918 . " AND " . $subtypesToPreserveClause . ")";
920 $subtypeClause = implode(' OR ', $subtypeClause);
922 $query = "DELETE custom.*
923 FROM {$tableName} custom
924 INNER JOIN civicrm_contact ON civicrm_contact.id = custom.entity_id
925 WHERE ($subtypeClause)";
927 CRM_Core_DAO
::singleValueQuery($query);
929 // rebuild triggers CRM-13587
930 CRM_Core_DAO
::triggerRebuild($tableName);
934 * Delete content / rows of a custom table specific entity-id for a given custom-group table.
936 * @param int $customTable
938 * @param int $entityID
941 * @return null|string
943 public static function deleteCustomRowsForEntityID($customTable, $entityID) {
944 $customTable = CRM_Utils_Type
::escape($customTable, 'String');
945 $query = "DELETE FROM {$customTable} WHERE entity_id = %1";
946 return CRM_Core_DAO
::singleValueQuery($query, [1 => [$entityID, 'Integer']]);