nur-sery/nur_src/prop.php

121 lines
3.9 KiB
PHP

<?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);
}
private static final function _set(ReflectionClass $c, object $object, string $property, $value, ?string $method) {
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);
}
}