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':
|
case 'changes':
|
||||||
return $this -> changes;
|
return $this -> changes;
|
||||||
default:
|
default:
|
||||||
return $this -> get_values($key);
|
return $this -> get_value($key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,14 +78,7 @@ class Entry {
|
||||||
else
|
else
|
||||||
$this -> error('Unexcepted DN value provided: must be a string or false');
|
$this -> error('Unexcepted DN value provided: must be a string or false');
|
||||||
default:
|
default:
|
||||||
$key = mb_strtolower($key);
|
$this -> set_value($key, $value);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +96,7 @@ class Entry {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an attribute values
|
* Get raw attribute values
|
||||||
* @param string $attr The expected attribute name
|
* @param string $attr The expected attribute name
|
||||||
* @param mixed $default The default value if attribute is not set
|
* @param mixed $default The default value if attribute is not set
|
||||||
* (optional, default: null or array() if $all_values is True)
|
* (optional, default: null or array() if $all_values is True)
|
||||||
|
@ -111,7 +104,7 @@ class Entry {
|
||||||
* first one (optional, default: true)
|
* first one (optional, default: true)
|
||||||
* @return ( $all_values is True ? array<string> : mixed )
|
* @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);
|
$attr = mb_strtolower($attr);
|
||||||
$values = false;
|
$values = false;
|
||||||
if (array_key_exists($attr, $this -> changes))
|
if (array_key_exists($attr, $this -> changes))
|
||||||
|
@ -123,6 +116,71 @@ class Entry {
|
||||||
return $all_values?$values:$values[0];
|
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
|
* Log and eventually raise an error
|
||||||
* @param string $error The error message
|
* @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 string $scope
|
||||||
* @property-read bool $raise_on_error
|
* @property-read bool $raise_on_error
|
||||||
* @property-read bool $use_schema
|
* @property-read bool $use_schema
|
||||||
|
* @property-read Schema|false $schema
|
||||||
*/
|
*/
|
||||||
class Ldap {
|
class Ldap {
|
||||||
|
|
||||||
|
@ -391,12 +392,11 @@ class Ldap {
|
||||||
case 'default_config':
|
case 'default_config':
|
||||||
return self :: $default_config;
|
return self :: $default_config;
|
||||||
case 'schema':
|
case 'schema':
|
||||||
if ($this->schema)
|
|
||||||
return $this->schema;
|
|
||||||
if (!$this->use_schema)
|
if (!$this->use_schema)
|
||||||
return false;
|
return false;
|
||||||
$this->schema = Schema :: load($this);
|
if (!$this->schema)
|
||||||
return $this->schema;
|
$this->schema = Schema :: load($this);
|
||||||
|
return $this->schema && $this->schema->loaded?$this->schema:false;
|
||||||
}
|
}
|
||||||
return $this -> error("Invalid property '$key' requested");
|
return $this -> error("Invalid property '$key' requested");
|
||||||
}
|
}
|
||||||
|
@ -506,7 +506,7 @@ class Ldap {
|
||||||
$attrs[$attr][$k] = $result[$i][$attr][$k];
|
$attrs[$attr][$k] = $result[$i][$attr][$k];
|
||||||
}
|
}
|
||||||
// @phpstan-ignore-next-line
|
// @phpstan-ignore-next-line
|
||||||
$entries[$dn] = new Entry($dn, $attrs);
|
$entries[$dn] = new Entry($dn, $attrs, $this);
|
||||||
}
|
}
|
||||||
// @phpstan-ignore-next-line
|
// @phpstan-ignore-next-line
|
||||||
return $entries;
|
return $entries;
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
namespace EesyLDAP;
|
namespace EesyLDAP;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @property-read bool $loaded
|
||||||
|
*/
|
||||||
class Schema {
|
class Schema {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,6 +56,12 @@ class Schema {
|
||||||
*/
|
*/
|
||||||
protected $oids = array();
|
protected $oids = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loaded telltale
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
protected $loaded = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* @param Ldap $ldap The LDAP connection
|
* @param Ldap $ldap The LDAP connection
|
||||||
|
@ -63,6 +72,23 @@ class Schema {
|
||||||
$this -> ldap = $ldap;
|
$this -> ldap = $ldap;
|
||||||
$this -> entry = $entry;
|
$this -> entry = $entry;
|
||||||
$this -> parse();
|
$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() {
|
protected function parse() {
|
||||||
foreach (self :: $attributes_to_entry_types as $attr => $type) {
|
foreach (self :: $attributes_to_entry_types as $attr => $type) {
|
||||||
$type_name = strtolower($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
|
// @phpstan-ignore-next-line
|
||||||
$entry = call_user_func("\\EesyLDAP\\Schema\\$type::parse", $value);
|
$entry = call_user_func("\\EesyLDAP\\Schema\\$type::parse", $value);
|
||||||
if (!$entry instanceof Schema\SchemaEntry) {
|
if (!$entry instanceof Schema\SchemaEntry) {
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace EesyLDAP\Schema;
|
namespace EesyLDAP\Schema;
|
||||||
|
|
||||||
|
use EesyLDAP\Schema;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property-read string $oid
|
* @property-read string $oid
|
||||||
|
@ -69,6 +70,32 @@ class Attribute extends SchemaEntry {
|
||||||
'multiple',
|
'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
|
* Magic method to get attribute schema entry key
|
||||||
* @param string $key
|
* @param string $key
|
||||||
|
@ -82,4 +109,31 @@ class Attribute extends SchemaEntry {
|
||||||
}
|
}
|
||||||
return parent::__get($key);
|
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()
|
* Note: mainly from PEAR Net_LDAP2_Schema::_parse_entry()
|
||||||
* @link https://pear.php.net/package/Net_LDAP2
|
* @link https://pear.php.net/package/Net_LDAP2
|
||||||
*
|
*
|
||||||
* @param string $value Attribute value
|
* @param string $value Attribute value
|
||||||
*
|
* @return array<string,mixed>
|
||||||
* @access protected
|
|
||||||
* @return SchemaEntry
|
|
||||||
*/
|
*/
|
||||||
public static function parse($value) {
|
public static function _parse($value) {
|
||||||
// tokens that have no value associated
|
// tokens that have no value associated
|
||||||
$noValue = array(
|
$noValue = array(
|
||||||
'single-value',
|
'single-value',
|
||||||
|
@ -116,6 +114,16 @@ class SchemaEntry {
|
||||||
$schema_entry['max_length'] = intval($matches[1]);
|
$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();
|
$type = get_called_class();
|
||||||
return new $type($schema_entry);
|
return new $type($schema_entry);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue