nur-sery/nur_src/ldap/CompositeValue.php

160 lines
4.8 KiB
PHP

<?php
namespace nur\ldap;
use nur\A;
use nur\b\coll\BaseArray;
use nur\b\ValueException;
use nur\data\types\Metadata;
use nur\ldap\syntaxes\AbstractSyntax;
use nur\ldap\syntaxes\cvalues;
/**
* Class CompositeValue: une valeur composite
*/
abstract class CompositeValue extends BaseArray {
/** @var array schéma des champs de la valeur composite */
const SCHEMA = null;
/** @var array syntaxes associées aux champs */
const SYNTAXES = null;
/** @var array liste et ordre des éléments obligatoires */
const MANDATORY_KEYS = null;
/** @var array liste et ordre des éléments facultatifs connus */
const OPTIONAL_KEYS = null;
/** @var array liste des clés qui identifient cet objet */
const KEY_KEYS = null;
static function compute_keys(array $values): string {
$keys = static::KEY_KEYS;
if ($keys === null) $keys = static::MANDATORY_KEYS;
if ($keys === null) $keys = array_keys($values);
$parts = [];
foreach ($keys as $key) {
$parts[] = A::get($values, $key);
}
return implode("-", $parts);
}
protected $ldapKeys, $keys, $optionalKeys;
protected $syntaxes;
/** initialiser l'objet */
function setup(LdapConn $conn): self {
$ldapKeys = [];
$keys = [];
$mandatoryKeys = ValueException::check_nn(static::MANDATORY_KEYS
, "Vous devez définir MANDATORY_KEYS");
$index = 0;
foreach ($mandatoryKeys as $key => $ldapKey) {
if ($key === $index) {
$index++;
$key = $ldapKey;
}
$ldapKeys[$key] = $ldapKey;
$keys[$ldapKey] = $key;
}
$optionalKeys = [];
$index = 0;
foreach (A::with(static::OPTIONAL_KEYS) as $key => $ldapKey) {
if ($key === $index) {
$index++;
$key = $ldapKey;
}
$ldapKeys[$key] = $ldapKey;
$keys[$ldapKey] = $key;
$optionalKeys[] = $key;
}
$schemaKeys = A::keys(static::SCHEMA);
foreach ($schemaKeys as $key) {
if (!in_array($key, $keys)) {
$ldapKeys[$key] = $key;
$keys[$key] = $key;
$optionalKeys[] = $key;
}
}
$this->ldapKeys = $ldapKeys;
$this->keys = $keys;
$this->optionalKeys = $optionalKeys;
##
$syntaxClasses = static::SYNTAXES;
if ($syntaxClasses !== null) {
$syntaxes = [];
foreach ($schemaKeys as $key) {
$class = A::get($syntaxClasses, $key);
if ($class !== null) {
$syntaxes[$key] = $conn->getSyntax($class);
}
}
$this->syntaxes = $syntaxes;
}
##
return $this;
}
function has($key): bool { return $this->_has($key); }
function &get($key, $default=null) { return $this->_get($key, $default); }
function set($key, $value): self { return $this->_set($key, $value); }
function add($value): self { return $this->_set(null, $value); }
function del($key): self { return $this->_del($key); }
/** obtenir la clé qui identifie cet objet */
function getKey(): string {
return self::compute_keys($this->data);
}
/** initialiser cet objet avec une valeur LDAP */
function parseLdap(string $value): self {
if (!preg_match_all('/\[.*?]/', $value, $ms)) {
throw ValueException::invalid_value($value, "composite value");
}
$this->data = [];
foreach ($ms[0] as $nameValue) {
if (preg_match('/\[(.*?)=(.*)]/', $nameValue, $ms)) {
$ldapKey = names::ldap_unescape($ms[1]);
$key = A::get($this->keys, $ldapKey, $ldapKey);
$value = names::ldap_unescape($ms[2]);
/** @var AbstractSyntax $syntax */
$syntax = A::get($this->syntaxes, $key);
if ($syntax !== null) $value = $syntax->ldap2php($value);
$this->data[$key] = $value;
}
}
return $this;
}
/** retourner cette valeur au format LDAP */
function formatLdap(): string {
$optionalKeys = $this->optionalKeys;
$parts = [];
foreach ($this->ldapKeys as $key => $ldapKey) {
$value = A::get($this->data, $key);
if ($value === null && in_array($key, $optionalKeys)) continue;
/** @var AbstractSyntax $syntax */
$syntax = A::get($this->syntaxes, $key);
if ($syntax !== null) $value = $syntax->php2ldap($value);
$ldapKey = ldap_escape($ldapKey, 0, LDAP_ESCAPE_FILTER);
$value = ldap_escape($value, 0, LDAP_ESCAPE_FILTER);
$parts[] = "[$ldapKey=$value]";
}
return implode("", $parts);
}
function reset(?array $values): CompositeValue {
$md = Metadata::with(static::SCHEMA);
$md->ensureSchema($values);
$this->data = $values;
return $this;
}
#############################################################################
static function _AUTOGEN_PROPERTIES(): array {
return cvalues::autogen_properties(static::SCHEMA);
}
## rajouter ceci dans les classes dérivées
#const _AUTOGEN_PROPERTIES = [[self::class, "_AUTOGEN_PROPERTIES"]];
}