Use schema Attribute in Entry to convert value from/to LDAP from/to PHP
This commit is contained in:
parent
a5b19f39cc
commit
bb68b10ec4
6 changed files with 236 additions and 22 deletions
|
@ -60,7 +60,7 @@ class Entry {
|
|||
case 'changes':
|
||||
return $this -> changes;
|
||||
default:
|
||||
return $this -> get_values($key);
|
||||
return $this -> get_value($key);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,14 +78,7 @@ class Entry {
|
|||
else
|
||||
$this -> error('Unexcepted DN value provided: must be a string or false');
|
||||
default:
|
||||
$key = mb_strtolower($key);
|
||||
if (is_null($value))
|
||||
$value = array();
|
||||
if (!is_array($value))
|
||||
$value = array($value);
|
||||
$this -> changes[$key] = array();
|
||||
foreach($value as $v)
|
||||
$this -> changes[$key][] = strval($v);
|
||||
$this -> set_value($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,7 +96,7 @@ class Entry {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get an attribute values
|
||||
* Get raw attribute values
|
||||
* @param string $attr The expected attribute name
|
||||
* @param mixed $default The default value if attribute is not set
|
||||
* (optional, default: null or array() if $all_values is True)
|
||||
|
@ -111,7 +104,7 @@ class Entry {
|
|||
* first one (optional, default: true)
|
||||
* @return ( $all_values is True ? array<string> : mixed )
|
||||
*/
|
||||
public function get_values($attr, $default=null, $all_values=true) {
|
||||
public function get_raw_values($attr, $default=null, $all_values=true) {
|
||||
$attr = mb_strtolower($attr);
|
||||
$values = false;
|
||||
if (array_key_exists($attr, $this -> changes))
|
||||
|
@ -123,6 +116,71 @@ class Entry {
|
|||
return $all_values?$values:$values[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an attribute value (using LDAP schema if used and a LDAP link is registered on entry)
|
||||
* @param string $attr The expected attribute name
|
||||
* @param mixed $default The default value if attribute is not set
|
||||
* (optional, default: null or array() if $all_values is True)
|
||||
* @param bool $first If True, return only the first attribute values, otherwise return
|
||||
* depending on the fact is single valued or not in LDAP schema (optional,
|
||||
* default: false)
|
||||
* @return mixed
|
||||
*/
|
||||
public function get_value($attr, $default=null, $first=false) {
|
||||
if (!$this -> ldap || !$this -> ldap -> schema)
|
||||
return $this -> get_raw_values($attr, $default, $first?false:true);
|
||||
$attr = mb_strtolower($attr);
|
||||
$values = false;
|
||||
if (array_key_exists($attr, $this -> changes))
|
||||
$values = &$this -> changes[$attr];
|
||||
elseif (array_key_exists($attr, $this -> data))
|
||||
$values = &$this -> data[$attr];
|
||||
$attribute = $this -> ldap -> schema -> attribute($attr);
|
||||
if (!$attribute)
|
||||
return $this -> error('Unkown attribute %s in schema', null, $attr);
|
||||
if (!$values) {
|
||||
if (is_null($default) && !$first && !$attribute->single)
|
||||
return array();
|
||||
return $default;
|
||||
}
|
||||
return $attribute -> ldap2php($values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set raw LDAP attribute values
|
||||
* @param string $attr
|
||||
* @param mixed $values
|
||||
* @return void
|
||||
*/
|
||||
public function set_raw_values($attr, $values) {
|
||||
$attr = mb_strtolower($attr);
|
||||
if (is_null($values))
|
||||
$values = array();
|
||||
else if (!is_array($values))
|
||||
$values = array($values);
|
||||
$this -> changes[$attr] = array();
|
||||
foreach($values as $value)
|
||||
$this -> changes[$attr][] = strval($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set LDAP attribute values
|
||||
* @param string $attr
|
||||
* @param mixed $value
|
||||
* @return void|false
|
||||
*/
|
||||
public function set_value($attr, $value) {
|
||||
if (!$this -> ldap || !$this -> ldap -> schema) {
|
||||
$this -> set_raw_values($attr, $value);
|
||||
return;
|
||||
}
|
||||
$attribute = $this -> ldap -> schema -> attribute($attr);
|
||||
if (!$attribute)
|
||||
return $this -> error('Unkown attribute %s in schema', null, $attr);
|
||||
$values = $attribute -> php2ldap($value);
|
||||
$this -> set_raw_values($attr, $values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log and eventually raise an error
|
||||
* @param string $error The error message
|
||||
|
|
10
src/Ldap.php
10
src/Ldap.php
|
@ -21,6 +21,7 @@ namespace EesyLDAP;
|
|||
* @property-read string $scope
|
||||
* @property-read bool $raise_on_error
|
||||
* @property-read bool $use_schema
|
||||
* @property-read Schema|false $schema
|
||||
*/
|
||||
class Ldap {
|
||||
|
||||
|
@ -391,12 +392,11 @@ class Ldap {
|
|||
case 'default_config':
|
||||
return self :: $default_config;
|
||||
case 'schema':
|
||||
if ($this->schema)
|
||||
return $this->schema;
|
||||
if (!$this->use_schema)
|
||||
return false;
|
||||
$this->schema = Schema :: load($this);
|
||||
return $this->schema;
|
||||
if (!$this->schema)
|
||||
$this->schema = Schema :: load($this);
|
||||
return $this->schema && $this->schema->loaded?$this->schema:false;
|
||||
}
|
||||
return $this -> error("Invalid property '$key' requested");
|
||||
}
|
||||
|
@ -506,7 +506,7 @@ class Ldap {
|
|||
$attrs[$attr][$k] = $result[$i][$attr][$k];
|
||||
}
|
||||
// @phpstan-ignore-next-line
|
||||
$entries[$dn] = new Entry($dn, $attrs);
|
||||
$entries[$dn] = new Entry($dn, $attrs, $this);
|
||||
}
|
||||
// @phpstan-ignore-next-line
|
||||
return $entries;
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
namespace EesyLDAP;
|
||||
|
||||
|
||||
/**
|
||||
* @property-read bool $loaded
|
||||
*/
|
||||
class Schema {
|
||||
|
||||
/**
|
||||
|
@ -53,6 +56,12 @@ class Schema {
|
|||
*/
|
||||
protected $oids = array();
|
||||
|
||||
/**
|
||||
* Loaded telltale
|
||||
* @var bool
|
||||
*/
|
||||
protected $loaded = false;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param Ldap $ldap The LDAP connection
|
||||
|
@ -63,6 +72,23 @@ class Schema {
|
|||
$this -> ldap = $ldap;
|
||||
$this -> entry = $entry;
|
||||
$this -> parse();
|
||||
$this -> loaded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic method to get schema key
|
||||
* @param string $key
|
||||
* @return mixed
|
||||
* @throws \EesyLDAP\InvalidPropertyException
|
||||
*/
|
||||
public function __get($key) {
|
||||
switch ($key) {
|
||||
case 'loaded':
|
||||
return $this -> loaded;
|
||||
}
|
||||
throw new \EesyLDAP\InvalidPropertyException(
|
||||
"Invalid property '$key' requested on '".get_called_class()."'"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -88,7 +114,7 @@ class Schema {
|
|||
protected function parse() {
|
||||
foreach (self :: $attributes_to_entry_types as $attr => $type) {
|
||||
$type_name = strtolower($type);
|
||||
foreach($this -> entry -> get_values($attr, array(), true) as $value) {
|
||||
foreach($this -> entry -> get_raw_values($attr, array(), true) as $value) {
|
||||
// @phpstan-ignore-next-line
|
||||
$entry = call_user_func("\\EesyLDAP\\Schema\\$type::parse", $value);
|
||||
if (!$entry instanceof Schema\SchemaEntry) {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace EesyLDAP\Schema;
|
||||
|
||||
use EesyLDAP\Schema;
|
||||
|
||||
/**
|
||||
* @property-read string $oid
|
||||
|
@ -69,6 +70,32 @@ class Attribute extends SchemaEntry {
|
|||
'multiple',
|
||||
);
|
||||
|
||||
/**
|
||||
* Map attribute syntax OID to corresponding sub Attribute types
|
||||
* @var array<string,class-string<Attribute>>
|
||||
*/
|
||||
protected static $map_syntax_to_subtypes = array(
|
||||
Schema::SYNTAX_BOOLEAN => Attribute\BooleanAttribute::class,
|
||||
);
|
||||
|
||||
/**
|
||||
* Parse a SubSchema attribute value into a SchemaEntry object
|
||||
* @param string $value Attribute value
|
||||
* @return Attribute
|
||||
*/
|
||||
public static function parse($value) {
|
||||
$schema_entry = self :: _parse($value);
|
||||
if (
|
||||
isset($schema_entry['syntax'])
|
||||
&& is_string($schema_entry['syntax'])
|
||||
&& array_key_exists($schema_entry['syntax'], self :: $map_syntax_to_subtypes)
|
||||
)
|
||||
$type = self :: $map_syntax_to_subtypes[$schema_entry['syntax']];
|
||||
else
|
||||
$type = self :: class;
|
||||
return new $type($schema_entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic method to get attribute schema entry key
|
||||
* @param string $key
|
||||
|
@ -82,4 +109,31 @@ class Attribute extends SchemaEntry {
|
|||
}
|
||||
return parent::__get($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert LDAP value to PHP value
|
||||
* @param array<int,string> $value
|
||||
* @return string|array<string>|null
|
||||
*/
|
||||
public function ldap2php($value) {
|
||||
if ($value)
|
||||
return $this->single?$value[0]:$value;
|
||||
return $this->single?null:array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert LDAP value to PHP value
|
||||
* @param mixed $value
|
||||
* @return array<int,string>
|
||||
*/
|
||||
public function php2ldap($value) {
|
||||
if (is_null($value))
|
||||
return array();
|
||||
if (!is_array($value))
|
||||
$value = array($value);
|
||||
$ldap_value = array();
|
||||
foreach($value as $v)
|
||||
$ldap_value[] = strval($v);
|
||||
return $ldap_value;
|
||||
}
|
||||
}
|
||||
|
|
68
src/Schema/Attribute/BooleanAttribute.php
Normal file
68
src/Schema/Attribute/BooleanAttribute.php
Normal file
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
namespace EesyLDAP\Schema\Attribute;
|
||||
|
||||
/**
|
||||
* LDAP Schema boolean attribute
|
||||
*/
|
||||
class BooleanAttribute extends \EesyLDAP\Schema\Attribute {
|
||||
|
||||
/**
|
||||
* LDAP stored value for true
|
||||
* @var string
|
||||
*/
|
||||
const TRUE_VALUE = 'TRUE';
|
||||
|
||||
/**
|
||||
* LDAP stored value for false
|
||||
* @var string
|
||||
*/
|
||||
const FALSE_VALUE = 'FALSE';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Convert one LDAP value to PHP value
|
||||
* @param string $value
|
||||
* @return bool|null
|
||||
*/
|
||||
protected function _ldap2php($value) {
|
||||
if ($value == self :: TRUE_VALUE)
|
||||
return true;
|
||||
if ($value == self :: FALSE_VALUE)
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Convert LDAP value to PHP value
|
||||
* @param array<int,string> $value
|
||||
* @return bool|null|array<bool|null>
|
||||
*/
|
||||
public function ldap2php($value) {
|
||||
$value = parent::ldap2php($value);
|
||||
if (is_string($value))
|
||||
return self :: _ldap2php($value);
|
||||
if (is_array($value)) {
|
||||
$php_value = array();
|
||||
foreach($value as $v)
|
||||
$php_value[] = self :: _ldap2php($v);
|
||||
return $php_value;
|
||||
}
|
||||
return $this->single?null:array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert LDAP value to PHP value
|
||||
* @param mixed $value
|
||||
* @return array<int,string>
|
||||
*/
|
||||
public function php2ldap($value) {
|
||||
if (is_null($value))
|
||||
return array();
|
||||
$value = is_array($value)?$value:array($value);
|
||||
$ldap_value = array();
|
||||
foreach(parent::php2ldap($value) as $value)
|
||||
$ldap_value[] = $value?self :: TRUE_VALUE:self :: FALSE_VALUE;
|
||||
return $ldap_value;
|
||||
}
|
||||
}
|
|
@ -50,17 +50,15 @@ class SchemaEntry {
|
|||
}
|
||||
|
||||
/**
|
||||
* Parses an SubSchema attribute value into a SchemaEntry object
|
||||
* Parse an SubSchema attribute value into a hash of entry properties
|
||||
*
|
||||
* Note: mainly from PEAR Net_LDAP2_Schema::_parse_entry()
|
||||
* @link https://pear.php.net/package/Net_LDAP2
|
||||
*
|
||||
* @param string $value Attribute value
|
||||
*
|
||||
* @access protected
|
||||
* @return SchemaEntry
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public static function parse($value) {
|
||||
public static function _parse($value) {
|
||||
// tokens that have no value associated
|
||||
$noValue = array(
|
||||
'single-value',
|
||||
|
@ -116,6 +114,16 @@ class SchemaEntry {
|
|||
$schema_entry['max_length'] = intval($matches[1]);
|
||||
}
|
||||
}
|
||||
return $schema_entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a SubSchema attribute value into a SchemaEntry object
|
||||
* @param string $value Attribute value
|
||||
* @return SchemaEntry|false
|
||||
*/
|
||||
public static function parse($value) {
|
||||
$schema_entry = self :: _parse($value);
|
||||
$type = get_called_class();
|
||||
return new $type($schema_entry);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue