2023-12-03 22:10:18 +04:00
|
|
|
<?php
|
|
|
|
namespace nur;
|
|
|
|
|
|
|
|
use ReflectionClass;
|
|
|
|
use ReflectionException;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Class prop: des outils pour accéder aux propriétés d'un objet. la différence
|
|
|
|
* avec {@link oprop} est qu'une tentative est effectuée pour accéder d'abord à
|
|
|
|
* la propriété via une méthode normalisée
|
|
|
|
*
|
|
|
|
* @see valx
|
|
|
|
*/
|
|
|
|
class prop {
|
|
|
|
static function split_prefix_name(string $name): array {
|
|
|
|
preg_match('/^(_*)(.*)/', $name, $ms);
|
|
|
|
return [$ms[1], $ms[2]];
|
|
|
|
}
|
|
|
|
|
|
|
|
static function get_getter_name(string $property, bool $bool=false): string {
|
|
|
|
[$prefix, $name] = self::split_prefix_name($property);
|
|
|
|
$get = $bool? "is": "get";
|
|
|
|
return $prefix.$get.str::upper1(str::us2camel($name));
|
|
|
|
}
|
|
|
|
|
|
|
|
static function get_setter_name(string $property): string {
|
|
|
|
[$prefix, $name] = self::split_prefix_name($property);
|
|
|
|
return $prefix."set".str::upper1(str::us2camel($name));
|
|
|
|
}
|
|
|
|
|
|
|
|
static function get_deletter_name(string $property): string {
|
|
|
|
[$prefix, $name] = self::split_prefix_name($property);
|
|
|
|
return $prefix."del".str::upper1(str::us2camel($name));
|
|
|
|
}
|
|
|
|
|
|
|
|
/** obtenir la valeur d'une propriété */
|
|
|
|
static final function get(object $object, string $property, $default=null, ?string $method=null) {
|
|
|
|
if ($method === null) $method = self::get_getter_name($property);
|
|
|
|
$c = new ReflectionClass($object);
|
|
|
|
try {
|
|
|
|
$m = $c->getMethod($method);
|
|
|
|
} catch (ReflectionException $e) {
|
|
|
|
return oprop::get($object, $property, $default);
|
|
|
|
}
|
|
|
|
return func::call([$object, $m], $default);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** spécifier la valeur d'une propriété */
|
|
|
|
static final function set(object $object, string $property, $value, ?string $method=null) {
|
|
|
|
$c = new ReflectionClass($object);
|
|
|
|
return self::_set($c, $object, $property, $value, $method);
|
|
|
|
}
|
|
|
|
|
2024-10-04 14:22:43 +04:00
|
|
|
private static function _set(ReflectionClass $c, object $object, string $property, $value, ?string $method) {
|
2023-12-03 22:10:18 +04:00
|
|
|
if ($method === null) $method = self::get_setter_name($property);
|
|
|
|
try {
|
|
|
|
$m = $c->getMethod($method);
|
|
|
|
} catch (ReflectionException $e) {
|
|
|
|
return oprop::_set($c, $object, $property, $value);
|
|
|
|
}
|
|
|
|
func::call([$object, $m], $value);
|
|
|
|
return $value;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* initialiser $dest avec les valeurs de $values
|
|
|
|
*
|
|
|
|
* les noms des clés de $values sont transformées en camelCase pour avoir les
|
|
|
|
* noms des propriétés correspondantes
|
|
|
|
*/
|
|
|
|
static final function set_values(object $object, ?array $values, ?array $keys=null): void {
|
|
|
|
if ($values === null) return;
|
|
|
|
if ($keys === null) $keys = array_keys($values);
|
|
|
|
$c = new ReflectionClass($object);
|
|
|
|
foreach ($keys as $key) {
|
|
|
|
if (array_key_exists($key, $values)) {
|
|
|
|
$property = str::us2camel($key);
|
|
|
|
self::_set($c, $object, $property, $values[$key], null);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** incrémenter la valeur d'une propriété */
|
|
|
|
static final function inc(object $object, string $property): int {
|
|
|
|
$value = intval(self::get($object, $property, 0));
|
|
|
|
$value++;
|
|
|
|
self::set($object, $property, $value);
|
|
|
|
return $value;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** décrémenter la valeur d'une propriété */
|
|
|
|
static final function dec(object $object, string $property, bool $allow_negative=false): int {
|
|
|
|
$value = intval(self::get($object, $property, 0));
|
|
|
|
if ($allow_negative || $value > 0) {
|
|
|
|
$value--;
|
|
|
|
self::set($object, $property, $value);
|
|
|
|
}
|
|
|
|
return $value;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Fusionner la valeur à la propriété qui est transformée en tableau si
|
|
|
|
* nécessaire
|
|
|
|
*/
|
|
|
|
static final function merge(object $object, string $property, $array): void {
|
|
|
|
$values = A::with(self::get($object, $property));
|
|
|
|
A::merge($values, A::with($array));
|
|
|
|
self::set($object, $property, $values);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Ajouter la valeur à la propriété qui est transformée en tableau si
|
|
|
|
* nécessaire
|
|
|
|
*/
|
|
|
|
static final function append(object $object, string $property, $value): void {
|
|
|
|
$values = A::with(self::get($object, $property));
|
|
|
|
$values[] = $value;
|
|
|
|
self::set($object, $property, $values);
|
|
|
|
}
|
|
|
|
}
|