restaurer func
This commit is contained in:
		
							parent
							
								
									a4b67ec721
								
							
						
					
					
						commit
						11a02002fa
					
				
							
								
								
									
										202
									
								
								src/php/func.php
									
									
									
									
									
								
							
							
						
						
									
										202
									
								
								src/php/func.php
									
									
									
									
									
								
							@ -4,7 +4,6 @@ namespace nur\sery\php;
 | 
			
		||||
use Closure;
 | 
			
		||||
use nur\sery\cl;
 | 
			
		||||
use nur\sery\ref\php\ref_func;
 | 
			
		||||
use nur\sery\str;
 | 
			
		||||
use nur\sery\ValueException;
 | 
			
		||||
use ReflectionClass;
 | 
			
		||||
use ReflectionFunction;
 | 
			
		||||
@ -12,111 +11,55 @@ use ReflectionMethod;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class func: outils pour appeler des fonctions et méthodes dynamiquement
 | 
			
		||||
 *
 | 
			
		||||
 * Les formats supportés sont:
 | 
			
		||||
 * - fonctions globales
 | 
			
		||||
 *   - "func"                   si function_exists("func")
 | 
			
		||||
 *   - [false, "func", ...]
 | 
			
		||||
 * - méthodes statiques
 | 
			
		||||
 *   - "::method"               méthode à lier à une classe avant l'appel
 | 
			
		||||
 *   - "class::method"
 | 
			
		||||
 *   - ["method"]               si !class_exists("method")
 | 
			
		||||
 *   - [null, "method", ...]    méthode à lier à une classe avant l'appel
 | 
			
		||||
 *   - ["class", "method", ...]
 | 
			
		||||
 * - méthodes
 | 
			
		||||
 *   - "->method"               méthode à lier à un objet avant l'appel
 | 
			
		||||
 *   - ["method"]               si !class_exists("method")
 | 
			
		||||
 *   - [null, "method", ...]    méthode à lier à un objet avant l'appel
 | 
			
		||||
 *   - [$object, "method", ...]
 | 
			
		||||
 * - classes
 | 
			
		||||
 *   - "class"                  si !function_exists("class")
 | 
			
		||||
 *   - "class::"
 | 
			
		||||
 *   - ["class"]                si class_exists("class")
 | 
			
		||||
 *   - ["class", null, ...]
 | 
			
		||||
 *
 | 
			
		||||
 * les formes "func" et "class" sont distinguées en vérifiant l'existence de la
 | 
			
		||||
 * fonction
 | 
			
		||||
 *
 | 
			
		||||
 * les formes ["class"] et ["method"] sont distinguées en vérifiant l'existence
 | 
			
		||||
 * de la classe
 | 
			
		||||
 */
 | 
			
		||||
class func {
 | 
			
		||||
  /** tester si $value est une chaine non vide */
 | 
			
		||||
  private static function is_ne($value): bool {
 | 
			
		||||
    return is_string($value) && strlen($value) > 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * tester si $func est d'une des formes suivantes:
 | 
			
		||||
   * - "func"                   si function_exists("func")
 | 
			
		||||
   * - [false, "func", ...]
 | 
			
		||||
   * tester si $func est une chaine de la forme "XXX::method" où XXX est une
 | 
			
		||||
   * chaine quelconque éventuellement vide, ou un tableau de la forme ["method"]
 | 
			
		||||
   * ou [anything, "method", ...]
 | 
			
		||||
   * 
 | 
			
		||||
   * Avec la forme tableau, "method" ne doit pas contenir le caractère '\', pour
 | 
			
		||||
   * pouvoir utiliser conjointement {@link is_class()}
 | 
			
		||||
   */
 | 
			
		||||
  static final function is_global($func): bool {
 | 
			
		||||
    if (self::is_ne($func)) {
 | 
			
		||||
  static final function is_static($func, bool $allowClass=false): bool {
 | 
			
		||||
    if (is_string($func)) {
 | 
			
		||||
      $pos = strpos($func, "::");
 | 
			
		||||
      return $pos === false && function_exists($func);
 | 
			
		||||
    } elseif (is_array($func)) {
 | 
			
		||||
      return ($func[0] ?? null) === false
 | 
			
		||||
        && self::is_ne($func[1] ?? null);
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static final function fix_global_args(&$func, ?array &$args): bool {
 | 
			
		||||
    if ($args === null) $args = [];
 | 
			
		||||
    if (is_array($func)) {
 | 
			
		||||
      if (count($func) > 2) {
 | 
			
		||||
        $prefix_args = array_slice($func, 2);
 | 
			
		||||
        $func = array_slice($func, 1, 1)[0];
 | 
			
		||||
        $args = array_merge($prefix_args, $args);
 | 
			
		||||
      } else {
 | 
			
		||||
        $func = $func[0];
 | 
			
		||||
      }
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * tester si $func est d'une des formes suivantes:
 | 
			
		||||
   * - "::method"
 | 
			
		||||
   * - "class::method"
 | 
			
		||||
   * - ["method"]               si !class_exists("method")
 | 
			
		||||
   * - [anything, "method", ...]
 | 
			
		||||
   */
 | 
			
		||||
  static final function is_static($func): bool {
 | 
			
		||||
    if (self::is_ne($func)) {
 | 
			
		||||
      $pos = strpos($func, "::");
 | 
			
		||||
      return $pos !== false && $pos + 2 < strlen($func);
 | 
			
		||||
      if ($pos === false) return false;
 | 
			
		||||
      return $pos + 2 < strlen($func);
 | 
			
		||||
    } elseif (is_array($func) && array_key_exists(0, $func)) {
 | 
			
		||||
      $count = count($func);
 | 
			
		||||
      if ($count == 1) {
 | 
			
		||||
        return self::is_ne($func[0]) && !class_exists($func[0]);
 | 
			
		||||
      } elseif ($count > 1 && array_key_exists(1, $func)) {
 | 
			
		||||
        return  self::is_ne($func[1]);
 | 
			
		||||
        if (!is_string($func[0]) || strlen($func[0]) == 0) return false;
 | 
			
		||||
        if (strpos($func[0], "\\") !== false) return false;
 | 
			
		||||
        return true;
 | 
			
		||||
      } elseif ($count > 1) {
 | 
			
		||||
        if (!array_key_exists(1, $func)) return false;
 | 
			
		||||
        if (!is_string($func[1]) || strlen($func[1]) == 0) return false;
 | 
			
		||||
        if (strpos($func[1], "\\") !== false) return false;
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * en assumant que {@link self::is_static()} retourne true:
 | 
			
		||||
   * - si $func est une chaine de la forme "::method" alors la remplacer par la
 | 
			
		||||
   * si $func est une chaine de la forme "::method" alors la remplacer par la
 | 
			
		||||
   * chaine "$class::method"
 | 
			
		||||
   * - si $func est un tableau de la forme ["method"] ou [null, "method"], alors
 | 
			
		||||
   *
 | 
			
		||||
   * si $func est un tableau de la forme ["method"] ou [null, "method"], alors
 | 
			
		||||
   * le remplacer par [$class, "method"]
 | 
			
		||||
   *
 | 
			
		||||
   * on assume que {@link is_static()}($func) retourne true
 | 
			
		||||
   *
 | 
			
		||||
   * @return bool true si la correction a été faite
 | 
			
		||||
   */
 | 
			
		||||
  static final function fix_static(&$func, $class): bool {
 | 
			
		||||
    if (is_object($class)) $class = get_class($class);
 | 
			
		||||
 | 
			
		||||
    if (is_string($func)) {
 | 
			
		||||
      if (substr($func, 0, 2) == "::") {
 | 
			
		||||
        $func = "$class$func";
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
    if (is_string($func) && substr($func, 0, 2) == "::") {
 | 
			
		||||
      $func = "$class$func";
 | 
			
		||||
      return true;
 | 
			
		||||
    } elseif (is_array($func) && array_key_exists(0, $func)) {
 | 
			
		||||
      $count = count($func);
 | 
			
		||||
      if ($count == 1) {
 | 
			
		||||
        $func = [$class, $func[0]];
 | 
			
		||||
@ -130,43 +73,37 @@ class func {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** tester si $method est une chaine de la forme "->method" */
 | 
			
		||||
  private static function isam(&$method, bool $requireArrow=false): bool {
 | 
			
		||||
    if (is_string($method)) {
 | 
			
		||||
      if (substr($method, 0, 2) == "->") {
 | 
			
		||||
        $method = substr($method, 2);
 | 
			
		||||
      } elseif ($requireArrow) {
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
      return strlen($method) > 0;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  private static function isam($method): bool {
 | 
			
		||||
    return is_string($method)
 | 
			
		||||
      && strlen($method) > 2
 | 
			
		||||
      && substr($method, 0, 2) == "->";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * tester si $func est d'une des formes suivantes:
 | 
			
		||||
   * - "->method"
 | 
			
		||||
   * - ["method"]               si !class_exists("method")
 | 
			
		||||
   * - [anything, "method", ...]
 | 
			
		||||
   * tester si $func est une chaine de la forme "->method" ou un tableau de la
 | 
			
		||||
   * forme ["->method", ...] ou [anything, "->method", ...]
 | 
			
		||||
   */
 | 
			
		||||
  static final function is_method($func): bool {
 | 
			
		||||
    if (is_string($func)) {
 | 
			
		||||
      return self::isam($func, true);
 | 
			
		||||
      return self::isam($func);
 | 
			
		||||
    } elseif (is_array($func) && array_key_exists(0, $func)) {
 | 
			
		||||
      $count = count($func);
 | 
			
		||||
      if ($count == 1) {
 | 
			
		||||
        return self::isam($func[0]) && !class_exists($func[0]);
 | 
			
		||||
      } elseif ($count > 1 && array_key_exists(1, $func)) {
 | 
			
		||||
        return self::isam($func[1]);
 | 
			
		||||
      if (self::isam($func[0])) {
 | 
			
		||||
        # ["->method", ...]
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
      if (array_key_exists(1, $func) && self::isam($func[1])) {
 | 
			
		||||
        # [anything, "->method", ...]
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * en assumant que {@link self::is_method()} retourne true:
 | 
			
		||||
   * - si $func est une chaine de la forme "->method" alors la remplacer par le
 | 
			
		||||
   * si $func est une chaine de la forme "->method" alors la remplacer par le
 | 
			
		||||
   * tableau [$object, "method"]
 | 
			
		||||
   * - si $func est un tableau de la forme ["method"] ou [anything, "method"],
 | 
			
		||||
   *
 | 
			
		||||
   * si $func est un tableau de la forme ["->method"] ou [anything, "->method"],
 | 
			
		||||
   * alors le remplacer par [$object, "method"]
 | 
			
		||||
   *
 | 
			
		||||
   * @return bool true si la correction a été faite
 | 
			
		||||
@ -176,18 +113,14 @@ class func {
 | 
			
		||||
 | 
			
		||||
    if (is_string($func)) {
 | 
			
		||||
      if (self::isam($func)) {
 | 
			
		||||
        $func = [$object, $func];
 | 
			
		||||
        $func = [$object, substr($func, 2)];
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      $count = count($func);
 | 
			
		||||
      if ($count == 1) {
 | 
			
		||||
        self::isam($func[0]);
 | 
			
		||||
        $func = [$object, $func[0]];
 | 
			
		||||
        return true;
 | 
			
		||||
      } else {
 | 
			
		||||
    } elseif (is_array($func) && array_key_exists(0, $func)) {
 | 
			
		||||
      if (self::isam($func[0])) $func = array_merge([null], $func);
 | 
			
		||||
      if (count($func) > 1 && array_key_exists(1, $func) && self::isam($func[1])) {
 | 
			
		||||
        $func[0] = $object;
 | 
			
		||||
        self::isam($func[1]);
 | 
			
		||||
        $func[1] = substr($func[1], 2);
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
@ -423,32 +356,29 @@ class func {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * tester si $class est d'une des formes suivantes:
 | 
			
		||||
   * - "class"                  si !function_exists("class")
 | 
			
		||||
   * - "class::"
 | 
			
		||||
   * - ["class"]                si class_exists("class")
 | 
			
		||||
   * - ["class", null, ...]
 | 
			
		||||
   * tester si $func est une chaine de la forme "XXX" où XXX est une classe
 | 
			
		||||
   * valide, ou un tableau de la forme ["XXX", ...]
 | 
			
		||||
   *
 | 
			
		||||
   * NB: il est possible d'avoir {@link is_static()} et {@link is_class()}
 | 
			
		||||
   * vraies pour la même valeur. s'il faut supporter les deux cas, appeler
 | 
			
		||||
   * {@link is_static()} d'abord, mais dans ce cas, on ne supporte que les
 | 
			
		||||
   * classes qui sont dans un package
 | 
			
		||||
   */
 | 
			
		||||
  static final function is_class($class): bool {
 | 
			
		||||
    if (self::is_ne($class)) {
 | 
			
		||||
      return str::ends_with("::", $class)
 | 
			
		||||
        || !function_exists($class);
 | 
			
		||||
    } elseif (is_array($class) && self::is_ne($class[0] ?? null)) {
 | 
			
		||||
      $count = count($class);
 | 
			
		||||
      if ($count == 1) {
 | 
			
		||||
        return class_exists($class[0]);
 | 
			
		||||
      } elseif ($count > 1 && array_key_exists(1, $class)) {
 | 
			
		||||
        return $class[1] === null;
 | 
			
		||||
      }
 | 
			
		||||
    if (is_string($class)) {
 | 
			
		||||
      return class_exists($class);
 | 
			
		||||
    } elseif (is_array($class) && array_key_exists(0, $class)) {
 | 
			
		||||
      return class_exists($class[0]);
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * si $class est un tableau de plus de 2 éléments, alors déplacer les éléments
 | 
			
		||||
   * supplémentaires au début de $args. par exemple:
 | 
			
		||||
   * en assumant que {@link is_class()} est vrai, si $class est un tableau de
 | 
			
		||||
   * plus de 1 éléments, alors déplacer les éléments supplémentaires au début de
 | 
			
		||||
   * $args. par exemple:
 | 
			
		||||
   * ~~~
 | 
			
		||||
   * $class = ["class", null, "arg1", "arg2"];
 | 
			
		||||
   * $class = ["class", "arg1", "arg2"];
 | 
			
		||||
   * $args = ["arg3"];
 | 
			
		||||
   * func::fix_class_args($class, $args)
 | 
			
		||||
   * # $class === "class"
 | 
			
		||||
@ -460,8 +390,8 @@ class func {
 | 
			
		||||
  static final function fix_class_args(&$class, ?array &$args): bool {
 | 
			
		||||
    if ($args === null) $args = [];
 | 
			
		||||
    if (is_array($class)) {
 | 
			
		||||
      if (count($class) > 2) {
 | 
			
		||||
        $prefix_args = array_slice($class, 2);
 | 
			
		||||
      if (count($class) > 1) {
 | 
			
		||||
        $prefix_args = array_slice($class, 1);
 | 
			
		||||
        $class = array_slice($class, 0, 1)[0];
 | 
			
		||||
        $args = array_merge($prefix_args, $args);
 | 
			
		||||
      } else {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user