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