LDAPAccountManager/lam/lib/lists.inc

1507 lines
46 KiB
PHP
Raw Normal View History

2004-05-31 20:10:36 +00:00
<?php
2016-12-24 12:04:31 +00:00
use LAM\TYPES\ConfiguredType;
2004-05-31 20:10:36 +00:00
/*
2009-10-27 18:47:12 +00:00
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
2018-02-09 19:32:44 +00:00
Copyright (C) 2003 - 2018 Roland Gruber
2004-05-31 20:10:36 +00:00
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/**
* This file includes functions to manage the list views.
*
* @package lists
* @author Roland Gruber
*/
2006-01-01 16:30:05 +00:00
/** Used to get type information. */
include_once("types.inc");
/** Used to get PDF information. */
include_once("pdfstruct.inc");
2006-01-03 22:02:03 +00:00
/** Used to create PDF files. */
include_once("pdf.inc");
2006-01-01 16:30:05 +00:00
/**
2006-01-01 16:30:05 +00:00
* Generates the list view.
*
* @package lists
* @author Roland Gruber
2006-09-23 11:19:36 +00:00
*
2006-01-01 16:30:05 +00:00
*/
class lamList {
2006-09-23 11:19:36 +00:00
2006-01-01 16:30:05 +00:00
/** Account type */
protected $type;
2006-09-23 11:19:36 +00:00
2006-01-01 16:30:05 +00:00
/** current page number */
protected $page = 1;
2006-09-23 11:19:36 +00:00
2006-01-01 16:30:05 +00:00
/** list of LDAP attributes */
protected $attrArray = array();
2006-09-23 11:19:36 +00:00
2006-01-01 16:30:05 +00:00
/** list of attribute descriptions */
protected $descArray = array();
2006-09-23 11:19:36 +00:00
2006-01-01 16:30:05 +00:00
/** maximum count of entries per page */
protected $maxPageEntries = 30;
2006-09-23 11:19:36 +00:00
2006-01-01 16:30:05 +00:00
/** sort column name */
protected $sortColumn;
2015-11-06 17:04:55 +00:00
/** sort direction: 1 for ascending, -1 for descending */
protected $sortDirection = 1;
2006-09-23 11:19:36 +00:00
2006-01-01 16:30:05 +00:00
/** LDAP suffix */
protected $suffix;
2006-09-23 11:19:36 +00:00
2006-01-01 16:30:05 +00:00
/** refresh page switch */
protected $refresh = true;
2006-09-23 11:19:36 +00:00
/** entries to show */
protected $entries;
2015-11-06 17:04:55 +00:00
/** entries from LDAP */
protected $ldapEntries;
2013-04-02 18:46:39 +00:00
/** sort mapping for entries array(original index => sorted index) */
protected $sortMapping;
2006-09-23 11:19:36 +00:00
/** list of filters (attribute name => filter input) */
protected $filters = array();
2006-09-23 11:19:36 +00:00
2006-01-01 16:30:05 +00:00
/** list of possible LDAP suffixes(organizational units) */
protected $possibleSuffixes;
2006-09-23 11:19:36 +00:00
2006-01-01 16:30:05 +00:00
/** list of account specific labels */
protected $labels;
2015-11-06 17:04:55 +00:00
/** configuration options */
private $configOptions;
2015-11-06 17:04:55 +00:00
/** tabindex for GUI elements */
protected $tabindex = 1;
2006-09-23 11:19:36 +00:00
/** defines if the server side filter changed */
protected $serverSideFilterChanged;
/** ID for list size config option */
const LIST_SIZE_OPTION_NAME = "L_SIZE";
2015-11-06 17:04:55 +00:00
/** prefix for virtual (non-LDAP) attributes */
const VIRTUAL_ATTRIBUTE_PREFIX = 'lam_virtual_';
2015-11-06 17:04:55 +00:00
2018-08-16 16:30:52 +00:00
/**
* List of attributes to filter on server side.
*
* @var string[]
*/
protected $serverSideFilterAttributes = array(
2018-05-31 06:58:30 +00:00
'cn', 'commonname', 'uid', 'memberuid', 'description',
'sn', 'surname', 'gn', 'givenname', 'company', 'mail'
);
2006-01-01 16:30:05 +00:00
/**
* Constructor
*
2016-12-24 12:04:31 +00:00
* @param LAM\TYPES\ConfiguredType $type account type
2006-01-01 16:30:05 +00:00
* @return lamList list object
*/
2007-12-28 16:08:56 +00:00
public function __construct($type) {
2006-01-01 16:30:05 +00:00
$this->type = $type;
$this->labels = array(
2012-02-09 17:08:39 +00:00
'nav' => _("Object count: %s"),
2006-01-01 16:30:05 +00:00
'error_noneFound' => _("No objects found!"),
'newEntry' => _("New object"),
2012-02-05 19:03:25 +00:00
'deleteEntry' => _("Delete selected objects"));
$this->configOptions = $this->listGetAllConfigOptions();
$this->listReadOptionsFromCookie();
}
2015-11-06 17:04:55 +00:00
/**
* Reads the list options from the cookie value.
*/
private function listReadOptionsFromCookie() {
if (sizeof($this->configOptions) > 0) {
2016-12-24 12:04:31 +00:00
if (isset($_COOKIE["ListOptions_" . $this->type->getId()])) {
$cookieValue = $_COOKIE["ListOptions_" . $this->type->getId()];
$valueParts = explode(";", $cookieValue);
$values = array();
for ($i = 0; $i < sizeof($valueParts); $i++) {
$key_value = explode('=', $valueParts[$i]);
if (sizeof($key_value) == 2) {
$values[$key_value[0]] = $key_value[1];
}
}
for ($i = 0; $i < sizeof($this->configOptions); $i++) {
if (isset($values[$this->configOptions[$i]->getID()])) {
$this->configOptions[$i]->setValue($values[$this->configOptions[$i]->getID()]);
}
}
// notify subclasses
$this->listConfigurationChanged();
}
}
2006-01-01 16:30:05 +00:00
}
2006-09-23 11:19:36 +00:00
2006-01-01 16:30:05 +00:00
/**
* Prints the HTML code to display the list view.
*/
public function showPage() {
$this->tabindex = 1;
2006-01-01 16:30:05 +00:00
// do POST actions
$postFragment = $this->listDoPost();
// update filter
$this->listBuildFilter();
2006-01-01 16:30:05 +00:00
// get some parameters
$this->listGetParams();
// print HTML head
2018-10-23 04:51:23 +00:00
$this->printHeader();
// print messages when redirected from other pages
$this->listPrintRedirectMessages();
2006-01-01 16:30:05 +00:00
// refresh data if needed
2010-02-13 19:05:33 +00:00
if ($this->refresh) {
$this->listRefreshData();
}
2018-05-31 06:58:30 +00:00
// local filtering
$this->applyLocalFilters();
2006-01-01 16:30:05 +00:00
// sort rows by sort column
2010-02-13 19:05:33 +00:00
if (isset($this->entries)) {
2013-04-02 18:46:39 +00:00
$this->listCreateSortMapping($this->entries);
2006-01-01 16:30:05 +00:00
}
// insert HTML fragment from listDoPost
echo $postFragment;
2011-04-09 10:04:56 +00:00
// config dialog
$this->listPrintConfigurationPage();
2006-01-01 16:30:05 +00:00
// show form
2010-08-21 08:30:11 +00:00
echo "<div class=\"ui-tabs-panel ui-widget-content ui-corner-bottom\">";
2010-08-23 18:01:06 +00:00
echo "<div id=\"listTabContentArea\">\n";
2018-12-23 10:01:29 +00:00
echo "<form action=\"list.php?type=" . $this->type->getId() . "&amp;norefresh=true\" method=\"post\">\n";
2006-01-01 16:30:05 +00:00
// draw account list if accounts were found
2010-02-13 19:05:33 +00:00
if (sizeof($this->entries) > 0) {
2007-02-11 18:06:42 +00:00
// buttons
$this->listPrintButtons(false);
2018-12-23 10:01:29 +00:00
echo "<br>\n";
2006-01-01 16:30:05 +00:00
// navigation bar
2010-02-13 19:05:33 +00:00
$this->listDrawNavigationBar(sizeof($this->entries));
2018-12-23 10:01:29 +00:00
echo "<br>\n";
2018-10-27 12:39:37 +00:00
$this->printAccountTable($this->entries);
2006-01-01 16:30:05 +00:00
}
else {
2007-02-11 18:06:42 +00:00
// buttons
$this->listPrintButtons(true);
2018-12-23 10:01:29 +00:00
echo "<br>\n";
2007-11-06 17:42:37 +00:00
// navigation bar
2010-02-13 19:05:33 +00:00
$this->listDrawNavigationBar(sizeof($this->entries));
2018-12-23 10:01:29 +00:00
echo "<br>\n";
2018-10-27 12:39:37 +00:00
$accounts = array();
$this->printAccountTable($accounts);
2006-01-01 16:30:05 +00:00
echo "</table><br>\n";
}
2018-10-23 04:51:23 +00:00
$this->printFooter();
}
2006-01-01 16:30:05 +00:00
/**
* Builds the regular expressions from the filter values.
*/
protected function listBuildFilter() {
if (isset($_GET['accountEditBack'])) {
return;
}
$oldFilter = $this->filters;
$this->serverSideFilterChanged = false;
$this->filters = array();
2013-01-14 17:10:03 +00:00
if (!isset($_POST['clear_filter'])) {
// build filter array
for ($i = 0; $i < sizeof($this->attrArray); $i++) {
$foundFilter = null;
if (isset($_GET["filter" . strtolower($this->attrArray[$i])])) {
$foundFilter = $_GET["filter" . strtolower($this->attrArray[$i])];
2010-04-07 19:23:11 +00:00
}
2013-01-14 17:10:03 +00:00
if (isset($_POST["filter" . strtolower($this->attrArray[$i])])) {
$foundFilter = $_POST["filter" . strtolower($this->attrArray[$i])];
}
if (isset($foundFilter) && ($foundFilter != '')) {
2015-11-06 17:04:55 +00:00
if (preg_match('/^([\p{L}\p{N} _\\*\\$\\.:@-])+$/iu', $foundFilter)) { // \p{L} matches any Unicode letter
$this->filters[strtolower($this->attrArray[$i])] = $foundFilter;
2013-01-14 17:10:03 +00:00
}
else {
StatusMessage('ERROR', _('Please enter a valid filter. Only letters, numbers and " _*$.@-" are allowed.'), htmlspecialchars($foundFilter));
}
2010-04-07 19:23:11 +00:00
}
2006-01-01 16:30:05 +00:00
}
}
$filterAttrs = array_merge(array_keys($oldFilter), array_keys($this->filters));
$filterAttrs = array_unique($filterAttrs);
foreach ($filterAttrs as $attrName) {
if (!$this->isAttributeFilteredByServer($attrName)) {
continue;
}
if (!isset($oldFilter[$attrName]) || !isset($this->filters[$attrName]) || ($oldFilter[$attrName] != $this->filters[$attrName])) {
$this->serverSideFilterChanged = true;
break;
}
}
2006-01-01 16:30:05 +00:00
}
2015-11-06 17:04:55 +00:00
2006-01-01 16:30:05 +00:00
/**
2013-04-02 18:46:39 +00:00
* Determines the sort mapping and stores it in $this->sortMapping.
* The sort mapping is used to display the right rows when the account table is created.
2006-01-01 16:30:05 +00:00
*
* @param array $info the account list
*/
2013-04-02 18:46:39 +00:00
protected function listCreateSortMapping(&$info) {
2018-12-23 10:01:29 +00:00
if (!is_array($this->attrArray) || !is_string($this->sortColumn)) {
return;
}
2013-04-02 18:46:39 +00:00
$toSort = array();
$col = $this->sortColumn;
$size = sizeof($info);
if ($this->sortColumn != 'dn') {
for ($i = 0; $i < $size; $i++) {
// sort by first attribute with name $sort
$toSort[] = &$info[$i][$col][0];
}
2004-05-31 20:10:36 +00:00
}
else {
2013-04-02 18:46:39 +00:00
for ($i = 0; $i < $size; $i++) {
$toSort[] = &$info[$i][$col];
}
2004-05-31 20:10:36 +00:00
}
2013-04-02 18:46:39 +00:00
natcasesort($toSort);
$sortResult = array();
if ($this->sortDirection == 1) {
foreach ($toSort as $orig => $val) {
$sortResult[] = $orig;
}
}
else {
$counter = sizeof($toSort);
foreach ($toSort as $orig => $val) {
$counter--;
$sortResult[$counter] = $orig;
}
}
$this->sortMapping = &$sortResult;
2004-05-31 20:10:36 +00:00
}
2006-01-01 16:30:05 +00:00
/**
* Draws a navigation bar to switch between pages
*
* @param integer $count number of account entries
*/
protected function listDrawNavigationBar($count) {
$filter = $this->getFilterAsTextForURL();
2018-10-26 18:13:13 +00:00
$row = new htmlResponsiveRow();
$row->setCSSClasses(array('maxrow'));
$countLabel = new htmlOutputText(sprintf($this->labels['nav'], $count));
$row->add($countLabel, 12, 6, 6);
$navGroup = new htmlGroup();
if ($count > $this->maxPageEntries) {
if ($this->page != 1) {
2018-10-26 18:13:13 +00:00
$linkHref = "list.php?type=" . $this->type->getId() . "&norefresh=true&page=1" .
"&sort=" . $this->sortColumn . "&sortdirection=" . $this->sortDirection . $filter;
$link = new htmlLink(null, $linkHref, '../../graphics/go-first.png');
$link->setTitle(_('Jump to first page'));
$link->setCSSClasses(array('margin5'));
$navGroup->addElement($link);
}
if ($this->page > 11) {
2018-10-26 18:13:13 +00:00
$linkHref = "list.php?type=" . $this->type->getId() . "&norefresh=true&page=" . ($this->page - 10) .
"&sort=" . $this->sortColumn . "&sortdirection=" . $this->sortDirection . $filter;
$link = new htmlLink(null, $linkHref, '../../graphics/go-previous.png');
$link->setTitle(_('Jump 10 pages backward'));
$link->setCSSClasses(array('margin5'));
$navGroup->addElement($link);
2010-07-30 16:08:20 +00:00
}
$pageCount = ceil($count / $this->maxPageEntries);
2012-07-22 17:32:23 +00:00
for ($i = $this->page - 6; $i < ($this->page + 5); $i++) {
if ($i >= $pageCount) {
break;
}
elseif ($i < 0) {
continue;
}
if ($i == $this->page - 1) {
2018-10-26 18:13:13 +00:00
$url = "list.php?type=" . $this->type->getId() . "&norefresh=true" .
"&sort=" . $this->sortColumn . "&sortdirection=" . $this->sortDirection . $filter;
$navInput = new htmlInputField('listNavPage', ($i + 1));
$navInput->setMinimumAndMaximumNumber(1, $pageCount);
$navInput->setCSSClasses(array('listPageInput'));
$navInput->setOnKeyPress('listPageNumberKeyPress(\'' . $url . '\', event);');
$navGroup->addElement($navInput);
}
else {
2018-10-26 18:13:13 +00:00
$linkHref = "list.php?type=" . $this->type->getId() . "&norefresh=true&page=" . ($i + 1) .
"&sort=" . $this->sortColumn . "&sortdirection=" . $this->sortDirection . $filter;
$link = new htmlLink(($i + 1), $linkHref);
$link->setCSSClasses(array('margin5'));
$navGroup->addElement($link);
}
2010-07-30 16:08:20 +00:00
}
if ($this->page < ($pageCount - 10)) {
2018-10-26 18:13:13 +00:00
$linkHref = "list.php?type=" . $this->type->getId() . "&norefresh=true&page=" . ($this->page + 10) .
"&sort=" . $this->sortColumn . "&sortdirection=" . $this->sortDirection . $filter;
$link = new htmlLink(null, $linkHref, '../../graphics/go-next.png');
$link->setTitle(_('Jump 10 pages forward'));
$link->setCSSClasses(array('margin5'));
$navGroup->addElement($link);
2006-01-01 16:30:05 +00:00
}
if ($this->page < $pageCount) {
2018-10-26 18:13:13 +00:00
$linkHref = "list.php?type=" . $this->type->getId() . "&norefresh=true&page=" . $pageCount .
"&sort=" . $this->sortColumn . "&sortdirection=" . $this->sortDirection . $filter;
$link = new htmlLink(null, $linkHref, '../../graphics/go-last.png');
$link->setTitle(_('Jump to last page'));
$link->setCSSClasses(array('margin5'));
$navGroup->addElement($link);
2006-01-01 16:30:05 +00:00
}
}
2018-10-26 18:13:13 +00:00
$row->add($navGroup, 12, 6, 6, 'responsiveLabel');
parseHtml(null, $row, array(), false, $this->tabindex, $this->type->getScope());
}
2015-11-06 17:04:55 +00:00
/**
* Returns the filter as text to be used as URL parameter.
2015-11-06 17:04:55 +00:00
*
* @return String filter text
*/
protected function getFilterAsTextForURL() {
$text = '';
foreach ($this->filters as $attr => $filter) {
2018-10-27 12:39:37 +00:00
$text .= "&filter" . strtolower($attr) . '=' . $filter;
}
return $text;
}
2006-09-23 11:19:36 +00:00
2018-10-27 12:39:37 +00:00
/**
* Prints the entry list
*
* @param array $info entries
*/
private function printAccountTable(&$info) {
$scope = $this->type->getScope();
$titles = $this->descArray;
array_unshift($titles, _('Actions'));
$data = array();
$data[] = $this->getSortingElements();
$data[] = $this->getFilterElements();
2018-10-27 14:43:04 +00:00
$onClickEvents = array();
$onDoubleClickEvents = array();
$this->addDataElements($data, $info, $onClickEvents, $onDoubleClickEvents);
2018-10-27 12:39:37 +00:00
$table = new htmlResponsiveTable($titles, $data);
$table->setRowClasses($scope . '-dark', $scope . '-bright');
$table->setCSSClasses(array($scope . '-border accountlist'));
2018-10-27 14:43:04 +00:00
$table->setOnClickEvents($onClickEvents);
$table->setOnDoubleClickEvents($onDoubleClickEvents);
2018-10-27 12:39:37 +00:00
parseHtml(null, $table, array(), false, $this->tabindex, $scope);
}
/**
* Returns the elements to show in sorting row.
*
* @return htmlElement[] elements
*/
private function getSortingElements() {
$filter = $this->getFilterAsTextForURL();
$sortElements = array(new htmlOutputText(_('Sort sequence')));
foreach ($this->attrArray as $attributeName) {
$link = "list.php?type=" . $this->type->getId() . "&".
"sort=" . strtolower($attributeName) . $filter . "&norefresh=y";
$buttons = new htmlGroup();
if (strtolower($attributeName) == $this->sortColumn) {
if ($this->sortDirection < 0) {
$buttons->addElement(new htmlLink(null, $link . '&sortdirection=1', '../../graphics/downarrows.png'));
$buttons->addElement(new htmlLink(null, $link . '&sortdirection=-1', '../../graphics/uparrows-black.png'));
}
else {
$buttons->addElement(new htmlLink(null, $link . '&sortdirection=1', '../../graphics/downarrows-black.png'));
$buttons->addElement(new htmlLink(null, $link . '&sortdirection=-1', '../../graphics/uparrows.png'));
}
}
else {
$buttons->addElement(new htmlLink(null, $link . '&sortdirection=1', '../../graphics/downarrows.png'));
$buttons->addElement(new htmlLink(null, $link . '&sortdirection=-1', '../../graphics/uparrows.png'));
}
$sortElements[] = $buttons;
}
return $sortElements;
}
/**
* Returns the elements to show in filter row.
*
* @return htmlElement[] elements
*/
private function getFilterElements() {
$actionElement = new htmlGroup();
$selectAll = new htmlInputCheckbox('tableSelectAll', false);
$selectAll->setCSSClasses(array('align-middle'));
$selectAll->setOnClick('list_switchAccountSelection();');
$actionElement->addElement($selectAll);
$actionElement->addElement(new htmlSpacer('1rem', null));
$actionElement->addElement(new htmlOutputText(_('Filter')));
$filterButton = new htmlButton('apply_filter', 'filter.png', true);
$filterButton->setTitle(_("Here you can input simple filter expressions (e.g. 'value' or 'v*'). The filter is case-insensitive."));
$actionElement->addElement($filterButton);
if (sizeof($this->filters) > 0) {
$clearFilterButton = new htmlButton('clear_filter', 'clearFilter.png', true);
$clearFilterButton->setTitle(_('Clear filter'));
$actionElement->addElement($clearFilterButton);
}
2018-10-28 09:11:45 +00:00
$filterElements = array(new htmlDiv(null, $actionElement, array('nowrap')));
2018-10-27 12:39:37 +00:00
$clearFilter = isset($_POST['clear_filter']);
foreach ($this->attrArray as $attributeName) {
$attributeName = strtolower($attributeName);
if ($this->canBeFiltered($attributeName)) {
$value = "";
if (!$clearFilter && isset($this->filters[$attributeName])) {
$value = $this->filters[$attributeName];
}
2018-10-28 09:11:45 +00:00
$filterInput = new htmlInputField('filter' . $attributeName, $value, null);
2018-10-27 12:39:37 +00:00
$filterInput->setCSSClasses(array($this->type->getScope() . '-bright'));
$filterInput->setOnKeyPress("SubmitForm('apply_filter', event);");
$filterElements[] = $filterInput;
}
else {
$filterElements[] = new htmlOutputText('');
}
}
return $filterElements;
}
2018-10-27 14:43:04 +00:00
/**
* Adds the LDAP data elements to the given array.
*
* @param array $data data for responsible table
* @param array $info entries
* @param array $onClickEvents row number => code
* @param array $onDoubleClickEvents row number => code
*/
private function addDataElements(&$data, &$info, &$onClickEvents, &$onDoubleClickEvents) {
// calculate which rows to show
$table_begin = ($this->page - 1) * $this->maxPageEntries;
2018-12-23 10:01:29 +00:00
if (($this->page * $this->maxPageEntries) > sizeof($info)) {
$table_end = sizeof($info);
}
else {
$table_end = ($this->page * $this->maxPageEntries);
}
2018-10-27 14:43:04 +00:00
// get sort mapping
$sortMapping = &$this->sortMapping;
if (empty($sortMapping)) {
$sortMapping = array();
$infoSize = sizeof($info);
for ($i = 0; $i < $infoSize; $i++) {
$sortMapping[$i] = $i;
}
}
// print account list
for ($i = $table_begin; $i < $table_end; $i++) {
$row = array();
$index = $sortMapping[$i];
$rowID = base64_encode($info[$index]['dn']);
$actionElement = new htmlGroup();
$checkbox = new htmlInputCheckbox($rowID, false);
$checkbox->setOnClick("list_click('" . $rowID . "');");
$checkbox->setCSSClasses(array('accountBoxUnchecked align-middle'));
$actionElement->addElement($checkbox);
$actionElement->addElement(new htmlSpacer('0.5rem', null));
$onClickEvents[$i + 2] = "list_click('" . $rowID . "');";
$onDoubleClickEvents[$i + 2] = "top.location.href='../account/edit.php?type=" . $this->type->getId() . "&amp;DN=" . rawurlencode($info[$index]['dn']) . "';";
$this->addToolLinks($info[$index], $rowID, $actionElement);
2018-10-28 09:11:45 +00:00
$row[] = new htmlDiv(null, $actionElement, array('nowrap'));
2018-10-27 14:43:04 +00:00
foreach ($this->attrArray as $attributeName) {
$attributeName = strtolower($attributeName);
2018-10-28 09:11:45 +00:00
$row[] = $this->getTableCellContent($info[$index], $attributeName);
2018-10-27 14:43:04 +00:00
}
$data[] = $row;
}
}
/**
* Adds the tool image links (e.g. edit and delete) for each account.
*
* @param array $account LDAP attributes
* @param String $id account ID
* @param htmlGroup $element location where to add tools
*/
private function addToolLinks($account, $id, &$element) {
$toolCount = 0;
// edit link
$editLink = new htmlLink('', "../account/edit.php?type=" . $this->type->getId() . "&DN='" . rawurlencode($account['dn']) . "'", '../../graphics/edit.png');
$editLink->setTitle(_("Edit"));
$element->addElement($editLink);
$toolCount++;
// delete link
if (checkIfWriteAccessIsAllowed($this->type->getId()) && checkIfDeleteEntriesIsAllowed($this->type->getId())) {
$deleteLink = new htmlLink('', "deletelink.php?type=" . $this->type->getId() . "&DN='" . rawurlencode($account['dn']) . "'", '../../graphics/delete.png');
$deleteLink->setTitle(_("Delete"));
$element->addElement($deleteLink);
$toolCount++;
}
// PDF button
$pdfButton = new htmlButton("createPDF_" . $id, 'pdf.png', true);
$pdfButton->setTitle(_('Create PDF file'));
$element->addElement($pdfButton);
$toolCount++;
// additional tools
$tools = $this->getAdditionalTools();
for ($i = 0; $i < sizeof($tools); $i++) {
$toolLink = new htmlLink('', $tools[$i]->getLinkTarget() . "?type=" . $this->type->getId() . "&DN='" . rawurlencode($account['dn']) . "'", '../../graphics/' . $tools[$i]->getImage());
$toolLink->setTitle($tools[$i]->getName());
$element->addElement($toolLink);
$toolCount++;
}
}
/**
* Returns if the given attribute can be filtered.
* If filtering is not possible then no filter box will be displayed.
* By default all attributes can be filtered.
2015-11-06 17:04:55 +00:00
*
* @param String $attr attribute name
* @return boolean filtering possible
*/
protected function canBeFiltered($attr) {
return true;
}
2006-01-01 16:30:05 +00:00
/**
2018-10-28 09:11:45 +00:00
* Returns the content of a cell in the account list for a given LDAP entry and attribute.
2007-02-17 16:26:08 +00:00
*
* @param array $entry LDAP attributes
* @param string $attribute attribute name
2018-10-28 09:11:45 +00:00
* @return htmlElement content
2007-02-17 16:26:08 +00:00
*/
2018-10-28 09:11:45 +00:00
protected function getTableCellContent(&$entry, &$attribute) {
2007-02-17 16:26:08 +00:00
// print all attribute entries seperated by "; "
if (isset($entry[$attribute]) && sizeof($entry[$attribute]) > 0) {
if (is_array($entry[$attribute])) {
2018-06-29 18:44:36 +00:00
if (($attribute == 'entryexpiretimestamp') && !empty($entry[$attribute][0])) {
2018-10-28 09:11:45 +00:00
return new htmlOutputText(formatLDAPTimestamp($entry[$attribute][0]));
2018-06-29 18:44:36 +00:00
}
else {
// sort array
sort($entry[$attribute]);
2018-10-28 09:11:45 +00:00
return new htmlOutputText(implode("; ", $entry[$attribute]));
2018-06-29 18:44:36 +00:00
}
2007-03-21 13:36:09 +00:00
}
else {
2018-10-28 09:11:45 +00:00
return new htmlOutputText($entry[$attribute]);
2007-02-17 16:26:08 +00:00
}
2015-11-06 17:04:55 +00:00
}
2007-02-17 16:26:08 +00:00
}
2006-09-23 11:19:36 +00:00
2006-01-01 16:30:05 +00:00
/**
* Manages all POST actions (e.g. button pressed) for the account lists.
2015-11-06 17:04:55 +00:00
*
* @return String HTML fragment to insert into beginning of account list
2006-01-01 16:30:05 +00:00
*/
2008-01-14 18:10:13 +00:00
protected function listDoPost() {
2015-05-14 11:49:56 +00:00
if (!empty($_POST)) {
validateSecurityToken();
}
// check if button was pressed and if we have to add/delete an account or call file upload
if (isset($_POST['new']) || isset($_POST['del']) || isset($_POST['fileUpload'])){
2016-12-24 12:04:31 +00:00
if (!checkIfWriteAccessIsAllowed($this->type->getId())) {
2007-12-30 16:08:54 +00:00
die();
}
2006-01-01 16:30:05 +00:00
// add new account
2016-12-24 12:04:31 +00:00
if (isset($_POST['new']) && checkIfNewEntriesAreAllowed($this->type->getId())){
2018-11-25 09:51:39 +00:00
metaRefresh("../account/edit.php?type=" . $this->type->getId() . "&suffix=" . $this->suffix);
exit;
}
2006-01-01 16:30:05 +00:00
// delete account(s)
2016-12-24 12:04:31 +00:00
elseif (isset($_POST['del']) && checkIfDeleteEntriesIsAllowed($this->type->getId())){
2006-01-01 16:30:05 +00:00
// search for checkboxes
$accounts = array_keys($_POST, "on");
2006-06-29 19:38:38 +00:00
// build DN list
2006-01-01 16:30:05 +00:00
$_SESSION['delete_dn'] = array();
for ($i = 0; $i < sizeof($accounts); $i++) {
2018-11-20 17:45:24 +00:00
if ($accounts[$i] == 'tableSelectAll') {
continue;
}
2010-01-04 20:15:25 +00:00
$_SESSION['delete_dn'][] = base64_decode($accounts[$i]);
2006-01-01 16:30:05 +00:00
}
if (sizeof($accounts) > 0) {
2016-12-24 12:04:31 +00:00
metaRefresh("../delete.php?type=" . $this->type->getId());
2006-01-01 16:30:05 +00:00
exit;
}
}
// file upload
2016-12-24 12:04:31 +00:00
elseif (isset($_POST['fileUpload']) && checkIfNewEntriesAreAllowed($this->type->getId())){
metaRefresh("../upload/masscreate.php?type=" . $this->type->getId());
exit;
}
2007-11-25 12:52:18 +00:00
}
// PDF button
foreach ($_POST as $key => $value) {
if (strpos($key, 'createPDF_') > -1) {
$parts = explode("_", $key);
2010-05-02 15:34:44 +00:00
if (sizeof($parts) == 2) {
2007-11-25 12:52:18 +00:00
$this->showPDFPage($parts[1]);
exit;
}
}
}
// PDF creation Ok
if (isset($_POST['createPDFok'])) {
$pdfStruct = $_POST['pdf_structure'];
2017-10-23 15:58:08 +00:00
$pdfFont = $_POST['pdf_font'];
2007-11-25 12:52:18 +00:00
$option = $_POST['createFor'];
$filename = '';
2007-11-25 12:52:18 +00:00
// create for clicked account
if ($option == 'DN') {
$_SESSION["accountPDF"] = new accountContainer($this->type, "accountPDF");
2009-12-06 18:34:24 +00:00
$_SESSION["accountPDF"]->load_account(base64_decode($_POST['clickedAccount']));
2017-10-23 15:58:08 +00:00
$filename = \LAM\PDF\createModulePDF(array($_SESSION["accountPDF"]), $pdfStruct, $pdfFont);
2007-11-25 12:52:18 +00:00
unset($_SESSION["accountPDF"]);
}
// create for all selected accounts
elseif ($option == 'SELECTED') {
2006-01-01 16:30:05 +00:00
// search for checkboxes
$accounts = array_keys($_POST, "on");
$list = array();
// load accounts from LDAP
for ($i = 0; $i < sizeof($accounts); $i++) {
$_SESSION["accountPDF-$i"] = new accountContainer($this->type, "accountPDF-$i");
2009-12-06 18:34:24 +00:00
$_SESSION["accountPDF-$i"]->load_account(base64_decode($accounts[$i]));
2006-01-01 16:30:05 +00:00
$list[$i] = $_SESSION["accountPDF-$i"];
}
if (sizeof($list) > 0) {
2017-10-23 15:58:08 +00:00
$filename = \LAM\PDF\createModulePDF($list, $pdfStruct, $pdfFont);
2007-11-25 12:52:18 +00:00
for ($i = 0; $i < sizeof($accounts); $i++) {
unset($_SESSION["accountPDF-$i"]);
}
2006-01-01 16:30:05 +00:00
}
}
2007-11-25 12:52:18 +00:00
// create for all accounts
elseif ($option == 'ALL') {
2006-01-01 16:30:05 +00:00
$list = array();
2013-04-02 18:46:39 +00:00
$entriesCount = sizeof($this->entries);
for ($i = 0; $i < $entriesCount; $i++) {
2006-01-01 16:30:05 +00:00
$_SESSION["accountPDF-$i"] = new accountContainer($this->type, "accountPDF-$i");
2006-01-03 22:02:03 +00:00
$_SESSION["accountPDF-$i"]->load_account($this->entries[$i]['dn']);
2006-01-01 16:30:05 +00:00
$list[$i] = $_SESSION["accountPDF-$i"];
}
if (sizeof($list) > 0) {
2018-02-09 19:32:44 +00:00
$filename = \LAM\PDF\createModulePDF($list, $pdfStruct, $pdfFont);
2013-04-02 18:46:39 +00:00
for ($i = 0; $i < $entriesCount; $i++) {
2007-11-25 12:52:18 +00:00
// clean session
unset($_SESSION["accountPDF-$i"]);
}
2006-01-01 16:30:05 +00:00
}
}
elseif ($option == 'SESSION') {
2018-02-09 19:32:44 +00:00
$filename = \LAM\PDF\createModulePDF(array($_SESSION[$_POST['PDFSessionID']]), $pdfStruct, $pdfFont);
2011-11-01 17:14:54 +00:00
unset($_SESSION[$_POST['PDFSessionID']]);
}
if ($filename != '') {
return "<script type=\"text/javascript\">window.open('" . $filename . "', '_blank');</script>";
}
}
// check if back from configuration page
if (sizeof($this->configOptions) > 0) {
if (isset($_POST['saveConfigOptions'])) {
$cookieValue = '';
for ($i = 0; $i < sizeof($this->configOptions); $i++) {
$this->configOptions[$i]->fillFromPostData();
$cookieValue .= $this->configOptions[$i]->getID() . "=" . $this->configOptions[$i]->getValue() . ';';
}
// save options as cookie for one year
2016-12-24 12:04:31 +00:00
setcookie("ListOptions_" . $this->type->getId(), $cookieValue, time()+60*60*24*365, "/", null, null, true);
// notify subclasses
$this->listConfigurationChanged();
}
}
return '';
}
2015-11-06 17:04:55 +00:00
2007-11-25 12:52:18 +00:00
/**
* Shows the page where the user may select the PDF options.
*
* @param String $id account ID
*/
private function showPDFPage($id) {
$sessionObject = null;
$PDFSessionID = null;
if (($id == null) && isset($_GET['PDFSessionID'])) {
$PDFSessionID = $_GET['PDFSessionID'];
$sessionObject = $_SESSION[$PDFSessionID];
}
2007-11-25 12:52:18 +00:00
// search for checkboxes
$selAccounts = array_keys($_POST, "on");
if (!in_array($id, $selAccounts)) {
$selAccounts[] = $id;
}
// get possible PDF structures
2017-01-05 20:05:17 +00:00
$pdf_structures = \LAM\PDF\getPDFStructures($this->type->getId());
2015-11-06 17:04:55 +00:00
2018-06-25 16:07:26 +00:00
$this->printHeader();
2007-11-25 12:52:18 +00:00
2016-12-24 12:04:31 +00:00
echo "<div class=\"ui-tabs-nav " . $this->type->getScope() . "-bright\">";
echo "<div class=\"smallPaddingContent\">\n";
2014-02-09 14:47:35 +00:00
$refresh = '&amp;norefresh=true';
if (isset($_GET['refresh']) && ($_GET['refresh'] == 'true')) {
$refresh = '&amp;refresh=true';
}
2016-12-24 12:04:31 +00:00
echo "<form action=\"list.php?type=" . $this->type->getId() . $refresh . "\" method=\"post\">\n";
2015-11-06 17:04:55 +00:00
2018-06-25 16:07:26 +00:00
$container = new htmlResponsiveRow();
$container->add(new htmlSubTitle(_('Create PDF file')), 12);
2015-11-06 17:04:55 +00:00
2018-06-25 16:07:26 +00:00
$container->add(new htmlResponsiveSelect('pdf_structure', $pdf_structures, array('default'), _('PDF structure'), '405'), 12);
2017-10-23 15:58:08 +00:00
$fonts = \LAM\PDF\getPdfFonts();
2018-06-25 16:07:26 +00:00
$fontSelection = new htmlResponsiveSelect('pdf_font', $fonts, array(), _('Font'), '411');
2017-10-23 15:58:08 +00:00
$fontSelection->setCSSClasses(array('lam-save-selection'));
$fontSelection->setHasDescriptiveElements(true);
$fontSelection->setSortElements(false);
2018-06-25 16:07:26 +00:00
$container->add($fontSelection, 12);
2015-11-06 17:04:55 +00:00
2018-06-25 16:07:26 +00:00
$container->addVerticalSpacer('1rem');
$container->addLabel(new htmlOutputText(_('Create for')));
// check if account object is already in session
if ($sessionObject != null) {
2018-06-25 16:07:26 +00:00
$container->addField(new htmlOutputText($sessionObject->finalDN));
$container->add(new htmlHiddenInput('createFor', 'SESSION'), 0);
$container->add(new htmlHiddenInput('PDFSessionID', $PDFSessionID), 0);
}
else {
$radioOptions = array(
2011-01-15 18:10:55 +00:00
getAbstractDN(base64_decode($id)) => 'DN',
sprintf(_('All selected accounts (%s)'), sizeof($selAccounts)) => 'SELECTED',
sprintf(_('All accounts (%s)'), sizeof($this->entries)) => 'ALL'
);
2018-06-25 16:07:26 +00:00
$container->addField(new htmlRadio('createFor', $radioOptions, 'DN'));
}
2015-11-06 17:04:55 +00:00
2018-06-25 16:07:26 +00:00
$container->addVerticalSpacer('2rem');
$container->addLabel(new htmlOutputText('&nbsp;', false));
$buttonContainer = new htmlGroup();
$buttonContainer->addElement(new htmlButton('createPDFok', _('Ok')));
2018-06-25 16:07:26 +00:00
$buttonContainer->addElement(new htmlSpacer('0.5rem', null));
$buttonContainer->addElement(new htmlButton('createPDFCancel', _('Cancel')));
2018-06-25 16:07:26 +00:00
$container->addField($buttonContainer);
2012-10-08 18:01:55 +00:00
// hidden inputs for selected accounts
for ($i = 0; $i < sizeof($selAccounts); $i++) {
2018-06-25 16:07:26 +00:00
$container->add(new htmlHiddenInput($selAccounts[$i], 'on'), 0);
2012-10-08 18:01:55 +00:00
}
2018-06-25 16:07:26 +00:00
$container->add(new htmlHiddenInput('clickedAccount', $id), 0);
2015-05-14 11:49:56 +00:00
addSecurityTokenToMetaHTML($container);
2015-11-06 17:04:55 +00:00
2016-12-24 12:04:31 +00:00
parseHtml(null, $container, array(), false, $this->tabindex, $this->type->getScope());
2015-11-06 17:04:55 +00:00
2018-06-25 16:07:26 +00:00
$this->printFooter();
2007-11-25 12:52:18 +00:00
}
2006-09-23 11:19:36 +00:00
2006-01-01 16:30:05 +00:00
/**
* Prints a combobox with possible sub-DNs.
2015-11-06 17:04:55 +00:00
*
2012-10-07 13:35:10 +00:00
* @return htmlGroup OU selection (may be empty)
2006-01-01 16:30:05 +00:00
*/
protected function listShowOUSelection() {
2012-10-07 13:35:10 +00:00
$group = new htmlGroup();
2006-01-01 16:30:05 +00:00
if (sizeof($this->possibleSuffixes) > 1) {
$suffixList = array();
2006-01-01 16:30:05 +00:00
for ($i = 0; $i < sizeof($this->possibleSuffixes); $i++) {
$suffixList[getAbstractDN($this->possibleSuffixes[$i])] = $this->possibleSuffixes[$i];
2006-01-01 16:30:05 +00:00
}
$suffixSelect = new htmlSelect('suffix', $suffixList, array($this->suffix));
2016-12-24 12:04:31 +00:00
$suffixSelect->setOnchangeEvent("listOUchanged('" . $this->type->getId() . "', this)");
$suffixSelect->setRightToLeftTextDirection(true);
$suffixSelect->setSortElements(false);
$suffixSelect->setHasDescriptiveElements(true);
$group->addElement($suffixSelect);
$group->addElement(new htmlSpacer('5px', null));
2006-01-01 16:30:05 +00:00
}
2012-10-07 13:35:10 +00:00
return $group;
}
2006-09-23 11:19:36 +00:00
2006-01-01 16:30:05 +00:00
/**
2007-11-25 12:52:18 +00:00
* Prints the create and delete buttons.
2006-01-01 16:30:05 +00:00
*
* @param boolean $createOnly true if only the create button should be displayed
2012-10-07 13:35:10 +00:00
* @param int $tabindex HTML tabindex counter
2006-01-01 16:30:05 +00:00
*/
protected function listPrintButtons($createOnly) {
2018-10-23 18:25:45 +00:00
$row = new htmlResponsiveRow();
$row->setCSSClasses(array('maxrow'));
2012-10-07 13:35:10 +00:00
$left = new htmlGroup();
// button part
2016-12-24 12:04:31 +00:00
if (checkIfWriteAccessIsAllowed($this->type->getId())) {
// add button
2016-12-24 12:04:31 +00:00
if (checkIfNewEntriesAreAllowed($this->type->getId())) {
$newButton = new htmlButton('new', $this->labels['newEntry']);
$newButton->setIconClass('createButton');
2018-10-23 18:25:45 +00:00
$newButton->setCSSClasses(array('fullwidth-mobile-only'));
$left->addElement($newButton);
}
// delete button
2016-12-24 12:04:31 +00:00
if (!$createOnly && checkIfDeleteEntriesIsAllowed($this->type->getId())) {
2012-10-07 13:35:10 +00:00
$delButton = new htmlButton('del', $this->labels['deleteEntry']);
$delButton->setIconClass('deleteButton');
2018-10-23 18:25:45 +00:00
$delButton->setCSSClasses(array('fullwidth-mobile-only'));
2012-10-07 13:35:10 +00:00
$left->addElement($delButton);
2007-12-30 16:08:54 +00:00
}
2012-08-13 17:43:48 +00:00
$toolSettings = $_SESSION['config']->getToolSettings();
2016-12-24 12:04:31 +00:00
if ($this->type->getBaseType()->supportsFileUpload() && checkIfNewEntriesAreAllowed($this->type->getId())
&& !(isset($toolSettings['tool_hide_toolFileUpload']) && ($toolSettings['tool_hide_toolFileUpload'] == 'true'))) {
2012-10-07 13:35:10 +00:00
$uploadButton = new htmlButton('fileUpload', _('File upload'));
$uploadButton->setIconClass('upButton');
2018-10-23 18:25:45 +00:00
$uploadButton->setCSSClasses(array('fullwidth-mobile-only'));
2012-10-07 13:35:10 +00:00
$left->addElement($uploadButton);
}
}
2015-11-06 17:04:55 +00:00
2012-10-07 13:35:10 +00:00
// OU selection and settings
2018-10-23 18:25:45 +00:00
$right = new htmlResponsiveRow();
$right->add($this->listShowOUSelection(), 12, 12, 10);
$rightButtonGroup = new htmlGroup();
2012-10-07 13:35:10 +00:00
$refreshButton = new htmlButton('refresh', 'refresh.png', true);
$refreshButton->setTitle(_("Refresh"));
2018-10-23 18:25:45 +00:00
$rightButtonGroup->addElement($refreshButton);
2012-10-07 13:35:10 +00:00
$settingsLink = new htmlLink('', '#', '../../graphics/tools.png');
$settingsLink->setOnClick('listShowSettingsDialog(\'' . _('Change list settings') . '\', \'' . _('Ok') . '\', \'' . _('Cancel') . '\');');
$settingsLink->setTitle(_('Change settings'));
2018-10-23 18:25:45 +00:00
$rightButtonGroup->addElement($settingsLink);
$right->add($rightButtonGroup, 12, 12, 2);
2015-11-06 17:04:55 +00:00
2012-10-07 13:35:10 +00:00
$this->addExtraInputElementsToTopArea($left, $right);
2018-10-23 18:25:45 +00:00
$row->add($left, 12, 6, 6, 'text-left');
$row->add($right, 12, 6, 6, 'text-right');
parseHtml(null, $row, array(), false, $this->tabindex, $this->type->getScope());
2012-10-07 13:35:10 +00:00
}
2015-11-06 17:04:55 +00:00
2012-10-07 13:35:10 +00:00
/**
* Can be used by subclasses to add e.g. additional buttons to the top area.
2015-11-06 17:04:55 +00:00
*
2012-10-07 13:35:10 +00:00
* @param htmlGroup $left left part
* @param htmlGroup $right right part
*/
protected function addExtraInputElementsToTopArea(&$left, &$right) {
// only used by subclasses
2007-02-11 18:06:42 +00:00
}
2015-11-06 17:04:55 +00:00
2018-06-25 16:07:26 +00:00
/**
* Prints the header part of the page.
*/
private function printHeader() {
include 'adminHeader.inc';
$this->printHeaderContent();
}
/**
* Prints any extra HTML for the header part.
*/
protected function printHeaderContent() {
// implemented by child classes if needed
2006-01-01 16:30:05 +00:00
}
2015-11-06 17:04:55 +00:00
2018-06-25 16:07:26 +00:00
/**
* Prints the footer area of the page.
*/
private function printFooter() {
$this->printFooterContent();
include 'adminFooter.inc';
}
/**
* Prints any extra HTML for the footer part.
*/
protected function printFooterContent() {
2010-08-31 17:35:36 +00:00
?>
2015-05-14 11:49:56 +00:00
<input type="hidden" name="<?php echo getSecurityTokenName(); ?>" value="<?php echo getSecurityTokenValue(); ?>">
2010-08-31 17:35:36 +00:00
</form></div></div>
<script type="text/javascript">
jQuery(document).ready(function() {
2016-12-24 12:04:31 +00:00
jQuery('#tab_<?php echo $this->type->getId(); ?>').addClass('ui-tabs-active');
jQuery('#tab_<?php echo $this->type->getId(); ?>').addClass('ui-state-active');
2010-08-31 17:35:36 +00:00
});
</script>
<?php
}
2006-09-23 11:19:36 +00:00
2006-01-01 16:30:05 +00:00
/**
* Returns an hash array containing with all attributes to be shown and their descriptions.
* Format: array(attribute => description)
*
* @return array attribute list
*/
protected function listGetAttributeDescriptionList() {
2016-12-24 12:04:31 +00:00
$attrs = $this->type->getAttributes();
2006-01-01 16:30:05 +00:00
$ret = array();
2016-12-24 12:04:31 +00:00
foreach ($attrs as $attr) {
$ret[$attr->getAttributeName()] = $attr->getAlias();
}
2006-01-01 16:30:05 +00:00
return $ret;
}
2006-09-23 11:19:36 +00:00
2006-01-01 16:30:05 +00:00
/**
* Sets some internal parameters.
*/
protected function listGetParams() {
if (isset($_GET['accountEditBack'])) {
$this->refresh = true;
return;
}
2010-01-04 20:50:39 +00:00
// check if only PDF should be shown
if (isset($_GET['printPDF'])) {
$this->showPDFPage(null);
2010-01-04 20:50:39 +00:00
exit();
}
2006-01-01 16:30:05 +00:00
// get current page
2018-12-23 10:01:29 +00:00
if (!empty($_GET["page"])) {
$this->page = $_GET["page"];
}
else {
$this->page = 1;
}
2006-01-01 16:30:05 +00:00
// generate attribute-description table
$temp_array = $this->listGetAttributeDescriptionList();
$this->attrArray = array_keys($temp_array); // list of LDAP attributes to show
$this->descArray = array_values($temp_array); // list of descriptions for the attributes
// get sorting column
if (isset($_GET["sort"])) {
if ($_GET["sort"] == $this->sortColumn) {
$this->sortDirection = -$this->sortDirection;
}
else {
$this->sortColumn = $_GET["sort"];
$this->sortDirection = 1;
}
}
else {
$this->sortColumn = strtolower($this->attrArray[0]);
$this->sortDirection = 1;
}
// get sort order
if (isset($_GET['sortdirection'])) {
2018-10-27 12:39:37 +00:00
$this->sortDirection = htmlspecialchars($_GET['sortdirection']);
}
2006-01-01 16:30:05 +00:00
// check search suffix
2016-12-24 12:04:31 +00:00
if (isset($_POST['suffix'])) {
// new suffix selected via combobox
$this->suffix = $_POST['suffix'];
}
elseif (isset($_GET['suffix'])) {
// new suffix selected via combobox
$this->suffix = $_GET['suffix'];
}
elseif (!$this->suffix) {
// default suffix
$this->suffix = $this->type->getSuffix();
}
2006-01-01 16:30:05 +00:00
// check if LDAP data should be refreshed
$this->refresh = true;
if (isset($_GET['norefresh'])) {
$this->refresh = false;
}
if (isset($_POST['refresh'])) {
2010-02-13 19:05:33 +00:00
$this->refresh = true;
}
if (isset($_POST['apply_filter']) || isset($_POST['clear_filter'])) {
if ($this->serverSideFilterChanged) {
$this->refresh = true;
}
}
2006-01-01 16:30:05 +00:00
}
2006-09-23 11:19:36 +00:00
2006-01-01 16:30:05 +00:00
/**
* Rereads the entries from LDAP.
*/
protected function listRefreshData() {
2012-04-20 18:24:13 +00:00
// check suffix
if (!$this->suffix) {
2016-12-24 12:04:31 +00:00
$this->suffix = $this->type->getSuffix(); // default suffix
2012-04-20 18:24:13 +00:00
}
2006-01-01 16:30:05 +00:00
// configure search filter
2016-12-24 12:04:31 +00:00
$module_filter = get_ldap_filter($this->type->getId()); // basic filter is provided by modules
$filter = "(&" . $module_filter . $this->buildLDAPAttributeFilter() . ")";
2006-01-01 16:30:05 +00:00
$attrs = $this->attrArray;
// remove virtual attributes from list
for ($i = 0; $i < sizeof($attrs); $i++) {
if (strpos($attrs[$i], self::VIRTUAL_ATTRIBUTE_PREFIX) === 0) {
unset($attrs[$i]);
}
}
$attrs = array_values($attrs);
// include additional attributes
$additionalAttrs = $this->getAdditionalLDAPAttributesToRead();
for ($i = 0; $i < sizeof($additionalAttrs); $i++) {
if (!in_array_ignore_case($additionalAttrs[$i], $attrs)) {
$attrs[] = $additionalAttrs[$i];
}
}
$this->ldapEntries = searchLDAP($this->suffix, $filter, $attrs);
$this->entries = array();
foreach ($this->ldapEntries as $index => &$attrs) {
$this->entries[$index] = &$attrs;
}
2010-02-14 18:01:20 +00:00
$lastError = getLastLDAPError();
if ($lastError != null) {
call_user_func_array('StatusMessage', $lastError);
}
2006-01-01 16:30:05 +00:00
// generate list of possible suffixes
2016-12-31 13:44:46 +00:00
$this->possibleSuffixes = $this->type->getSuffixList();
}
2015-11-06 17:04:55 +00:00
/**
* Builds the LDAP filter based on the filter entries in the GUI.
2015-11-06 17:04:55 +00:00
*
* @return String LDAP filter
*/
protected function buildLDAPAttributeFilter() {
$text = '';
foreach ($this->filters as $attr => $filter) {
if (!$this->isAttributeFilteredByServer($attr)) {
continue;
}
$text .= '(' . $attr . '=' . $filter . ')';
}
return $text;
}
2015-11-06 17:04:55 +00:00
/**
* Specifies if the given attribute name is used for server side filtering (LDAP filter string).
*
* @param string $attrName attribute name
* @return bool filter server side
*/
protected function isAttributeFilteredByServer($attrName) {
2018-08-16 16:30:52 +00:00
return in_array(strtolower($attrName), $this->serverSideFilterAttributes);
}
2018-05-31 06:58:30 +00:00
/**
* Applies any local filters for attributes that cannot be filtered server side.
*/
protected function applyLocalFilters() {
$this->entries = array();
foreach ($this->ldapEntries as $index => &$data) {
$this->entries[$index] = &$data;
}
$toFilter = array();
foreach ($this->filters as $filterAttribute => $filterValue) {
if ($this->isAttributeFilteredByServer($filterAttribute) || ($filterValue === '')) {
continue;
}
foreach ($this->entries as $index => &$data) {
if (in_array($index, $toFilter)) {
continue;
}
$regex = str_replace(array('*'), array('.*'), $filterValue);
$regex = '/^' . $regex . '$/i';
if (!$this->isFilterMatching($data, $filterAttribute, $regex)) {
$toFilter[] = $index;
}
}
}
foreach ($toFilter as $index) {
unset($this->entries[$index]);
}
$this->entries = array_values($this->entries);
}
/**
* Checks if the given LDAP data matches the filter.
*
* @param array $data LDAP attributes
* @param string $filterAttribute filter attribute name
* @param string $regex filter attribute regex
*/
protected function isFilterMatching(&$data, $filterAttribute, $regex) {
if (!isset($data[$filterAttribute])) {
return false;
}
foreach ($data[$filterAttribute] as $value) {
if (preg_match($regex, $value)) {
return true;
}
}
return false;
}
2013-01-20 19:14:16 +00:00
/**
* Forces a refresh of the LDAP data.
* Function must be called before $this->refresh option is checked to load new LDAP data (e.g. in listGetParams).
*/
protected function forceRefresh() {
$this->refresh = true;
if (isset($_GET['norefresh'])) {
unset($_GET['norefresh']);
}
}
2015-11-06 17:04:55 +00:00
/**
* Returns a list of additional LDAP attributes that should be read.
* This can be used to show additional data even if the user selected other attributes to show in the list.
2015-11-06 17:04:55 +00:00
*
* @return array additional attribute names
*/
protected function getAdditionalLDAPAttributesToRead() {
return array();
}
2015-11-06 17:04:55 +00:00
2007-02-11 18:06:42 +00:00
/**
* Returns a list of lamListTool objects to display next to the edit/delete buttons.
*
* @return lamListTool[] tools
2007-02-11 18:06:42 +00:00
*/
protected function getAdditionalTools() {
return array();
2007-02-11 18:06:42 +00:00
}
2015-11-06 17:04:55 +00:00
/**
* Returns a list of possible configuration options.
*
* @return array list of lamListOption objects
*/
protected function listGetAllConfigOptions() {
$listSizeOption = new lamSelectListOption(_("Maximum list entries"), array(10, 20, 30, 50, 75, 100, 500, 1000), self::LIST_SIZE_OPTION_NAME);
2010-09-26 11:12:02 +00:00
$listSizeOption->setHelpID('208');
$listSizeOption->setValue($this->maxPageEntries);
return array($listSizeOption);
}
/**
* Prints the list configuration page.
*/
protected function listPrintConfigurationPage() {
2018-10-27 09:42:45 +00:00
echo "<div id=\"settingsDialog\" class=\"hidden dialog-content\">\n";
2016-12-24 12:04:31 +00:00
echo "<form id=\"settingsDialogForm\" action=\"list.php?type=" . $this->type->getId() . "&amp;norefresh=true\" method=\"post\">\n";
2015-11-06 17:04:55 +00:00
2018-10-27 09:42:45 +00:00
$configContainer = new htmlResponsiveRow();
for ($i = 0; $i < sizeof($this->configOptions); $i++) {
2018-10-27 09:42:45 +00:00
$configContainer->add($this->configOptions[$i]->getMetaHTML(), 12);
}
2018-10-27 09:42:45 +00:00
$configContainer->add(new htmlHiddenInput('saveConfigOptions', 'ok'), 12);
2015-05-14 11:49:56 +00:00
addSecurityTokenToMetaHTML($configContainer);
2015-11-06 17:04:55 +00:00
2016-12-24 12:04:31 +00:00
parseHtml('', $configContainer, array(), false, $this->tabindex, $this->type->getScope());
2011-04-09 10:04:56 +00:00
echo '</form>';
echo "</div>\n";
}
2015-11-06 17:04:55 +00:00
/**
* Returns the configuration option with the given ID.
*
* @param String $ID ID
*/
protected function listGetConfigOptionByID($ID) {
for ($i = 0; $i < sizeof($this->configOptions); $i++) {
if ($this->configOptions[$i]->getID() === $ID) {
return $this->configOptions[$i];
}
}
return null;
}
2015-11-06 17:04:55 +00:00
/**
* Called when the configuration options changed.
*/
protected function listConfigurationChanged() {
$sizeOption = $this->listGetConfigOptionByID(self::LIST_SIZE_OPTION_NAME);
if ($sizeOption->getValue() != null) {
$this->maxPageEntries = $sizeOption->getValue();
}
return;
}
/**
* Prints messages when another page (e.g. delete/upload) redirects to the list view.
*/
protected function listPrintRedirectMessages() {
if (isset($_GET['deleteAllOk'])) {
StatusMessage('INFO', _('Deletion was successful.'));
}
2010-11-28 15:27:27 +00:00
elseif (isset($_GET['uploadAllOk'])) {
StatusMessage('INFO', _("Upload has finished"));
2012-02-05 10:38:59 +00:00
if (isset($_SESSION['mass_pdf']['file'])) {
2016-12-07 20:18:06 +00:00
StatusMessage('INFO', sprintf(_('You can download your PDF files {link=%s}{color=#d2131a}here{endcolor}{endlink}.'), $_SESSION['mass_pdf']['file']));
2012-02-05 10:38:59 +00:00
}
2010-11-28 15:27:27 +00:00
}
elseif (isset($_GET['accountEditInvalidID'])) {
StatusMessage('WARN', _('Please do not edit multiple accounts in parallel in multiple browser tabs.'));
}
2012-06-05 18:20:17 +00:00
if (isset($_SESSION['listRedirectMessages'])) {
2010-11-28 15:27:27 +00:00
for ($i = 0; $i < sizeof($_SESSION['listRedirectMessages']); $i++) {
call_user_func_array('StatusMessage', $_SESSION['listRedirectMessages'][$i]);
}
unset($_SESSION['listRedirectMessages']);
}
}
}
/**
* Represents a tool which can be included in the account lists.
*
* @package lists
* @author Roland Gruber
*/
class lamListTool {
2015-11-06 17:04:55 +00:00
2012-07-15 12:05:47 +00:00
/** tool name */
private $name;
2012-07-15 12:05:47 +00:00
/** tool image */
private $image;
2012-07-15 12:05:47 +00:00
/** link target */
private $target;
2015-11-06 17:04:55 +00:00
/**
* Constructor
*
* @param String $name tool name
* @param String $image image file
* @param String $target target page
* @return lamListTool tool object
*/
2007-12-28 16:08:56 +00:00
public function __construct($name, $image, $target) {
$this->name = $name;
$this->image = $image;
$this->target = $target;
}
/**
* Returns the name of the tool image.
* The image is returned without path (e.g. mytool.png). All images must reside in the graphics folder.
*
* @return String image name
*/
public function getImage() {
return $this->image;
}
/**
* Returns the tool name.
* This is used for the tool tip.
*
* @return String name
*/
public function getName() {
return $this->name;
}
/**
* Returns the PHP file (relative to 'templates/lists') which will be the target for this tool.
* The target page will be opened with two GET parameters: DN and type (e.g. user)
2015-11-06 17:04:55 +00:00
*
* @return String page file (e.g. 'mytool.php')
*/
public function getLinkTarget() {
return $this->target;
}
2006-01-01 16:30:05 +00:00
}
/**
* Represents a list configuration option.
*
* @package lists
* @author Roland Gruber
*/
abstract class lamListOption {
2015-11-06 17:04:55 +00:00
2012-07-15 12:05:47 +00:00
/** unique ID */
private $ID;
2012-07-15 12:05:47 +00:00
/** option value */
private $value;
2015-11-06 17:04:55 +00:00
/**
* Creates a new config option.
*
* @param String $ID unique ID
* @return lamConfigOption config option
*/
2007-12-28 16:08:56 +00:00
public function __construct($ID) {
$this->ID = $ID;
}
2015-11-06 17:04:55 +00:00
/**
* Returns the option ID.
*
* @return String ID
*/
public function getID() {
return $this->ID;
}
2015-11-06 17:04:55 +00:00
/**
* Fills the config option from POST data.
2015-11-06 17:04:55 +00:00
*
* @return array list of StatusMessages (array(<type>, <head line>, <body>))
*/
public abstract function fillFromPostData();
2015-11-06 17:04:55 +00:00
/**
* Returns the option value. The value must not contain "=" and ";".
*
* @return String value
*/
public function getValue() {
return $this->value;
}
2015-11-06 17:04:55 +00:00
/**
* Sets the config option value. The value must not contain "=" and ";".
*
* @param String $value
*/
public function setValue($value) {
if ((strpos($value, '=') > -1) || (strpos($value, ';') > -1)) {
user_error("Invalid value for list option: " . $value, E_ERROR);
}
$this->value = $value;
}
2015-11-06 17:04:55 +00:00
/**
* Returns the meta HTML data to display this option.
2015-11-06 17:04:55 +00:00
*
2018-10-27 09:42:45 +00:00
* @return htmlResponsiveRow meta HTML
*/
public abstract function getMetaHTML();
2015-11-06 17:04:55 +00:00
}
/**
* Boolean option for list configuration.
*
* @package lists
* @author Roland Gruber
*/
class lamBooleanListOption extends lamListOption {
2015-11-06 17:04:55 +00:00
2012-07-15 12:05:47 +00:00
/** option name */
private $name;
2015-11-06 17:04:55 +00:00
/**
* Creates a new boolean option.
*
* @param String $name name to show on config page
* @param String $ID unique ID
* @return lamBooleanListOption config option
*/
2007-12-28 16:08:56 +00:00
public function __construct($name, $ID) {
parent::__construct($ID);
$this->name = $name;
}
2015-11-06 17:04:55 +00:00
/**
* Returns if this option is selected.
*
* @return boolean true, if selected
*/
public function isSelected() {
return ($this->getValue() === "1");
}
2015-11-06 17:04:55 +00:00
/**
* Fills the config option from POST data.
2015-11-06 17:04:55 +00:00
*
* @return array list of StatusMessages (array(<type>, <head line>, <body>))
*/
public function fillFromPostData() {
if (isset($_POST[$this->getID()])) {
$this->setValue("1");
}
else {
$this->setValue("0");
}
}
/**
2018-10-27 09:42:45 +00:00
* {@inheritDoc}
* @see lamListOption::getMetaHTML()
*/
public function getMetaHTML() {
2018-10-27 09:42:45 +00:00
$return = new htmlResponsiveRow();
$return->add(new htmlResponsiveInputCheckbox($this->getID(), $this->isSelected(), $this->name), 12);
return $return;
}
}
/**
* Boolean option for list configuration.
*
* @package lists
* @author Roland Gruber
*/
class lamSelectListOption extends lamListOption {
2015-11-06 17:04:55 +00:00
2012-07-15 12:05:47 +00:00
/** option name */
private $name;
2012-07-15 12:05:47 +00:00
/** possible select options */
private $options;
2012-07-15 12:05:47 +00:00
/** help ID */
private $helpID;
2015-11-06 17:04:55 +00:00
/**
* Creates a new selection list option.
*
* @param String $name name to show on config page
* @param array $options list of possible values
* @param String $ID unique ID
* @return lamBooleanListOption config option
*/
2007-12-28 16:08:56 +00:00
public function __construct($name, $options, $ID) {
parent::__construct($ID);
$this->name = $name;
$this->options = $options;
}
2015-11-06 17:04:55 +00:00
/**
* Sets the help ID.
*
* @param Strign $id help ID
*/
public function setHelpID($id) {
$this->helpID = $id;
}
2015-11-06 17:04:55 +00:00
/**
* Fills the config option from POST data.
2015-11-06 17:04:55 +00:00
*
* @return array list of StatusMessages (array(<type>, <head line>, <body>))
*/
public function fillFromPostData() {
if (isset($_POST[$this->getID()])) {
$this->setValue($_POST[$this->getID()]);
}
else {
$this->setValue(null);
}
}
/**
2018-10-27 09:42:45 +00:00
* {@inheritDoc}
* @see lamListOption::getMetaHTML()
*/
public function getMetaHTML() {
2018-10-27 09:42:45 +00:00
$return = new htmlResponsiveRow();
$return->add(new htmlResponsiveSelect($this->getID(), $this->options, array($this->getValue()), $this->name, $this->helpID), 12);
return $return;
}
2015-11-06 17:04:55 +00:00
}
2004-05-31 20:10:36 +00:00
?>