CRM-15495 - Improve entityRef contact_type filter
[civicrm-core.git] / CRM / Contact / BAO / Group.php
index 97cdd214a245c919fcff9e3efb01c77520f19177..cb56c7317810f0a19796b42644888945718499d7 100644 (file)
@@ -1,9 +1,9 @@
 <?php
 /*
   +--------------------------------------------------------------------+
-  | CiviCRM version 4.4                                                |
+  | CiviCRM version 4.6                                                |
   +--------------------------------------------------------------------+
-  | Copyright CiviCRM LLC (c) 2004-2013                                |
+  | Copyright CiviCRM LLC (c) 2004-2014                                |
   +--------------------------------------------------------------------+
   | This file is a part of CiviCRM.                                    |
   |                                                                    |
 /**
  *
  * @package CRM
- * @copyright CiviCRM LLC (c) 2004-2013
+ * @copyright CiviCRM LLC (c) 2004-2014
  * $Id$
  *
  */
 class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group {
 
   /**
-   * class constructor
+   * Class constructor
    */
-  function __construct() {
+  public function __construct() {
     parent::__construct();
   }
 
@@ -51,11 +51,10 @@ class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group {
    * @param array $params   (reference ) an assoc array of name/value pairs
    * @param array $defaults (reference ) an assoc array to hold the flattened values
    *
-   * @return object CRM_Contact_BAO_Group object
-   * @access public
+   * @return CRM_Contact_BAO_Group object
    * @static
    */
-  static function retrieve(&$params, &$defaults) {
+  public static function retrieve(&$params, &$defaults) {
     $group = new CRM_Contact_DAO_Group();
     $group->copyValues($params);
     if ($group->find(TRUE)) {
@@ -67,17 +66,16 @@ class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group {
   }
 
   /**
-   * Function to delete the group and all the object that connect to
+   * Delete the group and all the object that connect to
    * this group. Incredibly destructive
    *
    * @param int $id group id
    *
    * @return null
-   * @access public
    * @static
    *
    */
-  static function discard($id) {
+  public static function discard($id) {
     CRM_Utils_Hook::pre('delete', 'Group', $id, CRM_Core_DAO::$_nullArray);
 
     $transaction = new CRM_Core_Transaction();
@@ -121,7 +119,7 @@ class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group {
         'is_enabled'
       )) {
       // clear any descendant groups cache if exists
-      $finalGroups = CRM_Core_BAO_Cache::deleteGroup('descendant groups for an org');
+      CRM_Core_BAO_Cache::deleteGroup('descendant groups for an org');
     }
 
     // delete from group table
@@ -145,7 +143,7 @@ class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group {
    * Returns an array of the contacts in the given group.
    *
    */
-  static function getGroupContacts($id) {
+  public static function getGroupContacts($id) {
     $params = array(array('group', 'IN', array($id => 1), 0, 0));
     list($contacts, $_) = CRM_Contact_BAO_Query::apiQuery($params, array('contact_id'));
     return $contacts;
@@ -154,13 +152,14 @@ class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group {
   /**
    * Get the count of a members in a group with the specific status
    *
-   * @param int $id      group id
-   * @param enum $status status of members in group
+   * @param int $id group id
+   * @param enum|string $status status of members in group
+   *
+   * @param bool $countChildGroups
    *
    * @return int count of members in the group with above status
-   * @access public
    */
-  static function memberCount($id, $status = 'Added', $countChildGroups = FALSE) {
+  public static function memberCount($id, $status = 'Added', $countChildGroups = FALSE) {
     $groupContact = new CRM_Contact_DAO_GroupContact();
     $groupIds = array($id);
     if ($countChildGroups) {
@@ -199,13 +198,13 @@ class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group {
   /**
    * Get the list of member for a group id
    *
-   * @param int $lngGroupId this is group id
+   * @param int $groupID
+   * @param bool $useCache
    *
-   * @return array $aMembers this arrray contains the list of members for this group id
-   * @access public
+   * @return array $aMembers this array contains the list of members for this group id
    * @static
    */
-  static function &getMember($groupID, $useCache = TRUE) {
+  public static function &getMember($groupID, $useCache = TRUE) {
     $params = array(array('group', 'IN', array($groupID => 1), 0, 0));
     $returnProperties = array('contact_id');
     list($contacts, $_) = CRM_Contact_BAO_Query::apiQuery($params, $returnProperties, NULL, NULL, 0, 0, $useCache);
@@ -221,14 +220,16 @@ class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group {
   /**
    * Returns array of group object(s) matching a set of one or Group properties.
    *
-   * @param array       $param             Array of one or more valid property_name=>value pairs.
-   *                                       Limits the set of groups returned.
-   * @param array       $returnProperties  Which properties should be included in the returned group objects.
+   * @param array $params Limits the set of groups returned.
+   * @param array $returnProperties Which properties should be included in the returned group objects.
    *                                       (member_count should be last element.)
    *
-   * @return  An array of group objects.
+   * @param null $sort
+   * @param null $offset
+   * @param null $rowCount
+   *
+   * @return array of group objects.
    *
-   * @access public
    *
    * @todo other BAO functions that use returnProperties (e.g. Query Objects) receive the array flipped & filled with 1s and
    * add in essential fields (e.g. id). This should follow a regular pattern like the others
@@ -297,15 +298,14 @@ class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group {
   }
 
   /**
-   * make sure that the user has permission to access this group
+   * Make sure that the user has permission to access this group
    *
    * @param int $id   the id of the object
    *
    * @return string   the permission that the user has (or null)
-   * @access public
    * @static
    */
-  static function checkPermission($id) {
+  public static function checkPermission($id) {
     $allGroups = CRM_Core_PseudoConstant::allGroup();
 
     $permissions = NULL;
@@ -341,7 +341,6 @@ class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group {
    * @param array $params     Associative array of parameters
    *
    * @return object|null      The new group BAO (if created)
-   * @access public
    * @static
    */
   public static function &create(&$params) {
@@ -497,10 +496,10 @@ class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group {
   }
 
   /**
-   * given a saved search compute the clause and the tables
+   * Given a saved search compute the clause and the tables
    * and store it for future use
    */
-  function buildClause() {
+  public function buildClause() {
     $params = array(array('group', 'IN', array($this->id => 1), 0, 0));
 
     if (!empty($params)) {
@@ -523,7 +522,6 @@ class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group {
    * @param array $params     Associative array of parameters
    *
    * @return object|null      The new group BAO (if created)
-   * @access public
    * @static
    */
   public static function createSmartGroup(&$params) {
@@ -546,7 +544,7 @@ class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group {
   }
 
   /**
-   * update the is_active flag in the db
+   * Update the is_active flag in the db
    *
    * @param int      $id        id of the database record
    * @param boolean  $isActive  value we want to set the is_active field
@@ -554,20 +552,20 @@ class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group {
    * @return Object             DAO object on sucess, null otherwise
    * @static
    */
-  static function setIsActive($id, $isActive) {
+  public static function setIsActive($id, $isActive) {
     return CRM_Core_DAO::setFieldValue('CRM_Contact_DAO_Group', $id, 'is_active', $isActive);
   }
 
   /**
-   * build the condition to retrieve groups.
+   * Build the condition to retrieve groups.
    *
-   * @param string  $groupType type of group(Access/Mailing) OR the key of the group
-   * @param boolen  $excludeHidden exclude hidden groups.
+   * @param string $groupType type of group(Access/Mailing) OR the key of the group
+   * @param bool|\boolen $excludeHidden exclude hidden groups.
    *
    * @return string $condition
    * @static
    */
-  static function groupTypeCondition($groupType = NULL, $excludeHidden = TRUE) {
+  public static function groupTypeCondition($groupType = NULL, $excludeHidden = TRUE) {
     $value = NULL;
     if ($groupType == 'Mailing') {
       $value = CRM_Core_DAO::VALUE_SEPARATOR . '2' . CRM_Core_DAO::VALUE_SEPARATOR;
@@ -597,6 +595,35 @@ class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group {
     return $condition;
   }
 
+  /**
+   * Get permission relevant clauses
+   * CRM-12209
+   *
+   * @param bool $force
+   *
+   * @return array
+   */
+  public static function getPermissionClause($force = FALSE) {
+    static $clause = 1;
+    static $retrieved = FALSE;
+    if ((!$retrieved || $force ) && !CRM_Core_Permission::check('view all contacts') && !CRM_Core_Permission::check('edit all contacts')) {
+      //get the allowed groups for the current user
+      $groups = CRM_ACL_API::group(CRM_ACL_API::VIEW);
+      if (!empty($groups)) {
+        $groupList = implode(', ', array_values($groups));
+        $clause = "groups.id IN ( $groupList ) ";
+      }
+      else {
+        $clause = '1 = 0';
+      }
+    }
+    $retrieved = TRUE;
+    return $clause;
+  }
+
+  /**
+   * @return string
+   */
   public function __toString() {
     return $this->title;
   }
@@ -608,10 +635,9 @@ class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group {
    * @param  array $params ( reference ) an assoc array of name/value pairs
    *
    * @return array ( smartGroupId, ssId ) smart group id and saved search id
-   * @access public
    * @static
    */
-  static function createHiddenSmartGroup($params) {
+  public static function createHiddenSmartGroup($params) {
     $ssId = CRM_Utils_Array::value('saved_search_id', $params);
 
     //add mapping record only for search builder saved search
@@ -682,7 +708,6 @@ class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group {
    *  -page= offset
    *  @todo there seems little reason for the small number of functions that call this to pass in
    *  params that then need to be translated in this function since they are coding them when calling
-   * @access public
    */
   static public function getGroupListSelector(&$params) {
     // format the params
@@ -707,8 +732,8 @@ class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group {
     if (!empty($groups)) {
       foreach ($groups as $id => $value) {
         $groupList[$id]['group_id'] = $value['id'];
+        $groupList[$id]['count'] = $value['count'];
         $groupList[$id]['group_name'] = $value['title'];
-        $groupList[$id]['class'] = implode(' ', $value['class']);
 
         // append parent names if in search mode
         if (empty($params['parent_id']) && !empty($value['parents'])) {
@@ -718,8 +743,10 @@ class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group {
             $title[] = $allGroups[$gId];
           }
           $groupList[$id]['group_name'] .= '<div class="crm-row-parent-name"><em>'.ts('Child of').'</em>: ' . implode(', ', $title) . '</div>';
-          $groupList[$id]['class'] = in_array('disabled', $value['class']) ? 'disabled' : '';
+          $value['class'] = array_diff($value['class'], array('crm-row-parent'));
         }
+        $value['class'][] = 'crm-entity';
+        $groupList[$id]['class'] = $value['id'] . ',' . implode(' ', $value['class']);
 
         $groupList[$id]['group_description'] = CRM_Utils_Array::value('description', $value);
         if (!empty($value['group_type'])) {
@@ -742,10 +769,11 @@ class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group {
   /**
    * This function to get list of groups
    *
-   * @param  array   $params associated array for params
-   * @access public
+   * @param  array $params associated array for params
+   *
+   * @return array
    */
-  static function getGroupList(&$params) {
+  public static function getGroupList(&$params) {
     $config = CRM_Core_Config::singleton();
 
     $whereClause = self::whereClause($params, FALSE);
@@ -786,10 +814,11 @@ class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group {
     $query = "
         SELECT groups.*, createdBy.sort_name as created_by {$select}
         FROM  civicrm_group groups
-              LEFT JOIN civicrm_contact createdBy
-                     ON createdBy.id = groups.created_id
-              {$from}
+        LEFT JOIN civicrm_contact createdBy
+          ON createdBy.id = groups.created_id
+        {$from}
         WHERE $whereClause {$where}
+        GROUP BY groups.id
         {$orderBy}
         {$limit}";
 
@@ -809,7 +838,7 @@ class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group {
     $links = self::actionLinks();
 
     $allTypes = CRM_Core_OptionGroup::values('group_type');
-    $values = array();
+    $values = $groupsToCount = array();
 
     $visibility = CRM_Core_SelectValues::ufVisibility();
 
@@ -821,7 +850,10 @@ class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group {
 
       if ($permission) {
         $newLinks = $links;
-        $values[$object->id] = array('class' => array());
+        $values[$object->id] = array(
+          'class' => array(),
+          'count' => '0',
+        );
         CRM_Core_DAO::storeValues($object, $values[$object->id]);
         if ($object->saved_search_id) {
           $values[$object->id]['title'] .= ' (' . ts('Smart Group') . ')';
@@ -865,6 +897,8 @@ class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group {
 
         $values[$object->id]['visibility'] = $visibility[$values[$object->id]['visibility']];
 
+        $groupsToCount[$object->saved_search_id ? 'civicrm_group_contact_cache' : 'civicrm_group_contact'][] = $object->id;
+
         if (isset($values[$object->id]['group_type'])) {
           $groupTypes = explode(CRM_Core_DAO::VALUE_SEPARATOR,
             substr($values[$object->id]['group_type'], 1, -1)
@@ -919,124 +953,161 @@ class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group {
       }
     }
 
+    // Get group counts
+    foreach ($groupsToCount as $table => $groups) {
+      $where = "group_id IN (" . implode(',', $groups) . ")";
+      if ($table == 'civicrm_group_contact') {
+        $where .= " AND status = 'Added'";
+      }
+      $dao = CRM_Core_DAO::executeQuery("SELECT group_id, COUNT(id) as `count` FROM $table WHERE $where GROUP BY group_id");
+      while($dao->fetch()) {
+        $values[$dao->group_id]['count'] = $dao->count;
+      }
+    }
+
     return $values;
   }
 
   /**
    * This function to get hierarchical list of groups (parent followed by children)
    *
-   * @param  array   $groupIDs array of group ids
+   * @param  array $groupIDs array of group ids
+   *
+   * @param null $parents
+   * @param string $spacer
+   * @param bool $titleOnly
    *
-   * @access public
+   * @return array
    */
-  static function getGroupsHierarchy (
+  static function getGroupsHierarchy(
     $groupIDs,
-    $parents  = NULL,
+    $parents = NULL,
     $spacer = '<span class="child-indent"></span>',
     $titleOnly = FALSE
-   ) {
+  ) {
     if (empty($groupIDs)) {
       return array();
     }
 
     $groupIdString = '(' . implode(',', array_keys($groupIDs)) . ')';
-     // <span class="child-icon"></span>
-     // need to return id, title (w/ spacer), description, visibility
-
-     // We need to build a list of tags ordered by hierarchy and sorted by
-     // name. The heirarchy will be communicated by an accumulation of
-     // separators in front of the name to give it a visual offset.
-     // Instead of recursively making mysql queries, we'll make one big
-     // query and build the heirarchy with the algorithm below.
-     $groups = array();
-     $args = array(1 => array($groupIdString, 'String'));
-     $query = "
+    // <span class="child-icon"></span>
+    // need to return id, title (w/ spacer), description, visibility
+
+    // We need to build a list of tags ordered by hierarchy and sorted by
+    // name. The heirarchy will be communicated by an accumulation of
+    // separators in front of the name to give it a visual offset.
+    // Instead of recursively making mysql queries, we'll make one big
+    // query and build the heirarchy with the algorithm below.
+    $groups = array();
+    $args = array(1 => array($groupIdString, 'String'));
+    $query = "
 SELECT id, title, description, visibility, parents
 FROM   civicrm_group
 WHERE  id IN $groupIdString
 ";
-     if ($parents) {
-       // group can have > 1 parent so parents may be comma separated list (eg. '1,2,5'). We just grab and match on 1st parent.
-       $parentArray = explode(',', $parents);
-       $parent = $parentArray[0];
-       $args[2] = array($parent, 'Integer');
-       $query .= " AND SUBSTRING_INDEX(parents, ',', 1) = %2";
-     }
-     $query .= " ORDER BY title";
-     $dao = CRM_Core_DAO::executeQuery($query, $args);
-
-     // Sort the groups into the correct storage by the parent
-     // $roots represent the current leaf nodes that need to be checked for
-     // children. $rows represent the unplaced nodes
-     $roots = $rows = $allGroups = array();
-     while ($dao->fetch()) {
-       $allGroups[$dao->id] = array('title' => $dao->title,
-                                    'visibility' => $dao->visibility,
-                                    'description' => $dao->description);
-
-       if ($dao->parents == $parents) {
-         $roots[] = array('id' => $dao->id,
-                          'prefix' => '',
-                          'title' => $dao->title);
-       }
-       else {
-         // group can have > 1 parent so $dao->parents may be comma separated list (eg. '1,2,5'). Grab and match on 1st parent.
-         $parentArray = explode(',', $dao->parents);
-         $parent = $parentArray[0];
-         $rows[] = array('id' => $dao->id,
-                          'prefix' => '',
-                          'title' => $dao->title,
-                          'parents' => $parent);
-       }
-     }
-     $dao->free();
-     // While we have nodes left to build, shift the first (alphabetically)
-     // node of the list, place it in our groups list and loop through the
-     // list of unplaced nodes to find its children. We make a copy to
-     // iterate through because we must modify the unplaced nodes list
-     // during the loop.
-     while (count($roots)) {
-       $new_roots         = array();
-       $current_rows      = $rows;
-       $root              = array_shift($roots);
-       $groups[$root['id']] = array($root['prefix'], $root['title']);
-
-       // As you find the children, append them to the end of the new set
-       // of roots (maintain alphabetical ordering). Also remove the node
-       // from the set of unplaced nodes.
-       if (is_array($current_rows)) {
-         foreach ($current_rows as $key => $row) {
-           if ($row['parents'] == $root['id']) {
-             $new_roots[] = array('id' => $row['id'], 'prefix' => $groups[$root['id']][0] . $spacer, 'title' => $row['title']);
-             unset($rows[$key]);
-           }
-         }
-       }
-
-       //As a group, insert the new roots into the beginning of the roots
-       //list. This maintains the hierarchical ordering of the tags.
-       $roots = array_merge($new_roots, $roots);
-     }
-
-     // Prefix titles with the calcuated spacing to give the visual
-     // appearance of ordering when transformed into HTML in the form layer. Add description and visibility.
-     $groupsReturn = array();
-     foreach ($groups as $key=>$value) {
-       if ($titleOnly) {
-         $groupsReturn[$key] = $value[0] . $value[1];
-       } else {
-         $groupsReturn[$key] = array(
-           'title' => $value[0] . $value[1],
-           'description' => $allGroups[$key]['description'],
-           'visibility' => $allGroups[$key]['visibility'],
-         );
-       }
-     }
-
-     return $groupsReturn;
+    if ($parents) {
+      // group can have > 1 parent so parents may be comma separated list (eg. '1,2,5'). We just grab and match on 1st parent.
+      $parentArray = explode(',', $parents);
+      $parent = $parentArray[0];
+      $args[2] = array($parent, 'Integer');
+      $query .= " AND SUBSTRING_INDEX(parents, ',', 1) = %2";
+    }
+    $query .= " ORDER BY title";
+    $dao = CRM_Core_DAO::executeQuery($query, $args);
+
+    // Sort the groups into the correct storage by the parent
+    // $roots represent the current leaf nodes that need to be checked for
+    // children. $rows represent the unplaced nodes
+    $roots = $rows = $allGroups = array();
+    while ($dao->fetch()) {
+      $allGroups[$dao->id] = array(
+        'title' => $dao->title,
+        'visibility' => $dao->visibility,
+        'description' => $dao->description
+      );
+
+      if ($dao->parents == $parents) {
+        $roots[] = array(
+          'id' => $dao->id,
+          'prefix' => '',
+          'title' => $dao->title
+        );
+      }
+      else {
+        // group can have > 1 parent so $dao->parents may be comma separated list (eg. '1,2,5'). Grab and match on 1st parent.
+        $parentArray = explode(',', $dao->parents);
+        $parent = $parentArray[0];
+        $rows[] = array(
+          'id' => $dao->id,
+          'prefix' => '',
+          'title' => $dao->title,
+          'parents' => $parent
+        );
+      }
+    }
+    $dao->free();
+    // While we have nodes left to build, shift the first (alphabetically)
+    // node of the list, place it in our groups list and loop through the
+    // list of unplaced nodes to find its children. We make a copy to
+    // iterate through because we must modify the unplaced nodes list
+    // during the loop.
+    while (count($roots)) {
+      $new_roots = array();
+      $current_rows = $rows;
+      $root = array_shift($roots);
+      $groups[$root['id']] = array($root['prefix'], $root['title']);
+
+      // As you find the children, append them to the end of the new set
+      // of roots (maintain alphabetical ordering). Also remove the node
+      // from the set of unplaced nodes.
+      if (is_array($current_rows)) {
+        foreach ($current_rows as $key => $row) {
+          if ($row['parents'] == $root['id']) {
+            $new_roots[] = array(
+              'id' => $row['id'],
+              'prefix' => $groups[$root['id']][0] . $spacer,
+              'title' => $row['title']
+            );
+            unset($rows[$key]);
+          }
+        }
+      }
+
+      //As a group, insert the new roots into the beginning of the roots
+      //list. This maintains the hierarchical ordering of the tags.
+      $roots = array_merge($new_roots, $roots);
+    }
+
+    // below is the redundant looping to ensure child groups are populated in the case where user does not have
+    // access to parent groups ( esp. using ACL permissions and logged in user can assess only child groups )
+    foreach ($rows as $value) {
+      $groups[$value['id']] = array($value['prefix'], $value['title']);
+    }
+    // Prefix titles with the calcuated spacing to give the visual
+    // appearance of ordering when transformed into HTML in the form layer. Add description and visibility.
+    $groupsReturn = array();
+    foreach ($groups as $key => $value) {
+      if ($titleOnly) {
+        $groupsReturn[$key] = $value[0] . $value[1];
+      }
+      else {
+        $groupsReturn[$key] = array(
+          'title' => $value[0] . $value[1],
+          'description' => $allGroups[$key]['description'],
+          'visibility' => $allGroups[$key]['visibility'],
+        );
+      }
+    }
+
+    return $groupsReturn;
   }
 
-  static function getGroupCount(&$params) {
+  /**
+   * @param array $params
+   *
+   * @return null|string
+   */
+  public static function getGroupCount(&$params) {
     $whereClause = self::whereClause($params, FALSE);
     $query = "SELECT COUNT(*) FROM civicrm_group groups";
 
@@ -1050,10 +1121,16 @@ WHERE {$whereClause}";
     return CRM_Core_DAO::singleValueQuery($query, $params);
   }
 
-  static function whereClause(&$params, $sortBy = TRUE, $excludeHidden = TRUE) {
+  /**
+   * Generate permissioned where clause for group search
+   * @param array $params
+   * @param bool $sortBy
+   * @param bool $excludeHidden
+   *
+   * @return string
+   */
+  public static function whereClause(&$params, $sortBy = TRUE, $excludeHidden = TRUE) {
     $values = array();
-    $clauses = array();
-
     $title = CRM_Utils_Array::value('title', $params);
     if ($title) {
       $clauses[] = "groups.title LIKE %1";
@@ -1122,27 +1199,6 @@ WHERE {$whereClause}";
       }
     }
 
-    /*
-      if ( $sortBy &&
-      $this->_sortByCharacter !== null ) {
-      $clauses[] =
-      "groups.title LIKE '" .
-      strtolower(CRM_Core_DAO::escapeWildCardString($this->_sortByCharacter)) .
-      "%'";
-      }
-
-      // dont do a the below assignement when doing a
-      // AtoZ pager clause
-      if ( $sortBy ) {
-      if ( count( $clauses ) > 1 ) {
-      $this->assign( 'isSearch', 1 );
-      } else {
-      $this->assign( 'isSearch', 0 );
-      }
-      }
-    */
-
-
     if (empty($clauses)) {
       $clauses[] = 'groups.is_active = 1';
     }
@@ -1150,26 +1206,19 @@ WHERE {$whereClause}";
     if ($excludeHidden) {
       $clauses[] = 'groups.is_hidden = 0';
     }
-    //CRM-12209
-    if (!CRM_Core_Permission::check('view all contacts')) {
-      //get the allowed groups for the current user
-      $groups = CRM_ACL_API::group(CRM_ACL_API::VIEW);
-      if (!empty( $groups)) {
-        $groupList = implode( ', ', array_values( $groups ) );
-        $clauses[] = "groups.id IN ( $groupList ) ";
-      }
-    }
+    ;
+    $clauses[] = self::getPermissionClause();
+
 
     return implode(' AND ', $clauses);
   }
 
   /**
-   * Function to define action links
+   * Define action links
    *
    * @return array $links array of action links
-   * @access public
    */
-  static function actionLinks() {
+  public static function actionLinks() {
     $links = array(
       CRM_Core_Action::VIEW => array(
         'name' => ts('Contacts'),
@@ -1204,7 +1253,13 @@ WHERE {$whereClause}";
     return $links;
   }
 
-  function pagerAtoZ($whereClause, $whereParams) {
+  /**
+   * @param $whereClause
+   * @param array $whereParams
+   *
+   * @return string
+   */
+  public function pagerAtoZ($whereClause, $whereParams) {
     $query = "
         SELECT DISTINCT UPPER(LEFT(groups.title, 1)) as sort_name
         FROM  civicrm_group groups
@@ -1216,4 +1271,3 @@ WHERE {$whereClause}";
     return CRM_Utils_PagerAToZ::getAToZBar($dao, $this->_sortByCharacter, TRUE);
   }
 }
-