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);
 | |
|   }
 | |
| }
 |