ldapsaisie/src/includes/class/class.LSrelation.php
Benjamin Renard 9907e08f18 Code cleaning
2021-08-25 18:02:37 +02:00

1024 lines
30 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 LSrelation extends LSlog_staticLoggerClass {
// Reference to the LSldapObject
private $obj = null;
// Relation name
private $name = null;
// Relation config
private $config = null;
/**
* LSrelation constructor
*
* An LSrelation object focus on one type of relations of a specific
* object. All non-static method are designed to manipulate this type
* of relation of the object specified at constuct time.
*
* @param[in] &$obj LSldapObject A reference to the LSldapObject
* @param [in] $relationName string The relation name
*
* @retval void
*/
public function __construct(&$obj, $relationName) {
$this -> obj =& $obj;
$this -> name = $relationName;
$this -> config = $obj -> getConfig("LSrelation.$relationName");
if (!is_array($this -> config) || !$this -> checkConfig()) {
$this -> config = null;
LSerror :: addErrorCode(
'LSrelation_02',
array(
'relation' => $relationName,
'LSobject' => $obj -> getType()
)
);
}
}
/**
* Allow conversion of LSrelation to string
*
* @retval string The string representation of the LSrelation
*/
public function __toString() {
return "<LSrelation ".$this -> name." on ".$this -> obj -> toString(false).">";
}
/**
* Return a configuration parameter (or default value)
*
* @param[] $param The configuration parameter
* @param[] $default The default value (default : null)
* @param[] $cast Cast resulting value in specific type (default : disabled)
*
* @retval mixed The configuration parameter value or default value if not set
**/
public function getConfig($param, $default=null, $cast=null) {
// Check relation is correctly configured
if (!$this -> correctly_configured)
return false;
return LSconfig :: get($param, $default, $cast, $this -> config);
}
/**
* Get relation info
*
* @param[in] $key string The info name
*
* @retval mixed The info value
*/
public function __get($key) {
switch ($key) {
case 'name':
return $this -> name;
case 'correctly_configured':
return boolval($this -> config);
case 'LSobject':
case 'linkAttribute':
case 'linkAttributeValue':
case 'linkAttributeOtherValues':
case 'list_function':
case 'getkeyvalue_function':
case 'update_function':
case 'remove_function':
case 'rename_function':
case 'canEdit_function':
case 'canEdit_attribute':
return $this -> getConfig($key);
case 'linkAttributeValues':
$linkAttributeValues = ensureIsArray($this -> linkAttributeOtherValues);
if ($this -> linkAttributeValue)
$linkAttributeValues[] = $this -> linkAttributeValue;
return $linkAttributeValues;
case 'relatedEditableAttribute':
return $this -> getConfig(
'canEdit_attribute',
$this -> getConfig('linkAttribute', false)
);
}
// Unknown key, log warning
self :: log_warning("__get($key): invalid property requested\n".LSlog :: get_debug_backtrace_context());
}
/**
* Check relation configuration
*
* @retval boolean True if relation is properly configured, False otherwise
*/
public function checkConfig() {
// Check LSobject parameter
if (!$this -> LSobject) {
LSerror :: addErrorCode(
'LSrelation_07',
array(
'parameter' => 'LSobject',
'relation' => $this -> name,
'LSobject' => $this -> LSobject
)
);
return false;
}
// Load related object type
if (!LSsession :: loadLSobject($this -> LSobject)) {
LSerror :: addErrorCode(
'LSrelation_04',
array(
'relation' => $this -> name,
'LSobject' => $this -> LSobject
)
);
return false;
}
// Check if it's a simple relation
if ($this -> linkAttribute && $this -> linkAttributeValue) {
// Check linkAttribute refered to an existing related object type attribute
if (!call_user_func(array($this -> LSobject, 'hasAttr'), $this -> linkAttribute)) {
LSerror :: addErrorCode(
'LSrelation_08',
array(
'parameter' => 'linkAttribute',
'relation' => $this -> name,
'LSobject' => $this -> LSobject
)
);
return false;
}
// Check linkAttributeValue
if ($this -> linkAttributeValue != 'dn' && !$this -> obj -> hasAttr($this -> linkAttributeValue)) {
LSerror :: addErrorCode(
'LSrelation_08',
array(
'parameter' => 'linkAttributeValue',
'relation' => $this -> name,
'LSobject' => $this -> LSobject
)
);
return false;
}
return true;
}
// Advanced relation: check all required parameters refered to related objects
// methods
$required_parameters = array(
'list_function', 'getkeyvalue_function', 'update_function',
'remove_function', 'rename_function', 'canEdit_function',
);
foreach($required_parameters as $p) {
// Check parameter is defined
if (!$this -> $p) {
LSerror :: addErrorCode(
'LSrelation_07',
array(
'parameter' => $p,
'relation' => $this -> name,
'LSobject' => $this -> LSobject
)
);
return false;
}
// Check parameter refered to an existing related object class method
if (!method_exists($this -> LSobject, $this -> $p)) {
LSerror :: addErrorCode(
'LSrelation_01',
array(
'parameter' => $p,
'function' => $this -> $p,
'LSobject' => $this -> LSobject,
'relation' => $this -> name,
)
);
return false;
}
}
return true;
}
/**
* Check a relation exist
*
* @param[in] $object_type string The object type
* @param[in] $relation_name string The relation name
*
* @retval boolean True if relation exist, false otherwise
*/
public static function exists($object_type, $relation_name) {
if ($object_type && LSsession :: loadLSobject($object_type)) {
return is_array(LSconfig :: get("LSobjects.$object_type.LSrelation.$relation_name"));
}
return false;
}
/**
* Get relation name
*
* @retval string The relation name
*/
public function getName() {
return $this -> name;
}
/**
* Check if user can edit this relation
*
* @retval boolean True if user can edit this relation, false otherwise
*/
public function canEdit() {
return LSsession :: relationCanEdit($this -> obj -> getValue('dn'),$this -> obj -> getType(),$this -> name);
}
/**
* Check if user can create a related object
*
* @retval boolean True if user can create a related object, false otherwise
*/
public function canCreate() {
return LSsession :: canCreate($this -> LSobject);
}
/**
* List related objects
*
* @retval array|false An array of related objects (LSldapObject), of false in case of error
*/
public function listRelatedObjects() {
// Check relation is correctly configured
if (!$this -> correctly_configured)
return false;
// Load related object type
if (!LSsession :: loadLSobject($this -> LSobject)) {
LSerror :: addErrorCode(
'LSrelation_04',
array(
'relation' => $this -> name,
'LSobject' => $this -> LSobject
)
);
return false;
}
// Instanciate related object
$objRel = new $this -> LSobject();
// Use list_function
if ($this -> list_function) {
if (method_exists($this -> LSobject, $this -> list_function)) {
return call_user_func_array(
array($objRel, $this -> list_function),
array(&$this -> obj)
);
}
LSerror :: addErrorCode(
'LSrelation_01',
array(
'parameter' => 'list_function',
'function' => $this -> list_function,
'LSobject' => $objRel -> getType(),
'relation' => $this -> name,
)
);
return False;
}
// Use linkAttribute & linkAttributeValue
if ($this -> linkAttribute && $this -> linkAttributeValue) {
return $objRel -> listObjectsInRelation(
$this -> obj,
$this -> linkAttribute,
$this -> obj -> getType(),
$this -> linkAttributeValues
);
}
// Configuration problem
LSerror :: addErrorCode(
'LSrelation_05',
array(
'relation' => $this -> name,
'LSobject' => $this -> LSobject,
'action' => _('listing related objects')
)
);
return false;
}
/**
* Get the value to store to created the relation with $this -> obj
*
* @retval array List of value of the link attribute
*/
public function getRelatedKeyValue() {
// Check relation is correctly configured
if (!$this -> correctly_configured)
return false;
// Load related object type
if (!LSsession :: loadLSobject($this -> LSobject)) {
LSerror :: addErrorCode(
'LSrelation_04',
array(
'relation' => $this -> name,
'LSobject' => $this -> LSobject
)
);
return false;
}
// Instanciate related object
$objRel = new $this -> LSobject();
// Use getkeyvalue_function
if ($this -> getkeyvalue_function) {
if (method_exists($this -> LSobject, $this -> getkeyvalue_function)) {
return call_user_func_array(
array($objRel, $this -> getkeyvalue_function),
array(&$this -> obj)
);
}
LSerror :: addErrorCode(
'LSrelation_01',
array(
'parameter' => 'getkeyvalue_function',
'function' => $this -> getkeyvalue_function,
'LSobject' => $objRel -> getType(),
'relation' => $this -> name,
)
);
return false;
}
// Use linkAttribute & linkAttributeValue
if ($this -> linkAttribute && $this -> linkAttributeValue) {
return $objRel -> getObjectKeyValueInRelation(
$this -> obj,
$this -> obj -> getType(),
$this -> linkAttributeValue
);
}
// Configuration problem
LSerror :: addErrorCode(
'LSrelation_05',
array(
'relation' => $this -> name,
'LSobject' => $this -> LSobject,
'action' => _('getting key value')
)
);
return false;
}
/**
* Check if user can edit the relation with the specified object
*
* @param[in] &$objRel LSldapObject A reference to the related object
*
* @retval boolean True if user can edit the relation with the specified object, false otherwise
*/
public function canEditRelationWithObject(&$objRel) {
// Check relation is correctly configured
if (!$this -> correctly_configured)
return false;
if (!$this -> canEdit()) return;
// Use canEdit_function
if ($this -> canEdit_function) {
if (method_exists($objRel, $this -> canEdit_function)) {
return call_user_func(array($objRel, $this -> canEdit_function));
}
LSerror :: addErrorCode(
'LSrelation_01',
array(
'parameter' => 'canEdit_function',
'function' => $this -> canEdit_function,
'LSobject' => $objRel -> getType(),
'relation' => $this -> name,
)
);
return False;
}
// Use related editable attribute
if ($this -> relatedEditableAttribute) {
return LSsession :: canEdit(
$objRel -> getType(),
$objRel -> getDn(),
$this -> relatedEditableAttribute
);
}
// Configuration problem
LSerror :: addErrorCode(
'LSrelation_05',
array(
'relation' => $this -> name,
'LSobject' => $this -> LSobject,
'action' => _('checking right on relation with specific object')
)
);
return false;
}
/**
* Remove relation with the specified object
*
* @param[in] &$objRel LSldapObject A reference to the related object
*
* @retval boolean True if relation removed, false otherwise
*/
public function removeRelationWithObject(&$objRel) {
// Check relation is correctly configured
if (!$this -> correctly_configured)
return false;
// Use remove_function
if ($this -> remove_function) {
if (method_exists($this -> LSobject, $this -> remove_function)) {
return call_user_func_array(
array($objRel, $this -> remove_function),
array(&$this -> obj)
);
}
LSerror :: addErrorCode(
'LSrelation_01',
array(
'parameter' => 'remove_function',
'function' => $this -> remove_function,
'LSobject' => $objRel -> getType(),
'relation' => $this -> name,
)
);
return False;
}
// Use linkAttribute & linkAttributeValue
if ($this -> linkAttribute && $this -> linkAttributeValue) {
return $objRel -> deleteOneObjectInRelation($this -> obj, $this -> linkAttribute, $this -> obj -> getType(), $this -> linkAttributeValue, null, $this -> linkAttributeValues);
}
// Configuration problem
LSerror :: addErrorCode(
'LSrelation_05',
array(
'relation' => $this -> name,
'LSobject' => $this -> LSobject,
'action' => _('removing relation with specific object')
)
);
return false;
}
/**
* Rename relation with the specified object
*
* @param[in] &$objRel LSldapObject A reference to the related object
* @param[in] $oldKeyValue string The old key value of the relation
*
* @retval boolean True if relation rename, false otherwise
*/
public function renameRelationWithObject(&$objRel, $oldKeyValue) {
// Check relation is correctly configured
if (!$this -> correctly_configured)
return false;
// Use rename_function
if ($this -> rename_function) {
if (method_exists($objRel,$this -> rename_function)) {
return call_user_func_array(array($objRel, $this -> rename_function), array(&$this -> obj, $oldKeyValue));
}
LSerror :: addErrorCode(
'LSrelation_01',
array(
'parameter' => 'rename_function',
'function' => $this -> rename_function,
'LSobject' => $objRel -> getType(),
'relation' => $this -> name,
)
);
return False;
}
// Use linkAttribute & linkAttributeValue
if ($this -> linkAttribute && $this -> linkAttributeValue) {
return $objRel -> renameOneObjectInRelation(
$this -> obj,
$oldKeyValue,
$this -> linkAttribute,
$this -> obj -> getType(),
$this -> linkAttributeValue
);
}
// Configuration problem
LSerror :: addErrorCode(
'LSrelation_05',
array(
'relation' => $this -> name,
'LSobject' => $this -> LSobject,
'action' => _('checking right on relation with specific object')
)
);
return false;
}
/**
* Update relation with the specified DN objects list
*
* @param[in] $listDns array Array of DN of the related objects
*
* @retval boolean True if relations updated, false otherwise
*/
public function updateRelations($listDns) {
// Check relation is correctly configured
if (!$this -> correctly_configured)
return false;
// Load related objects type
if (!LSsession :: loadLSobject($this -> LSobject)) {
LSerror :: addErrorCode(
'LSrelation_04',
array(
'relation' => $this -> name,
'LSobject' => $this -> LSobject
)
);
return false;
}
// Instanciate related object
$objRel = new $this -> LSobject();
// Use update_function
if ($this -> update_function) {
if (method_exists($objRel, $this -> update_function)) {
return call_user_func_array(
array($objRel, $this -> update_function),
array(&$this -> obj, $listDns)
);
}
LSerror :: addErrorCode(
'LSrelation_01',
array(
'parameter' => 'update_function',
'function' => $this -> update_function,
'LSobject' => $objRel -> getType(),
'relation' => $this -> name,
)
);
return false;
}
// Use linkAttribute & linkAttributeValue
if ($this -> linkAttribute && $this -> linkAttributeValue) {
return $objRel -> updateObjectsInRelation(
$this -> obj,
$listDns,
$this -> linkAttribute,
$this -> obj -> getType(),
$this -> linkAttributeValue,
null,
$this -> linkAttributeValues
);
}
// Configuration problem
LSerror :: addErrorCode(
'LSrelation_05',
array(
'relation' => $this -> name,
'LSobject' => $this -> LSobject,
'action' => _('updating relations')
)
);
return false;
}
/*
* Load display dependencies
*
* @retval void
*/
public static function loadDependenciesDisplay() {
if (LSsession :: loadLSclass('LSselect')) {
LSselect :: loadDependenciesDisplay();
}
LStemplate :: addJSscript('LSrelation.js');
LStemplate :: addCssFile('LSrelation.css');
LStemplate :: addJSconfigParam('LSrelation_labels', array(
'close_confirm_text' => _('Do you really want to delete'),
'close_confirm_title' => _('Warning'),
'close_confirm_validate' => _('Delete')
));
}
/*
* Load LSrelations information of an object to display it on LSview.
*
* LSrelations information are provided to template by usind LSrelations variable.
*
* @param[in] $object LSldapObject L'objet dont on cherche les LSrelations
*
* @retval void
*/
public static function displayInLSview($object) {
if (!($object instanceof LSldapObject))
return;
if (!is_array($object -> getConfig('LSrelation')))
return;
$LSrelations=array();
$LSrelation_JSparams=array();
foreach($object -> getConfig('LSrelation') as $relationName => $relationConf) {
// Check user access
if (!LSsession :: relationCanAccess($object -> getValue('dn'), $object->getType(), $relationName)) {
self :: log_debug("User have no access to relation $relationName of ".$object->getType());
continue;
}
$return=array(
'label' => __($relationConf['label']),
'LSobject' => $relationConf['LSobject']
);
if (isset($relationConf['emptyText'])) {
$return['emptyText'] = __($relationConf['emptyText']);
}
else {
$return['emptyText'] = _('No object.');
}
$id=rand();
$return['id']=$id;
$LSrelation_JSparams[$id]=array(
'emptyText' => $return['emptyText']
);
$_SESSION['LSrelation'][$id] = array(
'relationName' => $relationName,
'objectType' => $object -> getType(),
'objectDn' => $object -> getDn(),
);
$relation = new LSrelation($object, $relationName);
if (!$relation -> correctly_configured)
continue;
if ($relation -> canEdit()) {
$return['actions'][] = array(
'label' => _('Modify'),
'url' => "object/select/$id",
'action' => 'modify',
'class' => 'LSrelation_modify',
'data' => array(
'relation-id' => $id,
)
);
}
if ($relation -> canCreate()) {
$return['actions'][] = array(
'label' => _('New'),
'url' => 'object/'.$relationConf['LSobject'].'/create?LSrelation='.$relationName.'&amp;relatedLSobject='.$object->getType().'&amp;relatedLSobjectDN='.urlencode($object -> getValue('dn')),
'action' => 'create',
'class' => null,
);
}
$list = $relation -> listRelatedObjects();
if (is_array($list)) {
foreach($list as $o) {
$return['objectList'][] = array(
'text' => $o -> getDisplayName(
LSconfig :: get('display_name_format', null, null, $relationConf),
true
),
'dn' => $o -> getDn(),
'canEdit' => $relation -> canEditRelationWithObject($o)
);
}
}
else {
$return['objectList']=array();
}
$LSrelations[]=$return;
}
self :: loadDependenciesDisplay();
LStemplate :: assign('LSrelations',$LSrelations);
LStemplate :: addJSconfigParam('LSrelations',$LSrelation_JSparams);
}
/*
* AJAX methods
*/
/**
* Helper to check AJAX method call and instanciate corresponding
* LSldapObject and LSrelation objects.
*
* @param[in] &$data array Reference to AJAX returned data array
* @param[in] $additional_parameters array|string|null List of additional required parameter
*
* @retval array|false Array with LSobject and LSrelation
*/
public static function _ajax_check_call(&$data, &$conf, &$object, &$relation, $additional_required_parameters=null) {
$data['success'] = false;
// Check parameters
if (!isset($_REQUEST['id'])) {
self :: log_warning("Parameter 'id' is missing.");
LSerror :: addErrorCode('LSsession_12');
return false;
}
// Check additional required parameters
if ($additional_required_parameters) {
foreach(ensureIsArray($additional_required_parameters) as $p) {
if (!isset($_REQUEST[$p])) {
self :: log_warning("Parameter '$p' is missing.");
LSerror :: addErrorCode('LSsession_12');
return false;
}
$data[$p] = $_REQUEST[$p];
}
}
// Check relation exists in session
if (!isset($_SESSION['LSrelation'][$_REQUEST['id']])) {
self :: log_warning("No relation '".$_REQUEST['id']."' in session");
return false;
}
// Load object type
$conf = $_SESSION['LSrelation'][$_REQUEST['id']];
if (!LSsession ::loadLSobject($conf['objectType'])) {
self :: log_warning("Fail to load '".$conf['objectType']."'");
return false;
}
$data['id'] = $_REQUEST['id'];
// Check relation exists
if (!self :: exists($conf['objectType'], $conf['relationName'])) {
self :: log_warning("Relation '".$conf['relationName']."' not found in ".$conf['objectType']." configuration");
return false;
}
// Instanciate object and load its data
$object = new $conf['objectType']();
if (!$object -> loadData($conf['objectDn'])) {
self :: log_warning("Fail to load data of '".$conf['objectDn']."'");
return false;
}
// Instanciate relation
$relation = new LSrelation($object, $conf['relationName']);
// Check relation is correctly configured
if (!$relation -> correctly_configured)
return false;
// Check user access to it relation
if (!$relation -> canEdit()) {
LSerror :: addErrorCode('LSsession_11');
return false;
}
self :: log_debug("_ajax_check_call(): ok");
return true;
}
/**
* Init LSselect for a relation
*
* @param[in] &$data Reference to returned data array
*
* @retval void
*/
public static function ajax_initSelection(&$data) {
$conf = null;
$object = null;
$relation = null;
if (!self :: _ajax_check_call($data, $conf, $object, $relation, 'href')) {
return;
}
// Load LSselect
if(!LSsession :: loadLSclass('LSselect', null, true)) {
return;
}
// List related objects
$list = $relation -> listRelatedObjects();
if (!is_array($list)) {
self :: log_warning('Fail to list related objects');
return;
}
// Forge selected object list for LSselect
$selected_objects = array();
foreach($list as $o) {
$selected_objects[$o -> getDn()] = array(
'object_type' => $o -> getType(),
'editableAttr' => $relation -> relatedEditableAttribute,
);
}
// Init LSselect
LSselect :: init(
$_REQUEST['id'],
array (
$relation -> LSobject => array(
'object_type' => $relation -> LSobject,
)
),
true,
$selected_objects
);
// Set success
$data['success'] = true;
}
/**
* Update related object from LSselect result
*
* @param[in] &$data Reference to returned data array
*
* @retval void
*/
public static function ajax_updateFromSelection(&$data) {
$conf = null;
$object = null;
$relation = null;
if (!self :: _ajax_check_call($data, $conf, $object, $relation)) {
return;
}
$LSobjectInRelation = $object->getConfig("LSrelation.".$conf['relationName'].".LSobject");
$relationConf = $object->getConfig("LSrelation.".$conf['relationName']);
// Load LSselect
if(!LSsession :: loadLSclass('LSselect', null, true)) {
return;
}
// Retrieve selected object from LSselect
$selected_objects = LSselect :: getSelectedObjects($_REQUEST['id']);
if (!is_array($selected_objects)) {
self :: log_warning("Fail to retrieve selected object from LSselect");
return;
}
self :: log_debug('Selected objects: '.varDump($selected_objects));
// Update related objects
if (!$relation -> updateRelations(array_keys($selected_objects))) {
LSerror :: addErrorCode('LSrelation_03', $conf['relationName']);
self :: log_warning("Fail to update objects in relation");
return;
}
self :: log_debug('Related objects updated');
// List related objects
$list = $relation -> listRelatedObjects();
if (is_array($list) && !empty($list)) {
$data['html']="";
foreach($list as $o) {
if ($relation -> canEditRelationWithObject($o)) {
$class=' LSrelation_editable';
}
else {
$class='';
}
$data['html'].= "<li class='LSrelation'><a href='object/$LSobjectInRelation/".urlencode($o -> getDn())."' class='LSrelation$class' id='LSrelation_".$_REQUEST['id']."_".$o -> getDn()."'>".$o -> getDisplayName(NULL,true)."</a></li>\n";
}
}
else {
if (isset($relationConf['emptyText'])) {
$data['html'] = "<li>".__($relationConf['emptyText'])."</li>\n";
}
else {
$data['html'] = "<li>"._('No object.')."</li>\n";
}
}
$data['success'] = true;
}
/**
* Remove related object specify by DN
*
* @param[in] &$data Reference to returned data array
*
* @retval void
*/
public static function ajax_deleteByDn(&$data) {
$conf = null;
$object = null;
$relation = null;
if (!self :: _ajax_check_call($data, $conf, $object, $relation, 'dn')) {
return;
}
// List related objects
$list = $relation -> listRelatedObjects();
if (!is_array($list)) {
self :: log_warning('Fail to list related objects');
LSerror :: addErrorCode('LSrelation_03',$conf['relationName']);
return;
}
// For each related objects:
// - check if DN match
// - check user can edit relation with specific object
// - remove relation
$found = false;
foreach($list as $o) {
if($o -> getDn() == $_REQUEST['dn']) {
if (!$relation -> canEditRelationWithObject($o)) {
LSerror :: addErrorCode('LSsession_11');
return;
}
if (!$relation -> removeRelationWithObject($o)) {
LSerror :: addErrorCode('LSrelation_03', $conf['relationName']);
return;
}
else {
$found = true;
}
break;
}
}
// Check object found
if (!$found) {
self :: log_warning("Object '".$_REQUEST['dn']."' not found in related objects list.");
LSerror :: addErrorCode('LSrelation_03', $conf['relationName']);
return;
}
// Set success
$data['dn'] = $_REQUEST['dn'];
$data['success'] = true;
}
}
/**
* Error Codes
**/
LSerror :: defineError('LSrelation_01',
___("LSrelation : Invalid parameter '%{parameter}' of the relation %{relation}: objects %{LSobject} have no function '%{function}'.")
);
LSerror :: defineError('LSrelation_02',
___("LSrelation : Relation %{relation} of object type %{LSobject} unknown.")
);
LSerror :: defineError('LSrelation_03',
___("LSrelation : Error during relation update of the relation %{relation}.")
);
LSerror :: defineError('LSrelation_04',
___("LSrelation : Object type %{LSobject} unknown (Relation : %{relation}).")
);
LSerror :: defineError('LSrelation_05',
___("LSrelation : Incomplete configuration for LSrelation %{relation} of object type %{LSobject} for action : %{action}.")
);
LSerror :: defineError('LSrelation_06',
___("LSrelation : Invalid editable attribute for LSrelation %{relation} with LSobject %{LSobject}.")
);
LSerror :: defineError('LSrelation_07',
___("LSrelation : The configuration parameter '%{parameter}' of the relation %{relation} of %{LSobject} is missing.")
);
LSerror :: defineError('LSrelation_08',
___("LSrelation : The configuration parameter '%{parameter}' of the relation %{relation} of %{LSobject} is invalid.")
);