+ if (!isset($options['include_clients'])) $select_part .= ', r.rights';
+ if (isset($options['include_role'])) $select_part .= ', r.name as role_name, r.rank';
+
+ $from_part = ' from tt_users u';
+
+ $left_joins = null;
+ if (isset($options['max_rank']) || $skipClients || isset($options['include_role']))
+ $left_joins .= ' left join tt_roles r on (u.role_id = r.id)';
+
+ $where_part = " where u.org_id = $org_id and u.group_id = $group_id";
+ if (isset($options['status']))
+ $where_part .= ' and u.status = '.(int)$options['status'];
+ else
+ $where_part .= ' and u.status is not null';
+ if ($includeSelf) {
+ $where_part .= " and (u.id = $this->id || r.rank <= ".(int)$options['max_rank'].')';
+ } else {
+ if (isset($options['max_rank'])) $where_part .= ' and r.rank <= '.(int)$options['max_rank'];
+ }
+
+ $order_part = " order by upper(u.name)";
+
+ $sql = $select_part.$from_part.$left_joins.$where_part.$order_part;
+ $res = $mdb2->query($sql);
+ $user_list = array();
+ if (is_a($res, 'PEAR_Error'))
+ return false;
+
+ while ($val = $res->fetchRow()) {
+ if ($skipClients) {
+ $isClient = in_array('track_own_time', explode(',', $val['rights'])) ? 0 : 1; // Clients do not have track_own_time right.
+ if ($isClient)
+ continue; // Skip adding clients.
+ }
+ if ($include_quota) {
+ $quota = $val['quota_percent'];
+ if (ttEndsWith($quota, '.00'))
+ $quota = substr($quota, 0, strlen($quota)-3); // Trim trailing ".00";
+ elseif ($replaceDecimalMark)
+ $quota = str_replace('.', $decimal_mark, $quota);
+ $val['quota_percent'] = $quota.'%';
+ }
+ $user_list[] = $val;
+ }
+
+ if (isset($options['self_first'])) {
+ // Put own entry at the front.
+ $cnt = count($user_list);
+ for($i = 0; $i < $cnt; $i++) {
+ if ($user_list[$i]['id'] == $this->id) {
+ $self = $user_list[$i]; // Found self.
+ array_unshift($user_list, $self); // Put own entry at the front.
+ array_splice($user_list, $i+1, 1); // Remove duplicate.
+ }
+ }
+ }
+ return $user_list;
+ }
+
+ // getGroupsForDropdown obtains an array of groups to populate "Group" dropdown.
+ // It consists of:
+ // - User home group.
+ // - The entire stack of groups all the way down to current on behalf group.
+ // - All immediate children of the current on behalf group.
+ // This allows user to navigate easily to home group, anything in between, and 1 level below.
+ //
+ // Note 1: group dropdown is, by design, to be placed on all pages where "relevant",
+ // such as users.php, projects.php, tasks.php, etc. But some features may be disabled
+ // in some groups. We should check for feature availability on group change
+ // in post and redirect to feature_disabled.php when this happens.
+ // This will allow us to keep dropdown content consistent on all pages.
+ // Filtering content of the dropdown does not seem right.
+ //
+ // Note 2: Menu should display according to $user home group settings.
+ // Pages, should look according to $user->behalfGroup settings (if set).
+ // For example, if home group allows tasks, menu should display Tasks,
+ // even when we are on behalf of a subgroup without tasks.
+ //
+ // Note 3: Language of all pages should be as in $user home group even when
+ // subgroups have a different language.
+ function getGroupsForDropdown() {
+ $mdb2 = getConnection();
+
+ // Start with subgroups.
+ $groups = array();
+ $group_id = $this->getGroup();
+ $sql = "select id, name from tt_groups where org_id = $this->org_id and parent_id = $group_id and status = 1";
+ $res = $mdb2->query($sql);
+ if (!is_a($res, 'PEAR_Error')) {
+ while ($val = $res->fetchRow()) {
+ $groups[] = $val;
+ }
+ }
+
+ // Add current on behalf group to the beginning of array.
+ $selected_group_id = ($this->behalf_group_id ? $this->behalf_group_id : $this->group_id);
+ $selected_group_name = ($this->behalf_group_id ? $this->behalf_group_name : $this->group_name);
+ array_unshift($groups, array('id'=>$selected_group_id,'name'=>$selected_group_name));
+
+ // Iterate all the way to the home group, starting with selected ("on behalf") group.
+ $current_group_id = $selected_group_id;
+ while ($current_group_id != $this->group_id) {
+ $sql = "select parent_id from tt_groups where org_id = $this->org_id and id = $current_group_id and status = 1";
+ $res = $mdb2->query($sql);
+ if (is_a($res, 'PEAR_Error')) return false;
+
+ $val = $res->fetchRow();
+ $parent_id = $val['parent_id'];
+ if ($parent_id) {
+ // Get parent group name.
+ $sql = "select name from tt_groups where org_id = $this->org_id and id = $parent_id and status = 1";
+ $res = $mdb2->query($sql);
+ if (is_a($res, 'PEAR_Error')) return false;
+ $val = $res->fetchRow();
+ if (!$val) return false;
+ array_unshift($groups, array('id'=>$parent_id,'name'=>$val['name']));
+ $current_group_id = $parent_id;
+ } else {
+ return false;
+ }
+ }
+ return $groups;
+ }
+
+ // getSubgroups obtains a list of immediate subgroups.
+ function getSubgroups($group_id = null) {
+ $mdb2 = getConnection();
+
+ if (!$group_id) $group_id = $this->getGroup();
+
+ $sql = "select id, name, description from tt_groups where org_id = $this->org_id".
+ " and parent_id = $group_id and status is not null order by upper(name)";
+ $res = $mdb2->query($sql);
+ if (!is_a($res, 'PEAR_Error')) {
+ while ($val = $res->fetchRow()) {
+ $groups[] = $val;
+ }
+ }
+ return $groups;
+ }
+
+ // getUserDetails function is used to manage users in group and returns user details.
+ // At the moment, the function is used for user edits and deletes.
+ function getUserDetails($user_id) {
+ if (!$this->can('manage_users')) return false;
+
+ $mdb2 = getConnection();
+ $group_id = $this->getGroup();
+ $org_id = $this->org_id;
+
+ // Determine max rank. If we are searching in on behalf group
+ // then rank restriction does not apply.
+ $max_rank = $this->behalfGroup ? MAX_RANK : $this->rank;
+
+ $sql = "select u.id, u.name, u.login, u.role_id, u.client_id, u.status, u.rate, u.quota_percent, u.email from tt_users u".
+ " left join tt_roles r on (u.role_id = r.id)".
+ " where u.id = $user_id and u.group_id = $group_id and u.org_id = $org_id and u.status is not null".
+ " and (r.rank < $max_rank or (r.rank = $max_rank and u.id = $this->id))"; // Users with lesser roles or self.
+ $res = $mdb2->query($sql);
+ if (!is_a($res, 'PEAR_Error')) {
+ $val = $res->fetchRow();
+ return $val;
+ }