mirror of
https://gitlab.easter-eggs.com/ee/ldapsaisie.git
synced 2024-12-20 23:43:49 +01:00
1353 lines
38 KiB
PHP
1353 lines
38 KiB
PHP
<?php
|
|
/*******************************************************************************
|
|
* Copyright (C) 2007 Easter-eggs
|
|
* http://ldapsaisie.labs.libre-entreprise.org
|
|
*
|
|
* Author: See AUTHORS file in top-level directory.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License version 2
|
|
* as published by the Free Software Foundation.
|
|
*
|
|
* 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.
|
|
|
|
******************************************************************************/
|
|
|
|
/**
|
|
* Object LSsearch
|
|
*
|
|
* @author Benjamin Renard <brenard@easter-eggs.com>
|
|
*/
|
|
class LSsearch {
|
|
|
|
// The LdapObject type of search
|
|
private $LSobject=NULL;
|
|
|
|
// The configuration of search
|
|
private $config;
|
|
|
|
// The context of search
|
|
private $context;
|
|
|
|
// The parameters of the search
|
|
private $params=array (
|
|
// Search params
|
|
'filter' => NULL,
|
|
'pattern' => NULL,
|
|
'predefinedFilter' => false,
|
|
'basedn' => NULL,
|
|
'subDn' => NULL,
|
|
'scope' => NULL,
|
|
'sizelimit' => 0,
|
|
'attronly' => false, // If true, only attribute names are returned
|
|
'approx' => false,
|
|
'recursive' => false,
|
|
'attributes' => array(),
|
|
// Display params
|
|
'onlyAccessible' => NULL,
|
|
'sortDirection' => NULL,
|
|
'sortBy' => NULL,
|
|
'sortlimit' => 0,
|
|
'displaySubDn' => NULL,
|
|
'displayFormat' => NULL,
|
|
'nbObjectsByPage' => NB_LSOBJECT_LIST,
|
|
'nbPageLinkByPage' => 10,
|
|
'customInfos' => array(),
|
|
'withoutCache' => false,
|
|
'extraDisplayedColumns' => false,
|
|
);
|
|
|
|
// The cache of search parameters
|
|
private $_searchParams = NULL;
|
|
|
|
// The cache of the hash of the search parameters
|
|
private $_hash = NULL;
|
|
|
|
// The result of the search
|
|
private $result=NULL;
|
|
|
|
// Caches
|
|
private $_canCopy=NULL;
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* @param[in] $LSobject string The LdapObject type of search
|
|
* @param[in] $context string Context of search (LSrelation / LSldapObject/ ...)
|
|
* @param[in] $params array Parameters of search
|
|
* @param[in] $purgeParams boolean If params in session have to be purged
|
|
*
|
|
**/
|
|
function LSsearch($LSobject,$context,$params=null,$purgeParams=false) {
|
|
if (!LSsession :: loadLSobject($LSobject)) {
|
|
return;
|
|
}
|
|
$this -> LSobject = $LSobject;
|
|
|
|
$this -> loadConfig();
|
|
|
|
if (isset($_REQUEST['LSsearchPurgeSession'])) {
|
|
$this -> purgeSession();
|
|
}
|
|
|
|
$this -> context = $context;
|
|
|
|
if (!$purgeParams) {
|
|
if (! $this -> loadParamsFromSession()) {
|
|
LSdebug('LSsearch : load default parameters');
|
|
$this -> loadDefaultParameters();
|
|
}
|
|
}
|
|
else {
|
|
$this -> purgeParams();
|
|
$this -> loadDefaultParameters();
|
|
}
|
|
|
|
if (is_array($params)) {
|
|
$this -> setParams($params);
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Load configuration from LSconfig
|
|
*
|
|
* @retval void
|
|
*/
|
|
private function loadConfig() {
|
|
$this -> config = LSconfig::get("LSobjects.".$this -> LSobject.".LSsearch");
|
|
if (is_array($this -> config['predefinedFilters'])) {
|
|
foreach($this -> config['predefinedFilters'] as $filter => $label) {
|
|
if(!LSldap::isValidFilter($filter)) {
|
|
LSerror::addErrorCode('LSsearch_15',array('label' => $label, 'filter' => $filter, 'type' => $this -> LSobject));
|
|
unset($this -> config['predefinedFilters'][$key]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Load default search parameters from configuration
|
|
*
|
|
* @retval boolean True on success or False
|
|
*/
|
|
private function loadDefaultParameters() {
|
|
if (is_array($this -> config['params'])) {
|
|
return $this -> setParams($this -> config['params']);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Load search parameters from session
|
|
*
|
|
* @retval boolean True if params has been loaded from session or False
|
|
*/
|
|
private function loadParamsFromSession() {
|
|
LSdebug('LSsearch : load context params session '.$this -> context);
|
|
if (isset($_SESSION['LSsession']['LSsearch'][$this -> LSobject]['params'][$this -> context]) && is_array($_SESSION['LSsession']['LSsearch'][$this -> LSobject]['params'][$this -> context])) {
|
|
$params = $_SESSION['LSsession']['LSsearch'][$this -> LSobject]['params'][$this -> context];
|
|
|
|
if ($params['filter']) {
|
|
$params['filter'] = Net_LDAP2_Filter::parse($params['filter']);
|
|
}
|
|
|
|
$this -> params = $params;
|
|
return true;
|
|
}
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* Save search parameters in session
|
|
*
|
|
* @retval void
|
|
*/
|
|
private function saveParamsInSession() {
|
|
LSdebug('LSsearch : save context params session '.$this -> context);
|
|
$params = $this -> params;
|
|
if ($params['filter'] instanceof Net_LDAP2_Filter) {
|
|
$params['filter'] = $params['filter'] -> asString();
|
|
}
|
|
|
|
foreach ($params as $param => $value) {
|
|
if ( !isset($_SESSION['LSsession']['LSsearch'][$this -> LSobject]['params'][$this -> context][$param]) || $_SESSION['LSsession']['LSsearch'][$this -> LSobject]['params'][$this -> context][$param]!=$value) {
|
|
LSdebug("S: $param => $value");
|
|
$_SESSION['LSsession']['LSsearch'][$this -> LSobject]['params'][$this -> context][$param]=$value;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Purge parameters in session
|
|
*
|
|
* @param[in] $LSobject string The LSobject type
|
|
*
|
|
* @retval void
|
|
*/
|
|
public function purgeParams($LSobject=NULL) {
|
|
if (is_null($LSobject)) {
|
|
$LSobject = $this -> LSobject;
|
|
}
|
|
unset($_SESSION['LSsession']['LSsearch'][$LSobject]['params']);
|
|
}
|
|
|
|
/**
|
|
* Purge cache
|
|
*
|
|
* @retval void
|
|
*/
|
|
public function purgeCache($LSobject=NULL) {
|
|
if (is_null($LSobject))
|
|
$LSobject = $this -> LSobject;
|
|
unset($_SESSION['LSsession']['LSsearch'][$LSobject]);
|
|
}
|
|
|
|
/**
|
|
* Purge session
|
|
*
|
|
* @retval void
|
|
*/
|
|
private function purgeSession() {
|
|
unset($_SESSION['LSsession']['LSsearch']);
|
|
}
|
|
|
|
/**
|
|
* Define one search parameter
|
|
*
|
|
* @param[in] $param string The parameter name
|
|
* @param[in] $value mixed The parameter value
|
|
*
|
|
* @retval boolean True on success or False
|
|
*/
|
|
public function setParam($param,$value) {
|
|
return $this -> setParams(array($param => $value));
|
|
}
|
|
|
|
/**
|
|
* Define search parameters
|
|
*
|
|
* @param[in] $params array Parameters of search
|
|
*
|
|
* @retval boolean True on success or False
|
|
*/
|
|
public function setParams($params) {
|
|
$OK=true;
|
|
|
|
// Filter
|
|
if (isset($params['filter'])) {
|
|
if (is_string($params['filter'])) {
|
|
$filter = Net_LDAP2_Filter::parse($params['filter']);
|
|
if (!LSerror::isLdapError($filter)) {
|
|
$this -> params['filter'] = $filter;
|
|
}
|
|
else {
|
|
LSerror :: addErrorCode('LSsearch_01',$params['filter']);
|
|
$OK=false;
|
|
}
|
|
}
|
|
elseif($params['filter'] instanceof Net_LDAP2_Filter) {
|
|
$this -> params['filter'] =& $params['filter'];
|
|
}
|
|
}
|
|
|
|
// Approx
|
|
if (isset($params['approx'])) {
|
|
if (is_bool($params['approx']) || $params['approx']==0 || $params['approx']==1) {
|
|
$this -> params['approx'] = (bool)$params['approx'];
|
|
}
|
|
else {
|
|
LSerror :: addErrorCode('LSsearch_05','approx');
|
|
$OK=false;
|
|
}
|
|
}
|
|
|
|
// Without Cache
|
|
if (isset($params['withoutCache'])) {
|
|
if (is_bool($params['withoutCache']) || $params['withoutCache']==0 || $params['withoutCache']==1) {
|
|
$this -> params['withoutCache'] = (bool)$params['withoutCache'];
|
|
}
|
|
else {
|
|
LSerror :: addErrorCode('LSsearch_05','withoutCache');
|
|
$OK=false;
|
|
}
|
|
}
|
|
|
|
// Patterm
|
|
if (isset($params['pattern'])) {
|
|
if ($params['pattern']=="") {
|
|
$this -> params['pattern'] = NULL;
|
|
$this -> params['filter'] = NULL;
|
|
}
|
|
elseif ($this -> isValidPattern($params['pattern'])) {
|
|
$this -> params['pattern'] = $params['pattern'];
|
|
if (!is_string($params['filter'])) {
|
|
$this -> params['filter']=NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// BaseDN
|
|
if (isset($params['basedn']) && is_string($params['basedn'])) {
|
|
if (isCompatibleDNs(LSsession :: getRootDn(),$params['basedn'])) {
|
|
$this -> params['basedn'] = $params['basedn'];
|
|
}
|
|
else {
|
|
LSerror :: addErrorCode('LSsearch_02',$params['basedn']);
|
|
$OK=false;
|
|
}
|
|
}
|
|
|
|
// subDn
|
|
if (isset($params['subDn']) && is_string($params['subDn'])) {
|
|
if (LSsession :: validSubDnLdapServer($params['subDn'])) {
|
|
$this -> params['subDn'] = $params['subDn'];
|
|
}
|
|
else {
|
|
LSerror :: addErrorCode('LSsearch_03','subDn');
|
|
$OK=false;
|
|
}
|
|
}
|
|
|
|
// Scope
|
|
if (isset($params['scope']) && is_string($params['scope'])) {
|
|
if (in_array($params['scope'],array('sub','one','base'))) {
|
|
$this -> params['scope'] = $params['scope'];
|
|
}
|
|
else {
|
|
LSerror :: addErrorCode('LSsearch_03','scope');
|
|
$OK=false;
|
|
}
|
|
}
|
|
|
|
// nbObjectsByPage
|
|
if (isset($params['nbObjectsByPage'])) {
|
|
if (((int)$params['nbObjectsByPage'])>1 ) {
|
|
$this -> params['nbObjectsByPage'] = (int)$params['nbObjectsByPage'];
|
|
}
|
|
else {
|
|
LSerror :: addErrorCode('LSsearch_03','nbObjectsByPage');
|
|
$OK=false;
|
|
}
|
|
}
|
|
|
|
// Sort Limit
|
|
if (isset($params['sortlimit'])) {
|
|
if (is_int($params['sortlimit']) && $params['sortlimit']>=0 ) {
|
|
$this -> params['sortlimit'] = $params['sortlimit'];
|
|
}
|
|
elseif ((int)$params['sortlimit'] > 0) {
|
|
$this -> params['sortlimit'] = (int)$params['sortlimit'];
|
|
}
|
|
else {
|
|
LSerror :: addErrorCode('LSsearch_03','sortlimit');
|
|
$OK=false;
|
|
}
|
|
}
|
|
|
|
// Sort Direction
|
|
if (isset($params['sortDirection']) && is_string($params['sortDirection'])) {
|
|
if (in_array($params['sortDirection'],array('ASC','DESC'))) {
|
|
$this -> params['sortDirection'] = $params['sortDirection'];
|
|
}
|
|
else {
|
|
LSerror :: addErrorCode('LSsearch_03','sortDirection');
|
|
$OK=false;
|
|
}
|
|
}
|
|
|
|
// Sort By
|
|
if (isset($params['sortBy']) && is_string($params['sortBy'])) {
|
|
if (in_array($params['sortBy'],array('displayName','subDn')) || ($this ->extraDisplayedColumns && isset($this ->extraDisplayedColumns[$params['sortBy']]))) {
|
|
if ($this -> params['sortBy'] == $params['sortBy']) {
|
|
$this -> toggleSortDirection();
|
|
}
|
|
else {
|
|
$this -> params['sortBy'] = $params['sortBy'];
|
|
if (!is_string($params['sortDirection'])) {
|
|
$this -> params['sortDirection']='ASC';
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
LSerror :: addErrorCode('LSsearch_03','sortBy');
|
|
$OK=false;
|
|
}
|
|
}
|
|
|
|
// Size Limit
|
|
if (isset($params['sizelimit'])) {
|
|
if (((int)$params['sizelimit']) >= 0) {
|
|
$this -> params['sizelimit'] = $params['sizelimit'];
|
|
}
|
|
else {
|
|
LSerror :: addErrorCode('LSsearch_04');
|
|
$OK=false;
|
|
}
|
|
}
|
|
|
|
// Attronly
|
|
if (isset($params['attronly'])) {
|
|
if (is_bool($params['attronly']) || $params['attronly']==0 || $params['attronly']==1) {
|
|
$this -> params['attronly'] = (bool)$params['attronly'];
|
|
}
|
|
else {
|
|
LSerror :: addErrorCode('LSsearch_05','attronly');
|
|
$OK=false;
|
|
}
|
|
}
|
|
|
|
// Recursive
|
|
if (isset($params['recursive'])) {
|
|
if (is_bool($params['recursive']) || $params['recursive']==0 || $params['recursive']==1) {
|
|
$this -> params['recursive'] = (bool)$params['recursive'];
|
|
}
|
|
else {
|
|
LSerror :: addErrorCode('LSsearch_05','recursive');
|
|
$OK=false;
|
|
}
|
|
}
|
|
|
|
// displaySubDn
|
|
if (isset($params['displaySubDn'])) {
|
|
if (! LSsession :: isSubDnLSobject($this -> LSobject) ) {
|
|
if (is_bool($params['displaySubDn']) || $params['displaySubDn']==0 || $params['displaySubDn']==1) {
|
|
$this -> params['displaySubDn'] = (bool)$params['displaySubDn'];
|
|
}
|
|
else {
|
|
LSerror :: addErrorCode('LSsearch_05','displaySubDn');
|
|
$OK=false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Attributes
|
|
if (isset($params['attributes'])) {
|
|
if (is_string($params['attributes'])) {
|
|
$this -> params['attributes'] = array($params['attributes']);
|
|
}
|
|
elseif (is_array($params['attributes'])) {
|
|
$this -> params['attributes']=array();
|
|
foreach ($params['attributes'] as $attr) {
|
|
if (is_string($attr)) {
|
|
if (LSconfig::get("LSobjects.".$this -> LSobject.".attrs.$attr")) {;
|
|
$this -> params['attributes'][] = $attr;
|
|
}
|
|
else {
|
|
LSerror :: addErrorCode('LSsearch_11',$attr);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
LSerror :: addErrorCode('LSsearch_06');
|
|
$OK=false;
|
|
}
|
|
}
|
|
|
|
// Extra Columns
|
|
if (isset($params['extraDisplayedColumns'])) {
|
|
$this -> params['extraDisplayedColumns']=(bool)$params['extraDisplayedColumns'];
|
|
}
|
|
|
|
// predefinedFilter
|
|
if (isset($params['predefinedFilter'])) {
|
|
if (is_string($params['predefinedFilter'])) {
|
|
if (empty($params['predefinedFilter'])) {
|
|
$this->params['predefinedFilter']=false;
|
|
}
|
|
elseif(is_array($this -> config['predefinedFilters'])) {
|
|
if(isset($this->config['predefinedFilters'][$params['predefinedFilter']])) {
|
|
$this -> params['predefinedFilter'] = $params['predefinedFilter'];
|
|
}
|
|
else {
|
|
LSerror :: addErrorCode('LSsearch_03','predefinedFilter');
|
|
$OK=false;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
LSerror :: addErrorCode('LSsearch_03','predefinedFilter');
|
|
$OK=false;
|
|
}
|
|
}
|
|
|
|
// Display Format
|
|
if (isset($params['displayFormat']) && is_string($params['displayFormat'])) {
|
|
$this -> params['displayFormat'] = $params['displayFormat'];
|
|
}
|
|
|
|
// Custom Infos
|
|
if (isset($params['customInfos']) && is_array($params['customInfos'])) {
|
|
foreach($params['customInfos'] as $name => $data) {
|
|
if(is_array($data['function']) && is_string($data['function'][0])) {
|
|
LSsession::loadLSclass($data['function'][0]);
|
|
}
|
|
if (is_callable($data['function'])) {
|
|
$this -> params['customInfos'][$name] = array (
|
|
'function' => &$data['function'],
|
|
'args' => $data['args']
|
|
);
|
|
}
|
|
else {
|
|
LSerror :: addErrorCode('LSsearch_14',$name);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Only Accessible objects
|
|
if (isset($params['onlyAccessible'])) {
|
|
$this -> params['onlyAccessible'] = (bool)$params['onlyAccessible'];
|
|
}
|
|
|
|
$this -> saveParamsInSession();
|
|
return $OK;
|
|
}
|
|
|
|
/**
|
|
* Return true only if the form is submited
|
|
*
|
|
* @retval boolean True only if the is submited
|
|
**/
|
|
private function formIsSubmited() {
|
|
return isset($_REQUEST['LSsearch_submit']);
|
|
}
|
|
|
|
/**
|
|
* Define search parameters by reading Post Data ($_REQUEST)
|
|
*
|
|
* @retval void
|
|
*/
|
|
public function setParamsFormPostData() {
|
|
$data = $_REQUEST;
|
|
|
|
if (self::formIsSubmited()) {
|
|
// Recursive
|
|
if (is_null($data['recursive'])) {
|
|
$data['recursive']=false;
|
|
}
|
|
else {
|
|
$data['recursive']=true;
|
|
}
|
|
|
|
// Approx
|
|
if (is_null($data['approx'])) {
|
|
$data['approx']=false;
|
|
}
|
|
else {
|
|
$data['approx']=true;
|
|
}
|
|
|
|
if (isset($data['ajax']) && !isset($data['pattern'])) {
|
|
$data['pattern']="";
|
|
}
|
|
}
|
|
|
|
$this -> setParams($data);
|
|
}
|
|
|
|
/**
|
|
* Toggle the sort direction
|
|
*
|
|
* @retval void
|
|
**/
|
|
private function toggleSortDirection() {
|
|
if ($this -> params['sortDirection']=="ASC") {
|
|
$this -> params['sortDirection'] = "DESC";
|
|
}
|
|
else {
|
|
$this -> params['sortDirection'] = "ASC";
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Make a filter object with a pattern of search
|
|
*
|
|
* @param[in] $pattern The pattern of search. If is null, the pattern in params will be used.
|
|
*
|
|
* @retval mixed Net_LDAP2_Filter on success or False
|
|
*/
|
|
function getFilterFromPattern($pattern=NULL) {
|
|
if ($pattern==NULL) {
|
|
$pattern=$this -> params['pattern'];
|
|
}
|
|
if ($this -> isValidPattern($pattern)) {
|
|
$attrsConfig=LSconfig::get("LSobjects.".$this -> LSobject.".LSsearch.attrs");
|
|
$attrsList=array();
|
|
if (!is_array($attrsConfig)) {
|
|
foreach(LSconfig::get("LSobjects.".$this -> LSobject.".attrs") as $attr => $config) {
|
|
$attrsList[$attr]=array();
|
|
}
|
|
}
|
|
else {
|
|
foreach($attrsConfig as $key => $val) {
|
|
if(is_int($key)) {
|
|
$attrsList[$val]=array();
|
|
}
|
|
else {
|
|
$attrsList[$key]=$val;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (empty($attrsList)) {
|
|
LSerror :: addErrorCode('LSsearch_07');
|
|
return;
|
|
}
|
|
|
|
$filters=array();
|
|
foreach ($attrsList as $attr => $opts) {
|
|
if ($params['approx']) {
|
|
if (isset($opts['approxLSformat'])) {
|
|
$filter=Net_LDAP2_Filter::parse(getFData($opts['approxLSformat'],array('name'=>$attr,'pattern'=>$pattern)));
|
|
}
|
|
else {
|
|
$filter=Net_LDAP2_Filter::create($attr,'approx',$pattern);
|
|
}
|
|
}
|
|
else {
|
|
if (isset($opts['searchLSformat'])) {
|
|
$filter=Net_LDAP2_Filter::parse(getFData($opts['searchLSformat'],array('name'=>$attr,'pattern'=>$pattern)));
|
|
}
|
|
else {
|
|
$filter=Net_LDAP2_Filter::create($attr,'contains',$pattern);
|
|
}
|
|
}
|
|
|
|
if (!Net_LDAP2::isError($filter)) {
|
|
$filters[]=$filter;
|
|
}
|
|
else {
|
|
LSerror :: addErrorCode('LSsearch_08',array('attr' => $attr,'pattern' => $pattern));
|
|
return;
|
|
}
|
|
}
|
|
if(!empty($filters)) {
|
|
$filter=LSldap::combineFilters('or',$filters);
|
|
if ($filter) {
|
|
return $filter;
|
|
}
|
|
else {
|
|
LSerror :: addErrorCode('LSsearch_09');
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
LSerror :: addErrorCode('LSsearch_10');
|
|
}
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* Check if search pattern is valid
|
|
*
|
|
* @param[in] $pattern string The pattern
|
|
*
|
|
* @retval boolean True if pattern is valid or False
|
|
**/
|
|
public function isValidPattern($pattern) {
|
|
if (is_string($pattern) && $pattern!= "") {
|
|
$regex = (isset($this -> config['validPatternRegex'])?$this -> config['validPatternRegex']:'/^[\w \-\_\\\'\"^\[\]\(\)\{\}\=\+\£\%\$\€\.\:\;\,\?\/\@]+$/iu');
|
|
if (preg_match($regex, $pattern))
|
|
return True;
|
|
}
|
|
LSerror :: addErrorCode('LSsearch_17');
|
|
return False;
|
|
}
|
|
|
|
/**
|
|
* Check if cache is enabled
|
|
*
|
|
* @retval boolean True if cache is enabled or False
|
|
**/
|
|
public function cacheIsEnabled() {
|
|
if (isset($this -> config['cache'])) {
|
|
$conf=$this -> config['cache'];
|
|
if (is_bool($conf) || $conf==0 || $conf==1) {
|
|
return (bool)$conf;
|
|
}
|
|
else {
|
|
LSerror :: addErrorCode('LSsearch_03','cache');
|
|
}
|
|
}
|
|
return LSsession :: cacheSearch();
|
|
}
|
|
|
|
/**
|
|
* Methode for parameters value access
|
|
*
|
|
* @param[in] $key string The parameter name
|
|
*
|
|
* @retval mixed The parameter value or NULL
|
|
**/
|
|
public function getParam($key) {
|
|
if(in_array($key,array_keys($this -> params))) {
|
|
return $this -> params[$key];
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* Return hidden fileds to add in search form
|
|
*
|
|
* @retval array The hield fields whith their values
|
|
**/
|
|
public function getHiddenFieldForm() {
|
|
return array (
|
|
'LSobject' => $this -> LSobject
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Generate an array with search parameters, only parameters whitch have to be
|
|
* passed to Net_LDAP2 for the LDAP search. This array will be store in
|
|
* $this -> _searchParams private variable.
|
|
*
|
|
* @retval void
|
|
**/
|
|
private function generateSearchParams() {
|
|
// Purge the cache of the hash
|
|
$this -> _hash = NULL;
|
|
|
|
// Base
|
|
$retval = array(
|
|
'filter' => $this -> params['filter'],
|
|
'basedn' => $this -> params['basedn'],
|
|
'scope' => $this -> params['scope'],
|
|
'sizelimit' => $this -> params['sizelimit'],
|
|
'attronly' => $this -> params['attronly'],
|
|
'attributes' => $this -> params['attributes']
|
|
);
|
|
|
|
// Pattern
|
|
if (!is_null($this -> params['pattern'])) {
|
|
$filter=$this ->getFilterFromPattern();
|
|
if (is_null($retval['filter'])) {
|
|
$retval['filter']=$filter;
|
|
}
|
|
else {
|
|
$retval['filter']=LSldap::combineFilters('and',array($retval['filter'],$filter));
|
|
}
|
|
}
|
|
|
|
// predefinedFilter
|
|
if (is_string($this -> params['predefinedFilter'])) {
|
|
if (!is_null($retval['filter'])) {
|
|
$filter=LSldap::combineFilters('and',array($this -> params['predefinedFilter'],$retval['filter']));
|
|
if ($filter) {
|
|
$retval['filter']=$filter;
|
|
}
|
|
}
|
|
else {
|
|
$retval['filter']=$this -> params['predefinedFilter'];
|
|
}
|
|
}
|
|
|
|
// Filter
|
|
$objFilter=LSldapObject::getObjectFilter($this -> LSobject);
|
|
if ($objFilter) {
|
|
if (!is_null($retval['filter'])) {
|
|
$filter=LSldap::combineFilters('and',array($objFilter,$retval['filter']));
|
|
if ($filter) {
|
|
$retval['filter']=$filter;
|
|
}
|
|
}
|
|
else {
|
|
$retval['filter']=$objFilter;
|
|
}
|
|
}
|
|
|
|
// Recursive
|
|
if (is_null($retval['basedn'])) {
|
|
if (!is_null($this -> params['subDn'])) {
|
|
if ($this -> params['recursive']) {
|
|
$retval['basedn'] = $this -> params['subDn'];
|
|
}
|
|
else {
|
|
$retval['basedn'] = LSconfig::get("LSobjects.".$this -> LSobject.".container_dn").','.$this -> params['subDn'];
|
|
}
|
|
}
|
|
else {
|
|
if ($this -> params['recursive']) {
|
|
$retval['basedn'] = LSsession :: getTopDn();
|
|
}
|
|
else {
|
|
$retval['basedn'] = LSconfig::get("LSobjects.".$this -> LSobject.".container_dn").','.LSsession :: getTopDn();
|
|
}
|
|
}
|
|
}
|
|
if ($this -> params['recursive'] || !isset($retval['scope'])) {
|
|
$retval['scope'] = 'sub';
|
|
}
|
|
|
|
if (is_null($this -> params['displayFormat'])) {
|
|
$this -> params['displayFormat']=LSconfig::get("LSobjects.".$this -> LSobject.".display_name_format");
|
|
}
|
|
|
|
// Display Format
|
|
$attrs=getFieldInFormat($this -> params['displayFormat']);
|
|
if(is_array($retval['attributes'])) {
|
|
$retval['attributes']=array_merge($attrs,$retval['attributes']);
|
|
}
|
|
else {
|
|
$retval['attributes']=$attrs;
|
|
}
|
|
|
|
// Extra Columns
|
|
if ($this -> params['extraDisplayedColumns'] && is_array($this -> config['extraDisplayedColumns'])) {
|
|
foreach ($this -> config['extraDisplayedColumns'] as $id => $conf) {
|
|
$attrs=array();
|
|
if (isset($conf['LSformat'])) {
|
|
$attrs=getFieldInFormat($conf['LSformat']);
|
|
if(is_array($conf['alternativeLSformats'])) {
|
|
foreach ($conf['alternativeLSformats'] as $format) {
|
|
$attrs=array_merge($attrs,getFieldInFormat($format));
|
|
}
|
|
}
|
|
else {
|
|
$attrs=array_merge($attrs,getFieldInFormat($conf['alternativeLSformats']));
|
|
}
|
|
if(isset($conf['formaterLSformat'])) {
|
|
$attrs=array_unique(array_merge($attrs,getFieldInFormat($conf['formaterLSformat'])));
|
|
if(($key = array_search('val', $attrs)) !== false) {
|
|
unset($attrs[$key]);
|
|
}
|
|
}
|
|
}
|
|
if(isset($conf['additionalAttrs'])) {
|
|
$attrs=array_unique(array_merge($attrs,(is_array($conf['additionalAttrs'])?$conf['additionalAttrs']:array($conf['additionalAttrs']))));
|
|
}
|
|
if(is_array($retval['attributes'])) {
|
|
$retval['attributes']=array_merge($attrs,$retval['attributes']);
|
|
}
|
|
else {
|
|
$retval['attributes']=$attrs;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (is_array($retval['attributes'])) {
|
|
$retval['attributes']=array_unique($retval['attributes']);
|
|
}
|
|
|
|
$this -> _searchParams = $retval;
|
|
}
|
|
|
|
/**
|
|
* Run the search
|
|
*
|
|
* @param[in] $cache boolean Define if the cache can be used
|
|
*
|
|
* @retval boolean True on success or False
|
|
*/
|
|
public function run($cache=true) {
|
|
$this -> generateSearchParams();
|
|
if ($this -> _searchParams['filter'] instanceof Net_LDAP2_Filter) {
|
|
LSdebug('LSsearch : filter : '.$this -> _searchParams['filter']->asString());
|
|
}
|
|
LSdebug('LSsearch : basedn : '.$this -> _searchParams['basedn'].' - scope : '.$this -> _searchParams['scope']);
|
|
|
|
if( $cache && (!isset($_REQUEST['refresh'])) && (!$this -> params['withoutCache']) ) {
|
|
LSdebug('LSsearch : with the cache');
|
|
$this -> result = $this -> getResultFromCache();
|
|
}
|
|
else {
|
|
LSdebug('LSsearch : without the cache');
|
|
$this -> setParam('withoutCache',false);
|
|
}
|
|
|
|
if (!$this -> result) {
|
|
LSdebug('LSsearch : Not in cache');
|
|
$this -> result=array(
|
|
'sortBy' => NULL,
|
|
'sortDirection' => NULL
|
|
);
|
|
|
|
// Search in LDAP
|
|
$list = LSldap :: search(
|
|
$this -> _searchParams['filter'],
|
|
$this -> _searchParams['basedn'],
|
|
$this -> _searchParams
|
|
);
|
|
|
|
// Check result
|
|
if ($list === false) {
|
|
LSerror :: addErrorCode('LSsearch_12');
|
|
return;
|
|
}
|
|
|
|
if ($this -> getParam('onlyAccessible') && LSsession :: getLSuserObjectDn()) {
|
|
$this -> result['list']=array();
|
|
|
|
// Check user rights on objets
|
|
foreach($list as $id => $obj) {
|
|
if (LSsession :: canAccess($this -> LSobject,$obj['dn'])) {
|
|
$this -> result['list'][]=$obj;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
$this -> result['list']=$list;
|
|
}
|
|
|
|
$this -> addResultToCache();
|
|
}
|
|
|
|
$this -> doSort();
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Return an hash corresponding to the parameters of the search
|
|
*
|
|
* @param[in] $searchParams array An optional search params array
|
|
*
|
|
* @retval string The hash of the parameters of the search
|
|
**/
|
|
public function getHash($searchParams=null) {
|
|
if(is_null($searchParams)) {
|
|
$searchParams=$this -> _searchParams;
|
|
if ($this -> _hash) {
|
|
return $this -> _hash;
|
|
}
|
|
}
|
|
if ($searchParams['filter'] instanceof Net_LDAP_Filter) {
|
|
$searchParams['filter']=$searchParams['filter']->asString();
|
|
}
|
|
return hash('md5',print_r($searchParams,true));
|
|
}
|
|
|
|
/**
|
|
* Add the result of the search to cache of the session
|
|
*
|
|
* @retval void
|
|
**/
|
|
public function addResultToCache() {
|
|
if ($this -> cacheIsEnabled()) {
|
|
LSdebug('LSsearch : Save result in cache.');
|
|
$hash=$this->getHash();
|
|
$_SESSION['LSsession']['LSsearch'][$this -> LSobject][$hash]=$this->result;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the result of the search from cache of the session
|
|
*
|
|
* @retval array | False The array of the result of the search or False
|
|
**/
|
|
private function getResultFromCache() {
|
|
if ($this -> cacheIsEnabled()) {
|
|
$hash=$this->getHash();
|
|
if (isset($_SESSION['LSsession']['LSsearch'][$this -> LSobject][$hash])) {
|
|
LSdebug('LSsearch : Load result from cache.');
|
|
return $_SESSION['LSsession']['LSsearch'][$this -> LSobject][$hash];
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* Get page informations to display
|
|
*
|
|
* @param[in] $page integer The number of the page
|
|
*
|
|
* @retval array The information of the page
|
|
**/
|
|
public function getPage($page=0) {
|
|
if (!LSsession::loadLSclass('LSsearchEntry')) {
|
|
LSerror::addErrorCode('LSsession_05',$this -> LSobject);
|
|
return;
|
|
}
|
|
$page = (int)$page;
|
|
|
|
$retval=array(
|
|
'nb' => $page,
|
|
'nbPages' => 1,
|
|
'list' => array(),
|
|
'total' => $this -> total
|
|
);
|
|
|
|
if ($retval['total']>0) {
|
|
LSdebug('Total : '.$retval['total']);
|
|
|
|
if (!$this->params['nbObjectsByPage']) {
|
|
$this->params['nbObjectsByPage']=NB_LSOBJECT_LIST;
|
|
}
|
|
$retval['nbPages']=ceil($retval['total']/$this->params['nbObjectsByPage']);
|
|
|
|
$sortTable=$this -> getSortTable();
|
|
|
|
$list = array_slice(
|
|
$sortTable,
|
|
($page * $this->params['nbObjectsByPage']),
|
|
$this->params['nbObjectsByPage']
|
|
);
|
|
|
|
foreach ($list as $key => $id) {
|
|
$retval['list'][]=new LSsearchEntry($this,$this -> LSobject,$this -> params,$this -> _hash,$this -> result['list'],$id);
|
|
}
|
|
}
|
|
return $retval;
|
|
}
|
|
|
|
/**
|
|
* Get search entries
|
|
*
|
|
* @retval array The entries
|
|
**/
|
|
public function getSearchEntries() {
|
|
if (!LSsession::loadLSclass('LSsearchEntry')) {
|
|
LSerror::addErrorCode('LSsession_05',$this -> LSobject);
|
|
return;
|
|
}
|
|
$retval=array();
|
|
if ($this -> total>0) {
|
|
$sortTable=$this -> getSortTable();
|
|
|
|
foreach ($sortTable as $key => $id) {
|
|
$retval[]=new LSsearchEntry($this,$this -> LSobject,$this -> params,$this -> _hash,$this -> result['list'],$id);
|
|
}
|
|
}
|
|
return $retval;
|
|
}
|
|
|
|
/**
|
|
* Access to information of this object
|
|
*
|
|
* @param[in] $key string The key of the info
|
|
*
|
|
* @retval mixed The info
|
|
**/
|
|
public function __get($key) {
|
|
$params = array (
|
|
'basedn',
|
|
'sortBy',
|
|
'sortDirection'
|
|
);
|
|
if ($key=='LSobject') {
|
|
return $this -> LSobject;
|
|
}
|
|
elseif (in_array($key,$params)) {
|
|
return $this -> params[$key];
|
|
}
|
|
elseif ($key=='label_objectName') {
|
|
return LSldapObject::getLabel($this -> LSobject);
|
|
}
|
|
elseif ($key=='label_level') {
|
|
return LSsession :: getSubDnLabel();
|
|
}
|
|
elseif ($key=='label_actions') {
|
|
return _('Actions');
|
|
}
|
|
elseif ($key=='label_no_result') {
|
|
return _("This search didn't get any result.");
|
|
}
|
|
elseif ($key=='sort') {
|
|
if (isset($this -> params['sortlimit']) && ($this -> params['sortlimit']>0)) {
|
|
return ($this -> total < $this -> params['sortlimit']);
|
|
}
|
|
return true;
|
|
}
|
|
elseif ($key=='sortlimit') {
|
|
return $this -> params['sortlimit'];
|
|
}
|
|
elseif ($key=='total') {
|
|
return count($this -> result['list']);
|
|
}
|
|
elseif ($key=='label_total') {
|
|
return $this -> total." ".$this -> label_objectName;
|
|
}
|
|
elseif ($key=='displaySubDn') {
|
|
if (LSsession :: subDnIsEnabled()) {
|
|
if (!is_null($this -> params[$key])) {
|
|
return $this -> params[$key];
|
|
}
|
|
else {
|
|
return (! LSsession :: isSubDnLSobject($this -> LSobject) );
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
elseif ($key=='canCopy') {
|
|
if (!is_null($this -> _canCopy))
|
|
return $this -> _canCopy;
|
|
$this -> _canCopy = LSsession :: canCreate($this -> LSobject);
|
|
return $this -> _canCopy;
|
|
}
|
|
elseif ($key=='predefinedFilters') {
|
|
$retval=array();
|
|
if (is_array($this -> config['predefinedFilters'])) {
|
|
foreach($this -> config['predefinedFilters'] as $filter => $label) {
|
|
$retval[$filter]=__($label);
|
|
}
|
|
}
|
|
return $retval;
|
|
}
|
|
elseif ($key=='extraDisplayedColumns') {
|
|
if ($this->params['extraDisplayedColumns'] && is_array($this -> config['extraDisplayedColumns'])) {
|
|
return $this -> config['extraDisplayedColumns'];
|
|
}
|
|
else {
|
|
return False;
|
|
}
|
|
}
|
|
elseif ($key=='visibleExtraDisplayedColumns') {
|
|
if ($this->params['extraDisplayedColumns'] && is_array($this -> config['extraDisplayedColumns'])) {
|
|
$ret=array();
|
|
foreach($this->config['extraDisplayedColumns'] as $col => $conf) {
|
|
if (isset($conf['visibleTo']) && !LSsession :: isLSprofiles($this -> basedn, $conf['visibleTo'])) {
|
|
continue;
|
|
}
|
|
$ret[$col]=$conf;
|
|
}
|
|
return $ret;
|
|
}
|
|
}
|
|
else {
|
|
throw new Exception('Incorrect property !');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Function use with uasort to sort two entry
|
|
*
|
|
* @param[in] $a array One line of result
|
|
* @param[in] $b array One line of result
|
|
*
|
|
* @retval int Value for uasort
|
|
**/
|
|
private function _sortTwoEntry(&$a,&$b) {
|
|
$sortBy = $this -> params['sortBy'];
|
|
$sortDirection = $this -> params['sortDirection'];
|
|
if ($sortDirection=='ASC') {
|
|
$dir = 1;
|
|
}
|
|
else {
|
|
$dir = -1;
|
|
}
|
|
$oa = new LSsearchEntry($this,$this -> LSobject,$this -> params,$this -> _hash,$this -> result['list'],$a);
|
|
$va = $oa->$sortBy;
|
|
$ob = new LSsearchEntry($this,$this -> LSobject,$this -> params,$this -> _hash,$this -> result['list'],$b);
|
|
$vb = $ob->$sortBy;
|
|
|
|
if ($va == $vb) return 0;
|
|
|
|
$val = strnatcmp(strtolower($va), strtolower($vb));
|
|
return $val*$dir;
|
|
}
|
|
|
|
/**
|
|
* Function to run after using the result. It's update the cache
|
|
*
|
|
* IT'S FUNCTION IS VERY IMPORTANT !!!
|
|
*
|
|
* @retval void
|
|
**/
|
|
function afterUsingResult() {
|
|
$this -> addResultToCache();
|
|
}
|
|
|
|
/**
|
|
* Redirect user to object view if the search have only one result
|
|
*
|
|
* @retval boolean True only if user have been redirected
|
|
**/
|
|
function redirectWhenOnlyOneResult() {
|
|
if ($this -> total == 1 && $this -> result && self::formIsSubmited()) {
|
|
LSsession :: redirect('view.php?LSobject='.$this -> LSobject.'&dn='.urlencode($this -> result['list'][0]['dn']));
|
|
}
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* Run the sort if it's enabled and if the result is not in the cache
|
|
*
|
|
* @retval boolean True on success or false
|
|
**/
|
|
function doSort() {
|
|
if (!$this -> sort) {
|
|
LSdebug('doSort : sort is disabled');
|
|
return true;
|
|
}
|
|
if (is_null($this -> params['sortBy'])) {
|
|
return;
|
|
}
|
|
if (is_null($this -> params['sortDirection'])) {
|
|
$this -> params['sortDirection']='ASC';
|
|
}
|
|
|
|
if ($this->total==0) {
|
|
return true;
|
|
}
|
|
|
|
if (isset($this -> result['sort'][$this -> params['sortBy']][$this -> params['sortDirection']])) {
|
|
LSdebug('doSort : from cache');
|
|
return true;
|
|
}
|
|
|
|
LSdebug('doSort : '.$this -> params['sortBy'].' - '.$this -> params['sortDirection']);
|
|
|
|
$this -> result['sort'][$this -> params['sortBy']][$this -> params['sortDirection']]=range(0,($this -> total-1));
|
|
|
|
if (!LSsession :: loadLSClass('LSsearchEntry')) {
|
|
LSerror::addErrorCode('LSsession_05','LSsearchEntry');
|
|
return;
|
|
}
|
|
|
|
if (!uasort(
|
|
$this -> result['sort'][$this -> params['sortBy']][$this -> params['sortDirection']],
|
|
array($this,'_sortTwoEntry')
|
|
)) {
|
|
LSerror :: addErrorCode('LSsearch_13');
|
|
return;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Returns the id of table rows in the result sorted according to criteria
|
|
* defined in the parameters
|
|
*
|
|
* @retval array The Table of id lines of results sorted
|
|
**/
|
|
function getSortTable() {
|
|
if (isset($this -> result['sort'][$this -> params['sortBy']][$this -> params['sortDirection']])) {
|
|
return $this -> result['sort'][$this -> params['sortBy']][$this -> params['sortDirection']];
|
|
}
|
|
return range(0,($this -> total-1));
|
|
}
|
|
|
|
/**
|
|
* List objects name
|
|
*
|
|
* @retval Array DN associate with name
|
|
**/
|
|
public function listObjectsName() {
|
|
if (!LSsession::loadLSclass('LSsearchEntry')) {
|
|
LSerror::addErrorCode('LSsession_05',$this -> LSobject);
|
|
return;
|
|
}
|
|
|
|
$retval=array();
|
|
|
|
if ($this -> total>0) {
|
|
$sortTable=$this -> getSortTable();
|
|
|
|
foreach ($sortTable as $key => $id) {
|
|
$entry=new LSsearchEntry($this,$this -> LSobject,$this -> params,$this -> _hash,$this -> result['list'],$id);
|
|
$retval[$entry->dn]=$entry->displayName;
|
|
}
|
|
}
|
|
|
|
return $retval;
|
|
}
|
|
|
|
/**
|
|
* List LSldapObjects
|
|
*
|
|
* @retval Array of LSldapObjects
|
|
**/
|
|
public function listObjects() {
|
|
$retval=array();
|
|
|
|
if ($this -> total>0) {
|
|
$sortTable=$this -> getSortTable();
|
|
|
|
$c=0;
|
|
foreach ($sortTable as $key => $id) {
|
|
$retval[$c]=new $this -> LSobject();
|
|
$retval[$c] -> loadData($this -> result['list'][$id]['dn']);
|
|
$c++;
|
|
}
|
|
}
|
|
|
|
return $retval;
|
|
}
|
|
|
|
/**
|
|
* List objects dn
|
|
*
|
|
* @retval Array of DN
|
|
**/
|
|
public function listObjectsDn() {
|
|
$retval=array();
|
|
|
|
if ($this -> total>0) {
|
|
$sortTable=$this -> getSortTable();
|
|
|
|
$c=0;
|
|
foreach ($sortTable as $key => $id) {
|
|
$retval[$c] = $this -> result['list'][$id]['dn'];
|
|
$c++;
|
|
}
|
|
}
|
|
|
|
return $retval;
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Error Codes
|
|
**/
|
|
LSerror :: defineError('LSsearch_01',
|
|
_("LSsearch : Invalid filter : %{filter}.")
|
|
);
|
|
LSerror :: defineError('LSsearch_02',
|
|
_("LSsearch : Invalid basedn : %{basedn}.")
|
|
);
|
|
LSerror :: defineError('LSsearch_03',
|
|
_("LSsearch : Invalid value for %{param} parameter.")
|
|
);
|
|
LSerror :: defineError('LSsearch_04',
|
|
_("LSsearch : Invalid size limit. Must be an integer greater or equal to 0.")
|
|
);
|
|
LSerror :: defineError('LSsearch_05',
|
|
_("LSsearch : Invalid parameter %{attr}. Must be an boolean.")
|
|
);
|
|
LSerror :: defineError('LSsearch_06',
|
|
_("LSsearch : Invalid parameter attributes. Must be an string or an array of strings.")
|
|
);
|
|
LSerror :: defineError('LSsearch_07',
|
|
_("LSsearch : Can't build attributes list for make filter.")
|
|
);
|
|
LSerror :: defineError('LSsearch_08',
|
|
_("LSsearch : Error building filter with attribute '%{attr}' and pattern '%{pattern}'")
|
|
);
|
|
LSerror :: defineError('LSsearch_09',
|
|
_("LSsearch : Error combining filters.")
|
|
);
|
|
LSerror :: defineError('LSsearch_10',
|
|
_("LSsearch : Invalid pattern.")
|
|
);
|
|
LSerror :: defineError('LSsearch_11',
|
|
_("LSsearch : Invalid attribute %{attr} in parameters.")
|
|
);
|
|
LSerror :: defineError('LSsearch_12',
|
|
_("LSsearch : Error during the search.")
|
|
);
|
|
LSerror :: defineError('LSsearch_13',
|
|
_("LSsearch : Error sorting the search.")
|
|
);
|
|
LSerror :: defineError('LSsearch_14',
|
|
_("LSsearch : The function of the custum information %{name} is not callable.")
|
|
);
|
|
LSerror :: defineError('LSsearch_15',
|
|
_("LSsearch : Invalid predefinedFilter for LSobject type %{type} : %{label} (filter : %{filter}).")
|
|
);
|
|
LSerror :: defineError('LSsearch_16',
|
|
_("LSsearch : Error during execution of the custom action %{customAction}.")
|
|
);
|
|
LSerror :: defineError('LSsearch_17',
|
|
_("LSsearch : Invalid search pattern.")
|
|
);
|