128 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			128 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
namespace nur\b\coll;
 | 
						|
 | 
						|
use nur\A;
 | 
						|
use nur\b\IllegalAccessException;
 | 
						|
use ReflectionMethod;
 | 
						|
 | 
						|
/**
 | 
						|
 * Trait TAutomethods: support des méthodes automatiques
 | 
						|
 */
 | 
						|
trait TAutomethods {
 | 
						|
  /**
 | 
						|
   * return @array un tableau {$method => $key} qui associe des noms de getters
 | 
						|
   * aux clés correspondantes. cette valeur est utilisée pour implémenter les
 | 
						|
   * getters automatiques
 | 
						|
   */
 | 
						|
  protected static function _AUTO_GETTERS(): ?array {
 | 
						|
    return static::_AUTO_GETTERS;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * return @array un tableau {$method => $key} qui associe des noms de setters
 | 
						|
   * aux clés correspondantes. cette valeur est utilisée pour implémenter les
 | 
						|
   * setters automatiques
 | 
						|
   */
 | 
						|
  protected static function _AUTO_SETTERS(): ?array {
 | 
						|
    return static::_AUTO_SETTERS;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * return @array un tableau {$method => $key} qui associe des noms de deleters
 | 
						|
   * aux clés correspondantes. cette valeur est utilisée pour implémenter les
 | 
						|
   * deleters automatiques
 | 
						|
   */
 | 
						|
  protected static function _AUTO_DELETERS(): ?array {
 | 
						|
    return static::_AUTO_DELETERS;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * return @array un tableau {$method => $key} qui associe des noms de getters
 | 
						|
   * aux clés composites correspondantes. cette valeur est utilisée pour
 | 
						|
   * implémenter les getters automatiques
 | 
						|
   */
 | 
						|
  protected static function _AUTO_CI_GETTERS(): ?array {
 | 
						|
    return static::_AUTO_CI_GETTERS;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * return @array un tableau {$method => $key} qui associe des noms de setters
 | 
						|
   * aux clés composites correspondantes. cette valeur est utilisée pour
 | 
						|
   * implémenter les setters automatiques
 | 
						|
   */
 | 
						|
  protected static function _AUTO_CI_SETTERS(): ?array {
 | 
						|
    return static::_AUTO_CI_SETTERS;
 | 
						|
  }
 | 
						|
 | 
						|
  static function _TAutomethods__have_method(string $method): bool {
 | 
						|
    $autoLists = [
 | 
						|
      static::_AUTO_GETTERS,
 | 
						|
      static::_AUTO_SETTERS,
 | 
						|
      static::_AUTO_DELETERS,
 | 
						|
      static::_AUTO_CI_GETTERS,
 | 
						|
      static::_AUTO_CI_SETTERS,
 | 
						|
    ];
 | 
						|
    foreach ($autoLists as $method2properties) {
 | 
						|
      if ($method2properties !== null && array_key_exists($method, $method2properties)) {
 | 
						|
        return true;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
 | 
						|
  function _haveMethod(string $method): bool {
 | 
						|
    if (method_exists($this, $method)) return true;
 | 
						|
    return self::_TAutomethods__have_method($method);
 | 
						|
  }
 | 
						|
 | 
						|
  private static function call_args(object $object, string $method, array $args) {
 | 
						|
    $rf = new ReflectionMethod($object, $method);
 | 
						|
    if (!$rf->isVariadic()) {
 | 
						|
      $maxArgs = $rf->getNumberOfParameters();
 | 
						|
      $args = array_slice($args, 0, $maxArgs);
 | 
						|
      while (count($args) < $maxArgs) {
 | 
						|
        $args[] = null;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (count($args) === 0) return $rf->invoke($object);
 | 
						|
    else return $rf->invokeArgs($object, $args);
 | 
						|
  }
 | 
						|
 | 
						|
  function __call(string $name, array $args) {
 | 
						|
    $getter_keys = static::_AUTO_GETTERS();
 | 
						|
    if ($getter_keys !== null && array_key_exists($name, $getter_keys)) {
 | 
						|
      $key = $getter_keys[$name];
 | 
						|
      $default = A::get($args, 0);
 | 
						|
      return self::call_args($this, "get", [$key, $default]);
 | 
						|
    }
 | 
						|
    $setter_keys = static::_AUTO_SETTERS();
 | 
						|
    if ($setter_keys !==null && array_key_exists($name, $setter_keys)) {
 | 
						|
      $key = $setter_keys[$name];
 | 
						|
      $value = A::get($args, 0);
 | 
						|
      if (is_string($value)) {
 | 
						|
        $type = $this->md()->getType($key, false);
 | 
						|
        if ($type !== null) $value = $type->with($value);
 | 
						|
      }
 | 
						|
      return self::call_args($this, "set", [$key, $value]);
 | 
						|
    }
 | 
						|
    $deleter_keys = static::_AUTO_DELETERS();
 | 
						|
    if ($deleter_keys !== null && array_key_exists($name, $deleter_keys)) {
 | 
						|
      $key = $deleter_keys[$name];
 | 
						|
      return self::call_args($this, "del", [$key]);
 | 
						|
    }
 | 
						|
    $ci_getter_keys = static::_AUTO_CI_GETTERS();
 | 
						|
    if ($ci_getter_keys !== null && array_key_exists($name, $ci_getter_keys)) {
 | 
						|
      $key = $ci_getter_keys[$name];
 | 
						|
      return $this->md()->get($this->data, $key, null, false);
 | 
						|
    }
 | 
						|
    $ci_setter_keys = static::_AUTO_CI_SETTERS();
 | 
						|
    if ($ci_setter_keys !==null && array_key_exists($name, $ci_setter_keys)) {
 | 
						|
      $key = $ci_setter_keys[$name];
 | 
						|
      $value = A::get($args, 0);
 | 
						|
      $this->md()->set($this->data, $key, $value);
 | 
						|
      return null;
 | 
						|
    }
 | 
						|
    throw IllegalAccessException::not_implemented($name);
 | 
						|
  }
 | 
						|
}
 |