// Gets department ID for AD user. If department doesn't exist, creates a new one. Returns FALSE if there should be no department set.
// returns array:
// 'ID' - department id
// 'IS_HEAD' - true if this user is head of the department, false if not
function GetDepartmentIdForADUser($department, $managerDN, $username, &$cache=FALSE, $iblockId = FALSE, $names = FALSE)
{
global $APPLICATION;
// check for loops in manager structure, if loop is found - quit
// should be done before cache lookup
if ($names && isset($names[$username]))
return false;
// if department id for this user is already stored in cache
if ($cache)
{
$departmentCached = $cache[$username];
// if user was not set as head earlier, then do not get his id from cache
if ($departmentCached)
return $departmentCached;
}
// if it is a first call in recursive chain
if (!$iblockId)
{
// check module inclusions
if (!IsModuleInstalled('intranet') || !CModule::IncludeModule('iblock'))
return false;
// get structure's iblock id
$iblockId=COption::GetOptionInt("intranet", "iblock_structure", false, false);
if (!$iblockId)
return false;
$names = array();
}
// save current username as already visited
$names[$username] = true;
// manager's department ID
$managerDepId = false;
// if there's a manager - query it
if ($managerDN)
{
$user = substr($managerDN, 0, strpos($managerDN, ','));
$userArr = $this->GetUserArray($user);
if (count($userArr)>0)
{
// contents of userArr are already in local encoding, no need for conversion here
$mgrDepartment = $userArr[0][$this->arFields['USER_DEPARTMENT_ATTR']];
if ($mgrDepartment && trim($mgrDepartment)!='')
{
// if manager's department name is set - then get it's id
$mgrManagerDN = $userArr[0][$this->arFields['USER_MANAGER_ATTR']];
$mgrUserName = $userArr[0][$this->arFields['USER_ID_ATTR']];
$arManagerDep = $this->GetDepartmentIdForADUser($mgrDepartment, $mgrManagerDN, $mgrUserName, $cache, $iblockId, $names);
// fill in cache
if ($cache && $arManagerDep)
$cache[$mgrUserName] = $arManagerDep;
}
}
}
// prepare result and create department (if needed)
$arResult = array('IS_HEAD'=>true); // by default, thinking of user as a head of the department
if ($arManagerDep)
{ // if got manager's data correctly
if ($department && trim($department)!='' && ($mgrDepartment!=$department))
{ // if our department is set && differs from manager's, set manager's as parent
$parentSectionId = $arManagerDep['ID'];
}
else
{
// - if user has no department, but somehow have manager - then he is assumed to be in manager's department
// - if user has same department name as manager - then he is not head
// here we can return manager's department id immediately
$arResult = $arManagerDep;
$arResult['IS_HEAD'] = false;
return $arResult;
}
}
else
{
// if there's no manager's data
if ($department && trim($department)!='')
$parentSectionId = $this->arFields['ROOT_DEPARTMENT'];
else
{
// if have no manager's department and no own department:
// - use default as our department and root as parent section if default is set
// - or just root if default has empty value
// - or return false, if setting of default department is turned off
if ($this->arFields['STRUCT_HAVE_DEFAULT'] && $this->arFields['STRUCT_HAVE_DEFAULT'] == "Y")
{
// if can use default department
$department = $this->arFields['DEFAULT_DEPARTMENT_NAME'];
if ($department && trim($department)!='')
{
// if department is not empty
$parentSectionId = $this->arFields['ROOT_DEPARTMENT'];
}
else
{
// if it is empty - return parent
return array('ID' => $this->arFields['ROOT_DEPARTMENT']);
}
}
else
{
// if have no department in AD and no default - then do not set a department
return false;
}
}
}
// 3. if there's no department set for this user, this means there was no default department name (which substituted in *) - then there's no need to set department id for this user at all
if (!$department || trim($department)=='')
return false;
// 4. detect this user's department ID, using parent id and department name string, which we certainly have now (these 2 parameters are required to get an ID)
// see if this department already exists
$bs = new CIBlockSection();
$dbExistingSections = GetIBlockSectionList(
$iblockId,
($parentSectionId >= 0 ? $parentSectionId : false),
$arOrder = Array("left_margin" => "asc"),
$cnt = 0,
$arFilter = Array('NAME' => $department)
);
$departmentId = false;
if($arItem = $dbExistingSections->GetNext())
$departmentId = $arItem['ID'];
if (!$departmentId)
{
//create new department
$arNewSectFields = Array(
"ACTIVE" => "Y",
"IBLOCK_ID" => $iblockId,
"NAME" => $department
);
if ($parentSectionId>=0)
$arNewSectFields["IBLOCK_SECTION_ID"] = $parentSectionId;
// and get it's Id
$departmentId = $bs->Add($arNewSectFields);
}
$arElement = $GLOBALS["USER_FIELD_MANAGER"]->GetUserFields(
'IBLOCK_'.$iblockId.'_SECTION',
$departmentId
);
// if the head of the department is already set, do not change it
if (!empty($arElement['UF_HEAD']['VALUE']))
$arResult['IS_HEAD'] = false;
$arResult['ID'] = $departmentId;
return $arResult;
}