CRM-19068 remove references to 'descendant groups for an org'
[civicrm-core.git] / CRM / Contact / BAO / GroupNesting.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
7e9e8871 4 | CiviCRM version 4.7 |
6a488035
TO
5 +--------------------------------------------------------------------+
6 | Copyright U.S. PIRG Education Fund (c) 2007 |
7 | Licensed to CiviCRM under the Academic Free License version 3.0. |
8 +--------------------------------------------------------------------+
9 | This file is a part of CiviCRM. |
10 | |
11 | CiviCRM is free software; you can copy, modify, and distribute it |
12 | under the terms of the GNU Affero General Public License |
13 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
14 | |
15 | CiviCRM is distributed in the hope that it will be useful, but |
16 | WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
18 | See the GNU Affero General Public License for more details. |
19 | |
20 | You should have received a copy of the GNU Affero General Public |
21 | License and the CiviCRM Licensing Exception along |
22 | with this program; if not, contact CiviCRM LLC |
23 | at info[AT]civicrm[DOT]org. If you have questions about the |
24 | GNU Affero General Public License or the licensing of CiviCRM, |
25 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
26 +--------------------------------------------------------------------+
d25dd0ee 27 */
6a488035
TO
28
29/**
30 *
31 * @package CRM
32 * @copyright U.S. PIRG 2007
6a488035
TO
33 */
34class CRM_Contact_BAO_GroupNesting extends CRM_Contact_DAO_GroupNesting implements Iterator {
35
36 static $_sortOrder = 'ASC';
37
38 private $_current;
39
40 private $_parentStack = array();
41
42 private $_lastParentlessGroup;
43
44 private $_styleLabels;
45
46 private $_styleIndent;
47
48 private $_alreadyStyled = FALSE;
49
50 /**
fe482240 51 * Class constructor.
607fa308
EM
52 *
53 * @param bool $styleLabels
54 * @param string $styleIndent
6a488035 55 */
00be9182 56 public function __construct($styleLabels = FALSE, $styleIndent = "&nbsp;--&nbsp;") {
6a488035
TO
57 parent::__construct();
58 $this->_styleLabels = $styleLabels;
59 $this->_styleIndent = $styleIndent;
60 }
61
86538308
EM
62 /**
63 * @param $sortOrder
64 */
00be9182 65 public function setSortOrder($sortOrder) {
6a488035
TO
66 switch ($sortOrder) {
67 case 'ASC':
68 case 'DESC':
69 if ($sortOrder != self::$_sortOrder) {
70 self::$_sortOrder = $sortOrder;
71 $this->rewind();
72 }
73 break;
74
75 default:
76 // spit out some error, someday
77 }
78 }
79
86538308
EM
80 /**
81 * @return string
82 */
00be9182 83 public function getSortOrder() {
6a488035
TO
84 return self::$_sortOrder;
85 }
86
86538308
EM
87 /**
88 * @return int
89 */
00be9182 90 public function getCurrentNestingLevel() {
6a488035
TO
91 return count($this->_parentStack);
92 }
93
94 /**
95 * Go back to the first element in the group nesting graph,
96 * which is the first group (according to _sortOrder) that
97 * has no parent groups
98 */
00be9182 99 public function rewind() {
6a488035
TO
100 $this->_parentStack = array();
101 // calling _getNextParentlessGroup w/ no arguments
102 // makes it return the first parentless group
103 $firstGroup = $this->_getNextParentlessGroup();
104 $this->_current = $firstGroup;
105 $this->_lastParentlessGroup = $firstGroup;
106 $this->_alreadyStyled = FALSE;
107 }
108
2b37475d
CW
109 /**
110 * @return mixed
111 */
00be9182 112 public function current() {
6a488035
TO
113 if ($this->_styleLabels &&
114 $this->valid() &&
115 !$this->_alreadyStyled
116 ) {
353ffa53 117 $styledGroup = clone($this->_current);
6a488035 118 $nestingLevel = $this->getCurrentNestingLevel();
353ffa53 119 $indent = '';
6a488035
TO
120 while ($nestingLevel--) {
121 $indent .= $this->_styleIndent;
122 }
123 $styledGroup->title = $indent . $styledGroup->title;
124
125 $this->_current = &$styledGroup;
126 $this->_alreadyStyled = TRUE;
127 }
128 return $this->_current;
129 }
130
86538308
EM
131 /**
132 * @return string
133 */
00be9182 134 public function key() {
6a488035
TO
135 $group = &$this->_current;
136 $ids = array();
137 foreach ($this->_parentStack as $parentGroup) {
138 $ids[] = $parentGroup->id;
139 }
140 $key = implode('-', $ids);
141 if (strlen($key) > 0) {
142 $key .= '-';
143 }
144 $key .= $group->id;
145 return $key;
146 }
147
86538308
EM
148 /**
149 * @return CRM_Contact_BAO_Group|null
150 */
00be9182 151 public function next() {
6a488035
TO
152 $currentGroup = &$this->_current;
153 $childGroup = $this->_getNextChildGroup($currentGroup);
154 if ($childGroup) {
155 $nextGroup = &$childGroup;
156 $this->_parentStack[] = &$this->_current;
157 }
158 else {
159 $nextGroup = $this->_getNextSiblingGroup($currentGroup);
160 if (!$nextGroup) {
161 // no sibling, find an ancestor w/ a sibling
3bdca100 162 for (;;) {
b44e3f84 163 // since we pop this array every time, we should be
6a488035
TO
164 // reasonably safe from infinite loops, I think :)
165 $ancestor = array_pop($this->_parentStack);
166 $this->_current = &$ancestor;
167 if ($ancestor == NULL) {
168 break;
169 }
170 $nextGroup = $this->_getNextSiblingGroup($ancestor);
171 if ($nextGroup) {
172 break;
173 }
174 }
175 }
176 }
177 $this->_current = &$nextGroup;
178 $this->_alreadyStyled = FALSE;
179 return $nextGroup;
180 }
181
86538308
EM
182 /**
183 * @return bool
184 */
00be9182 185 public function valid() {
6a488035
TO
186 if ($this->_current) {
187 return TRUE;
188 }
189 else {
190 return FALSE;
191 }
192 }
193
86538308
EM
194 /**
195 * @param null $group
196 *
197 * @return CRM_Contact_BAO_Group|null
198 */
00be9182 199 public function _getNextParentlessGroup(&$group = NULL) {
6a488035 200 $lastParentlessGroup = $this->_lastParentlessGroup;
353ffa53 201 $nextGroup = new CRM_Contact_BAO_Group();
6a488035
TO
202 $nextGroup->order_by = 'title ' . self::$_sortOrder;
203 $nextGroup->find();
204 if ($group == NULL) {
205 $sawLast = TRUE;
206 }
207 else {
208 $sawLast = FALSE;
209 }
210 while ($nextGroup->fetch()) {
211 if (!self::hasParentGroups($nextGroup->id) && $sawLast) {
212 return $nextGroup;
213 }
214 elseif ($lastParentlessGroup->id == $nextGroup->id) {
215 $sawLast = TRUE;
216 }
217 }
218 return NULL;
219 }
220
86538308
EM
221 /**
222 * @param $parentGroup
223 * @param null $group
224 *
225 * @return CRM_Contact_BAO_Group|null
226 */
00be9182 227 public function _getNextChildGroup(&$parentGroup, &$group = NULL) {
6a488035
TO
228 $children = self::getChildGroupIds($parentGroup->id);
229 if (count($children) > 0) {
230 // we have child groups, so get the first one based on _sortOrder
231 $childGroup = new CRM_Contact_BAO_Group();
232 $cgQuery = "SELECT * FROM civicrm_group WHERE id IN (" . implode(',', $children) . ") ORDER BY title " . self::$_sortOrder;
233 $childGroup->query($cgQuery);
234 $currentGroup = &$this->_current;
235 if ($group == NULL) {
236 $sawLast = TRUE;
237 }
238 else {
239 $sawLast = FALSE;
240 }
241 while ($childGroup->fetch()) {
242 if ($sawLast) {
243 return $childGroup;
244 }
245 elseif ($currentGroup->id === $childGroup->id) {
246 $sawLast = TRUE;
247 }
248 }
249 }
250 return NULL;
251 }
252
86538308
EM
253 /**
254 * @param $group
255 *
256 * @return CRM_Contact_BAO_Group|null
257 */
00be9182 258 public function _getNextSiblingGroup(&$group) {
6a488035
TO
259 $parentGroup = end($this->_parentStack);
260 if ($parentGroup) {
261 $nextGroup = $this->_getNextChildGroup($parentGroup, $group);
262 return $nextGroup;
263 }
264 else {
265 /* if we get here, it could be because we're out of siblings
e70a7fc0
TO
266 * (in which case we return null) or because we're at the
267 * top level groups which do not have parents but may still
268 * have siblings, so check for that first.
269 */
6a488035
TO
270
271 $nextGroup = $this->_getNextParentlessGroup($group);
272 if ($nextGroup) {
273 $this->_lastParentlessGroup = $nextGroup;
274 return $nextGroup;
275 }
276 return NULL;
277 }
278 }
279
280 /**
281 * Adds a new child group identified by $childGroupId to the group
282 * identified by $groupId
283 *
77c5b619
TO
284 * @param int $parentID
285 * Id of the group to add the child to.
286 * @param int $childID
287 * Id of the new child group.
6a488035 288 */
00be9182 289 public static function add($parentID, $childID) {
6a488035
TO
290 // TODO: Add checks here to make sure invalid nests can't be created
291 $dao = new CRM_Contact_DAO_GroupNesting();
292 $query = "REPLACE INTO civicrm_group_nesting (child_group_id, parent_group_id) VALUES ($childID,$parentID);";
293 $dao->query($query);
294 }
295
296 /**
297 * Removes a child group identified by $childGroupId from the group
298 * identified by $groupId; does not delete child group, just the
299 * association between the two
300 *
77c5b619
TO
301 * @param $parentID
302 * The id of the group to remove the child from.
303 * @param $childID
304 * The id of the child group being removed.
6a488035 305 */
00be9182 306 public static function remove($parentID, $childID) {
6a488035
TO
307 $dao = new CRM_Contact_DAO_GroupNesting();
308 $query = "DELETE FROM civicrm_group_nesting WHERE child_group_id = $childID AND parent_group_id = $parentID";
309 $dao->query($query);
310 }
311
312 /**
313 * Removes associations where a child group is identified by $childGroupId from the group
314 * identified by $groupId; does not delete child group, just the
315 * association between the two
316 *
77c5b619
TO
317 * @param int $childID
318 * The id of the child group being removed.
6a488035 319 */
00be9182 320 public static function removeAllParentForChild($childID) {
6a488035
TO
321 $dao = new CRM_Contact_DAO_GroupNesting();
322 $query = "DELETE FROM civicrm_group_nesting WHERE child_group_id = $childID";
323 $dao->query($query);
324 }
325
326 /**
327 * Returns true if the association between parent and child is present,
328 * false otherwise.
329 *
77c5b619
TO
330 * @param $parentID
331 * The parent id of the association.
332 * @param $childID
333 * The child id of the association.
6a488035 334 *
3bdca100 335 * @return bool
2b37475d 336 * True if association is found, false otherwise.
6a488035 337 */
00be9182 338 public static function isParentChild($parentID, $childID) {
6a488035
TO
339 $dao = new CRM_Contact_DAO_GroupNesting();
340 $query = "SELECT id FROM civicrm_group_nesting WHERE child_group_id = $childID AND parent_group_id = $parentID";
341 $dao->query($query);
342 if ($dao->fetch()) {
343 return TRUE;
344 }
345 return FALSE;
346 }
347
348 /**
349 * Returns true if if the given groupId has 1 or more child groups,
350 * false otherwise.
351 *
77c5b619
TO
352 * @param $groupId
353 * The id of the group to check for child groups.
6a488035 354 *
3bdca100 355 * @return bool
2b37475d 356 * True if 1 or more child groups are found, false otherwise.
6a488035 357 */
00be9182 358 public static function hasChildGroups($groupId) {
6a488035
TO
359 $dao = new CRM_Contact_DAO_GroupNesting();
360 $query = "SELECT child_group_id FROM civicrm_group_nesting WHERE parent_group_id = $groupId LIMIT 1";
361 //print $query . "\n<br><br>";
362 $dao->query($query);
363 if ($dao->fetch()) {
364 return TRUE;
365 }
366 return FALSE;
367 }
368
369 /**
370 * Returns true if the given groupId has 1 or more parent groups,
371 * false otherwise.
372 *
77c5b619
TO
373 * @param $groupId
374 * The id of the group to check for parent groups.
6a488035 375 *
3bdca100 376 * @return bool
2b37475d 377 * True if 1 or more parent groups are found, false otherwise.
6a488035 378 */
00be9182 379 public static function hasParentGroups($groupId) {
6a488035
TO
380 $dao = new CRM_Contact_DAO_GroupNesting();
381 $query = "SELECT parent_group_id FROM civicrm_group_nesting WHERE child_group_id = $groupId LIMIT 1";
382 $dao->query($query);
383 if ($dao->fetch()) {
384 return TRUE;
385 }
386 return FALSE;
387 }
388
389 /**
390 * Returns true if checkGroupId is a parent of one of the groups in
391 * groupIds, false otherwise.
392 *
5a4f6742
CW
393 * @param array $groupIds
394 * of group ids (or one group id) to serve as the starting point.
77c5b619
TO
395 * @param $checkGroupId
396 * The group id to check if it is a parent of the $groupIds group(s).
6a488035 397 *
3bdca100 398 * @return bool
2b37475d 399 * True if $checkGroupId points to a group that is a parent of one of the $groupIds groups, false otherwise.
6a488035 400 */
00be9182 401 public static function isParentGroup($groupIds, $checkGroupId) {
6a488035
TO
402 if (!is_array($groupIds)) {
403 $groupIds = array($groupIds);
404 }
405 $dao = new CRM_Contact_DAO_GroupNesting();
406 $query = "SELECT parent_group_id FROM civicrm_group_nesting WHERE child_group_id IN (" . implode(',', $groupIds) . ")";
407 $dao->query($query);
408 while ($dao->fetch()) {
409 $parentGroupId = $dao->parent_group_id;
410 if ($parentGroupId == $checkGroupId) {
411 /* print "One of these: <pre>";
e70a7fc0
TO
412 print_r($groupIds);
413 print "</pre> has groupId $checkGroupId as an ancestor.<br/>"; */
6a488035
TO
414
415 return TRUE;
416 }
417 }
418 return FALSE;
419 }
420
421 /**
422 * Returns true if checkGroupId is a child of one of the groups in
423 * groupIds, false otherwise.
424 *
5a4f6742
CW
425 * @param array $groupIds
426 * of group ids (or one group id) to serve as the starting point.
77c5b619
TO
427 * @param $checkGroupId
428 * The group id to check if it is a child of the $groupIds group(s).
6a488035 429 *
3bdca100 430 * @return bool
2b37475d 431 * True if $checkGroupId points to a group that is a child of one of the $groupIds groups, false otherwise.
6a488035 432 */
00be9182 433 public static function isChildGroup($groupIds, $checkGroupId) {
6a488035
TO
434
435 if (!is_array($groupIds)) {
436 $groupIds = array($groupIds);
437 }
438 $dao = new CRM_Contact_DAO_GroupNesting();
439 $query = "SELECT child_group_id FROM civicrm_group_nesting WHERE parent_group_id IN (" . implode(',', $groupIds) . ")";
440 //print $query;
441 $dao->query($query);
442 while ($dao->fetch()) {
443 $childGroupId = $dao->child_group_id;
444 if ($childGroupId == $checkGroupId) {
445 /* print "One of these: <pre>";
e70a7fc0
TO
446 print_r($groupIds);
447 print "</pre> has groupId $checkGroupId as a descendent.<br/><br/>"; */
6a488035
TO
448
449 return TRUE;
450 }
451 }
452 return FALSE;
453 }
454
455 /**
456 * Returns true if checkGroupId is an ancestor of one of the groups in
457 * groupIds, false otherwise.
458 *
5a4f6742
CW
459 * @param array $groupIds
460 * of group ids (or one group id) to serve as the starting point.
77c5b619
TO
461 * @param $checkGroupId
462 * The group id to check if it is an ancestor of the $groupIds group(s).
6a488035 463 *
3bdca100 464 * @return bool
2b37475d 465 * True if $checkGroupId points to a group that is an ancestor of one of the $groupIds groups, false otherwise.
6a488035 466 */
00be9182 467 public static function isAncestorGroup($groupIds, $checkGroupId) {
6a488035
TO
468 if (!is_array($groupIds)) {
469 $groupIds = array($groupIds);
470 }
471 $dao = new CRM_Contact_DAO_GroupNesting();
472 $query = "SELECT parent_group_id FROM civicrm_group_nesting WHERE child_group_id IN (" . implode(',', $groupIds) . ")";
473 $dao->query($query);
474 $nextGroupIds = array();
475 $gotAtLeastOneResult = FALSE;
476 while ($dao->fetch()) {
477 $gotAtLeastOneResult = TRUE;
478 $parentGroupId = $dao->parent_group_id;
479 if ($parentGroupId == $checkGroupId) {
480 /* print "One of these: <pre>";
e70a7fc0
TO
481 print_r($groupIds);
482 print "</pre> has groupId $checkGroupId as an ancestor.<br/>"; */
6a488035
TO
483
484 return TRUE;
485 }
486 $nextGroupIds[] = $parentGroupId;
487 }
488 if ($gotAtLeastOneResult) {
489 return self::isAncestorGroup($nextGroupIds, $checkGroupId);
490 }
491 else {
492 return FALSE;
493 }
494 }
495
496 /**
497 * Returns true if checkGroupId is a descendent of one of the groups in
498 * groupIds, false otherwise.
499 *
5a4f6742
CW
500 * @param array $groupIds
501 * of group ids (or one group id) to serve as the starting point.
77c5b619
TO
502 * @param $checkGroupId
503 * The group id to check if it is a descendent of the $groupIds group(s).
6a488035 504 *
3bdca100 505 * @return bool
2b37475d 506 * True if $checkGroupId points to a group that is a descendent of one of the $groupIds groups, false otherwise.
6a488035 507 */
00be9182 508 public static function isDescendentGroup($groupIds, $checkGroupId) {
6a488035
TO
509 if (!is_array($groupIds)) {
510 $groupIds = array($groupIds);
511 }
512 $dao = new CRM_Contact_DAO_GroupNesting();
513 $query = "SELECT child_group_id FROM civicrm_group_nesting WHERE parent_group_id IN (" . implode(',', $groupIds) . ")";
514 $dao->query($query);
515 $nextGroupIds = array();
516 $gotAtLeastOneResult = FALSE;
517 while ($dao->fetch()) {
518 $gotAtLeastOneResult = TRUE;
519 $childGroupId = $dao->child_group_id;
520 if ($childGroupId == $checkGroupId) {
521 /* print "One of these: <pre>";
e70a7fc0
TO
522 print_r($groupIds);
523 print "</pre> has groupId $checkGroupId as a descendent.<br/><br/>"; */
6a488035
TO
524
525 return TRUE;
526 }
527 $nextGroupIds[] = $childGroupId;
528 }
529 if ($gotAtLeastOneResult) {
530 return self::isDescendentGroup($nextGroupIds, $checkGroupId);
531 }
532 else {
533 return FALSE;
534 }
535 }
536
537 /**
538 * Returns array of group ids of ancestor groups of the specified group.
539 *
5a4f6742 540 * @param array $groupIds
77c5b619 541 * An array of valid group ids (passed by reference).
6a488035 542 *
2a6da8d7 543 * @param bool $includeSelf
6a488035 544 *
2b37475d 545 * @return array
364c80f1 546 * List of groupIds that represent the requested group and its ancestors
6a488035 547 */
00be9182 548 public static function getAncestorGroupIds($groupIds, $includeSelf = TRUE) {
6a488035
TO
549 if (!is_array($groupIds)) {
550 $groupIds = array($groupIds);
551 }
552 $dao = new CRM_Contact_DAO_GroupNesting();
553 $query = "SELECT parent_group_id, child_group_id
554 FROM civicrm_group_nesting
555 WHERE child_group_id IN (" . implode(',', $groupIds) . ")";
556 $dao->query($query);
557 $tmpGroupIds = array();
558 $parentGroupIds = array();
559 if ($includeSelf) {
560 $parentGroupIds = $groupIds;
561 }
562 while ($dao->fetch()) {
563 // make sure we're not following any cyclical references
564 if (!array_key_exists($dao->child_group_id, $parentGroupIds) && $dao->parent_group_id != $groupIds[0]) {
565 $tmpGroupIds[] = $dao->parent_group_id;
566 }
567 }
568 if (!empty($tmpGroupIds)) {
569 $newParentGroupIds = self::getAncestorGroupIds($tmpGroupIds);
570 $parentGroupIds = array_merge($parentGroupIds, $newParentGroupIds);
571 }
572 return $parentGroupIds;
573 }
574
575 /**
576 * Returns array of ancestor groups of the specified group.
577 *
5a4f6742 578 * @param array $groupIds
77c5b619 579 * An array of valid group ids (passed by reference).
6a488035 580 *
2a6da8d7 581 * @param bool $includeSelf
2b37475d 582 * @return array
364c80f1 583 * List of ancestor groups
6a488035 584 */
00be9182 585 public static function getAncestorGroups($groupIds, $includeSelf = TRUE) {
6a488035
TO
586 $groupIds = self::getAncestorGroupIds($groupIds, $includeSelf);
587 $params['id'] = $groupIds;
588 return CRM_Contact_BAO_Group::getGroups($params);
589 }
590
591 /**
592 * Returns array of group ids of child groups of the specified group.
593 *
5a4f6742 594 * @param array $groupIds
77c5b619 595 * An array of valid group ids (passed by reference).
6a488035 596 *
2b37475d 597 * @return array
364c80f1 598 * List of groupIds that represent the requested group and its children
6a488035 599 */
00be9182 600 public static function getChildGroupIds($groupIds) {
6a488035
TO
601 if (!is_array($groupIds)) {
602 $groupIds = array($groupIds);
603 }
604 $dao = new CRM_Contact_DAO_GroupNesting();
605 $query = "SELECT child_group_id FROM civicrm_group_nesting WHERE parent_group_id IN (" . implode(',', $groupIds) . ")";
606 $dao->query($query);
607 $childGroupIds = array();
608 while ($dao->fetch()) {
609 $childGroupIds[] = $dao->child_group_id;
610 }
611 return $childGroupIds;
612 }
613
614 /**
615 * Returns array of group ids of parent groups of the specified group.
616 *
5a4f6742 617 * @param array $groupIds
77c5b619 618 * An array of valid group ids (passed by reference).
6a488035 619 *
2b37475d 620 * @return array
364c80f1 621 * List of groupIds that represent the requested group and its parents
6a488035 622 */
00be9182 623 public static function getParentGroupIds($groupIds) {
6a488035
TO
624 if (!is_array($groupIds)) {
625 $groupIds = array($groupIds);
626 }
627 $dao = new CRM_Contact_DAO_GroupNesting();
628 $query = "SELECT parent_group_id FROM civicrm_group_nesting WHERE child_group_id IN (" . implode(',', $groupIds) . ")";
629 $dao->query($query);
630 $parentGroupIds = array();
631 while ($dao->fetch()) {
632 $parentGroupIds[] = $dao->parent_group_id;
633 }
634 return $parentGroupIds;
635 }
636
637 /**
638 * Returns array of group ids of descendent groups of the specified group.
639 *
5a4f6742 640 * @param array $groupIds
77c5b619 641 * An array of valid group ids (passed by reference).
6a488035 642 *
2a6da8d7 643 * @param bool $includeSelf
2b37475d 644 * @return array
364c80f1 645 * List of groupIds that represent the requested group and its descendents
6a488035 646 */
00be9182 647 public static function getDescendentGroupIds($groupIds, $includeSelf = TRUE) {
6a488035
TO
648 if (!is_array($groupIds)) {
649 $groupIds = array($groupIds);
650 }
651 $dao = new CRM_Contact_DAO_GroupNesting();
652 $query = "SELECT child_group_id, parent_group_id FROM civicrm_group_nesting WHERE parent_group_id IN (" . implode(',', $groupIds) . ")";
653 $dao->query($query);
654 $tmpGroupIds = array();
655 $childGroupIds = array();
656 if ($includeSelf) {
657 $childGroupIds = $groupIds;
658 }
659 while ($dao->fetch()) {
660 // make sure we're not following any cyclical references
661 if (!array_key_exists($dao->parent_group_id, $childGroupIds) && $dao->child_group_id != $groupIds[0]) {
662 $tmpGroupIds[] = $dao->child_group_id;
663 }
664 }
665 if (!empty($tmpGroupIds)) {
666 $newChildGroupIds = self::getDescendentGroupIds($tmpGroupIds);
667 $childGroupIds = array_merge($childGroupIds, $newChildGroupIds);
668 }
669 return $childGroupIds;
670 }
671
672 /**
673 * Returns array of descendent groups of the specified group.
674 *
5a4f6742 675 * @param array $groupIds
2b37475d 676 * An array of valid group ids
6a488035 677 *
2a6da8d7 678 * @param bool $includeSelf
2b37475d 679 * @return array
364c80f1 680 * List of descendent groups
6a488035 681 */
00be9182 682 public static function getDescendentGroups($groupIds, $includeSelf = TRUE) {
6a488035
TO
683 $groupIds = self::getDescendentGroupIds($groupIds, $includeSelf);
684 $params['id'] = $groupIds;
685 return CRM_Contact_BAO_Group::getGroups($params);
686 }
687
688 /**
689 * Returns array of group ids of valid potential child groups of the specified group.
690 *
77c5b619
TO
691 * @param $groupId
692 * The group id to get valid potential children for.
6a488035 693 *
2b37475d 694 * @return array
364c80f1 695 * List of groupIds that represent the valid potential children of the group
6a488035 696 */
00be9182 697 public static function getPotentialChildGroupIds($groupId) {
6a488035
TO
698 $groups = CRM_Contact_BAO_Group::getGroups();
699 $potentialChildGroupIds = array();
700 foreach ($groups as $group) {
701 $potentialChildGroupId = $group->id;
702 // print "Checking if $potentialChildGroupId is a descendent/ancestor of $groupId<br/><br/>";
703 if (!self::isDescendentGroup($groupId, $potentialChildGroupId) &&
704 !self::isAncestorGroup($groupId, $potentialChildGroupId) &&
705 $potentialChildGroupId != $groupId
706 ) {
707 $potentialChildGroupIds[] = $potentialChildGroupId;
708 }
709 }
710 return $potentialChildGroupIds;
711 }
712
86538308 713 /**
100fef9d
CW
714 * @param int $contactId
715 * @param int $parentGroupId
86538308
EM
716 *
717 * @return array
718 */
00be9182 719 public static function getContainingGroups($contactId, $parentGroupId) {
6a488035
TO
720 $groups = CRM_Contact_BAO_Group::getGroups();
721 $containingGroups = array();
722 foreach ($groups as $group) {
723 if (self::isDescendentGroup($parentGroupId, $group->id)) {
724 $members = CRM_Contact_BAO_Group::getMember($group->id);
725 if ($members[$contactId]) {
726 $containingGroups[] = $group->title;
727 }
728 }
729 }
730
731 return $containingGroups;
732 }
96025800 733
6a488035 734}