ldapsaisie/src/includes/class/class.LSselect.php
2023-01-02 01:17:46 +01:00

474 lines
17 KiB
PHP

<?php
/*******************************************************************************
* Copyright (C) 2007 Easter-eggs
* https://ldapsaisie.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.
******************************************************************************/
LSsession :: loadLSclass('LSlog_staticLoggerClass');
class LSselect extends LSlog_staticLoggerClass {
/*
* Méthode chargeant les dépendances d'affichage
*
* @return void
*/
public static function loadDependenciesDisplay() {
if (LSsession :: loadLSclass('LSsmoothbox')) {
LSsmoothbox :: loadDependenciesDisplay();
}
LStemplate :: addJSscript('LSselect.js');
LStemplate :: addCssFile('LSselect.css');
}
/**
* Init a LSobjects selection
* @param string $id The LSselect ID
* @param array $LSobjects Selectable LSobject types configuration. Must be an array
* with object type as key and configuration as value with the
* following info:
* - object_type: the LSobject type (same as key, required)
* - display_name_format: display name LSformat (optional, default: object type default)
* - filter: LDAP filter string for selectable objects (optional, default: no filter)
* - onlyAccessible: filter on only accessible objects (optional, default: false)
* - editableAttr: attribute name of object that must be writable to the object be selectable (optional)
* @param boolean $multiple True if this selection permit to select more than one object, False otherwise (optional,
* default: false)
* @param array|null $current_selected_objects Array of current selected objects (optional, see setSelectedObjects for format specification)
* @return void
*/
public static function init($id, $LSobjects, $multiple=false, $current_selected_objects=null) {
if ( !isset($_SESSION['LSselect']) || !is_array($_SESSION['LSselect']))
$_SESSION['LSselect'] = array();
$_SESSION['LSselect'][$id] = array (
'LSobjects' => $LSobjects,
'multiple' => $multiple,
'selected_objects' => array(),
);
if (is_array($current_selected_objects))
self :: setSelectedObjects($id, $current_selected_objects);
self :: log_debug("Initialized with id=$id: multiple=".($multiple?'yes':'no')." ".count($_SESSION['LSselect'][$id]['selected_objects'])." selected object(s).");
}
/**
* Check a LSselect exist by ID
*
* @param string $id The LSselect ID
*
* @return boolean
*/
public static function exists($id) {
if (isset($_SESSION['LSselect']) && is_array($_SESSION['LSselect']) &&
isset($_SESSION['LSselect'][$id]) && is_array($_SESSION['LSselect'][$id]))
return true;
return false;
}
/**
* Return a configuration parameter (or default value)
*
* @param string $id The LSselect ID
* @param string $key The configuration parameter
* @param mixed $default The default value (optional, default : null)
* @param string $cast Cast string|null resulting value in specific type
* (optional, default : null=disabled)
*
* @return mixed The configuration parameter value or default value if not set
**/
public static function getConfig($id, $key, $default=null, $cast=null) {
if (!self :: exists($id))
return false;
return LSconfig :: get($key, $default, $cast, $_SESSION['LSselect'][$id]);
}
/**
* Check if LSselect exist and is multiple
*
* @param string $id The LSselect ID
*
* @return boolean
*/
public static function isMultiple($id) {
return self :: getConfig($id, 'multiple', false, 'bool');
}
/**
* Get LSsearch object corresponding to the specified selection
*
* @param string $id The LSselect ID
* @param string|null $object_type The object type of the search (optional,
* default: first one object type configured)
*
* @return LSsearch|false The LSsearch object, or false in case of error
*/
public static function &getSearch($id, $object_type=null) {
// Check parameters
if (!self :: exists($id)) {
self :: log_debug("getSearch($id): does not exists.");
return false;
}
if (is_null($object_type))
$object_type = array_keys($_SESSION['LSselect'][$id]['LSobjects'])[0];
elseif (!array_key_exists($object_type, $_SESSION['LSselect'][$id]['LSobjects'])) {
self :: log_debug("getSearch($id): this selection does not joined '$object_type' objects.");
return false;
}
// Load LSobject type & LSsearch
if ( !LSsession :: loadLSobject($object_type) || !LSsession :: loadLSclass('LSsearch', null, true) ) {
self :: log_debug("getSearch($id): fail to load $object_type object type or LSsearch class");
return false;
}
// Instanciate object
$search = new LSsearch($object_type, "LSselect::$id");
/*
* Set parameters from config
*/
// filter (optional)
$filter = self :: getConfig($id, "LSobjects.$object_type.filter");
if ($filter) $search -> setParam('filter', $filter);
// display_name_format (optional)
$display_name_format = self :: getConfig($id, "LSobjects.$object_type.display_name_format");
if ($display_name_format) $search -> setParam('displayFormat', $display_name_format);
// onlyAccessible (default: false)
$search -> setParam(
'onlyAccessible',
self :: getConfig($id, "LSobjects.$object_type.onlyAccessible", false, 'bool')
);
// Add LSsearchEntry customInfos
$search -> setParam('customInfos', array (
'selectable' => array (
'function' => array('LSselect', 'selectable'),
'args' => $id,
),
'selected' => array (
'function' => array('LSselect', 'selected'),
'args' => $id,
'cache' => false,
),
));
return $search;
}
/**
* Get selectable object types
*
* @param string $id The LSselect ID
*
* @return array|false Array of selectable object types with name as key
* and label as value, or false if LSselect doesn't exists.
*/
public static function getSelectableObjectTypes($id) {
if (!self :: exists($id))
return false;
$selectable_objects = array();
foreach ($_SESSION['LSselect'][$id]['LSobjects'] as $type => $conf)
if (LSsession :: loadLSobject($type))
$selectable_objects[$type] = LSldapObject :: getLabel($type);
return $selectable_objects;
}
/**
* Get selectable objects info
*
* @param string $id The LSselect ID
*
* @return array|false Array of selectable object info with objects's DN as key
* and array of object's info as value. Objects's info returned
* currently contains only the object type (object_type). if
* LSselect specified doesn't exists, this method return false.
*/
public static function getSelectedObjects($id) {
if (!self :: exists($id))
return false;
if (is_array($_SESSION['LSselect'][$id]['selected_objects']))
return $_SESSION['LSselect'][$id]['selected_objects'];
return false;
}
/**
* Set selectable objects info
*
* @param string $id The LSselect ID
* @param array $selected_objects Array of selectable object info with objects's DN
* as key and array of object's info as value. Objects's
* info currently contains only the object type (key=object_type).
*
* @return array|false Array of selectable object info with objects's DN as key
* and array of object's info as value. Objects's info returned
* currently contains only the object type (object_type). if
* LSselect specified doesn't exists, this method return false.
*
* @return void
*/
public static function setSelectedObjects($id, $selected_objects) {
if (!self :: exists($id))
return;
if (!is_array($selected_objects))
return;
$_SESSION['LSselect'][$id]['selected_objects'] = array();
foreach($selected_objects as $dn => $info) {
if (!is_array($info) || !isset($info['object_type'])) {
self :: log_warning("setSelectedObjects($id): invalid object info for dn='$dn'");
continue;
}
if (self :: checkObjectIsSelectable($id, $info['object_type'], $dn))
$_SESSION['LSselect'][$id]['selected_objects'][$dn] = $info;
else {
self :: log_warning("setSelectedObjects($id): object type='".$info['object_type']."' and dn='$dn' is not selectable".varDump($_SESSION['LSselect'][$id]));
}
}
self :: log_debug("id=$id: updated with ".count($_SESSION['LSselect'][$id]['selected_objects'])." selected object(s).");
}
/**
* Check if an object is selectable
*
* @param string $id The LSselect ID
* @param string $object_type The object type
* @param string $object_dn The object DN
*
* @return boolean True if object is selectable, false otherwise
*/
public static function checkObjectIsSelectable($id, $object_type, $object_dn) {
if (!self :: exists($id)) {
self :: log_warning("checkObjectIsSelectable($id, $object_type, $object_dn): LSselect $id doesn't exists");
return false;
}
if (!array_key_exists($object_type, $_SESSION['LSselect'][$id]['LSobjects'])) {
self :: log_warning("checkObjectIsSelectable($id, $object_type, $object_dn): object type $object_type not selectabled");
return false;
}
// Load LSobject type
if ( !LSsession :: loadLSobject($object_type) ) {
self :: log_warning("checkObjectIsSelectable($id, $object_type, $object_dn): fail to load object type $object_type");
return false;
}
// Instanciate object and load object data from DN
$object = new $object_type();
if (!$object -> loadData($object_dn, self :: getConfig($id, "LSobjects.$object_type.filter", null))) {
self :: log_warning("checkObjectIsSelectable($id, $object_type, $object_dn): object $object_dn not found (or does not match with selection filter)");
return false;
}
// Handle onlyAccessible parameter
if (self :: getConfig($id, "LSobjects.$object_type.onlyAccessible", false, 'bool')) {
if (!LSsession :: canAccess($object_type, $object_dn)) {
self :: log_warning("checkObjectIsSelectable($id, $object_type, $object_dn): object $object_dn not accessible");
return false;
}
}
self :: log_debug("checkObjectIsSelectable($id, $object_type, $object_dn): object selectable");
return true;
}
/*
* AJAX methods
*/
/**
* Add a selected object to selection
*
* Request parameters:
* - LSselect_id: The LSselect ID
* - object_type: The selected object type
* - object_dn: The selected object DN
*
* Data in answer:
* - success: True if object added to selection, false otherwise
*
* @param array &$data Reference to returned data array
*
* @return void
*/
public static function ajax_addSelectedObject(&$data) {
$data['success'] = false;
if (!isset($_REQUEST['LSselect_id']) || !isset($_REQUEST['object_type']) || !isset($_REQUEST['object_dn'])) {
self :: log_warning('ajax_addSelectedObject(): missing parameter.');
LSerror :: addErrorCode('LSsession_12');
return;
}
$id = $_REQUEST['LSselect_id'];
$dn = $_REQUEST['object_dn'];
$type = $_REQUEST['object_type'];
if (!self :: checkObjectIsSelectable($id, $type, $dn)) {
self :: log_warning("ajax_addSelectedObject($id): object type='$type' dn='$dn' is not selectable.");
return;
}
self :: log_debug("id=$id: add $type '$dn'");
if (!$_SESSION['LSselect'][$id]['multiple']) {
$_SESSION['LSselect'][$id]['selected_objects'] = array(
$dn => array('object_type' => $type),
);
self :: log_debug("ajax_addSelectedObject($id): $dn replace current selected object.");
}
else if (!array_key_exists($dn, $_SESSION['LSselect'][$id]['selected_objects'])) {
$_SESSION['LSselect'][$id]['selected_objects'][$dn] = array('object_type' => $type);
self :: log_debug("ajax_addSelectedObject($id): $dn added to current selected objects.");
}
else {
self :: log_warning("ajax_addSelectedObject($id): $dn already present in selected objects.");
}
$data['success'] = true;
}
/**
* Drop a selected object in selection
*
* Request parameters:
* - LSselect_id: The LSselect ID
* - object_dn: The selected object DN
*
* Data in answer:
* - success: True if object added to selection, false otherwise
*
* @param array &$data Reference to returned data array
*
* @return void
*/
public static function ajax_dropSelectedObject(&$data) {
$data['success'] = false;
if (!isset($_REQUEST['LSselect_id']) || !isset($_REQUEST['object_dn'])) {
self :: log_warning('ajax_dropSelectedObject(): missing parameter.');
LSerror :: addErrorCode('LSsession_12');
return;
}
$id = $_REQUEST['LSselect_id'];
$dn = $_REQUEST['object_dn'];
if (!self :: exists($id)) {
self :: log_warning("ajax_dropSelectedObject($id): invalid LSselect ID '$id'.");
return;
}
self :: log_debug("id=$id: remove '$dn'");
if (array_key_exists($dn, $_SESSION['LSselect'][$id]['selected_objects'])) {
unset($_SESSION['LSselect'][$id]['selected_objects'][$dn]);
self :: log_debug("ajax_dropSelectedObject($id): $dn removed from selected objects.");
}
else {
self :: log_warning("ajax_dropSelectedObject($id): $dn not present in selected objects.");
}
$data['success'] = true;
}
/**
* Update selected objects of the selection
*
* Request parameters:
* - LSselect_id: The LSselect ID
* - selected_objects: Array of selected object info (see setSelectedObjects for format)
*
* Data in answer: any
*
* @param array &$data Reference to returned data array
*
* @return void
*/
public static function ajax_updateSelectedObjects(&$data) {
if (isset($_REQUEST['LSselect_id']) && isset($_REQUEST['selected_objects']) ) {
$selected_objects = json_decode($_REQUEST['selected_objects'], true);
if (is_array($selected_objects)) {
self :: log_debug('ajax_updateSelectedObjects(): set selected objects: '.varDump($selected_objects));
self :: setSelectedObjects($_REQUEST['LSselect_id'], $selected_objects);
}
else
self :: log_warning('ajax_updateSelectedObjects(): fail to decode JSON values.');
$data = array(
'selected_objects' => $selected_objects
);
}
else {
LSerror :: addErrorCode('LSsession_12');
}
}
/**
* Get selected objects of the selection
*
* Request parameters:
* - LSselect_id: The LSselect ID
*
* Data in answer:
* - objects: The selected objects info (see getSelectedObjects for format)
*
* @param array &$data Reference to returned data array
*
* @return void
*/
public static function ajax_getSelectedObjects(&$data) {
if (isset($_REQUEST['LSselect_id'])) {
$data=array(
'objects' => self :: getSelectedObjects($_REQUEST['LSselect_id'])
);
}
else {
LSerror :: addErrorCode('LSsession_12');
}
}
/*
* LSsearchEntry customInfos helpers
*/
/**
* LSsearchEntry selectable customInfos method : check if object is selectable
*
* @param LSsearchEntry $obj The LSsearchEntry object
* @param string $id The LSselect ID
*
* @return boolean True if object is selectable, False otherwise
*/
public static function selectable($obj, $id) {
$editableAttr = self :: getConfig($id, "LSobjects.".$obj->type.".editableAttr");
if (!$editableAttr)
return true;
if ($editableAttr && call_user_func(array($obj->type, 'hasAttr'), $editableAttr))
return LSsession::canEdit($obj->type, $obj->dn, $editableAttr);
return false;
}
/**
* LSsearchEntry selected customInfos method : check if object is selected
*
* @param LSsearchEntry $obj The LSsearchEntry object
* @param string $id The LSselect ID
*
* @return boolean True if object is selected, False otherwise
*/
public static function selected($obj, $id) {
if (self :: exists($id) &&
is_array($_SESSION['LSselect'][$id]['selected_objects']) &&
array_key_exists($obj->dn, $_SESSION['LSselect'][$id]['selected_objects']))
return true;
return false;
}
}