X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=gosa-core%2Finclude%2Fclass_listing.inc;h=e2bdb9a44a2d7e608db8d888dbf9cc66f59bea41;hb=fdc518a8263e1cf9d6c6dd76970e60a0e5e21924;hp=aab36da186b2f8e805b98d1b6f35506071b507a9;hpb=26f16620dc7257018c358e1317db4c2fe415cbbe;p=gosa.git diff --git a/gosa-core/include/class_listing.inc b/gosa-core/include/class_listing.inc index aab36da18..e2bdb9a44 100644 --- a/gosa-core/include/class_listing.inc +++ b/gosa-core/include/class_listing.inc @@ -1,22 +1,114 @@ pid= preg_replace("/[^0-9]/", "", microtime(TRUE)); + if (!$this->load($filename)) { die("Cannot parse $filename!"); } + + // Set base for filter + $this->base= session::global_get("CurrentMainBase"); + if ($this->base == null) { + $this->base= $config->current['BASE']; + } + $this->refreshBasesList(); + + // Move footer information + $this->showFooter= ($config->get_cfg_value("listSummary") == "true"); + + // Register build in filters + $this->registerElementFilter("objectType", "listing::filterObjectType"); + $this->registerElementFilter("departmentLink", "listing::filterDepartmentLink"); + $this->registerElementFilter("link", "listing::filterLink"); + $this->registerElementFilter("actions", "listing::filterActions"); + } + + + function setCopyPasteHandler($handler) + { + $this->copyPasteHandler= &$handler; + } + + + function setSnapshotHandler($handler) + { + $this->snapshotHandler= &$handler; + } + + + function setFilter($filter) + { + $this->filter= &$filter; + if ($this->departmentBrowser){ + $this->departments= $this->getDepartments(); + } + $this->filter->setBase($this->base); + $this->entries= $this->filter->query(); + } + + + function registerElementFilter($name, $call) + { + if (!isset($this->filters[$name])) { + $this->filters[$name]= $call; + return true; + } + + return false; } @@ -32,48 +124,119 @@ class listing { $this->xmlData= $this->xmlData["list"]; // Load some definition values - foreach (array("departmentBrowser", "departmentRootVisible", "multiSelect") as $token) { + foreach (array("departmentBrowser", "departmentRootVisible", "multiSelect", "baseMode") as $token) { if (isset($this->xmlData['definition'][$token]) && $this->xmlData['definition'][$token] == "true"){ $this->$token= true; } } + // Fill objectTypes from departments and xml definition + $types = departmentManagement::get_support_departments(); + foreach ($types as $class => $data) { + $this->objectTypes[]= array("label" => $data['TITLE'], + "objectClass" => $data['OC'], + "image" => $data['IMG']); + } + $this->categories= array(); + if (isset($this->xmlData['definition']['objectType'])) { + if(isset($this->xmlData['definition']['objectType']['label'])) { + $this->xmlData['definition']['objectType']= array($this->xmlData['definition']['objectType']); + } + foreach ($this->xmlData['definition']['objectType'] as $index => $otype) { + $this->objectTypes[]= $this->xmlData['definition']['objectType'][$index]; + if (isset($this->xmlData['definition']['objectType'][$index]['category'])){ + $this->categories[]= $this->xmlData['definition']['objectType'][$index]['category']; + } + } + } + // Parse layout per column $this->colprops= $this->parseLayout($this->xmlData['table']['layout']); // Prepare table headers + $this->renderHeader(); + + // Assign headline/module + $this->headline= _($this->xmlData['definition']['label']); + $this->module= $this->xmlData['definition']['module']; + if (!is_array($this->categories)){ + $this->categories= array($this->categories); + } + + return true; + } + + + function renderHeader() + { $this->header= array(); + + // Initialize sort? + $sortInit= false; + if (!$this->sortDirection) { + $this->sortColumn= 0; + if (isset($this->xmlData['definition']['defaultSortColumn'])){ + $this->sortColumn= $this->xmlData['definition']['defaultSortColumn']; + } else { + $this->sortAttribute= ""; + } + $this->sortDirection= array(); + $sortInit= true; + } + if (isset($this->xmlData['table']['column'])){ foreach ($this->xmlData['table']['column'] as $index => $config) { - if (isset($config['header'])) { - $this->header[$index]= "colprops[$index].">".xml::getLocalizedAttribute($config['header'], $GLOBALS['t_language']).""; + // Initialize everything to one direction + if ($sortInit) { + $this->sortDirection[$index]= false; + } + + $sorter= ""; + if ($index == $this->sortColumn && isset($config['sortAttribute']) && + isset($config['sortType'])) { + $this->sortAttribute= $config['sortAttribute']; + $this->sortType= $config['sortType']; + $sorter= " "; + } + $sortable= (isset($config['sortAttribute'])); + + $link= "href='?plug=".$_GET['plug']."&PID=".$this->pid."&act=SORT_$index'"; + if (isset($config['label'])) { + if ($sortable) { + $this->header[$index]= "colprops[$index].">"._($config['label'])."$sorter"; + } else { + $this->header[$index]= "colprops[$index].">"._($config['label']).""; + } } else { - $this->header[$index]= "colprops[$index]."> "; + if ($sortable) { + $this->header[$index]= "colprops[$index]."> $sorter"; + } else { + $this->header[$index]= "colprops[$index]."> "; + } } } } - - return true; } - function render() { - #print_a($this->xmlData); - #print_a($this->entries); -echo "Fill summary, handle empty lists differently, alternating
"; - $summary= "empty"; + // Check for exeeded sizelimit + if (($message= check_sizelimit()) != ""){ + return($message); + } // Initialize list - $result= " + $result= ""; + $result.= "
"; + $result.= "
"; // New table for the real list contents - $result.= "
"; - $num_cols= count($this->colprops) + ($this->multiSelect?1:0); + $this->numColumns= count($this->colprops) + ($this->multiSelect?1:0); // Build list header $result.= ""; if ($this->multiSelect) { - $result.= ""; + $result.= ""; } foreach ($this->header as $header) { $result.= $header; @@ -83,56 +246,224 @@ echo "Fill summary, handle empty lists differently, alternating
"; $result.= "
 
"; - - // Fill with contents - $first= true; - foreach ($this->entries as $entry){ - $result.=""; - foreach ($this->xmlData['table']['column'] as $config) { - if ($first) { - - } else { + $result.= "
"; + + // No results? Just take an empty colspanned row + if (count($this->entries) + count($this->departments) == 0) { + $result.= ""; + } + + // Line color alternation + $alt= 0; + $deps= 0; + + // Draw department browser if configured and we're not in sub mode + if ($this->departmentBrowser && $this->filter->scope != "sub") { + // Fill with department browser if configured this way + $departmentIterator= new departmentSortIterator($this->departments, $this->sortDirection[$this->sortColumn]); + foreach ($departmentIterator as $row => $entry){ + $result.=""; + + // Render multi select if needed + if ($this->multiSelect) { + $result.=""; } + + // Render defined department columns, fill the rest with some stuff + $rest= $this->numColumns - 1; + foreach ($this->xmlData['table']['department'] as $index => $config) { + $colspan= 1; + if (isset($config['span'])){ + $colspan= $config['span']; + } + $result.=""; + $rest-= $colspan; + } + + // Fill remaining cols with nothing + $last= $this->numColumns - $rest; + for ($i= 0; $i<$rest; $i++){ + $result.= ""; + } + $result.=""; + + $alt++; } - $first= false; + $deps= $alt; + } + + // Fill with contents, sort as configured + foreach ($this->entry as $row => $entry) { + $trow =""; + + // Render multi select if needed + if ($this->multiSelect) { + $trow.=""; + } + + foreach ($this->xmlData['table']['column'] as $index => $config) { + $renderedCell= $this->renderCell($config['value'], $entry, $row); + $trow.=""; + + // Save rendered column + $this->entry[$row]["_sort$index"]= $renderedCell; + } + $trow.=""; + + // Save rendered entry + $this->entry[$row]['_rendered']= $trow; + + $alt++; + } + + // Complete list by sorting entries for _sort$index and appending them to the output + $entryIterator= new listingSortIterator($this->entries, $this->sortDirection[$this->sortColumn], "_sort".$this->sortColumn, $this->sortType); + foreach ($entryIterator as $row => $entry){ + $result.= $entry['_rendered']; } -# for ($i= 0; $i<10; $i++) { -# $result.=""; -# $result.=""; -# $result.=""; -# $result.=""; -# $result.=""; -# $result.=""; -# $result.=""; -# } // Need to fill the list if it's not full (nobody knows why this is 22 ;-)) - if (count($this->entries) < 22) { + $emptyListStyle= (count($this->entries) + $deps == 0)?"border:0;":""; + if ((count($this->entries) + $deps) < 22) { $result.= ""; - for ($i= 0; $i<=$num_cols; $i++) { + for ($i= 0; $i<$this->numColumns; $i++) { if ($i == 0) { - $result.= ""; + $result.= ""; continue; } - if ($i != $num_cols-1) { - $result.= ""; + if ($i != $this->numColumns-1) { + $result.= ""; } else { - $result.= ""; + $result.= ""; } } $result.= ""; } - $result.= "
 
 colprops[$index]." class='list1'>".$this->renderCell($config['value'], $entry, $row)."colprops[$last+$i-1]." class='list1'> 
colprops[$index]." class='list0'>".$renderedCell."
 Administrativa - [Funktionelle Daten]  
      
"; + $result.= "
"; - return $result; + // Add the footer if requested + if ($this->showFooter) { + $result.= "
"; + + foreach ($this->objectTypes as $objectType) { + if (isset($this->objectTypeCount[$objectType['label']])) { + $label= _($objectType['label']); + $result.= "$label ".$this->objectTypeCount[$objectType['label']]."    "; + } + } + + $result.= " 
"; + } + + $result.= ""; + + $smarty= get_smarty(); + $smarty->assign("FILTER", $this->filter->render()); + $smarty->assign("SIZELIMIT", print_sizelimit_warning()); + $smarty->assign("LIST", $result); + + // Assign navigation elements + $nav= $this->renderNavigation(); + foreach ($nav as $key => $html) { + $smarty->assign($key, $html); + } + + // Assign action menu / base + $smarty->assign("ACTIONS", $this->renderActionMenu()); + $smarty->assign("BASE", $this->renderBase()); + + // Assign separator + $smarty->assign("SEPARATOR", "-"); + + // Assign summary + $smarty->assign("HEADLINE", $this->headline); + + return ($smarty->fetch(get_template_path($this->xmlData['definition']['template'], true))); } - function setEntries($entries) + function update() { - $this->entries= &$entries; + global $config; + $ui= get_userinfo(); + + // Reset object counter + $this->objectTypeCount= array(); + + // Do not do anything if this is not our PID + if(isset($_REQUEST['PID']) && $_REQUEST['PID'] != $this->pid) { + return; + } + + // Save base + if (isset($_POST['BASE']) && $this->baseMode == true) { + $base= validate($_POST['BASE']); + if (isset($this->bases[$base])) { + $this->base= $base; + } + } + + // Override the base if we got a message from the browser navigation + if ($this->departmentBrowser && isset($_GET['act'])) { + if (preg_match('/^department_([0-9]+)$/', validate($_GET['act']), $match)){ + if (isset($this->departments[$match[1]])){ + $this->base= $this->departments[$match[1]]['dn']; + } + } + } + + // Filter GET with "act" attributes + if (isset($_GET['act'])) { + $key= validate($_GET['act']); + if (preg_match('/^SORT_([0-9]+)$/', $key, $match)) { + // Switch to new column or invert search order? + $column= $match[1]; + if ($this->sortColumn != $column) { + $this->sortColumn= $column; + } else { + $this->sortDirection[$column]= !$this->sortDirection[$column]; + } + + // Allow header to update itself according to the new sort settings + $this->renderHeader(); + } + } + + // Override base if we got signals from the navigation elements + $action= ""; + foreach ($_POST as $key => $value) { + if (preg_match('/^(ROOT|BACK|HOME)_x$/', $key, $match)) { + $action= $match[1]; + break; + } + } + + // Navigation handling + if ($action == 'ROOT') { + $deps= $ui->get_module_departments($this->module); + $this->base= $deps[0]; + } + if ($action == 'BACK') { + $deps= $ui->get_module_departments($this->module); + $base= preg_replace("/^[^,]+,/", "", $this->base); + if(in_array_ics($base, $deps)){ + $this->base= $base; + } + } + if ($action == 'HOME') { + $ui= get_userinfo(); + $this->base= get_base_from_people($ui->dn); + } + + // Reload departments + if ($this->departmentBrowser){ + $this->departments= $this->getDepartments(); + } + + // Update filter and refresh entries + $this->filter->setBase($this->base); + $this->entries= $this->filter->query(); } @@ -171,6 +502,804 @@ echo "Fill summary, handle empty lists differently, alternating
"; } } + // Save number of columns for later use + $this->numColumns= count($cols); + + return $result; + } + + + function renderCell($data, $config, $row) + { + // Replace flat attributes in data string + for ($i= 0; $i<$config['count']; $i++) { + $attr= $config[$i]; + $value= ""; + if (is_array($config[$attr])) { + $value= $config[$attr][0]; + } else { + $value= $config[$attr]; + } + $data= preg_replace("/%\{$attr\}/", $value, $data); + } + + // Watch out for filters and prepare to execute them + $data= $this->processElementFilter($data, $config, $row); + + // Replace all non replaced %{...} instances because they + // are non resolved attributes or filters + $data= preg_replace('/%{[^}]+}/', ' ', $data); + + return $data; + } + + + function renderBase() + { + $result= ""; + + // Reset the currently used base to the first DN we found if there + // was no match. + if(!$found){ + $this->base = $firstDN; + } + + return $result; + } + + + function processElementFilter($data, $config, $row) + { + preg_match_all("/%\{filter:([^(]+)\((.*)\)\}/", $data, $matches, PREG_SET_ORDER); + + foreach ($matches as $match) { + if (!isset($this->filters[$match[1]])) { + continue; + } + $cl= preg_replace('/::.*$/', '', $this->filters[$match[1]]); + $method= preg_replace('/^.*::/', '', $this->filters[$match[1]]); + + // Prepare params for function call + $params= array(); + preg_match_all('/"[^"]+"|[^,]+/', $match[2], $parts); + foreach ($parts[0] as $param) { + + // Row is replaced by the row number + if ($param == "row") { + $params[]= $row; + } + + // pid is replaced by the current PID + if ($param == "pid") { + $params[]= $this->pid; + } + + // Fixie with "" is passed directly + if (preg_match('/^".*"$/', $param)){ + $params[]= preg_replace('/"/', '', $param); + } + + // LDAP variables get replaced by their objects + for ($i= 0; $i<$config['count']; $i++) { + if ($param == $config[$i]) { + $values= $config[$config[$i]]; + if (is_array($values)){ + unset($values['count']); + } + $params[]= $values; + } + } + + // Move dn if needed + if ($param == "dn") { + $params[]= LDAP::fix($config["dn"]); + } + } + + // Replace information + if ($cl == "listing") { + // Non static call - seems to result in errors + $data= @preg_replace('/'.preg_quote($match[0]).'/', call_user_func_array(array($this, "$method"), $params), $data); + } else { + // Static call + $data= preg_replace('/'.preg_quote($match[0]).'/', call_user_func_array(array($cl, $method), $params), $data); + } + } + + return $data; + } + + + function getObjectType($types, $classes) + { + // Walk thru types and see if there's something matching + foreach ($types as $objectType) { + $ocs= $objectType['objectClass']; + if (!is_array($ocs)){ + $ocs= array($ocs); + } + + $found= true; + foreach ($ocs as $oc){ + if (preg_match('/^!(.*)$/', $oc, $match)) { + $oc= $match[1]; + if (in_array($oc, $classes)) { + $found= false; + } + } else { + if (!in_array($oc, $classes)) { + $found= false; + } + } + } + + if ($found) { + return $objectType; + } + } + + return null; + } + + + function filterObjectType($dn, $classes) + { + // Walk thru classes and return on first match + $result= " "; + + $objectType= $this->getObjectType($this->objectTypes, $classes); + if ($objectType) { + $result= ""; + if (!isset($this->objectTypeCount[$objectType['label']])) { + $this->objectTypeCount[$objectType['label']]= 0; + } + $this->objectTypeCount[$objectType['label']]++; + } + return $result; + } + + + function filterActions($dn, $row, $classes) + { + // Do nothing if there's no menu defined + if (!isset($this->xmlData['actiontriggers']['action'])) { + return " "; + } + + // Go thru all actions + $result= ""; + $actions= $this->xmlData['actiontriggers']['action']; + foreach($actions as $action) { + // Skip the entry completely if there's no permission to execute it + if (!$this->hasActionPermission($action, $dn)) { + continue; + } + + // If there's an objectclass definition and we don't have it + // add an empty picture here. + if (isset($action['objectclass'])){ + $objectclass= $action['objectclass']; + if (preg_match('/^!(.*)$/', $objectclass, $m)){ + $objectclass= $m[1]; + if(in_array($objectclass, $classes)) { + $result.= " "; + continue; + } + } else { + if(!in_array($objectclass, $classes)) { + $result.= " "; + continue; + } + } + } + + // Render normal entries as usual + if ($action['type'] == "entry") { + $label= $this->processElementFilter($action['label'], $this->entries[$row], $row); + $image= $this->processElementFilter($action['image'], $this->entries[$row], $row); + $result.=""; + } + + // Handle special types + if ($action['type'] == "copypaste" || $action['type'] == "snapshot") { + + $objectType= $this->getObjectType($this->objectTypes, $this->entries[$row]['objectClass']); + $category= $class= null; + if ($objectType) { + $category= $objectType['category']; + $class= $objectType['class']; + } + + if ($action['type'] == "copypaste") { + $result.= $this->renderCopyPasteActions($row, $this->entries[$row]['dn'], $category, $class); + } else { + $result.= $this->renderSnapshotActions($row, $this->entries[$row]['dn'], $category, $class); + } + } + } + + return $result; + } + + + function filterDepartmentLink($row, $dn, $description) + { + $attr= $this->departments[$row]['sort-attribute']; + $name= $this->departments[$row][$attr]; + if (is_array($name)){ + $name= $name[0]; + } + $result= sprintf("%s [%s]", $name, $description[0]); + return("pid&act=department_$row' title='$dn'>$result"); + } + + + function filterLink() + { + $result= " "; + + $row= func_get_arg(0); + $pid= $this->pid; + $dn= LDAP::fix(func_get_arg(1)); + $params= array(func_get_arg(2)); + + // Collect sprintf params + for ($i = 3;$i < func_num_args();$i++) { + $val= func_get_arg($i); + if (is_array($val)){ + $params[]= $val[0]; + continue; + } + $params[]= $val; + } + + $result= " "; + $trans= call_user_func_array("sprintf", $params); + if ($trans != "") { + return("$trans"); + } + + return $result; + } + + + function renderNavigation() + { + $result= array(); + $enableBack = true; + $enableRoot = true; + $enableHome = true; + + $ui = get_userinfo(); + + /* Check if base = first available base */ + $deps = $ui->get_module_departments($this->module); + + if(!count($deps) || $deps[0] == $this->filter->base){ + $enableBack = false; + $enableRoot = false; + } + + $listhead =""; + + /* Check if we are in users home department */ + if(!count($deps) ||$this->filter->base == get_base_from_people($ui->dn)){ + $enableHome = false; + } + + /* Draw root button */ + if($enableRoot){ + $result["ROOT"]= ""; + }else{ + $result["ROOT"]= ""._("Root").""; + } + + /* Draw back button */ + if($enableBack){ + $result["BACK"]= ""; + }else{ + $result["BACK"]= ""._("Up").""; + } + + /* Draw home button */ + if($enableHome){ + $result["HOME"]= ""; + }else{ + $result["HOME"]= ""._("Home").""; + } + + /* Draw reload button, this button is enabled everytime */ + $result["RELOAD"]= ""; + + return ($result); + } + + + function getAction() + { + // Do not do anything if this is not our PID + if(isset($_REQUEST['PID']) && $_REQUEST['PID'] != $this->pid) { + return; + } + + $result= array("targets" => array(), "action" => ""); + + // Filter GET with "act" attributes + if (isset($_GET['act'])) { + $key= validate($_GET['act']); + $target= preg_replace('/^listing_[a-zA-Z_]+_([0-9]+)$/', '$1', $key); + if (isset($this->entries[$target]['dn'])) { + $result['action']= preg_replace('/^listing_([a-zA-Z_]+)_[0-9]+$/', '$1', $key); + $result['targets'][]= $this->entries[$target]['dn']; + } + + // Drop targets if empty + if (count($result['targets']) == 0) { + unset($result['targets']); + } + return $result; + } + + // Filter POST with "listing_" attributes + foreach ($_POST as $key => $prop) { + + // Capture selections + if (preg_match('/^listing_selected_[0-9]+$/', $key)) { + $target= preg_replace('/^listing_selected_([0-9]+)$/', '$1', $key); + if (isset($this->entries[$target]['dn'])) { + $result['targets'][]= $this->entries[$target]['dn']; + } + continue; + } + + // Capture action with target - this is a one shot + if (preg_match('/^listing_[a-zA-Z_]+_[0-9]+(|_x)$/', $key)) { + $target= preg_replace('/^listing_[a-zA-Z_]+_([0-9]+)(|_x)$/', '$1', $key); + if (isset($this->entries[$target]['dn'])) { + $result['action']= preg_replace('/^listing_([a-zA-Z_]+)_[0-9]+(|_x)$/', '$1', $key); + $result['targets']= array($this->entries[$target]['dn']); + } + break; + } + + // Capture action without target + if (preg_match('/^listing_[a-zA-Z_]+(|_x)$/', $key)) { + $result['action']= preg_replace('/^listing_([a-zA-Z_]+)(|_x)$/', '$1', $key); + continue; + } + } + + // Filter POST with "act" attributes -> posted from action menu + if (isset($_POST['act']) && $_POST['act'] != '') { + $result['action']= validate($_POST['act']); + } + + // Drop targets if empty + if (count($result['targets']) == 0) { + unset($result['targets']); + } + return $result; + } + + + function renderActionMenu() + { + // Don't send anything if the menu is not defined + if (!isset($this->xmlData['actionmenu']['action'])){ + return ""; + } + + // Load shortcut + $actions= &$this->xmlData['actionmenu']['action']; + $result= "". + "
"; + } + + + function recurseActions($actions) + { + static $level= 2; + $result= ""; + return $result; + } + + + function hasActionPermission($action, $dn) + { + $ui= get_userinfo(); + + if (isset($action['acl'])) { + $acls= $action['acl']; + if (!is_array($acls)) { + $acls= array($acls); + } + + // Every ACL has to pass + foreach ($acls as $acl) { + $module= $this->module; + $aclList= array(); + + // Split for category and plugins if needed + // match for "[rw]" style entries + if (preg_match('/^\[([rwcdm]+)\]$/', $acl, $match)){ + $aclList= array($match[1]); + } + + // match for "users[rw]" style entries + if (preg_match('/^([a-zA-Z0-9]+)\[([rwcdm]+)\]$/', $acl, $match)){ + $module= $match[1]; + $aclList= array($match[2]); + } + + // match for "users/user[rw]" style entries + if (preg_match('/^([a-zA-Z0-9]+\/[a-zA-Z0-9]+)\[([rwcdm]+)\]$/', $acl, $match)){ + $module= $match[1]; + $aclList= array($match[2]); + } + + // match "users/user[userPassword:rw(,...)*]" style entries + if (preg_match('/^([a-zA-Z0-9]+\/[a-zA-Z0-9]+)\[([a-zA-Z0-9]+:[rwcdm]+(,[a-zA-Z0-9]+:[rwcdm]+)*)\]$/', $acl, $match)){ + $module= $match[1]; + $aclList= split(',', $match[2]); + } + + // Walk thru prepared ACL by using $module + foreach($aclList as $sAcl) { + $checkAcl= ""; + + // Category or detailed permission? + if (strpos('/', $module) === false) { + if (preg_match('/([a-zA-Z0-9]+):([rwcdm]+)/', $sAcl, $m) ) { + $checkAcl= $ui->get_permissions($dn, $module, $m[1]); + $sAcl= $m[2]; + } else { + $checkAcl= $ui->get_permissions($dn, $module, '0'); + } + } else { + $checkAcl= $ui->get_category_permissions($dn, $module); + } + + // Split up remaining part of the acl and check if it we're + // allowed to do something... + $parts= str_split($sAcl); + foreach ($parts as $part) { + if (strpos($checkAcl, $part) === false){ + return false; + } + } + + } + } + } + + return true; + } + + + function refreshBasesList() + { + global $config; + $ui= get_userinfo(); + + // Do some array munching to get it user friendly + $ids= $config->idepartments; + $d= $ui->get_module_departments($this->module); + $k_ids= array_keys($ids); + $deps= array_intersect($d,$k_ids); + + // Fill internal bases list + $this->bases= array(); + foreach($k_ids as $department){ + $this->bases[$department] = $ids[$department]; + } + } + + + function getDepartments() + { + $departments= array(); + $ui= get_userinfo(); + + // Get list of supported department types + $types = departmentManagement::get_support_departments(); + + // Load departments allowed by ACL + $validDepartments = $ui->get_module_departments($this->module); + + // Build filter and look in the LDAP for possible sub departments + // of current base + $filter= "(&(objectClass=gosaDepartment)(|"; + $attrs= array("description", "objectClass"); + foreach($types as $name => $data){ + $filter.= "(objectClass=".$data['OC'].")"; + $attrs[]= $data['ATTR']; + } + $filter.= "))"; + $res= get_list($filter, $this->module, $this->base, $attrs, GL_NONE | GL_SIZELIMIT); + + // Analyze list of departments + foreach ($res as $department) { + if (!in_array($department['dn'], $validDepartments)) { + continue; + } + + // Add the attribute where we use for sorting + $oc= null; + foreach(array_keys($types) as $type) { + if (in_array($type, $department['objectClass'])) { + $oc= $type; + break; + } + } + $department['sort-attribute']= $types[$oc]['ATTR']; + + // Move to the result list + $departments[]= $department; + } + + return $departments; + } + + + function renderCopyPasteMenu($separator, $copy= true, $cut= true) + { + // We can only provide information if we've got a copypaste handler + // instance + if(!(isset($this->copyPasteHandler) && is_object($this->copyPasteHandler))){ + return ""; + } + + // Presets + $result= ""; + $read= $paste= false; + $ui= get_userinfo(); + + // Switch flags to on if there's at least one category which allows read/paste + foreach($this->categories as $category){ + $read= $read || preg_match('/r/', $ui->get_category_permissions($this->base, $category)); + $paste= $paste || $ui->is_pasteable($this->base, $category) == 1; + } + + + // Draw entries that allow copy and cut + if($read){ + + // Copy entry + if($copy){ + $result.= " "._("Copy").""; + $separator= ""; + } + + // Cut entry + if($cut){ + $result.= " "._("Cut").""; + $separator= ""; + } + } + + // Draw entries that allow pasting entries + if($paste){ + if($this->copyPasteHandler->entries_queued()){ + $result.= " "._("Paste").""; + }else{ + $result.= " "._("Paste").""; + } + } + + return($result); + } + + + function renderCopyPasteActions($row, $dn, $category, $class, $copy= true, $cut= true) + { + // We can only provide information if we've got a copypaste handler + // instance + if(!(isset($this->copyPasteHandler) && is_object($this->copyPasteHandler))){ + return ""; + } + + // Presets + $ui = get_userinfo(); + $result = ""; + + // Render cut entries + if($cut){ + if($ui->is_cutable($dn, $category, $class)){ + $result .= ""; + }else{ + $result.=" "; + } + } + + // Render copy entries + if($copy){ + if($ui->is_copyable($dn, $category, $class)){ + $result.= ""; + }else{ + $result.=" "; + } + } + + return($result); + } + + + function renderSnapshotMenu($separator) + { + // We can only provide information if we've got a snapshot handler + // instance + if(!(isset($this->snapshotHandler) && is_object($this->snapshotHandler))){ + return ""; + } + + // Presets + $result = ""; + $ui = get_userinfo(); + + if($this->snapshotHandler->enabled() && $ui->allow_snapshot_restore($this->base, $this->module)){ + + // Check if there is something to restore + $restore= false; + foreach($this->snapshotHandler->getSnapshotBases() as $base){ + $restore= $restore || count($this->snapshotHandler->getDeletedSnapshots($base)) > 0; + } + + // Draw icons according to the restore flag + if($restore){ + $result.= " "._("Restore snapshots").""; + }else{ + $result.= " "._("Restore snapshots").""; + } + } + + return($result); + } + + + function renderSnapshotActions($row, $dn, $category, $class, $copy= true, $cut= true) + { + // We can only provide information if we've got a snapshot handler + // instance + if(!(isset($this->snapshotHandler) && is_object($this->snapshotHandler))){ + return ""; + } + + // Presets + $result= ""; + $ui = get_userinfo(); + + // Only act if enabled here + if($this->snapshotHandler->enabled()){ + + // Draw restore button + if ($ui->allow_snapshot_restore($dn, $category)){ + + // Do we have snapshots for this dn? + if($this->snapshotHandler->hasSnapshots($dn)){ + $result.= ""; + } else { + $result.= " "; + } + } + + // Draw snapshot button + if($ui->allow_snapshot_create($dn, $category)){ + $result.= ""; + }else{ + $result.= " "; + } + } + + return($result); + } + + + function renderDaemonMenu($separator) + { + $result= ""; + + // If there is a daemon registered, draw the menu entries + if(class_available("DaemonEvent")){ + $events= DaemonEvent::get_event_types_by_category($this->categories); + if(isset($events['BY_CLASS']) && count($events['BY_CLASS'])){ + foreach($events['BY_CLASS'] as $name => $event){ + $result.= "".$event['MenuImage']." ".$event['s_Menu_Name'].""; + $separator= ""; + } + } + } + return $result; }