1
0
mirror of https://github.com/processwire/processwire.git synced 2025-08-13 18:24:57 +02:00

Add wireClassNamespace() function to accopmany existing wireClassName() function and others. Also improve wireEmpty() function to recognize objects that can be cast to empty strings.

This commit is contained in:
Ryan Cramer
2020-01-24 10:01:32 -05:00
parent 57540cfab2
commit 045f69d96d

View File

@@ -857,6 +857,101 @@ function wireClassName($className, $withNamespace = false, $verbose = false) {
return $className;
}
/**
* Get namespace for given class
*
* ~~~~~
* echo wireClassNamespace('Page'); // returns: "\ProcessWire\"
* echo wireClassNamespace('DirectoryIterator'); // returns: "\"
* echo wireClassNamespace('UnknownClass'); // returns "" (blank)
*
* // Specify true for 2nd argument to make it include class name
* echo wireClassNamespace('Page', true); // outputs: \ProcessWire\Page
*
* // Specify true for 3rd argument to find all matching classes
* // and return array if more than 1 matches (or string if just 1):
* $val = wireClassNamespace('Foo', true, true);
* if(is_array($val)) {
* // 2+ classes found, so array value is returned
* // $val: [ '\Bar\Foo', '\Foo', '\Baz\Foo' ]
* } else {
* // string value is returned when only one class matches
* // $val: '\Bar\Foo'
* }
* ~~~~~
*
* @param string|object $className
* @param bool $withClass Include class name in returned namespace? (default=false)
* @param bool $strict Return array of namespaces if multiple match? (default=false)
* @return string|array Returns one of the following:
* - String of `\Namespace\` (leading+trailing backslashes) if namespace found.
* - String of `\` if class in root namespace.
* - Blank string if unable to find namespace for class.
* - Array of namespaces only if $strict option is true AND multiple namespaces were found for class.
* - If the $withClass option is true, then return value(s) have class, i.e. `\Namespace\ClassName`.
* @since 3.0.150
*
*/
function wireClassNamespace($className, $withClass = false, $strict = false) {
$bs = "\\";
$ns = "";
if(is_object($className)) {
$className = get_class($className);
}
if(strpos($className, $bs) !== false) {
// namespace is already included in class name
$a = explode($bs, $className);
array_pop($a); // class
$ns = count($a) ? implode($bs, $a) : $bs;
if(empty($ns)) $ns = $bs;
$strict = false; // strict not necessary
} else if(class_exists(__NAMESPACE__ . "$bs$className")) {
// class in ProcessWire namespace
$ns = __NAMESPACE__;
} else if(class_exists("$bs$className")) {
// class in root namespace
$ns = $bs;
}
if(empty($ns) || $strict) {
// hunt down namespace from declared classes
$nsa = array();
$name = strtolower($className);
foreach(get_declared_classes() as $class) {
if(strpos($class, $bs) === false) {
// root namespace
if(!$strict) continue;
$class = "$bs$class";
}
if(stripos($class, "$bs$className") === false) continue;
if(strtolower(substr($class, -1 * strlen($className))) !== $name) continue;
$a = explode($bs, trim($class, $bs));
$cn = array_pop($a);
$ns = count($a) ? implode($bs, $a) : $bs;
if($ns && $ns !== $bs) $ns = $bs . trim($ns, $bs) . $bs;
if($withClass) $ns .= $cn;
$nsa[] = $ns;
if(!$strict) break;
}
$n = count($nsa);
// return array now for multi-match strict mode
if($strict && $n > 1) return $nsa;
$ns = $n ? reset($nsa) : '';
} else if($ns && $ns !== $bs) {
// format with leading/trailing backslashes, i.e. \Namespace\
$ns = $bs . trim($ns, $bs) . $bs;
if($withClass) $ns .= $className;
}
return $ns;
}
/**
* Does the given class name exist?
@@ -950,7 +1045,12 @@ function wireClassParents($className, $autoload = true) {
$className = wireClassName($className, true);
if(!class_exists($className, false)) {
$_className = wireClassName($className, false);
if(class_exists("\\$_className")) $className = $_className;
if(class_exists("\\$_className")) {
$className = $_className;
} else {
$ns = wireClassNamespace($_className);
if($ns) $className = $ns . $_className;
}
}
$parents = class_parents(ltrim($className, "\\"), $autoload);
}
@@ -1088,6 +1188,7 @@ function wireCount($value) {
* - It returns true for Countable objects that have 0 items.
* - It considers whitespace-only strings to be empty.
* - It considers WireNull objects (like NullPage or any others) to be empty (3.0.149+).
* - It uses the string value of objects that can be typecast strings (3.0.150+).
* - You cannot pass it an undefined variable without triggering a PHP warning.
*
* ~~~~~
@@ -1119,8 +1220,11 @@ function wireEmpty($value) {
if(is_object($value)) {
if($value instanceof \Countable && !count($value)) return true;
if($value instanceof WireNull) return true; // 3.0.149+
} else if(is_string($value)) {
if(!strlen(trim($value))) return true;
if(method_exists($value, '__toString')) $value = (string) $value;
}
if(is_string($value)) {
$value = trim($value);
if(empty($value)) return true;
}
return false;
}