<?php


class UsersLdapHelper {

	public static function getUser($userName, $allAttrs = false) {
		$ldapUsers = array();

		$fetchAttrs = array('uid', 'apple-generateduid', 'givenName', 'uidNumber', 'cn', 'mail');// (givenName, sn) = cn

		Lib::loadClass('LDAP');
		$ldap = LDAP::getInstance();

		$filter = (false !== strpos($userName, '@'))? "(mail={$userName})" : "(uid={$userName})";
		$filter = "(&(objectClass=apple-user){$filter})";// apple-user posixAccount inetOrgPerson
		//$filter = "(&(objectClass=inetOrgPerson){$filter})";
		$attributes = array();
		$res = $ldap->search($filter, 'cn=users', $attributes);
		$entry = $ldap->first_entry($res);
		while ($entry) {
			$attrs = $ldap->get_attributes($entry);
			if(V::get('DBG_L', '', $_GET) > 0){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">attrs(' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($attrs);echo'</pre>';}
			$userObj = new stdClass();
			if ($allAttrs) {
				for ($i = 0; $i < $attrs['count']; $i++) {
					$vAttrName = $attrs[$i];
					$vAttrVal = $attrs[$vAttrName];
					if (is_array($vAttrVal) && !empty($vAttrVal)) {
						$userObj->{$vAttrName} = $vAttrVal[0];
					}
				}
			} else {
				foreach ($fetchAttrs as $vAttrName) {
					$vAttrVal = V::get($vAttrName, '', $attrs);
					if (is_array($vAttrVal) && !empty($vAttrVal)) {
						$userObj->{$vAttrName} = $vAttrVal[0];
					}
				}
			}
			$ldapUsers[] = $userObj;

			$entry = $ldap->next_entry($entry);
		}
		$ldap->free_result($res);

		return $ldapUsers;
	}

	public static function getUsersAll() {
		$allLdapUsers = array();

		$fetchAttrs = array('uid', 'apple-generateduid', 'givenName', 'uidNumber', 'cn', 'mail');// (givenName, sn) = cn

		Lib::loadClass('LDAP');
		$ldap = LDAP::getInstance();

		$filter = "(objectClass=apple-user)";// apple-user posixAccount inetOrgPerson
		$attributes = array();
		$res = $ldap->search($filter, 'cn=users', $attributes);
		$entry = $ldap->first_entry($res);
		while ($entry) {
			$attrs = $ldap->get_attributes($entry);
			$userObj = new stdClass();
			foreach ($fetchAttrs as $vAttrName) {
				$vAttrVal = V::get($vAttrName, '', $attrs);
				if (is_array($vAttrVal) && !empty($vAttrVal)) {
					$userObj->{$vAttrName} = $vAttrVal[0];
				}
			}
			$allLdapUsers[] = $userObj;

			$entry = $ldap->next_entry($entry);
		}
		$ldap->free_result($res);

		return $allLdapUsers;
	}

	public static function getUserGroups($userName, $authLDAPSubGroupDepth = 3) {
		$userLdapGroups = array();

		$fetchAttrs = array('apple-generateduid'=>'appleUID', 'gidNumber'=>'gidNumber', 'cn'=>'cn');// (givenName, sn) = cn

		Lib::loadClass('LDAP');
		$ldap = LDAP::getInstance();

		$lastLoopFound = array();
		for ($i = 0; $i <= $authLDAPSubGroupDepth; $i++) {
			$userLdapGroupsAdd = array();

			if ($i == 0) {
				$filter = "(&(objectClass=apple-group)(memberUid={$userName}))";
			} else {
				$queryOrArr = array();
				foreach ($lastLoopFound as $vAppleUid) {
					$queryOrArr[] = "apple-group-nestedgroup={$vAppleUid}";
				}
				if (!empty($queryOrArr)) {
					$queryOr = '(|(' . implode(')(', $queryOrArr) . '))';
					$filter = "(&(objectClass=apple-group){$queryOr})";
				} else {
					break;
				}
			}

			//if($DBG){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">ldap_search (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r(array('ldaprdn'=>'cn=groups,' . $ldap->getBaseDN(), 'filter'=>$filter, 'attributes'=>$attributes));echo'</pre>';}

			$attributes = array();
			$res = $ldap->search($filter, 'cn=groups', $attributes);
			if(V::get('DBG_L', '', $_GET) > 0){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">search(' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($filter);echo'</pre>';}
			$entry = $ldap->first_entry($res);
			while ($entry) {
				$attrs = $ldap->get_attributes($entry);
				if(V::get('DBG_L', '', $_GET) > 0){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">user('.$userName.') (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($attrs);echo'</pre>';}

				$groupObj = new stdClass();
				foreach ($fetchAttrs as $kAttrName => $vField) {
					$vAttrVal = V::get($kAttrName, '', $attrs);
					if (is_array($vAttrVal) && !empty($vAttrVal)) {
						$groupObj->{$vField} = $vAttrVal[0];
					}
				}

				if ($groupObj->cn && $groupObj->gidNumber) {
					$userLdapGroupsAdd[$groupObj->gidNumber] = $groupObj;
				} else {
					echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">Error: brak cn lub apple-generateduid (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($attrs);echo'</pre>';
				}

				$entry = $ldap->next_entry($entry);
			}
			$ldap->free_result($res);

			if (empty($userLdapGroupsAdd)) {
				break;
			} else {
				if(V::get('DBG_L', '', $_GET) > 0){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">userLdapGroupsAdd('.count($userLdapGroupsAdd).') (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($userLdapGroupsAdd);echo'</pre>';}
				$lastLoopFound = array();
				foreach ($userLdapGroupsAdd as $kAppleID => $vGroup) {
					$userLdapGroups[$kAppleID] = $vGroup;
					$lastLoopFound[] = $vGroup->appleUID;
				}
				//$lastLoopFound = array_keys($userLdapGroupsAdd);
			}
		}

		return $userLdapGroups;
	}

	public static function getGroupsByAppleUids($appleUids, $allAttrs = false) {
		$allLdapGroups = array();
		if (empty($appleUids)) return $allLdapGroups;

		$fetchAttrs = array('apple-generateduid'=>'appleUID', 'gidNumber'=>'gidNumber', 'cn'=>'cn');// (givenName, sn) = cn
		$fetchAttrs['apple-group-realname'] = 'realName';
		$fetchAttrs['apple-group-nestedgroup'] = 'nestedGroups';

		Lib::loadClass('LDAP');
		$ldap = LDAP::getInstance();

		$filters = array();
		foreach ($appleUids as $vAppleUid) $filters[] = "(apple-generateduid={$vAppleUid})";
		$filter = "(&(objectClass=apple-group)(|" . implode("", $filters) . "))";
		$attributes = array();
		$res = $ldap->search($filter, 'cn=groups', $attributes);
		$entry = $ldap->first_entry($res);
		while ($entry) {
			$attrs = $ldap->get_attributes($entry);

			$groupObj = new stdClass();

			if ($allAttrs) {
				for ($i = 0; $i < $attrs['count']; $i++) {
					$vAttrName = $attrs[$i];
					$vFldName = V::get($vAttrName, $vAttrName, $fetchAttrs);
					$vAttrVal = $attrs[$vAttrName];
					if (is_array($vAttrVal) && !empty($vAttrVal)) {
						if ($vAttrVal['count'] > 1) {
							$groupObj->{$vFldName} = array();
							for ($j = 0; $j < $vAttrVal['count']; $j++) {
								$groupObj->{$vFldName}[] = $vAttrVal[$j];
							}
						} else {
							$groupObj->{$vFldName} = $vAttrVal[0];
						}
					}
				}
			} else {
				foreach ($fetchAttrs as $kAttrName => $vFldName) {
					$vAttrVal = V::get($kAttrName, '', $attrs);
					if (is_array($vAttrVal) && !empty($vAttrVal)) {
						if ($vAttrVal['count'] > 1) {
							$groupObj->{$vFldName} = array();
							for ($j = 0; $j < $vAttrVal['count']; $j++) {
								$groupObj->{$vFldName}[] = $vAttrVal[$j];
							}
						} else {
							$groupObj->{$vFldName} = $vAttrVal[0];
						}
					}
				}
			}


			if ($groupObj->cn && $groupObj->appleUID) {
				$allLdapGroups[$groupObj->appleUID] = $groupObj;
			} else {
				echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">Error: brak cn lub apple-generateduid (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r(array('attrs'=>$attrs, 'groupObj'=>$groupObj));echo'</pre>';
			}

			$entry = $ldap->next_entry($entry);
		}
		$ldap->free_result($res);

		return $allLdapGroups;
	}

	public static function getGroupsByID($groupID, $allAttrs = false) {
		$allLdapGroups = array();

		$fetchAttrs = array('apple-generateduid'=>'appleUID', 'gidNumber'=>'gidNumber', 'cn'=>'cn');// (givenName, sn) = cn
		$fetchAttrs['apple-group-realname'] = 'realName';
		$fetchAttrs['apple-group-nestedgroup'] = 'nestedGroups';

		Lib::loadClass('LDAP');
		$ldap = LDAP::getInstance();

		$filter = "(&(objectClass=apple-group)(|(cn={$groupID}-*)(cn={$groupID}_*)))";
		$attributes = array();
		$res = $ldap->search($filter, 'cn=groups', $attributes);
		$entry = $ldap->first_entry($res);
		while ($entry) {
			$attrs = $ldap->get_attributes($entry);

			$groupObj = new stdClass();

			if ($allAttrs) {
				for ($i = 0; $i < $attrs['count']; $i++) {
					$vAttrName = $attrs[$i];
					$vFldName = V::get($vAttrName, $vAttrName, $fetchAttrs);
					$vAttrVal = $attrs[$vAttrName];
					if (is_array($vAttrVal) && !empty($vAttrVal)) {
						if ($vAttrVal['count'] > 1) {
							$groupObj->{$vFldName} = array();
							for ($j = 0; $j < $vAttrVal['count']; $j++) {
								$groupObj->{$vFldName}[] = $vAttrVal[$j];
							}
						} else {
							$groupObj->{$vFldName} = $vAttrVal[0];
						}
					}
				}
			} else {
				foreach ($fetchAttrs as $kAttrName => $vFldName) {
					$vAttrVal = V::get($kAttrName, '', $attrs);
					if (is_array($vAttrVal) && !empty($vAttrVal)) {
						if ($vAttrVal['count'] > 1) {
							$groupObj->{$vFldName} = array();
							for ($j = 0; $j < $vAttrVal['count']; $j++) {
								$groupObj->{$vFldName}[] = $vAttrVal[$j];
							}
						} else {
							$groupObj->{$vFldName} = $vAttrVal[0];
						}
					}
				}
			}


			if ($groupObj->cn && $groupObj->appleUID) {
				$allLdapGroups[$groupObj->appleUID] = $groupObj;
			} else {
				echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">Error: brak cn lub apple-generateduid (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r(array('attrs'=>$attrs, 'groupObj'=>$groupObj));echo'</pre>';
			}

			$entry = $ldap->next_entry($entry);
		}
		$ldap->free_result($res);

		return $allLdapGroups;
	}

	public static function getGroupsAll($allAttrs = false) {
		$allLdapGroups = array();

		$fetchAttrs = array('apple-generateduid'=>'appleUID', 'gidNumber'=>'gidNumber', 'cn'=>'cn');// (givenName, sn) = cn
		$fetchAttrs['apple-group-realname'] = 'realName';
		$fetchAttrs['apple-group-nestedgroup'] = 'nestedGroups';

		Lib::loadClass('LDAP');
		$ldap = LDAP::getInstance();

		$filter = "(objectClass=apple-group)";
		$attributes = array();
		$res = $ldap->search($filter, 'cn=groups', $attributes);
		$entry = $ldap->first_entry($res);
		while ($entry) {
			$attrs = $ldap->get_attributes($entry);

			$groupObj = new stdClass();

			if ($allAttrs) {
				for ($i = 0; $i < $attrs['count']; $i++) {
					$vAttrName = $attrs[$i];
					$vFldName = V::get($vAttrName, $vAttrName, $fetchAttrs);
					$vAttrVal = $attrs[$vAttrName];
					if (is_array($vAttrVal) && !empty($vAttrVal)) {
						if ($vAttrVal['count'] > 1) {
							$groupObj->{$vFldName} = array();
							for ($j = 0; $j < $vAttrVal['count']; $j++) {
								$groupObj->{$vFldName}[] = $vAttrVal[$j];
							}
						} else {
							$groupObj->{$vFldName} = $vAttrVal[0];
						}
					}
				}
			} else {
				foreach ($fetchAttrs as $kAttrName => $vFldName) {
					$vAttrVal = V::get($kAttrName, '', $attrs);
					if (is_array($vAttrVal) && !empty($vAttrVal)) {
						if ($vAttrVal['count'] > 1) {
							$groupObj->{$vFldName} = array();
							for ($j = 0; $j < $vAttrVal['count']; $j++) {
								$groupObj->{$vFldName}[] = $vAttrVal[$j];
							}
						} else {
							$groupObj->{$vFldName} = $vAttrVal[0];
						}
					}
				}
			}


			if ($groupObj->cn && $groupObj->appleUID) {
				$allLdapGroups[$groupObj->appleUID] = $groupObj;
			} else {
				echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">Error: brak cn lub apple-generateduid (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r(array('attrs'=>$attrs, 'groupObj'=>$groupObj));echo'</pre>';
			}

			$entry = $ldap->next_entry($entry);
		}
		$ldap->free_result($res);

		return $allLdapGroups;
	}

}
