Merge pull request #4837 from eileenmcnaughton/CRM-15779
[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
158 for (;; ) {
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 *
c490a46a
CW
280 * @param int $parentID id of the group to add the child to
281 * @param int $childID id of the new child group
fd31fa4c 282 *
6a488035 283 *
c490a46a 284 * @return void
6a488035 285 */
00be9182 286 public static function add($parentID, $childID) {
6a488035
TO
287 // TODO: Add checks here to make sure invalid nests can't be created
288 $dao = new CRM_Contact_DAO_GroupNesting();
289 $query = "REPLACE INTO civicrm_group_nesting (child_group_id, parent_group_id) VALUES ($childID,$parentID);";
290 $dao->query($query);
291 }
292
293 /**
294 * Removes a child group identified by $childGroupId from the group
295 * identified by $groupId; does not delete child group, just the
296 * association between the two
297 *
298 * @param $parentID The id of the group to remove the child from
299 * @param $childID The id of the child group being removed
300 *
301 * @return void
302 *
6a488035 303 */
00be9182 304 public static function remove($parentID, $childID) {
6a488035
TO
305 $dao = new CRM_Contact_DAO_GroupNesting();
306 $query = "DELETE FROM civicrm_group_nesting WHERE child_group_id = $childID AND parent_group_id = $parentID";
307 $dao->query($query);
308 }
309
310 /**
311 * Removes associations where a child group is identified by $childGroupId from the group
312 * identified by $groupId; does not delete child group, just the
313 * association between the two
314 *
c490a46a 315 * @param int $childID The id of the child group being removed
6a488035
TO
316 *
317 * @return void
318 *
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 *
330 * @param $parentID The parent id of the association
331 * @param $childID The child id of the association
332 *
333 * @return boolean True if association is found, false otherwise.
334 *
6a488035 335 */
00be9182 336 public static function isParentChild($parentID, $childID) {
6a488035
TO
337 $dao = new CRM_Contact_DAO_GroupNesting();
338 $query = "SELECT id FROM civicrm_group_nesting WHERE child_group_id = $childID AND parent_group_id = $parentID";
339 $dao->query($query);
340 if ($dao->fetch()) {
341 return TRUE;
342 }
343 return FALSE;
344 }
345
346 /**
347 * Returns true if if the given groupId has 1 or more child groups,
348 * false otherwise.
349 *
350 * @param $groupId The id of the group to check for child groups
351 *
352 * @return boolean True if 1 or more child groups are found, false otherwise.
353 *
6a488035 354 */
00be9182 355 public static function hasChildGroups($groupId) {
6a488035
TO
356 $dao = new CRM_Contact_DAO_GroupNesting();
357 $query = "SELECT child_group_id FROM civicrm_group_nesting WHERE parent_group_id = $groupId LIMIT 1";
358 //print $query . "\n<br><br>";
359 $dao->query($query);
360 if ($dao->fetch()) {
361 return TRUE;
362 }
363 return FALSE;
364 }
365
366 /**
367 * Returns true if the given groupId has 1 or more parent groups,
368 * false otherwise.
369 *
370 * @param $groupId The id of the group to check for parent groups
371 *
372 * @return boolean True if 1 or more parent groups are found, false otherwise.
373 *
6a488035 374 */
00be9182 375 public static function hasParentGroups($groupId) {
6a488035
TO
376 $dao = new CRM_Contact_DAO_GroupNesting();
377 $query = "SELECT parent_group_id FROM civicrm_group_nesting WHERE child_group_id = $groupId LIMIT 1";
378 $dao->query($query);
379 if ($dao->fetch()) {
380 return TRUE;
381 }
382 return FALSE;
383 }
384
385 /**
386 * Returns true if checkGroupId is a parent of one of the groups in
387 * groupIds, false otherwise.
388 *
389 * @param $groupIds Array of group ids (or one group id) to serve as the starting point
390 * @param $checkGroupId The group id to check if it is a parent of the $groupIds group(s)
391 *
392 * @return boolean True if $checkGroupId points to a group that is a parent of one of the $groupIds groups, false otherwise.
393 *
6a488035 394 */
00be9182 395 public static function isParentGroup($groupIds, $checkGroupId) {
6a488035
TO
396 if (!is_array($groupIds)) {
397 $groupIds = array($groupIds);
398 }
399 $dao = new CRM_Contact_DAO_GroupNesting();
400 $query = "SELECT parent_group_id FROM civicrm_group_nesting WHERE child_group_id IN (" . implode(',', $groupIds) . ")";
401 $dao->query($query);
402 while ($dao->fetch()) {
403 $parentGroupId = $dao->parent_group_id;
404 if ($parentGroupId == $checkGroupId) {
405 /* print "One of these: <pre>";
406 print_r($groupIds);
407 print "</pre> has groupId $checkGroupId as an ancestor.<br/>"; */
408
409 return TRUE;
410 }
411 }
412 return FALSE;
413 }
414
415 /**
416 * Returns true if checkGroupId is a child of one of the groups in
417 * groupIds, false otherwise.
418 *
419 * @param $groupIds Array of group ids (or one group id) to serve as the starting point
420 * @param $checkGroupId The group id to check if it is a child of the $groupIds group(s)
421 *
422 * @return boolean True if $checkGroupId points to a group that is a child of one of the $groupIds groups, false otherwise.
423 *
6a488035 424 */
00be9182 425 public static function isChildGroup($groupIds, $checkGroupId) {
6a488035
TO
426
427 if (!is_array($groupIds)) {
428 $groupIds = array($groupIds);
429 }
430 $dao = new CRM_Contact_DAO_GroupNesting();
431 $query = "SELECT child_group_id FROM civicrm_group_nesting WHERE parent_group_id IN (" . implode(',', $groupIds) . ")";
432 //print $query;
433 $dao->query($query);
434 while ($dao->fetch()) {
435 $childGroupId = $dao->child_group_id;
436 if ($childGroupId == $checkGroupId) {
437 /* print "One of these: <pre>";
438 print_r($groupIds);
439 print "</pre> has groupId $checkGroupId as a descendent.<br/><br/>"; */
440
441 return TRUE;
442 }
443 }
444 return FALSE;
445 }
446
447 /**
448 * Returns true if checkGroupId is an ancestor of one of the groups in
449 * groupIds, false otherwise.
450 *
451 * @param $groupIds Array of group ids (or one group id) to serve as the starting point
452 * @param $checkGroupId The group id to check if it is an ancestor of the $groupIds group(s)
453 *
454 * @return boolean True if $checkGroupId points to a group that is an ancestor of one of the $groupIds groups, false otherwise.
455 *
6a488035 456 */
00be9182 457 public static function isAncestorGroup($groupIds, $checkGroupId) {
6a488035
TO
458 if (!is_array($groupIds)) {
459 $groupIds = array($groupIds);
460 }
461 $dao = new CRM_Contact_DAO_GroupNesting();
462 $query = "SELECT parent_group_id FROM civicrm_group_nesting WHERE child_group_id IN (" . implode(',', $groupIds) . ")";
463 $dao->query($query);
464 $nextGroupIds = array();
465 $gotAtLeastOneResult = FALSE;
466 while ($dao->fetch()) {
467 $gotAtLeastOneResult = TRUE;
468 $parentGroupId = $dao->parent_group_id;
469 if ($parentGroupId == $checkGroupId) {
470 /* print "One of these: <pre>";
471 print_r($groupIds);
472 print "</pre> has groupId $checkGroupId as an ancestor.<br/>"; */
473
474 return TRUE;
475 }
476 $nextGroupIds[] = $parentGroupId;
477 }
478 if ($gotAtLeastOneResult) {
479 return self::isAncestorGroup($nextGroupIds, $checkGroupId);
480 }
481 else {
482 return FALSE;
483 }
484 }
485
486 /**
487 * Returns true if checkGroupId is a descendent of one of the groups in
488 * groupIds, false otherwise.
489 *
490 * @param $groupIds Array of group ids (or one group id) to serve as the starting point
491 * @param $checkGroupId The group id to check if it is a descendent of the $groupIds group(s)
492 *
493 * @return boolean True if $checkGroupId points to a group that is a descendent of one of the $groupIds groups, false otherwise.
494 *
6a488035 495 */
00be9182 496 public static function isDescendentGroup($groupIds, $checkGroupId) {
6a488035
TO
497 if (!is_array($groupIds)) {
498 $groupIds = array($groupIds);
499 }
500 $dao = new CRM_Contact_DAO_GroupNesting();
501 $query = "SELECT child_group_id FROM civicrm_group_nesting WHERE parent_group_id IN (" . implode(',', $groupIds) . ")";
502 $dao->query($query);
503 $nextGroupIds = array();
504 $gotAtLeastOneResult = FALSE;
505 while ($dao->fetch()) {
506 $gotAtLeastOneResult = TRUE;
507 $childGroupId = $dao->child_group_id;
508 if ($childGroupId == $checkGroupId) {
509 /* print "One of these: <pre>";
510 print_r($groupIds);
511 print "</pre> has groupId $checkGroupId as a descendent.<br/><br/>"; */
512
513 return TRUE;
514 }
515 $nextGroupIds[] = $childGroupId;
516 }
517 if ($gotAtLeastOneResult) {
518 return self::isDescendentGroup($nextGroupIds, $checkGroupId);
519 }
520 else {
521 return FALSE;
522 }
523 }
524
525 /**
526 * Returns array of group ids of ancestor groups of the specified group.
527 *
528 * @param $groupIds An array of valid group ids (passed by reference)
529 *
2a6da8d7 530 * @param bool $includeSelf
6a488035 531 *
2a6da8d7 532 * @return array $groupIdArray List of groupIds that represent the requested group and its ancestors@access public
6a488035 533 */
00be9182 534 public static function getAncestorGroupIds($groupIds, $includeSelf = TRUE) {
6a488035
TO
535 if (!is_array($groupIds)) {
536 $groupIds = array($groupIds);
537 }
538 $dao = new CRM_Contact_DAO_GroupNesting();
539 $query = "SELECT parent_group_id, child_group_id
540 FROM civicrm_group_nesting
541 WHERE child_group_id IN (" . implode(',', $groupIds) . ")";
542 $dao->query($query);
543 $tmpGroupIds = array();
544 $parentGroupIds = array();
545 if ($includeSelf) {
546 $parentGroupIds = $groupIds;
547 }
548 while ($dao->fetch()) {
549 // make sure we're not following any cyclical references
550 if (!array_key_exists($dao->child_group_id, $parentGroupIds) && $dao->parent_group_id != $groupIds[0]) {
551 $tmpGroupIds[] = $dao->parent_group_id;
552 }
553 }
554 if (!empty($tmpGroupIds)) {
555 $newParentGroupIds = self::getAncestorGroupIds($tmpGroupIds);
556 $parentGroupIds = array_merge($parentGroupIds, $newParentGroupIds);
557 }
558 return $parentGroupIds;
559 }
560
561 /**
562 * Returns array of ancestor groups of the specified group.
563 *
564 * @param $groupIds An array of valid group ids (passed by reference)
565 *
2a6da8d7
EM
566 * @param bool $includeSelf
567 * @return \An $groupArray List of ancestor groups@access public
6a488035 568 */
00be9182 569 public static function getAncestorGroups($groupIds, $includeSelf = TRUE) {
6a488035
TO
570 $groupIds = self::getAncestorGroupIds($groupIds, $includeSelf);
571 $params['id'] = $groupIds;
572 return CRM_Contact_BAO_Group::getGroups($params);
573 }
574
575 /**
576 * Returns array of group ids of child groups of the specified group.
577 *
578 * @param $groupIds An array of valid group ids (passed by reference)
579 *
2a6da8d7 580 * @return array $groupIdArray List of groupIds that represent the requested group and its children@access public
6a488035 581 */
00be9182 582 public static function getChildGroupIds($groupIds) {
6a488035
TO
583 if (!is_array($groupIds)) {
584 $groupIds = array($groupIds);
585 }
586 $dao = new CRM_Contact_DAO_GroupNesting();
587 $query = "SELECT child_group_id FROM civicrm_group_nesting WHERE parent_group_id IN (" . implode(',', $groupIds) . ")";
588 $dao->query($query);
589 $childGroupIds = array();
590 while ($dao->fetch()) {
591 $childGroupIds[] = $dao->child_group_id;
592 }
593 return $childGroupIds;
594 }
595
596 /**
597 * Returns array of group ids of parent groups of the specified group.
598 *
599 * @param $groupIds An array of valid group ids (passed by reference)
600 *
77b97be7 601 * @return array $groupIdArray List of groupIds that represent the requested group and its parents@access public
6a488035 602 */
00be9182 603 public static function getParentGroupIds($groupIds) {
6a488035
TO
604 if (!is_array($groupIds)) {
605 $groupIds = array($groupIds);
606 }
607 $dao = new CRM_Contact_DAO_GroupNesting();
608 $query = "SELECT parent_group_id FROM civicrm_group_nesting WHERE child_group_id IN (" . implode(',', $groupIds) . ")";
609 $dao->query($query);
610 $parentGroupIds = array();
611 while ($dao->fetch()) {
612 $parentGroupIds[] = $dao->parent_group_id;
613 }
614 return $parentGroupIds;
615 }
616
617 /**
618 * Returns array of group ids of descendent groups of the specified group.
619 *
620 * @param $groupIds An array of valid group ids (passed by reference)
621 *
2a6da8d7
EM
622 * @param bool $includeSelf
623 * @return array $groupIdArray List of groupIds that represent the requested group and its descendents@access public
6a488035 624 */
00be9182 625 public static function getDescendentGroupIds($groupIds, $includeSelf = TRUE) {
6a488035
TO
626 if (!is_array($groupIds)) {
627 $groupIds = array($groupIds);
628 }
629 $dao = new CRM_Contact_DAO_GroupNesting();
630 $query = "SELECT child_group_id, parent_group_id FROM civicrm_group_nesting WHERE parent_group_id IN (" . implode(',', $groupIds) . ")";
631 $dao->query($query);
632 $tmpGroupIds = array();
633 $childGroupIds = array();
634 if ($includeSelf) {
635 $childGroupIds = $groupIds;
636 }
637 while ($dao->fetch()) {
638 // make sure we're not following any cyclical references
639 if (!array_key_exists($dao->parent_group_id, $childGroupIds) && $dao->child_group_id != $groupIds[0]) {
640 $tmpGroupIds[] = $dao->child_group_id;
641 }
642 }
643 if (!empty($tmpGroupIds)) {
644 $newChildGroupIds = self::getDescendentGroupIds($tmpGroupIds);
645 $childGroupIds = array_merge($childGroupIds, $newChildGroupIds);
646 }
647 return $childGroupIds;
648 }
649
650 /**
651 * Returns array of descendent groups of the specified group.
652 *
653 * @param $groupIds An array of valid group ids (passed by reference)
654 *
2a6da8d7
EM
655 * @param bool $includeSelf
656 * @return \An $groupArray List of descendent groups@access public
6a488035 657 */
00be9182 658 public static function getDescendentGroups($groupIds, $includeSelf = TRUE) {
6a488035
TO
659 $groupIds = self::getDescendentGroupIds($groupIds, $includeSelf);
660 $params['id'] = $groupIds;
661 return CRM_Contact_BAO_Group::getGroups($params);
662 }
663
664 /**
665 * Returns array of group ids of valid potential child groups of the specified group.
666 *
667 * @param $groupId The group id to get valid potential children for
668 *
2a6da8d7 669 * @return array $groupIdArray List of groupIds that represent the valid potential children of the group@access public
6a488035 670 */
00be9182 671 public static function getPotentialChildGroupIds($groupId) {
6a488035
TO
672 $groups = CRM_Contact_BAO_Group::getGroups();
673 $potentialChildGroupIds = array();
674 foreach ($groups as $group) {
675 $potentialChildGroupId = $group->id;
676 // print "Checking if $potentialChildGroupId is a descendent/ancestor of $groupId<br/><br/>";
677 if (!self::isDescendentGroup($groupId, $potentialChildGroupId) &&
678 !self::isAncestorGroup($groupId, $potentialChildGroupId) &&
679 $potentialChildGroupId != $groupId
680 ) {
681 $potentialChildGroupIds[] = $potentialChildGroupId;
682 }
683 }
684 return $potentialChildGroupIds;
685 }
686
86538308 687 /**
100fef9d
CW
688 * @param int $contactId
689 * @param int $parentGroupId
86538308
EM
690 *
691 * @return array
692 */
00be9182 693 public static function getContainingGroups($contactId, $parentGroupId) {
6a488035
TO
694 $groups = CRM_Contact_BAO_Group::getGroups();
695 $containingGroups = array();
696 foreach ($groups as $group) {
697 if (self::isDescendentGroup($parentGroupId, $group->id)) {
698 $members = CRM_Contact_BAO_Group::getMember($group->id);
699 if ($members[$contactId]) {
700 $containingGroups[] = $group->title;
701 }
702 }
703 }
704
705 return $containingGroups;
706 }
707}