mirror of
https://github.com/humhub/humhub.git
synced 2025-03-14 20:19:47 +01:00
Enh: Code de-duplication by introducing PermissionManager::handlePermissionStateChange()
(#6750)
* Code deduplication by introducing `PermissionManager::handlePermissionStateChange()` * Throw error if record isn't saved * Fix: clear local cache also if permission is reset to default * Move `checkClassType` and `classUsesTraits` from `Helpers` to `DataTypeHelper` * Requested Changes Pt. I * Requested Changes Pt. 2 * Requested Changes Pt. 3 * Requested Changes Pt. 4 * Update documentation * Remove `filterClassType()` * Fix `filterBool()` * Change `ensure*` methods' return type to `void`
This commit is contained in:
parent
344ebc0a6f
commit
fab82dbd76
@ -3,6 +3,7 @@ HumHub Changelog
|
||||
|
||||
1.16.0 (Unreleased)
|
||||
-------------------
|
||||
- Enh #6750: Code de-duplication by introducing `PermissionManager::handlePermissionStateChange()`
|
||||
- Fix #6772: Polymorphic relation lookup (Regression #6587)
|
||||
- Enh #6745: Harmonise term `enabled/disabled` vs `active/inactive` for modules
|
||||
- Fix #6754: Regression due to return type (#6550)
|
||||
|
@ -10,7 +10,7 @@ namespace humhub\components\behaviors;
|
||||
|
||||
use Exception;
|
||||
use humhub\components\ActiveRecord;
|
||||
use humhub\libs\Helpers;
|
||||
use humhub\helpers\DataTypeHelper;
|
||||
use humhub\modules\content\components\ContentActiveRecord;
|
||||
use humhub\modules\content\components\ContentAddonActiveRecord;
|
||||
use ReflectionClass;
|
||||
@ -156,7 +156,7 @@ class PolymorphicRelation extends Behavior
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Helpers::checkClassType($object, $this->mustBeInstanceOf, false)) { //|| $object->asa($instance) !== null
|
||||
if (DataTypeHelper::matchClassType($object, $this->mustBeInstanceOf)) { //|| $object->asa($instance) !== null
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -23,9 +23,9 @@ trait InvalidArgumentExceptionTrait
|
||||
protected bool $isInstantiating = true;
|
||||
|
||||
/**
|
||||
* @param string $parameterOrMessage Name of parameter in question, or alternatively the full message string containing at
|
||||
* least one space character (ASCII 32). In this case, `$valid` and `$given` are considered to be
|
||||
* `$code` and `$previous` respectively
|
||||
* @param string $parameterOrMessage Name of parameter in question, or alternatively the full message string
|
||||
* containing at least one space character (ASCII 32). In this case, `$valid` and `$given` are considered to be
|
||||
* `$code` and `$previous` respectively
|
||||
* @param string|string[] $valid (List of) valid parameter(s)
|
||||
* @param mixed $given Parameter received
|
||||
* @param int $code Optional exception code
|
||||
@ -41,25 +41,46 @@ trait InvalidArgumentExceptionTrait
|
||||
|
||||
try {
|
||||
if (!is_string($parameterOrMessage)) {
|
||||
throw new InvalidArgumentTypeException('$parameterOrMessage', ['string'], $parameterOrMessage, 0, $this);
|
||||
throw new InvalidArgumentTypeException(
|
||||
'$parameterOrMessage',
|
||||
['string'],
|
||||
$parameterOrMessage,
|
||||
0,
|
||||
$this
|
||||
);
|
||||
}
|
||||
|
||||
if (empty($parameterOrMessage = trim($parameterOrMessage))) {
|
||||
throw new InvalidArgumentValueException('$parameterOrMessage', 'non-empty string', $parameterOrMessage, 0, $this);
|
||||
throw new InvalidArgumentValueException(
|
||||
'$parameterOrMessage',
|
||||
'non-empty string',
|
||||
$parameterOrMessage,
|
||||
0,
|
||||
$this
|
||||
);
|
||||
}
|
||||
|
||||
// check if $parameter is actually the $message
|
||||
if (strpos($parameterOrMessage, ' ') !== false) {
|
||||
$message = $parameterOrMessage;
|
||||
$code = $code ?? $valid ?? 0;
|
||||
$previous = $previous ?? $given;
|
||||
$code ??= is_int($valid) ? $valid : 0;
|
||||
if ($given instanceof Throwable) {
|
||||
$previous ??= $given;
|
||||
}
|
||||
} else {
|
||||
$trace = debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS, 2);
|
||||
$trace = end($trace);
|
||||
$this->methodName = ltrim(($trace['class'] ?? '') . '::' . ($trace['function'] ?? 'unknown method'), ':');
|
||||
|
||||
$this->parameter = $parameterOrMessage;
|
||||
if (false !== $pos = strrpos($parameterOrMessage, '::')) {
|
||||
$this->methodName = trim(substr($parameterOrMessage, 0, $pos), ':');
|
||||
$this->parameter = trim(substr($parameterOrMessage, $pos), ':');
|
||||
} else {
|
||||
$trace = debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS, 2);
|
||||
$trace = end($trace);
|
||||
$this->methodName = ltrim(
|
||||
($trace['class'] ?? '') . '::' . ($trace['function'] ?? 'unknown method'),
|
||||
':'
|
||||
);
|
||||
|
||||
$this->parameter = $parameterOrMessage;
|
||||
}
|
||||
try {
|
||||
$this->setValid($valid);
|
||||
} catch (InvalidArgumentTypeException $t) {
|
||||
@ -84,7 +105,7 @@ trait InvalidArgumentExceptionTrait
|
||||
}
|
||||
|
||||
/**
|
||||
* @see static::__construct()
|
||||
* @see static::__construct()
|
||||
* @noinspection PhpUnhandledExceptionInspection
|
||||
* @noinspection PhpDocMissingThrowsInspection
|
||||
*/
|
||||
|
711
protected/humhub/helpers/DataTypeHelper.php
Normal file
711
protected/humhub/helpers/DataTypeHelper.php
Normal file
@ -0,0 +1,711 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @link https://www.humhub.org/
|
||||
* @copyright Copyright (c) 2023 HumHub GmbH & Co. KG
|
||||
* @license https://www.humhub.com/licences
|
||||
*/
|
||||
|
||||
namespace humhub\helpers;
|
||||
|
||||
use humhub\exceptions\InvalidArgumentClassException;
|
||||
use humhub\exceptions\InvalidArgumentTypeException;
|
||||
use humhub\exceptions\InvalidArgumentValueException;
|
||||
use Stringable;
|
||||
|
||||
use function gettype;
|
||||
|
||||
/**
|
||||
* @since 1.16
|
||||
*/
|
||||
class DataTypeHelper
|
||||
{
|
||||
public const TYPE_CHECK_VALUE_IS_NULL = 128;
|
||||
public const TYPE_CHECK_TYPE_NOT_IN_LIST = 32;
|
||||
public const TYPE_CHECK_INVALID_TYPE_PARAMETER = 2;
|
||||
public const TYPE_CHECK_VALUE_IS_EMPTY = 4;
|
||||
public const TYPE_CHECK_INVALID_VALUE_PARAMETER = 1;
|
||||
public const TYPE_CHECK_INVALID_TYPE = 8;
|
||||
public const TYPE_CHECK_NON_EXISTING_CLASS = 16;
|
||||
public const TYPE_CHECK_VALUE_IS_INSTANCE = 64;
|
||||
|
||||
public const BOOLEAN = 'boolean';
|
||||
public const INTEGER = 'integer';
|
||||
public const STRING = 'string';
|
||||
public const ARRAY = 'array';
|
||||
public const OBJECT = 'object';
|
||||
public const RESOURCE = 'resource';
|
||||
public const RESOURCE_CLOSED = 'resource (closed)';
|
||||
public const UNKNOWN_TYPE = 'unknown type';
|
||||
public const DOUBLE = 'double';
|
||||
public const FLOAT = 'float';
|
||||
public const NULL = 'NULL';
|
||||
|
||||
|
||||
/**
|
||||
* @param mixed $value Variable to be checked.
|
||||
* @param string|string[]|object[] $allowedTypes Allowed types.
|
||||
*
|
||||
* @since 1.16
|
||||
* @see self::matchClassType()
|
||||
*/
|
||||
public static function isClassType($value, $allowedTypes): bool
|
||||
{
|
||||
return self::matchClassType($value, $allowedTypes) !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value Variable to be checked.
|
||||
* @param string|string[]|object[] $allowedTypes Allowed types.
|
||||
*
|
||||
* @since 1.16
|
||||
* @see self::matchType()
|
||||
*/
|
||||
public static function isType($value, $allowedTypes): bool
|
||||
{
|
||||
return self::matchType($value, $allowedTypes) !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value Variable to be checked.
|
||||
* @param string|string[]|object[] $allowedTypes Allowed types. Valid input are
|
||||
* ``
|
||||
* - simple type names as returned by gettype()
|
||||
* - `null` value or `'NULL'` string
|
||||
* - class, interface, or trait names
|
||||
* - class instances whose class type will be checked
|
||||
* - `callable`, e.g. `is_scalar`
|
||||
* ``
|
||||
* rather that it's name.
|
||||
*
|
||||
* @return string|null Returns the first match of `$value` against the `$allowedTypes`.
|
||||
* ``
|
||||
* - If the matched type is a `NULL` value, the string "NULL" is returned.
|
||||
* - If the matched type is an object instance, its class name is returned.
|
||||
* - If the matched type is a `callable`, the callable´s string representation (name) is returned.
|
||||
* - If no match is found, a `NULL` value is returned.
|
||||
*``
|
||||
* @throws InvalidArgumentTypeException|InvalidArgumentValueException
|
||||
* @since 1.16
|
||||
* @see gettype()
|
||||
*/
|
||||
public static function matchType($value, $allowedTypes, bool $throwException = false): ?string
|
||||
{
|
||||
$validTypes = self::parseTypes($allowedTypes, $allowNull, $checkTraits);
|
||||
|
||||
if ($value === null) {
|
||||
if ($allowNull) {
|
||||
return self::NULL;
|
||||
}
|
||||
|
||||
if (!$throwException) {
|
||||
return null;
|
||||
}
|
||||
|
||||
throw new InvalidArgumentTypeException(
|
||||
'$value',
|
||||
$validTypes,
|
||||
$value,
|
||||
self::TYPE_CHECK_INVALID_VALUE_PARAMETER + self::TYPE_CHECK_VALUE_IS_EMPTY + self::TYPE_CHECK_INVALID_TYPE + self::TYPE_CHECK_VALUE_IS_NULL
|
||||
);
|
||||
}
|
||||
|
||||
$inputType = gettype($value);
|
||||
$inputTraits = $checkTraits ? self::classUsesTraits($value, false) : null;
|
||||
|
||||
foreach ($allowedTypes as $i => $typeToCheck) {
|
||||
if (static::matchTypeHelper($typeToCheck, $value, $inputType, $inputTraits) !== null) {
|
||||
return $validTypes[$i];
|
||||
}
|
||||
}
|
||||
|
||||
if (!$throwException) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$code = self::TYPE_CHECK_INVALID_VALUE_PARAMETER + self::TYPE_CHECK_TYPE_NOT_IN_LIST;
|
||||
|
||||
if (is_object($value)) {
|
||||
$code |= self::TYPE_CHECK_VALUE_IS_INSTANCE;
|
||||
}
|
||||
|
||||
throw new InvalidArgumentClassException(
|
||||
'$value',
|
||||
$allowedTypes,
|
||||
$value,
|
||||
$code
|
||||
);
|
||||
}
|
||||
|
||||
protected static function matchTypeHelper($typeToCheck, &$input, string $inputType, ?array &$inputTraits = null): ?string
|
||||
{
|
||||
|
||||
if (is_string($typeToCheck) || (is_object($typeToCheck) && $typeToCheck = get_class($typeToCheck))) {
|
||||
switch ($typeToCheck) {
|
||||
case self::STRING:
|
||||
case self::ARRAY:
|
||||
case self::OBJECT:
|
||||
case self::RESOURCE:
|
||||
case self::RESOURCE_CLOSED: // as of PHP 7.2.0
|
||||
case self::NULL:
|
||||
case self::UNKNOWN_TYPE:
|
||||
return $inputType === $typeToCheck
|
||||
? $typeToCheck
|
||||
: null;
|
||||
|
||||
case self::BOOLEAN: // the result of gettype()
|
||||
case 'bool': // the name as it is defined in code
|
||||
return $inputType === self::BOOLEAN
|
||||
// return it the way it was tested
|
||||
? $typeToCheck
|
||||
: null;
|
||||
|
||||
case self::INTEGER: // the result of gettype()
|
||||
case 'int': // the name as it is defined in code
|
||||
return $inputType === self::INTEGER
|
||||
// return it the way it was tested
|
||||
? $typeToCheck
|
||||
: null;
|
||||
|
||||
case self::DOUBLE:
|
||||
case self::FLOAT:
|
||||
return $inputType === self::DOUBLE
|
||||
// return it the way it was tested
|
||||
? $typeToCheck
|
||||
: null;
|
||||
|
||||
case Stringable::class:
|
||||
return $inputType === self::OBJECT
|
||||
&& ($input instanceof Stringable || is_callable([$input, '__toString']))
|
||||
? $typeToCheck
|
||||
: null;
|
||||
|
||||
default:
|
||||
/**
|
||||
* Autoload is not used in any of the following functions, since the $typeToCheck has already been loaded in `self::parseTypes()`
|
||||
*
|
||||
* @see self::parseTypes()
|
||||
* @noinspection NotOptimalIfConditionsInspection
|
||||
*/
|
||||
if (
|
||||
(class_exists($typeToCheck, false) || interface_exists($typeToCheck, false))
|
||||
&& $input instanceof $typeToCheck
|
||||
) {
|
||||
return $typeToCheck;
|
||||
}
|
||||
|
||||
if (
|
||||
$inputTraits !== null
|
||||
&& trait_exists($typeToCheck, false)
|
||||
&& in_array($typeToCheck, $inputTraits, true)
|
||||
) {
|
||||
return $typeToCheck;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
is_callable($typeToCheck, false, $name)
|
||||
&& $typeToCheck($input)
|
||||
) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the provided `$value` is of or implements any class, interface or trait as provided by the
|
||||
* `$allowedTypes` parameter. The function throws an Exception if none of the provided types is matched. Please see
|
||||
* self::matchClassType() for more information on the parameters.
|
||||
*
|
||||
* @see self::matchClassType()
|
||||
* @throws InvalidArgumentTypeException|InvalidArgumentClassException|InvalidArgumentValueException
|
||||
* @since 1.16
|
||||
*/
|
||||
public static function ensureClassType($value, $allowedTypes): void
|
||||
{
|
||||
self::matchClassType($value, $allowedTypes, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the provided `$value` is of or implements any type as provided by the `$allowedTypes` parameter.
|
||||
* The function throws an Exception if none of the provided types is matched.
|
||||
* Please see self::matchType() for more information on the parameters.
|
||||
*
|
||||
* @since 1.16
|
||||
* @see self::matchType()
|
||||
* @see InvalidArgumentTypeException
|
||||
* @throws InvalidArgumentTypeException|InvalidArgumentValueException
|
||||
*/
|
||||
public static function ensureType($value, $allowedTypes): void
|
||||
{
|
||||
self::matchType($value, $allowedTypes, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper variable that returns the input `$value` if it is matched against the `$allowedTypes`
|
||||
*
|
||||
* @return mixed|null The `$value` if it matches any type given in $allowedTypes, or NULL otherwise
|
||||
*
|
||||
* @since 1.16
|
||||
* @see self::matchType()
|
||||
* @see InvalidArgumentTypeException
|
||||
*/
|
||||
private static function filterType($value, $allowedTypes, bool $throwException = false)
|
||||
{
|
||||
return self::matchType($value, $allowedTypes, $throwException) === null
|
||||
? null
|
||||
: $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the boolean value of `$value`, or NULL if it's not a boolean and cannot be converted.
|
||||
* See the parameter description for more information.
|
||||
*
|
||||
* @param mixed $value value to be tested or converted
|
||||
* @param bool $strict indicates if strict comparison should be performed:
|
||||
* ``
|
||||
* - if TRUE, `$value` must already be of type `boolean`. In that case, its value is returned, NULL otherwise.
|
||||
* - if FALSE, a conversion to `boolean` is attempted using `(bool)`. No exception is thrown, ever.
|
||||
* Note: "false", "off", "no" yield TRUE in this case.
|
||||
* - if NULL, a conversion to `boolean` is attempted, where
|
||||
* "1", "true", "on", and "yes" yield TRUE,
|
||||
* "0", "false", "off", "no", and "" yield FALSE.
|
||||
* ``
|
||||
* @param bool $throwException throws an exception instead of returning `null`
|
||||
*
|
||||
* @return bool|null see `$strict` parameter for details
|
||||
*
|
||||
* @see filter_var()
|
||||
* @since 1.16
|
||||
*/
|
||||
public static function filterBool($value, ?bool $strict = false, bool $throwException = false): ?bool
|
||||
{
|
||||
if ($strict) {
|
||||
return self::filterType($value, [self::BOOLEAN], $throwException);
|
||||
}
|
||||
|
||||
if ($strict === false) {
|
||||
try {
|
||||
return (bool)$value;
|
||||
} catch (\Throwable $e) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
$input = is_array($value) ? !empty($value) : filter_var(
|
||||
$value,
|
||||
FILTER_VALIDATE_BOOLEAN,
|
||||
FILTER_NULL_ON_FAILURE
|
||||
);
|
||||
|
||||
return self::filterType($input, [self::BOOLEAN, null], $throwException);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the class or object has one of the given classes, interfaces or traits as one of its parents or
|
||||
* implements it.
|
||||
*
|
||||
* @param string|object|null|mixed $value Object or classname to be checked. Null may be valid if included in
|
||||
* $type. Everything else is invalid and either throws an error (default) or returns NULL, if $throw is false.
|
||||
* @param string|string[]|object[] $allowedTypes (List of) allowed class, interface or trait names, or object
|
||||
* instances. Object instances may only be passed as part of an array. In such a case, the object's type/class
|
||||
* is used for comparison. If a string is provided, it will be split by `|`. If NULL value or the "NULL"
|
||||
* string
|
||||
* is included, NULL values are also allowed. *
|
||||
* @param bool $throwException throws an exception instead of returning `null`.
|
||||
* Code of the thrown Exception is a bit-mask consisting of the following bits:
|
||||
* ``
|
||||
* - self::CLASS_CHECK_INVALID_CLASSNAME_PARAMETER: Invalid $className parameter
|
||||
* - self::CLASS_CHECK_INVALID_TYPE_PARAMETER: Invalid $type parameter
|
||||
* - self::CLASS_CHECK_VALUE_IS_EMPTY: Empty parameter
|
||||
* - self::CLASS_CHECK_INVALID_TYPE: Invalid type
|
||||
* - self::CLASS_CHECK_NON_EXISTING_CLASS: Non-existing class
|
||||
* - self::CLASS_CHECK_TYPE_NOT_IN_LIST: Class that is not in $type parameter
|
||||
* - self::CLASS_CHECK_VALUE_IS_INSTANCE: $className is an object instance
|
||||
* - self::CLASS_CHECK_VALUE_IS_NULL: NULL value
|
||||
* ``
|
||||
*
|
||||
* @return string|null
|
||||
* @throws InvalidArgumentTypeException|InvalidArgumentClassException|InvalidArgumentValueException
|
||||
* @noinspection PhpDocMissingThrowsInspection
|
||||
* @noinspection PhpUnhandledExceptionInspection
|
||||
* @since 1.16
|
||||
*/
|
||||
public static function matchClassType($value, $allowedTypes, bool $throwException = false): ?string
|
||||
{
|
||||
$allowedTypes = static::parseTypes($allowedTypes, $allowNull, $checkTraits, false, false);
|
||||
|
||||
// check for null input
|
||||
if ($value === null) {
|
||||
// check if null is allowed
|
||||
if ($allowNull) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!$throwException) {
|
||||
return null;
|
||||
}
|
||||
|
||||
throw new InvalidArgumentTypeException(
|
||||
'$value',
|
||||
$allowedTypes,
|
||||
$value,
|
||||
self::TYPE_CHECK_INVALID_VALUE_PARAMETER + self::TYPE_CHECK_VALUE_IS_EMPTY + self::TYPE_CHECK_INVALID_TYPE + self::TYPE_CHECK_VALUE_IS_NULL
|
||||
);
|
||||
}
|
||||
|
||||
// check for other empty input values
|
||||
if (empty($value)) {
|
||||
if (!$throwException) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @noinspection PhpUnhandledExceptionInspection */
|
||||
throw is_string($value)
|
||||
? new InvalidArgumentClassException(
|
||||
'$value',
|
||||
$allowedTypes,
|
||||
$value,
|
||||
self::TYPE_CHECK_INVALID_VALUE_PARAMETER + self::TYPE_CHECK_VALUE_IS_EMPTY + self::TYPE_CHECK_INVALID_TYPE + self::TYPE_CHECK_TYPE_NOT_IN_LIST
|
||||
)
|
||||
: new InvalidArgumentTypeException(
|
||||
'$value',
|
||||
$allowedTypes,
|
||||
$value,
|
||||
self::TYPE_CHECK_INVALID_VALUE_PARAMETER + self::TYPE_CHECK_VALUE_IS_EMPTY + self::TYPE_CHECK_INVALID_TYPE
|
||||
);
|
||||
}
|
||||
|
||||
if ($checkTraits) {
|
||||
$checkTraits = self::classUsesTraits($value, false);
|
||||
}
|
||||
|
||||
if ($isObject = is_object($value)) {
|
||||
$type = get_class($value);
|
||||
} elseif (is_string($value)) {
|
||||
if (!class_exists($value)) {
|
||||
if (!$throwException) {
|
||||
return null;
|
||||
}
|
||||
|
||||
throw new InvalidArgumentValueException(
|
||||
'$value',
|
||||
'a valid class name or an object instance',
|
||||
$value,
|
||||
self::TYPE_CHECK_INVALID_VALUE_PARAMETER + self::TYPE_CHECK_NON_EXISTING_CLASS
|
||||
);
|
||||
}
|
||||
|
||||
$type = $value;
|
||||
} else {
|
||||
if (!$throwException) {
|
||||
return null;
|
||||
}
|
||||
|
||||
throw new InvalidArgumentTypeException(
|
||||
'$value',
|
||||
$allowedTypes,
|
||||
$value,
|
||||
self::TYPE_CHECK_INVALID_VALUE_PARAMETER + self::TYPE_CHECK_INVALID_TYPE
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($allowedTypes as $matchingClass) {
|
||||
if ($checkTraits !== null && in_array($matchingClass, $checkTraits, true)) {
|
||||
return $type;
|
||||
}
|
||||
|
||||
if ($isObject ? $value instanceof $matchingClass : is_a($value, $matchingClass, true)) {
|
||||
return $type;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$throwException) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$code = self::TYPE_CHECK_INVALID_VALUE_PARAMETER + self::TYPE_CHECK_TYPE_NOT_IN_LIST;
|
||||
|
||||
if ($isObject) {
|
||||
$code |= self::TYPE_CHECK_VALUE_IS_INSTANCE;
|
||||
}
|
||||
|
||||
throw new InvalidArgumentClassException(
|
||||
'$value',
|
||||
$allowedTypes,
|
||||
$value,
|
||||
$code
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the boolean value of `$value`, or NULL if it's not a float and cannot be converted.
|
||||
* See the parameter description for more information.
|
||||
*
|
||||
* @param mixed $value value to be tested or converted
|
||||
* @param bool $strict indicates if strict comparison should be performed:
|
||||
* ``
|
||||
* - if TRUE, `$value` must already be of type `float`.
|
||||
* - if FALSE, a conversion to `float` is attempted.
|
||||
* ``
|
||||
* @param bool $throwException throws an exception instead of returning `null`
|
||||
*
|
||||
* @since 1.16
|
||||
*/
|
||||
public static function filterFloat($value, bool $strict = false, bool $throwException = false): ?float
|
||||
{
|
||||
if ($strict) {
|
||||
return self::filterType($value, [self::FLOAT], $throwException);
|
||||
}
|
||||
|
||||
$input = filter_var($value, FILTER_VALIDATE_FLOAT, FILTER_NULL_ON_FAILURE);
|
||||
|
||||
return self::filterType($input, [self::FLOAT, null], $throwException);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the boolean value of `$value`, or NULL if it's not an integer and cannot be converted.
|
||||
* See the parameter description for more information.
|
||||
*
|
||||
* @param mixed $value value to be tested or converted
|
||||
* @param bool $strict indicates if strict comparison should be performed:
|
||||
* ``
|
||||
* - if TRUE, `$value` must already be of type `int`.
|
||||
* - if FALSE, a conversion to `int` is attempted.
|
||||
* ``
|
||||
* @param bool $throwException throws an exception instead of returning `null`
|
||||
*
|
||||
* @return int|null
|
||||
* @since 1.16
|
||||
*/
|
||||
public static function filterInt($value, bool $strict = false, bool $throwException = false): ?int
|
||||
{
|
||||
if ($strict) {
|
||||
return self::filterType($value, [self::INTEGER], $throwException);
|
||||
}
|
||||
|
||||
$input = filter_var($value, FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE);
|
||||
|
||||
return self::filterType($input, [self::INTEGER, null], $throwException);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the boolean value of `$value`, or NULL if it's not a scalar.
|
||||
* See the parameter description for more information.
|
||||
*
|
||||
* @param mixed $value value to be tested or converted
|
||||
* @param bool $strict indicates if strict comparison should be performed:
|
||||
* ``
|
||||
* - if TRUE, `$value` must already be a scalar value.
|
||||
* - if FALSE, `NULL` is also allowed (not throwing an exception, if `$throw` is TRUE).
|
||||
* ``
|
||||
* @param bool $throwException throws an exception instead of returning `null`
|
||||
*
|
||||
* @return bool|int|float|string|null
|
||||
* @since 1.16
|
||||
*/
|
||||
public static function filterScalar($value, bool $strict = false, bool $throwException = false)
|
||||
{
|
||||
if ($strict) {
|
||||
return self::filterType($value, ['is_scalar'], $throwException);
|
||||
}
|
||||
|
||||
return self::filterType($value, [null, 'is_scalar'], $throwException);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the boolean value of `$value`, or NULL if it's not a string and cannot be converted.
|
||||
* See the parameter description for more information.
|
||||
*
|
||||
* @param mixed $value value to be tested or converted
|
||||
* @param bool $strict indicates if strict comparison should be performed:
|
||||
* ``
|
||||
* - if TRUE, `$value` must already be of type `string`.
|
||||
* - if FALSE, a conversion to `string` is attempted.
|
||||
* ``
|
||||
* @param bool $throwException throws an exception instead of returning `null`
|
||||
*
|
||||
* @since 1.16
|
||||
*/
|
||||
public static function filterString($value, bool $strict = false, bool $throwException = false): ?string
|
||||
{
|
||||
$allowedTypes = $strict ? [self::STRING] : [self::STRING, null, Stringable::class, 'is_scalar'];
|
||||
|
||||
switch (self::matchType($value, $allowedTypes, $throwException)) {
|
||||
case self::STRING:
|
||||
return $value;
|
||||
|
||||
case self::NULL:
|
||||
return null;
|
||||
|
||||
case Stringable::class:
|
||||
return $value->__toString();
|
||||
|
||||
case 'is_scalar':
|
||||
return (string)$value;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method evaluates all the traits used in an object/class, including the ones inherited from parent classes
|
||||
*
|
||||
* @param string|object $class Class name or instance to be checked
|
||||
* @param bool $autoload Indicates whether autoload should be performed for classes that are not yet loaded.
|
||||
*
|
||||
* @return array an array of trait names used by the given class
|
||||
* @since 1.16
|
||||
* @see https://www.php.net/manual/en/function.class-uses.php#122427
|
||||
*/
|
||||
public static function classUsesTraits($class, bool $autoload = true): array
|
||||
{
|
||||
$traits = [];
|
||||
|
||||
// Get all the traits of $class and its parent classes
|
||||
do {
|
||||
$class_name = is_object($class) ? get_class($class) : $class;
|
||||
|
||||
if (class_exists($class_name, $autoload)) {
|
||||
$traits = array_merge(class_uses($class, $autoload), $traits);
|
||||
}
|
||||
} while ($class = get_parent_class($class));
|
||||
|
||||
// Get traits of all parent traits
|
||||
$traits_to_search = $traits;
|
||||
while (!empty($traits_to_search)) {
|
||||
$new_traits = class_uses(array_pop($traits_to_search), $autoload);
|
||||
$traits = array_merge($new_traits, $traits);
|
||||
$traits_to_search = array_merge($new_traits, $traits_to_search);
|
||||
};
|
||||
|
||||
return array_unique($traits);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
* @throws InvalidArgumentTypeException|InvalidArgumentValueException
|
||||
* @since 1.16
|
||||
*/
|
||||
protected static function parseTypes(&$allowedTypes, ?bool &$allowNull = false, ?array &$checkTraits = null, bool $allowCallables = true, bool $allowGetTypes = true): array
|
||||
{
|
||||
$allowNull = false;
|
||||
$checkTraits = null;
|
||||
|
||||
if ($allowedTypes === null) {
|
||||
$allowNull = true;
|
||||
$allowedTypes = [null];
|
||||
return [];
|
||||
}
|
||||
|
||||
if (is_string($allowedTypes)) {
|
||||
if ($allowedTypes === '') {
|
||||
throw new InvalidArgumentValueException(
|
||||
'$allowedTypes',
|
||||
[self::STRING, 'string[]', 'object[]'],
|
||||
$allowedTypes,
|
||||
self::TYPE_CHECK_INVALID_TYPE_PARAMETER + self::TYPE_CHECK_VALUE_IS_EMPTY
|
||||
);
|
||||
}
|
||||
|
||||
$allowedTypes = explode('|', $allowedTypes);
|
||||
}
|
||||
|
||||
if (!is_array($allowedTypes)) {
|
||||
throw new InvalidArgumentTypeException(
|
||||
'$allowedTypes',
|
||||
[self::STRING, 'string[]', 'object[]', null],
|
||||
$allowedTypes,
|
||||
self::TYPE_CHECK_INVALID_TYPE_PARAMETER + self::TYPE_CHECK_INVALID_TYPE
|
||||
);
|
||||
}
|
||||
|
||||
if (count($allowedTypes) === 0) {
|
||||
throw new InvalidArgumentValueException(
|
||||
'$allowedTypes',
|
||||
[self::STRING, 'string[]', 'object[]'],
|
||||
$allowedTypes,
|
||||
self::TYPE_CHECK_INVALID_TYPE_PARAMETER + self::TYPE_CHECK_VALUE_IS_EMPTY
|
||||
);
|
||||
}
|
||||
|
||||
$valid = [];
|
||||
|
||||
// validate the type array
|
||||
foreach ($allowedTypes as $index => &$item) {
|
||||
if ($item === null || $item === self::NULL) {
|
||||
$allowNull = true;
|
||||
$item = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_object($item)) {
|
||||
$item = $valid[$index] = get_class($item);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($allowCallables && is_callable($item, false, $name)) {
|
||||
$valid[$index] = $name;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!is_string($item)) {
|
||||
throw new InvalidArgumentValueException(
|
||||
sprintf('$allowedTypes[%s]', $index),
|
||||
['class', self::OBJECT],
|
||||
$item,
|
||||
self::TYPE_CHECK_INVALID_TYPE_PARAMETER + self::TYPE_CHECK_INVALID_TYPE
|
||||
);
|
||||
}
|
||||
|
||||
if ($allowGetTypes) {
|
||||
switch ($item) {
|
||||
case self::BOOLEAN: // the result of gettype()
|
||||
case 'bool': // the name as it is defined in code
|
||||
case self::INTEGER: // the result of gettype()
|
||||
case 'int': // the name as it is defined in code
|
||||
case self::STRING:
|
||||
case self::ARRAY:
|
||||
case self::OBJECT:
|
||||
case self::RESOURCE:
|
||||
case self::RESOURCE_CLOSED: // as of PHP 7.2.0
|
||||
case self::UNKNOWN_TYPE:
|
||||
case self::DOUBLE:
|
||||
case self::FLOAT:
|
||||
$valid[$index] = $item;
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Here autoload is active, so the class is loaded even if it is an interface or a trait
|
||||
if (class_exists($item)) {
|
||||
$valid[$index] = $item;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Here autoload is no longer required. See above.
|
||||
if (interface_exists($item, false)) {
|
||||
$valid[$index] = $item;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Here autoload is no longer required. See above.
|
||||
if (trait_exists($item, false)) {
|
||||
$valid[$index] = $item;
|
||||
$checkTraits[] = $item;
|
||||
continue;
|
||||
}
|
||||
|
||||
throw new InvalidArgumentValueException(
|
||||
sprintf('$allowedTypes[%s]', $index),
|
||||
'a valid class/interface/trait name or an object instance',
|
||||
$item,
|
||||
self::TYPE_CHECK_INVALID_TYPE_PARAMETER + self::TYPE_CHECK_NON_EXISTING_CLASS
|
||||
);
|
||||
}
|
||||
|
||||
return $valid;
|
||||
}
|
||||
}
|
@ -11,8 +11,8 @@ namespace humhub\libs;
|
||||
use humhub\exceptions\InvalidArgumentClassException;
|
||||
use humhub\exceptions\InvalidArgumentTypeException;
|
||||
use humhub\exceptions\InvalidArgumentValueException;
|
||||
use humhub\helpers\DataTypeHelper;
|
||||
use Yii;
|
||||
use yii\base\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* This class contains a lot of html helpers for the views
|
||||
@ -21,20 +21,68 @@ use yii\base\InvalidArgumentException;
|
||||
*/
|
||||
class Helpers
|
||||
{
|
||||
public const CLASS_CHECK_INVALID_CLASSNAME_PARAMETER = 1;
|
||||
public const CLASS_CHECK_INVALID_TYPE_PARAMETER = 2;
|
||||
public const CLASS_CHECK_VALUE_IS_EMPTY = 4;
|
||||
public const CLASS_CHECK_INVALID_TYPE = 8;
|
||||
public const CLASS_CHECK_NON_EXISTING_CLASS = 16;
|
||||
public const CLASS_CHECK_TYPE_NOT_IN_LIST = 32;
|
||||
public const CLASS_CHECK_VALUE_IS_INSTANCE = 64;
|
||||
public const CLASS_CHECK_VALUE_IS_NULL = 128;
|
||||
/**
|
||||
* @var int
|
||||
* @deprecated since 1.16; Use constant in DataTypeHelper class instead
|
||||
* @see DataTypeHelper
|
||||
* */
|
||||
public const CLASS_CHECK_INVALID_CLASSNAME_PARAMETER = DataTypeHelper::TYPE_CHECK_INVALID_VALUE_PARAMETER;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
* @deprecated since 1.16; Use constant in DataTypeHelper class instead
|
||||
* @see DataTypeHelper
|
||||
* */
|
||||
public const CLASS_CHECK_INVALID_TYPE_PARAMETER = DataTypeHelper::TYPE_CHECK_INVALID_TYPE_PARAMETER;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
* @deprecated since 1.16; Use constant in DataTypeHelper class instead
|
||||
* @see DataTypeHelper
|
||||
* */
|
||||
public const CLASS_CHECK_VALUE_IS_EMPTY = DataTypeHelper::TYPE_CHECK_VALUE_IS_EMPTY;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
* @deprecated since 1.16; Use constant in DataTypeHelper class instead
|
||||
* @see DataTypeHelper
|
||||
* */
|
||||
public const CLASS_CHECK_INVALID_TYPE = DataTypeHelper::TYPE_CHECK_INVALID_TYPE;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
* @deprecated since 1.16; Use constant in DataTypeHelper class instead
|
||||
* @see DataTypeHelper
|
||||
* */
|
||||
public const CLASS_CHECK_NON_EXISTING_CLASS = DataTypeHelper::TYPE_CHECK_NON_EXISTING_CLASS;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
* @deprecated since 1.16; Use constant in DataTypeHelper class instead
|
||||
* @see DataTypeHelper
|
||||
* */
|
||||
public const CLASS_CHECK_TYPE_NOT_IN_LIST = DataTypeHelper::TYPE_CHECK_TYPE_NOT_IN_LIST;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
* @deprecated since 1.16; Use constant in DataTypeHelper class instead
|
||||
* @see DataTypeHelper
|
||||
* */
|
||||
public const CLASS_CHECK_VALUE_IS_INSTANCE = DataTypeHelper::TYPE_CHECK_VALUE_IS_INSTANCE;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
* @deprecated since 1.16; Use constant in DataTypeHelper class instead
|
||||
* @see DataTypeHelper
|
||||
* */
|
||||
public const CLASS_CHECK_VALUE_IS_NULL = DataTypeHelper::TYPE_CHECK_VALUE_IS_NULL;
|
||||
|
||||
/**
|
||||
* Shorten a text string
|
||||
*
|
||||
* @param string $text - Text string you will shorten
|
||||
* @param integer $length - Count of characters to show
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function truncateText($text, $length): string
|
||||
@ -56,6 +104,7 @@ class Helpers
|
||||
|
||||
/**
|
||||
* Compare two arrays values
|
||||
*
|
||||
* @param array $a - First array to compare against..
|
||||
* @param array $b - Second array
|
||||
*
|
||||
@ -76,20 +125,27 @@ class Helpers
|
||||
|
||||
/**
|
||||
* Temp Function to use UTF8 SubStr
|
||||
*
|
||||
* @deprecated since 1.11 Use mb_substr() instead.
|
||||
*
|
||||
* @param string $str
|
||||
* @param integer $from
|
||||
* @param integer $len
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function substru($str, $from, $len): string
|
||||
{
|
||||
return preg_replace('#^(?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){0,' . $from . '}' . '((?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){0,' . $len . '}).*#s', '$1', $str);
|
||||
return preg_replace(
|
||||
'#^(?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){0,' . $from . '}' . '((?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){0,' . $len . '}).*#s',
|
||||
'$1',
|
||||
$str
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a readable time format from seconds
|
||||
*
|
||||
* @param string $sekunden - Seconds you will formatting
|
||||
* */
|
||||
public static function getFormattedTime($sekunden)
|
||||
@ -121,6 +177,7 @@ class Helpers
|
||||
* Source: http://php.net/manual/en/function.ini-get.php
|
||||
*
|
||||
* @param String $val
|
||||
*
|
||||
* @return int bytes
|
||||
* @deprecated bug on PHP7 "A non well formed numeric value encountered"
|
||||
* @see \humhub\libs\Helpers::getBytesOfIniValue instead
|
||||
@ -188,240 +245,25 @@ class Helpers
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the class has this class as one of its parents
|
||||
*
|
||||
* Code of the thrown Exception is a bit-mask consisting of the following bits
|
||||
* - self::CLASS_CHECK_INVALID_CLASSNAME_PARAMETER: Invalid $className parameter
|
||||
* - self::CLASS_CHECK_INVALID_TYPE_PARAMETER: Invalid $type parameter
|
||||
* - self::CLASS_CHECK_VALUE_IS_EMPTY: Empty parameter
|
||||
* - self::CLASS_CHECK_INVALID_TYPE: Invalid type
|
||||
* - self::CLASS_CHECK_NON_EXISTING_CLASS: Non-existing class
|
||||
* - self::CLASS_CHECK_TYPE_NOT_IN_LIST: Class that is not in $type parameter
|
||||
* - self::CLASS_CHECK_VALUE_IS_INSTANCE: $className is an object instance
|
||||
* - self::CLASS_CHECK_VALUE_IS_NULL: NULL value
|
||||
*
|
||||
* @param string|object|null|mixed $className Object or classname to be checked. Null may be valid if included in $type.
|
||||
* Everything else is invalid and either throws an error (default) or returns NULL, if $throw is false.
|
||||
* @param string|string[] $types (List of) class, interface or trait names that are allowed.
|
||||
* If NULL is included, NULL values are also allowed.
|
||||
* @param bool $throw Determines if an Exception should be thrown if $className doesn't match $type, or simply return NULL.
|
||||
* Invalid $types always throw an error!
|
||||
* @param bool $strict If set to true, no invalid characters are removed from a $className string.
|
||||
* If set to false, please make sure you use the function's return value, rather than $className, as they might diverge
|
||||
*
|
||||
* @return string|null
|
||||
* @throws InvalidArgumentTypeException|InvalidArgumentClassException|InvalidArgumentValueException
|
||||
* @noinspection PhpDocMissingThrowsInspection
|
||||
* @noinspection PhpUnhandledExceptionInspection
|
||||
* @deprecated since 1.16; use DataTypeHelper::checkClassType()
|
||||
* @see DataTypeHelper::matchClassType
|
||||
*/
|
||||
public static function checkClassType($className, $types, bool $throw = true, ?bool $strict = true): ?string
|
||||
public static function checkClassType($className, $type = '')
|
||||
{
|
||||
if (empty($types)) {
|
||||
throw new InvalidArgumentValueException('$type', ['string', 'string[]'], $types, self::CLASS_CHECK_INVALID_TYPE_PARAMETER + self::CLASS_CHECK_VALUE_IS_EMPTY);
|
||||
if (is_string($className)) {
|
||||
$className = preg_replace('/[^a-z0-9_\-\\\]/i', '', $className);
|
||||
}
|
||||
|
||||
$types = (array)$types;
|
||||
$valid = [];
|
||||
$allowNull = false;
|
||||
|
||||
// validate the type array
|
||||
foreach ($types as $index => &$item) {
|
||||
if ($item === null) {
|
||||
$allowNull = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_object($item)) {
|
||||
$valid[get_class($item)] = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!is_string($item)) {
|
||||
throw new InvalidArgumentValueException(sprintf('$type[%s]', $index), ['class', 'object'], $item, self::CLASS_CHECK_INVALID_TYPE_PARAMETER + self::CLASS_CHECK_INVALID_TYPE);
|
||||
}
|
||||
|
||||
$isTrait = false;
|
||||
|
||||
if (!class_exists($item) && !interface_exists($item, false) && !($isTrait = trait_exists($item, false))) {
|
||||
throw new InvalidArgumentValueException(sprintf('$type[%s]', $index), 'a valid class/interface/trait name or an object instance', $item, self::CLASS_CHECK_INVALID_TYPE_PARAMETER + self::CLASS_CHECK_NON_EXISTING_CLASS);
|
||||
}
|
||||
|
||||
$valid[$item] = $isTrait;
|
||||
}
|
||||
// make sure the reference is not going to be overwritten
|
||||
unset($item);
|
||||
|
||||
// save the types for throwing exceptions
|
||||
$types = array_keys($valid);
|
||||
if ($allowNull) {
|
||||
$types[] = null;
|
||||
}
|
||||
|
||||
// check for null input
|
||||
if ($className === null) {
|
||||
// check if null is allowed
|
||||
if ($allowNull) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!$throw) {
|
||||
return null;
|
||||
}
|
||||
|
||||
throw new InvalidArgumentTypeException(
|
||||
'$className',
|
||||
$types,
|
||||
$className,
|
||||
self::CLASS_CHECK_INVALID_CLASSNAME_PARAMETER + self::CLASS_CHECK_VALUE_IS_EMPTY + self::CLASS_CHECK_INVALID_TYPE + self::CLASS_CHECK_VALUE_IS_NULL
|
||||
);
|
||||
}
|
||||
|
||||
// check for other empty input
|
||||
if (empty($className)) {
|
||||
if ((!$strict && $allowNull) || !$throw) {
|
||||
return null;
|
||||
}
|
||||
|
||||
throw is_string($className)
|
||||
? new InvalidArgumentClassException(
|
||||
'$className',
|
||||
$types,
|
||||
$className,
|
||||
self::CLASS_CHECK_INVALID_CLASSNAME_PARAMETER + self::CLASS_CHECK_VALUE_IS_EMPTY + self::CLASS_CHECK_INVALID_TYPE + self::CLASS_CHECK_TYPE_NOT_IN_LIST
|
||||
)
|
||||
: new InvalidArgumentTypeException(
|
||||
'$className',
|
||||
$types,
|
||||
$className,
|
||||
self::CLASS_CHECK_INVALID_CLASSNAME_PARAMETER + self::CLASS_CHECK_VALUE_IS_EMPTY + self::CLASS_CHECK_INVALID_TYPE
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
// Validation for object instances
|
||||
if (is_object($className)) {
|
||||
foreach ($valid as $matchingClass => $isTrait) {
|
||||
if ($isTrait) {
|
||||
if (in_array($matchingClass, static::classUsesTraits($className, false), true)) {
|
||||
return get_class($className);
|
||||
}
|
||||
} elseif ($className instanceof $matchingClass) {
|
||||
return get_class($className);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$throw) {
|
||||
return null;
|
||||
}
|
||||
|
||||
throw new InvalidArgumentClassException(
|
||||
'$className',
|
||||
$types,
|
||||
$className,
|
||||
self::CLASS_CHECK_INVALID_CLASSNAME_PARAMETER + self::CLASS_CHECK_TYPE_NOT_IN_LIST + self::CLASS_CHECK_VALUE_IS_INSTANCE
|
||||
);
|
||||
}
|
||||
|
||||
if (!is_string($className)) {
|
||||
if (!$throw) {
|
||||
return null;
|
||||
}
|
||||
|
||||
throw new InvalidArgumentTypeException(
|
||||
'$className',
|
||||
$types,
|
||||
$className,
|
||||
self::CLASS_CHECK_INVALID_CLASSNAME_PARAMETER + self::CLASS_CHECK_INVALID_TYPE
|
||||
);
|
||||
}
|
||||
|
||||
$cleaned = preg_replace('/[^a-z0-9_\-\\\]/i', '', $className);
|
||||
|
||||
if ($strict && $cleaned !== $className) {
|
||||
if (!$throw) {
|
||||
return null;
|
||||
}
|
||||
|
||||
throw new InvalidArgumentClassException(
|
||||
'$className',
|
||||
'a valid class name or an object instance',
|
||||
$className,
|
||||
self::CLASS_CHECK_INVALID_CLASSNAME_PARAMETER
|
||||
);
|
||||
}
|
||||
|
||||
$className = $cleaned;
|
||||
|
||||
if (!class_exists($className)) {
|
||||
if (!$throw) {
|
||||
return null;
|
||||
}
|
||||
|
||||
throw new InvalidArgumentValueException(
|
||||
'$className',
|
||||
'a valid class name or an object instance',
|
||||
$className,
|
||||
self::CLASS_CHECK_INVALID_CLASSNAME_PARAMETER + self::CLASS_CHECK_NON_EXISTING_CLASS
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($valid as $matchingClass => $isTrait) {
|
||||
if ($isTrait) {
|
||||
if (in_array($matchingClass, static::classUsesTraits($className, false), true)) {
|
||||
return $className;
|
||||
}
|
||||
} elseif (is_a($className, $matchingClass, true)) {
|
||||
return $className;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$throw) {
|
||||
return null;
|
||||
}
|
||||
|
||||
throw new InvalidArgumentClassException(
|
||||
'$className',
|
||||
$types,
|
||||
$className,
|
||||
self::CLASS_CHECK_INVALID_CLASSNAME_PARAMETER + self::CLASS_CHECK_TYPE_NOT_IN_LIST
|
||||
);
|
||||
return DataTypeHelper::matchClassType($className, $type, false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|object $class
|
||||
* @param bool $autoload
|
||||
*
|
||||
* @return array|null
|
||||
* @see https://www.php.net/manual/en/function.class-uses.php#122427
|
||||
* @deprecated since 1.16; use DataTypeHelper::classUsesTraits()
|
||||
* @see DataTypeHelper::classUsesTraits
|
||||
*/
|
||||
public static function &classUsesTraits($class, bool $autoload = true): ?array
|
||||
{
|
||||
$traits = [];
|
||||
|
||||
// Get all the traits of $class and its parent classes
|
||||
do {
|
||||
$class_name = is_object($class) ? get_class($class) : $class;
|
||||
|
||||
if (class_exists($class_name, $autoload)) {
|
||||
$traits = array_merge(class_uses($class, $autoload), $traits);
|
||||
}
|
||||
} while ($class = get_parent_class($class));
|
||||
|
||||
// Get traits of all parent traits
|
||||
$traits_to_search = $traits;
|
||||
while (!empty($traits_to_search)) {
|
||||
$new_traits = class_uses(array_pop($traits_to_search), $autoload);
|
||||
$traits = array_merge($new_traits, $traits);
|
||||
$traits_to_search = array_merge($new_traits, $traits_to_search);
|
||||
};
|
||||
|
||||
if (count($traits) === 0) {
|
||||
$traits = null;
|
||||
} else {
|
||||
$traits = array_unique($traits);
|
||||
}
|
||||
|
||||
return $traits;
|
||||
return DataTypeHelper::classUsesTraits($class, $autoload);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -442,6 +284,7 @@ class Helpers
|
||||
*
|
||||
* @param string $a First subject string to compare.
|
||||
* @param string $b Second subject string to compare.
|
||||
*
|
||||
* @return bool true if the strings are the same, false if they are different or if
|
||||
* either is not a string.
|
||||
*/
|
||||
@ -472,6 +315,7 @@ class Helpers
|
||||
* This is mainly required for grouped notifications.
|
||||
*
|
||||
* @param $event
|
||||
*
|
||||
* @since 1.2.1
|
||||
*/
|
||||
public static function SqlMode($event)
|
||||
|
@ -31,7 +31,6 @@ use yii\web\HttpException;
|
||||
*/
|
||||
class GroupController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
@ -118,18 +117,12 @@ class GroupController extends Controller
|
||||
|
||||
$this->checkGroupAccess($group);
|
||||
|
||||
// Save changed permission states
|
||||
if (!$group->isNewRecord && Yii::$app->request->post('dropDownColumnSubmit')) {
|
||||
$permission = Yii::$app->user->permissionManager->getById(Yii::$app->request->post('permissionId'), Yii::$app->request->post('moduleId'));
|
||||
if ($permission === null) {
|
||||
throw new HttpException(500, 'Could not find permission!');
|
||||
}
|
||||
Yii::$app->user->permissionManager->setGroupState($group->id, $permission, Yii::$app->request->post('state'));
|
||||
|
||||
return $this->asJson([]);
|
||||
if (!$group->isNewRecord) {
|
||||
// Save changed permission state
|
||||
$return = Yii::$app->user->permissionManager->handlePermissionStateChange($group->id);
|
||||
}
|
||||
|
||||
return $this->render('permissions', ['group' => $group]);
|
||||
return $return ?? $this->render('permissions', ['group' => $group]);
|
||||
}
|
||||
|
||||
public function actionManageGroupUsers()
|
||||
|
@ -9,6 +9,8 @@
|
||||
namespace humhub\modules\admin\controllers;
|
||||
|
||||
use humhub\modules\admin\models\SpaceSearch;
|
||||
use humhub\modules\admin\permissions\ManageSettings;
|
||||
use humhub\modules\admin\permissions\ManageSpaces;
|
||||
use humhub\modules\content\components\ContentContainerDefaultPermissionManager;
|
||||
use humhub\modules\content\models\Content;
|
||||
use humhub\modules\space\models\Space;
|
||||
@ -16,8 +18,6 @@ use humhub\modules\space\Module;
|
||||
use humhub\modules\user\helpers\AuthHelper;
|
||||
use Yii;
|
||||
use humhub\modules\admin\components\Controller;
|
||||
use humhub\modules\admin\permissions\ManageSpaces;
|
||||
use humhub\modules\admin\permissions\ManageSettings;
|
||||
use yii\web\HttpException;
|
||||
|
||||
/**
|
||||
@ -27,7 +27,6 @@ use yii\web\HttpException;
|
||||
*/
|
||||
class SpaceController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
@ -164,21 +163,12 @@ class SpaceController extends Controller
|
||||
}
|
||||
|
||||
// Handle permission state change
|
||||
if (Yii::$app->request->post('dropDownColumnSubmit')) {
|
||||
Yii::$app->response->format = 'json';
|
||||
$permission = $defaultPermissionManager->getById(Yii::$app->request->post('permissionId'), Yii::$app->request->post('moduleId'));
|
||||
if ($permission === null) {
|
||||
throw new HttpException(500, 'Could not find permission!');
|
||||
}
|
||||
$defaultPermissionManager->setGroupState($groupId, $permission, Yii::$app->request->post('state'));
|
||||
return [];
|
||||
}
|
||||
$return = $defaultPermissionManager->handlePermissionStateChange($groupId);
|
||||
|
||||
return $this->render('permissions', [
|
||||
return $return ?? $this->render('permissions', [
|
||||
'defaultPermissionManager' => $defaultPermissionManager,
|
||||
'groups' => $groups,
|
||||
'groupId' => $groupId,
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -69,17 +69,9 @@ class UserPermissionsController extends Controller
|
||||
}
|
||||
|
||||
// Handle permission state change
|
||||
if (Yii::$app->request->post('dropDownColumnSubmit')) {
|
||||
Yii::$app->response->format = 'json';
|
||||
$permission = $defaultPermissionManager->getById(Yii::$app->request->post('permissionId'), Yii::$app->request->post('moduleId'));
|
||||
if ($permission === null) {
|
||||
throw new HttpException(500, 'Could not find permission!');
|
||||
}
|
||||
$defaultPermissionManager->setGroupState($groupId, $permission, Yii::$app->request->post('state'));
|
||||
return [];
|
||||
}
|
||||
$return = $defaultPermissionManager->handlePermissionStateChange($groupId);
|
||||
|
||||
return $this->render('default', [
|
||||
return $return ?? $this->render('default', [
|
||||
'defaultPermissionManager' => $defaultPermissionManager,
|
||||
'groups' => $groups,
|
||||
'groupId' => $groupId,
|
||||
|
@ -10,7 +10,7 @@ namespace humhub\modules\comment\controllers;
|
||||
|
||||
use humhub\components\access\ControllerAccess;
|
||||
use humhub\components\Controller;
|
||||
use humhub\libs\Helpers;
|
||||
use humhub\helpers\DataTypeHelper;
|
||||
use humhub\modules\comment\models\Comment;
|
||||
use humhub\modules\comment\models\forms\AdminDeleteCommentForm;
|
||||
use humhub\modules\comment\models\forms\CommentForm;
|
||||
@ -65,7 +65,7 @@ class CommentController extends Controller
|
||||
$modelPk = (int)Yii::$app->request->get('objectId', Yii::$app->request->post('objectId'));
|
||||
|
||||
/** @var Comment|ContentActiveRecord $modelClass */
|
||||
$modelClass = Helpers::checkClassType($modelClass, [Comment::class, ContentActiveRecord::class]);
|
||||
$modelClass = DataTypeHelper::matchClassType($modelClass, [Comment::class, ContentActiveRecord::class], true);
|
||||
$this->target = $modelClass::findOne(['id' => $modelPk]);
|
||||
|
||||
if (!$this->target) {
|
||||
|
@ -10,12 +10,11 @@ namespace humhub\modules\content\components;
|
||||
|
||||
use humhub\components\behaviors\PolymorphicRelation;
|
||||
use humhub\components\Controller;
|
||||
use humhub\libs\Helpers;
|
||||
use humhub\helpers\DataTypeHelper;
|
||||
use Yii;
|
||||
use yii\base\Exception;
|
||||
use yii\web\HttpException;
|
||||
|
||||
|
||||
/**
|
||||
* ContentAddonController is a base controller for ContentAddons.
|
||||
*
|
||||
@ -29,7 +28,6 @@ use yii\web\HttpException;
|
||||
*/
|
||||
class ContentAddonController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Content this addon belongs to
|
||||
*
|
||||
@ -88,7 +86,11 @@ class ContentAddonController extends Controller
|
||||
}
|
||||
|
||||
/** @var ContentAddonActiveRecord|ContentActiveRecord $modelClass */
|
||||
$modelClass = Helpers::checkClassType($modelClass, [ContentAddonActiveRecord::class, ContentActiveRecord::class]);
|
||||
$modelClass = DataTypeHelper::matchClassType(
|
||||
$modelClass,
|
||||
[ContentAddonActiveRecord::class, ContentActiveRecord::class],
|
||||
true
|
||||
);
|
||||
$target = $modelClass::findOne(['id' => $pk]);
|
||||
|
||||
if ($target === null) {
|
||||
@ -122,7 +124,7 @@ class ContentAddonController extends Controller
|
||||
public function loadContentAddon($className, $pk)
|
||||
{
|
||||
/** @var ContentAddonActiveRecord|null $className */
|
||||
$className = Helpers::checkClassType($className, ContentAddonActiveRecord::class);
|
||||
$className = DataTypeHelper::matchClassType($className, ContentAddonActiveRecord::class);
|
||||
if ($className === null) {
|
||||
throw new Exception("Given className is not a content addon model!");
|
||||
}
|
||||
@ -139,5 +141,4 @@ class ContentAddonController extends Controller
|
||||
|
||||
$this->contentAddon = $target;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,18 +8,18 @@
|
||||
|
||||
namespace humhub\modules\file\actions;
|
||||
|
||||
use humhub\helpers\DataTypeHelper;
|
||||
use humhub\libs\Html;
|
||||
use humhub\modules\content\components\ContentActiveRecord;
|
||||
use humhub\modules\content\components\ContentAddonActiveRecord;
|
||||
use humhub\modules\file\libs\FileHelper;
|
||||
use humhub\modules\file\libs\ImageHelper;
|
||||
use humhub\modules\file\models\File;
|
||||
use humhub\modules\file\models\FileUpload;
|
||||
use Yii;
|
||||
use yii\base\Action;
|
||||
use yii\db\ActiveRecord;
|
||||
use yii\web\UploadedFile;
|
||||
use humhub\libs\Helpers;
|
||||
use humhub\modules\file\models\FileUpload;
|
||||
use humhub\modules\file\libs\FileHelper;
|
||||
use humhub\modules\file\models\File;
|
||||
use humhub\modules\content\components\ContentActiveRecord;
|
||||
use humhub\modules\content\components\ContentAddonActiveRecord;
|
||||
|
||||
/**
|
||||
* UploadAction provides an Ajax/JSON way to upload new files
|
||||
@ -138,7 +138,7 @@ class UploadAction extends Action
|
||||
|
||||
|
||||
/** @var ActiveRecord|string $model */
|
||||
if ($model != '' && $pk != '' && $model = Helpers::checkClassType($model, ActiveRecord::class)) {
|
||||
if ($model != '' && $pk != '' && $model = DataTypeHelper::matchClassType($model, ActiveRecord::class, true)) {
|
||||
$record = $model::findOne(['id' => $pk]);
|
||||
if ($record !== null && ($record instanceof ContentActiveRecord || $record instanceof ContentAddonActiveRecord)) {
|
||||
if ($record->content->canEdit()) {
|
||||
|
@ -68,30 +68,22 @@ class SecurityController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows space permessions
|
||||
* Shows space permissions
|
||||
*/
|
||||
public function actionPermissions()
|
||||
{
|
||||
$space = $this->getSpace();
|
||||
|
||||
$groups = $space->getUserGroups();
|
||||
$groups = $space::getUserGroups();
|
||||
$groupId = Yii::$app->request->get('groupId', Space::USERGROUP_MEMBER);
|
||||
if (!array_key_exists($groupId, $groups)) {
|
||||
throw new HttpException(500, 'Invalid group id given!');
|
||||
}
|
||||
|
||||
// Handle permission state change
|
||||
if (Yii::$app->request->post('dropDownColumnSubmit')) {
|
||||
Yii::$app->response->format = 'json';
|
||||
$permission = $space->permissionManager->getById(Yii::$app->request->post('permissionId'), Yii::$app->request->post('moduleId'));
|
||||
if ($permission === null) {
|
||||
throw new HttpException(500, 'Could not find permission!');
|
||||
}
|
||||
$space->permissionManager->setGroupState($groupId, $permission, Yii::$app->request->post('state'));
|
||||
return [];
|
||||
}
|
||||
$return = $space->permissionManager->handlePermissionStateChange($groupId);
|
||||
|
||||
return $this->render('permissions', [
|
||||
return $return ?? $this->render('permissions', [
|
||||
'space' => $space,
|
||||
'groups' => $groups,
|
||||
'groupId' => $groupId
|
||||
|
@ -9,14 +9,22 @@
|
||||
namespace humhub\modules\user\components;
|
||||
|
||||
use humhub\components\Module;
|
||||
use humhub\helpers\DataTypeHelper;
|
||||
use humhub\libs\BasePermission;
|
||||
use humhub\modules\user\models\Group;
|
||||
use humhub\modules\user\models\GroupPermission;
|
||||
use humhub\modules\user\models\User as UserModel;
|
||||
use RuntimeException;
|
||||
use Throwable;
|
||||
use Yii;
|
||||
use yii\base\Component;
|
||||
use yii\base\Exception;
|
||||
use yii\base\InvalidConfigException;
|
||||
use yii\base\Module as BaseModule;
|
||||
use yii\db\ActiveQuery;
|
||||
use yii\db\ActiveRecord;
|
||||
use yii\db\StaleObjectException;
|
||||
use yii\web\HttpException;
|
||||
|
||||
/**
|
||||
* Description of PermissionManager
|
||||
@ -27,7 +35,8 @@ class PermissionManager extends Component
|
||||
{
|
||||
/**
|
||||
* User identity.
|
||||
* @var \humhub\modules\user\models\User
|
||||
*
|
||||
* @var UserModel
|
||||
*/
|
||||
public $subject;
|
||||
|
||||
@ -59,8 +68,9 @@ class PermissionManager extends Component
|
||||
* @param string|array|BasePermission $permission
|
||||
* @param array $params
|
||||
* @param boolean $allowCaching
|
||||
*
|
||||
* @return boolean
|
||||
* @throws \yii\base\InvalidConfigException
|
||||
* @throws InvalidConfigException
|
||||
*/
|
||||
public function can($permission, $params = [], $allowCaching = true)
|
||||
{
|
||||
@ -94,6 +104,7 @@ class PermissionManager extends Component
|
||||
* Return boolean for verifyAll
|
||||
*
|
||||
* @param array $params
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isVerifyAll($params = [])
|
||||
@ -114,6 +125,7 @@ class PermissionManager extends Component
|
||||
* Verifies a single permission for a given permission subject.
|
||||
*
|
||||
* @param BasePermission $permission
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
protected function verify(BasePermission $permission)
|
||||
@ -131,7 +143,7 @@ class PermissionManager extends Component
|
||||
* If the permission objects $subject property is not set this method returns the currently
|
||||
* logged in user identity.
|
||||
*
|
||||
* @return \humhub\modules\user\models\User
|
||||
* @return UserModel
|
||||
*/
|
||||
protected function getSubject()
|
||||
{
|
||||
@ -155,9 +167,9 @@ class PermissionManager extends Component
|
||||
* @param string $groupId
|
||||
* @param string|BasePermission $permission either permission class or instance
|
||||
* @param string $state
|
||||
* @throws \Exception
|
||||
* @throws \yii\base\InvalidConfigException
|
||||
* @throws \yii\db\StaleObjectException
|
||||
*
|
||||
* @throws InvalidConfigException
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function setGroupState($groupId, $permission, $state)
|
||||
{
|
||||
@ -168,6 +180,7 @@ class PermissionManager extends Component
|
||||
if ($state === '' || $state === null) {
|
||||
if ($record !== null) {
|
||||
$record->delete();
|
||||
$this->clear();
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -179,11 +192,14 @@ class PermissionManager extends Component
|
||||
$record->permission_id = $permission->getId();
|
||||
$record->module_id = $permission->getModuleId();
|
||||
$record->class = get_class($permission);
|
||||
$record->group_id = $groupId;
|
||||
$record->group_id = (string)$groupId; // content container permissions require a text value here
|
||||
$record->state = $state;
|
||||
if ($record->save()) {
|
||||
$this->clear();
|
||||
|
||||
if ($record->save() === false) {
|
||||
throw new RuntimeException("Saving permission failed: " . implode('; ', $record->getErrorSummary(true)));
|
||||
}
|
||||
|
||||
$this->clear();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -335,7 +351,7 @@ class PermissionManager extends Component
|
||||
* @param string $permissionId
|
||||
* @param string $moduleId
|
||||
* @return BasePermission|null
|
||||
* @throws \yii\base\InvalidConfigException
|
||||
* @throws InvalidConfigException
|
||||
*/
|
||||
public function getById($permissionId, $moduleId)
|
||||
{
|
||||
@ -355,7 +371,8 @@ class PermissionManager extends Component
|
||||
* Not used anymore, permissions are now prefetched into $_groupPermissions array
|
||||
* @param $groupId
|
||||
* @param BasePermission $permission
|
||||
* @return array|null|\yii\db\ActiveRecord
|
||||
*
|
||||
* @return array|null|ActiveRecord
|
||||
* @deprecated since 1.10
|
||||
*
|
||||
*/
|
||||
@ -372,7 +389,7 @@ class PermissionManager extends Component
|
||||
* Returns a list of all Permission objects
|
||||
*
|
||||
* @return array of BasePermissions
|
||||
* @throws \yii\base\InvalidConfigException
|
||||
* @throws InvalidConfigException
|
||||
*/
|
||||
public function getPermissions()
|
||||
{
|
||||
@ -398,7 +415,7 @@ class PermissionManager extends Component
|
||||
*
|
||||
* @param BaseModule $module
|
||||
* @return array of BasePermissions
|
||||
* @throws \yii\base\InvalidConfigException
|
||||
* @throws InvalidConfigException
|
||||
*/
|
||||
protected function getModulePermissions(BaseModule $module)
|
||||
{
|
||||
@ -418,7 +435,7 @@ class PermissionManager extends Component
|
||||
/**
|
||||
* Creates a Permission Database record
|
||||
*
|
||||
* @return \yii\db\ActiveRecord
|
||||
* @return ActiveRecord
|
||||
*/
|
||||
protected function createPermissionRecord()
|
||||
{
|
||||
@ -428,7 +445,7 @@ class PermissionManager extends Component
|
||||
/**
|
||||
* Creates a Permission Database Query
|
||||
*
|
||||
* @return \yii\db\ActiveQuery
|
||||
* @return ActiveQuery
|
||||
*/
|
||||
protected function getQuery()
|
||||
{
|
||||
@ -441,8 +458,8 @@ class PermissionManager extends Component
|
||||
* @param int $groupId id of the group
|
||||
* @param bool $returnOnlyChangeable
|
||||
* @return array the permission array
|
||||
* @throws \yii\base\Exception
|
||||
* @throws \yii\base\InvalidConfigException
|
||||
* @throws Exception
|
||||
* @throws InvalidConfigException
|
||||
*/
|
||||
public function createPermissionArray($groupId, $returnOnlyChangeable = false)
|
||||
{
|
||||
@ -476,6 +493,38 @@ class PermissionManager extends Component
|
||||
return $permissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|string $groupId
|
||||
*
|
||||
* @return array|null
|
||||
* @throws InvalidConfigException
|
||||
* @throws HttpException
|
||||
* @throws StaleObjectException
|
||||
* @since 1.16
|
||||
*/
|
||||
public function handlePermissionStateChange($groupId): ?array
|
||||
{
|
||||
if (Yii::$app->request->post('dropDownColumnSubmit')) {
|
||||
Yii::$app->response->format = 'json';
|
||||
|
||||
$permission = $this->getById(
|
||||
Yii::$app->request->post('permissionId'),
|
||||
Yii::$app->request->post('moduleId')
|
||||
);
|
||||
|
||||
if ($permission === null) {
|
||||
throw new HttpException(500, 'Could not find permission!');
|
||||
}
|
||||
|
||||
$groupId = DataTypeHelper::filterInt($groupId) ?? DataTypeHelper::filterString($groupId);
|
||||
$state = DataTypeHelper::filterInt(Yii::$app->request->post('state'));
|
||||
$this->setGroupState($groupId, $permission, $state);
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a query for users which are granted given permission
|
||||
|
@ -8,6 +8,8 @@
|
||||
|
||||
namespace humhub\modules\user\controllers;
|
||||
|
||||
use Collator;
|
||||
use Exception;
|
||||
use humhub\compat\HForm;
|
||||
use humhub\modules\content\widgets\ContainerTagPicker;
|
||||
use humhub\modules\space\helpers\MembershipHelper;
|
||||
@ -18,10 +20,14 @@ use humhub\modules\user\helpers\AuthHelper;
|
||||
use humhub\modules\user\models\forms\AccountChangeEmail;
|
||||
use humhub\modules\user\models\forms\AccountChangeUsername;
|
||||
use humhub\modules\user\models\forms\AccountDelete;
|
||||
use humhub\modules\user\models\forms\AccountSettings;
|
||||
use humhub\modules\user\models\Password;
|
||||
use humhub\modules\user\models\User;
|
||||
use humhub\modules\user\Module;
|
||||
use Throwable;
|
||||
use Yii;
|
||||
use yii\web\HttpException;
|
||||
use yii\web\Response;
|
||||
|
||||
/**
|
||||
* AccountController provides all standard actions for the current logged in
|
||||
@ -59,7 +65,7 @@ class AccountController extends BaseAccountController
|
||||
|
||||
/**
|
||||
* Redirect to current users profile
|
||||
* @throws \Throwable
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function actionIndex()
|
||||
{
|
||||
@ -72,7 +78,7 @@ class AccountController extends BaseAccountController
|
||||
|
||||
/**
|
||||
* Edit Users Profile
|
||||
* @throws \Throwable
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function actionEdit()
|
||||
{
|
||||
@ -113,7 +119,7 @@ class AccountController extends BaseAccountController
|
||||
/** @var User $user */
|
||||
$user = Yii::$app->user->getIdentity();
|
||||
|
||||
$model = new \humhub\modules\user\models\forms\AccountSettings();
|
||||
$model = new AccountSettings();
|
||||
$model->language = Yii::$app->i18n->getAllowedLanguage($user->language);
|
||||
$model->timeZone = $user->time_zone;
|
||||
if (empty($model->timeZone)) {
|
||||
@ -148,7 +154,7 @@ class AccountController extends BaseAccountController
|
||||
|
||||
// Sort countries list based on user language
|
||||
$languages = Yii::$app->i18n->getAllowedLanguages();
|
||||
$col = new \Collator(Yii::$app->language);
|
||||
$col = new Collator(Yii::$app->language);
|
||||
$col->asort($languages);
|
||||
|
||||
/* @var $module Module */
|
||||
@ -175,7 +181,7 @@ class AccountController extends BaseAccountController
|
||||
|
||||
/**
|
||||
* Change Account
|
||||
* @throws \Exception
|
||||
* @throws Exception
|
||||
* @todo Add Group
|
||||
*/
|
||||
public function actionPermissions()
|
||||
@ -204,17 +210,9 @@ class AccountController extends BaseAccountController
|
||||
}
|
||||
|
||||
// Handle permission state change
|
||||
if (Yii::$app->request->post('dropDownColumnSubmit')) {
|
||||
Yii::$app->response->format = 'json';
|
||||
$permission = $this->getUser()->permissionManager->getById(Yii::$app->request->post('permissionId'), Yii::$app->request->post('moduleId'));
|
||||
if ($permission === null) {
|
||||
throw new HttpException(500, 'Could not find permission!');
|
||||
}
|
||||
$this->getUser()->permissionManager->setGroupState($currentGroup, $permission, Yii::$app->request->post('state'));
|
||||
return [];
|
||||
}
|
||||
$return = $this->getUser()->permissionManager->handlePermissionStateChange($currentGroup);
|
||||
|
||||
return $this->render('permissions', ['user' => $this->getUser(), 'groups' => $groups, 'group' => $currentGroup, 'multipleGroups' => (count($groups) > 1)]);
|
||||
return $return ?? $this->render('permissions', ['user' => $this->getUser(), 'groups' => $groups, 'group' => $currentGroup, 'multipleGroups' => (count($groups) > 1)]);
|
||||
}
|
||||
|
||||
public function actionConnectedAccounts()
|
||||
@ -268,9 +266,9 @@ class AccountController extends BaseAccountController
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|AccountController|\yii\console\Response|\yii\web\Response
|
||||
* @return array|AccountController|\yii\console\Response|Response
|
||||
* @throws HttpException
|
||||
* @throws \Throwable
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function actionEnableModule()
|
||||
{
|
||||
@ -290,9 +288,9 @@ class AccountController extends BaseAccountController
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|AccountController|\yii\console\Response|\yii\web\Response
|
||||
* @return array|AccountController|\yii\console\Response|Response
|
||||
* @throws HttpException
|
||||
* @throws \Throwable
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function actionDisableModule()
|
||||
{
|
||||
@ -394,7 +392,7 @@ class AccountController extends BaseAccountController
|
||||
}
|
||||
|
||||
// Check if E-Mail is in use, e.g. by other user
|
||||
$emailAvailablyCheck = \humhub\modules\user\models\User::findOne(['email' => $email]);
|
||||
$emailAvailablyCheck = User::findOne(['email' => $email]);
|
||||
if ($emailAvailablyCheck != null) {
|
||||
throw new HttpException(404, Yii::t('UserModule.account', 'The entered e-mail address is already in use by another user.'));
|
||||
}
|
||||
@ -414,7 +412,7 @@ class AccountController extends BaseAccountController
|
||||
throw new HttpException(500, 'Password change is not allowed');
|
||||
}
|
||||
|
||||
$userPassword = new \humhub\modules\user\models\Password();
|
||||
$userPassword = new Password();
|
||||
$userPassword->scenario = 'changePassword';
|
||||
|
||||
if ($userPassword->load(Yii::$app->request->post()) && $userPassword->validate()) {
|
||||
@ -491,7 +489,7 @@ class AccountController extends BaseAccountController
|
||||
*
|
||||
* @return User the user
|
||||
* @throws HttpException
|
||||
* @throws \Throwable
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function getUser()
|
||||
{
|
||||
|
@ -9,11 +9,10 @@
|
||||
namespace humhub\modules\user\models;
|
||||
|
||||
use humhub\components\ActiveRecord;
|
||||
use humhub\libs\Helpers;
|
||||
use humhub\helpers\DataTypeHelper;
|
||||
use humhub\modules\user\models\fieldtype\BaseType;
|
||||
use Yii;
|
||||
use yii\db\ActiveQuery;
|
||||
use yii\helpers\Html;
|
||||
|
||||
/**
|
||||
* This is the model class for table "profile_field".
|
||||
@ -45,7 +44,6 @@ use yii\helpers\Html;
|
||||
*/
|
||||
class ProfileField extends ActiveRecord
|
||||
{
|
||||
|
||||
/**
|
||||
* Field Type Instance
|
||||
*
|
||||
@ -151,10 +149,14 @@ class ProfileField extends ActiveRecord
|
||||
*/
|
||||
public function getFieldType(): ?BaseType
|
||||
{
|
||||
if ($this->_fieldType != null)
|
||||
if ($this->_fieldType != null) {
|
||||
return $this->_fieldType;
|
||||
}
|
||||
|
||||
if ($this->field_type_class != '' && $type = Helpers::checkClassType($this->field_type_class, fieldtype\BaseType::class)) {
|
||||
if (
|
||||
$this->field_type_class != ''
|
||||
&& $type = DataTypeHelper::matchClassType($this->field_type_class, fieldtype\BaseType::class, true)
|
||||
) {
|
||||
$this->_fieldType = new $type();
|
||||
$this->_fieldType->setProfileField($this);
|
||||
return $this->_fieldType;
|
||||
@ -287,7 +289,6 @@ class ProfileField extends ActiveRecord
|
||||
{
|
||||
|
||||
if (!$this->isNewRecord) {
|
||||
|
||||
// Dont allow changes of internal_name - Maybe not the best way to check it.
|
||||
$currentProfileField = ProfileField::findOne(['id' => $this->id]);
|
||||
if ($this->field_type_class != $currentProfileField->field_type_class) {
|
||||
@ -328,5 +329,4 @@ class ProfileField extends ActiveRecord
|
||||
|
||||
return "UserModule.profile";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
namespace humhub\modules\user\models\fieldtype;
|
||||
|
||||
use humhub\libs\Helpers;
|
||||
use humhub\helpers\DataTypeHelper;
|
||||
use humhub\modules\user\models\Profile;
|
||||
use humhub\modules\user\models\ProfileField;
|
||||
use humhub\modules\user\models\User;
|
||||
@ -172,7 +172,7 @@ class BaseType extends Model
|
||||
{
|
||||
$types = [];
|
||||
foreach ($this->getFieldTypes() as $className => $title) {
|
||||
$className = Helpers::checkClassType($className, static::class);
|
||||
$className = DataTypeHelper::matchClassType($className, static::class, true);
|
||||
/** @var BaseType $instance */
|
||||
$instance = new $className();
|
||||
if ($profileField !== null) {
|
||||
|
@ -13,8 +13,8 @@ use humhub\components\Application;
|
||||
use humhub\components\Event;
|
||||
use humhub\components\Module;
|
||||
use humhub\events\MigrationEvent;
|
||||
use humhub\helpers\DataTypeHelper;
|
||||
use humhub\interfaces\ApplicationInterface;
|
||||
use humhub\libs\Helpers;
|
||||
use Throwable;
|
||||
use Yii;
|
||||
use yii\base\ActionEvent;
|
||||
@ -44,7 +44,7 @@ class MigrationService extends Component
|
||||
*/
|
||||
public function __construct(?BaseModule $module = null)
|
||||
{
|
||||
Helpers::checkClassType($module, [ApplicationInterface::class, Module::class, null]);
|
||||
DataTypeHelper::ensureClassType($module, [ApplicationInterface::class, Module::class, null]);
|
||||
|
||||
$this->module = $module ?? Yii::$app;
|
||||
|
||||
|
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @link https://www.humhub.org/
|
||||
* @copyright Copyright (c) 2018-2023 HumHub GmbH & Co. KG
|
||||
* @license https://www.humhub.com/licences
|
||||
*/
|
||||
|
||||
/**
|
||||
* @noinspection PhpIllegalPsrClassPathInspection
|
||||
*/
|
||||
|
||||
namespace humhub\tests\codeception\unit\helpers;
|
||||
|
||||
use humhub\helpers\DataTypeHelper;
|
||||
|
||||
/**
|
||||
* Class DataTypeHelperTest
|
||||
*/
|
||||
class DataTypeHelperMock extends DataTypeHelper
|
||||
{
|
||||
public static function matchTypeHelper($typeToCheck, &$input, string $inputType, ?array &$inputTraits = null): ?string
|
||||
{
|
||||
return parent::matchTypeHelper($typeToCheck, $input, $inputType, $inputTraits);
|
||||
}
|
||||
|
||||
public static function parseTypes(&$allowedTypes, ?bool &$allowNull = false, ?array &$checkTraits = null, bool $allowCallables = true, bool $allowGetTypes = true): array
|
||||
{
|
||||
return parent::parseTypes($allowedTypes, $allowNull, $checkTraits, $allowCallables, $allowGetTypes);
|
||||
}
|
||||
}
|
@ -0,0 +1,630 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @link https://www.humhub.org/
|
||||
* @copyright Copyright (c) 2018-2023 HumHub GmbH & Co. KG
|
||||
* @license https://www.humhub.com/licences
|
||||
*/
|
||||
|
||||
/**
|
||||
* @noinspection PhpIllegalPsrClassPathInspection
|
||||
*/
|
||||
|
||||
namespace humhub\tests\codeception\unit\helpers;
|
||||
|
||||
use Codeception\Test\Feature\Stub;
|
||||
use Codeception\Test\Unit;
|
||||
use Codeception\TestInterface;
|
||||
use humhub\exceptions\InvalidArgumentClassException;
|
||||
use humhub\exceptions\InvalidArgumentTypeException;
|
||||
use humhub\exceptions\InvalidArgumentValueException;
|
||||
use humhub\helpers\DataTypeHelper;
|
||||
use PHPUnit\Framework\Exception;
|
||||
use stdClass;
|
||||
use Stringable;
|
||||
use yii\base\ArrayableTrait;
|
||||
use yii\base\BaseObject;
|
||||
use yii\base\Configurable;
|
||||
use yii\base\Model;
|
||||
|
||||
/**
|
||||
* Class DataTypeHelperTest
|
||||
*/
|
||||
class DataTypeHelperTest extends Unit
|
||||
{
|
||||
public function testClassTypeHelperCase1()
|
||||
{
|
||||
static::assertNull(DataTypeHelperMock::matchTypeHelper(null, $value, ''));
|
||||
static::assertNull(DataTypeHelperMock::matchTypeHelper(1, $value, ''));
|
||||
static::assertNull(DataTypeHelperMock::matchTypeHelper(1.2, $value, ''));
|
||||
static::assertNull(DataTypeHelperMock::matchTypeHelper(true, $value, ''));
|
||||
}
|
||||
|
||||
public function testClassTypeHelperCase2()
|
||||
{
|
||||
$handle = fopen('php://memory', 'ab');
|
||||
fclose($handle);
|
||||
|
||||
$tests = [
|
||||
'boolean' => [
|
||||
true,
|
||||
'bool'
|
||||
],
|
||||
'integer' => [
|
||||
1,
|
||||
'int'
|
||||
],
|
||||
'string' => [
|
||||
'',
|
||||
],
|
||||
'array' => [
|
||||
[],
|
||||
],
|
||||
'object' => [
|
||||
new stdClass(),
|
||||
],
|
||||
'resource' => [
|
||||
fopen('php://memory', 'ab'),
|
||||
],
|
||||
'resource (closed)' => [
|
||||
$handle,
|
||||
],
|
||||
'NULL' => [
|
||||
null,
|
||||
],
|
||||
'float' => [
|
||||
1.2,
|
||||
'double'
|
||||
],
|
||||
];
|
||||
|
||||
$values = array_combine(array_keys($tests), array_column($tests, 0));
|
||||
|
||||
foreach ($tests as $key => $test) {
|
||||
codecept_debug("- Testing $key");
|
||||
|
||||
$current = gettype($test[0]);
|
||||
|
||||
static::assertEquals($key, DataTypeHelperMock::matchTypeHelper($key, $value, $current));
|
||||
|
||||
if (array_key_exists(1, $test)) {
|
||||
static::assertEquals($test[1], DataTypeHelperMock::matchTypeHelper($test[1], $value, $current));
|
||||
}
|
||||
|
||||
foreach ($values as $i => $type) {
|
||||
if ($i === $key) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$current = gettype($type);
|
||||
static::assertNull(DataTypeHelperMock::matchTypeHelper($key, $value, $current));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function testClassTypeHelperCase3()
|
||||
{
|
||||
$value = new class () implements Stringable {
|
||||
public function __toString(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
static::assertEquals('object', DataTypeHelperMock::matchTypeHelper('object', $value, 'object'));
|
||||
static::assertEquals(
|
||||
Stringable::class,
|
||||
DataTypeHelperMock::matchTypeHelper(Stringable::class, $value, 'object')
|
||||
);
|
||||
|
||||
$value = new class () {
|
||||
public function __toString(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
static::assertEquals(
|
||||
'object',
|
||||
DataTypeHelperMock::matchTypeHelper('object', $value, gettype($value))
|
||||
);
|
||||
static::assertEquals(
|
||||
Stringable::class,
|
||||
DataTypeHelperMock::matchTypeHelper(Stringable::class, $value, 'object')
|
||||
);
|
||||
|
||||
$value = new static();
|
||||
|
||||
static::assertEquals(
|
||||
'object',
|
||||
DataTypeHelperMock::matchTypeHelper('object', $value, gettype($value))
|
||||
);
|
||||
|
||||
// test class
|
||||
static::assertEquals(
|
||||
static::class,
|
||||
DataTypeHelperMock::matchTypeHelper(static::class, $value, gettype($value))
|
||||
);
|
||||
|
||||
// test interface
|
||||
static::assertEquals(
|
||||
TestInterface::class,
|
||||
DataTypeHelperMock::matchTypeHelper(TestInterface::class, $value, gettype($value))
|
||||
);
|
||||
|
||||
// test trait
|
||||
$traits = DataTypeHelper::classUsesTraits($value);
|
||||
static::assertEquals(
|
||||
Stub::class,
|
||||
DataTypeHelperMock::matchTypeHelper(Stub::class, $value, gettype($value), $traits)
|
||||
);
|
||||
}
|
||||
|
||||
public function testParseTypeCase1()
|
||||
{
|
||||
$types = null;
|
||||
static::assertEquals([], DataTypeHelperMock::parseTypes($types));
|
||||
static::assertEquals([null], $types);
|
||||
|
||||
$types = ['string'];
|
||||
static::assertEquals(['string'], DataTypeHelperMock::parseTypes($types));
|
||||
static::assertEquals(['string'], $types);
|
||||
|
||||
$types = 'int';
|
||||
static::assertEquals(['int'], DataTypeHelperMock::parseTypes($types));
|
||||
static::assertEquals(['int'], $types);
|
||||
|
||||
$types = 'string|int';
|
||||
static::assertEquals(['string', 'int'], DataTypeHelperMock::parseTypes($types));
|
||||
static::assertEquals(['string', 'int'], $types);
|
||||
}
|
||||
|
||||
public function testParseTypeCase2()
|
||||
{
|
||||
$message = 'Argument $allowedTypes passed to humhub\helpers\DataTypeHelper::parseTypes must be one of string, string[], object[] - empty string given.';
|
||||
|
||||
$this->expectException(InvalidArgumentValueException::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
|
||||
$types = '';
|
||||
DataTypeHelperMock::parseTypes($types);
|
||||
}
|
||||
|
||||
public function testParseTypeCase3()
|
||||
{
|
||||
$message = 'Argument $allowedTypes passed to humhub\helpers\DataTypeHelper::parseTypes must be one of string, string[], object[] - [] given.';
|
||||
|
||||
$this->expectException(InvalidArgumentValueException::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
|
||||
$types = [];
|
||||
DataTypeHelperMock::parseTypes($types);
|
||||
}
|
||||
|
||||
public function testParseTypeCase4()
|
||||
{
|
||||
$message = 'Argument $allowedTypes[0] passed to humhub\helpers\DataTypeHelper::parseTypes must be a valid class/interface/trait name or an object instance - test given.';
|
||||
|
||||
$this->expectException(InvalidArgumentValueException::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
|
||||
$types = ['test'];
|
||||
DataTypeHelperMock::parseTypes($types);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testClassTypeHelperCase1
|
||||
* @depends testClassTypeHelperCase2
|
||||
* @depends testClassTypeHelperCase3
|
||||
* @depends testParseTypeCase1
|
||||
* @depends testParseTypeCase2
|
||||
* @depends testParseTypeCase3
|
||||
*/
|
||||
public function testCheckTypeCase()
|
||||
{
|
||||
$tests = [
|
||||
'boolean' => true,
|
||||
'bool' => true,
|
||||
'integer' => 1,
|
||||
'int' => 1,
|
||||
'string' => '',
|
||||
'array' => [],
|
||||
'object' => new stdClass(),
|
||||
'resource' => fopen('php://memory', 'ab'),
|
||||
'NULL' => null,
|
||||
'float' => 1.2,
|
||||
'double' => 1.2,
|
||||
];
|
||||
|
||||
foreach ($tests as $key => $value) {
|
||||
codecept_debug("- Testing $key");
|
||||
|
||||
static::assertEquals($key, DataTypeHelper::matchType($value, [$key]));
|
||||
}
|
||||
|
||||
static::assertEquals('string', DataTypeHelper::matchType('', [null, 'string']));
|
||||
static::assertEquals('string', DataTypeHelper::matchType('', ['string', null]));
|
||||
static::assertEquals('string', DataTypeHelper::matchType('', ['string', 'NULL']));
|
||||
|
||||
$values = [
|
||||
new class () implements Stringable {
|
||||
public function __toString(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
},
|
||||
new class () {
|
||||
public function __toString(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
foreach ($values as $value) {
|
||||
static::assertEquals('object', DataTypeHelper::matchType($value, ['object']));
|
||||
static::assertEquals(
|
||||
Stringable::class,
|
||||
DataTypeHelper::matchType($value, [Stringable::class])
|
||||
);
|
||||
static::assertEquals('is_object', DataTypeHelper::matchType($value, ['is_object']));
|
||||
|
||||
// type order is of significance, if multiple types match
|
||||
static::assertEquals(
|
||||
'object',
|
||||
DataTypeHelper::matchType($value, ['object', Stringable::class])
|
||||
);
|
||||
static::assertEquals(
|
||||
Stringable::class,
|
||||
DataTypeHelper::matchType($value, [Stringable::class, 'object'])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCheckTypeCase
|
||||
*/
|
||||
public function testFilterBoolStrict()
|
||||
{
|
||||
static::assertTrue(DataTypeHelper::filterBool(true, true));
|
||||
static::assertNull(DataTypeHelper::filterBool('true', true));
|
||||
static::assertNull(DataTypeHelper::filterBool(1, true));
|
||||
|
||||
static::assertFalse(DataTypeHelper::filterBool(false, true));
|
||||
static::assertNull(DataTypeHelper::filterBool('false', true));
|
||||
static::assertNull(DataTypeHelper::filterBool(0, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCheckTypeCase
|
||||
*/
|
||||
public function testFilterBoolConversion()
|
||||
{
|
||||
static::assertTrue(DataTypeHelper::filterBool(true, null));
|
||||
static::assertTrue(DataTypeHelper::filterBool('true', null));
|
||||
static::assertTrue(DataTypeHelper::filterBool(1, null));
|
||||
static::assertTrue(DataTypeHelper::filterBool('1', null));
|
||||
static::assertTrue(DataTypeHelper::filterBool([''], null));
|
||||
static::assertTrue(DataTypeHelper::filterBool([0], null));
|
||||
static::assertTrue(DataTypeHelper::filterBool([1], null));
|
||||
|
||||
static::assertFalse(DataTypeHelper::filterBool('false', null));
|
||||
static::assertFalse(DataTypeHelper::filterBool('0', null));
|
||||
static::assertFalse(DataTypeHelper::filterBool('', null));
|
||||
static::assertFalse(DataTypeHelper::filterBool(0, null));
|
||||
static::assertFalse(DataTypeHelper::filterBool([], null));
|
||||
static::assertFalse(DataTypeHelper::filterBool(null, null));
|
||||
|
||||
static::assertNull(DataTypeHelper::filterBool(new static(), null));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCheckTypeCase
|
||||
*/
|
||||
public function testFilterBoolDefault()
|
||||
{
|
||||
static::assertTrue(DataTypeHelper::filterBool(true, false));
|
||||
static::assertTrue(DataTypeHelper::filterBool(1, false));
|
||||
static::assertTrue(DataTypeHelper::filterBool('1', false));
|
||||
static::assertTrue(DataTypeHelper::filterBool('foo', false));
|
||||
static::assertTrue(DataTypeHelper::filterBool(['1'], false));
|
||||
static::assertTrue(DataTypeHelper::filterBool('false', false));
|
||||
|
||||
static::assertFalse(DataTypeHelper::filterBool(false, false));
|
||||
static::assertFalse(DataTypeHelper::filterBool('0', false));
|
||||
static::assertFalse(DataTypeHelper::filterBool('', false));
|
||||
static::assertFalse(DataTypeHelper::filterBool(0, false));
|
||||
static::assertFalse(DataTypeHelper::filterBool([], false));
|
||||
static::assertFalse(DataTypeHelper::filterBool(null, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCheckTypeCase
|
||||
*/
|
||||
public function testFilterFloat()
|
||||
{
|
||||
static::assertEquals(1.1, DataTypeHelper::filterFloat(1.1, true));
|
||||
static::assertNull(DataTypeHelper::filterFloat('1.1', true));
|
||||
|
||||
static::assertEquals(1.0, DataTypeHelper::filterFloat(1));
|
||||
static::assertEquals(1.0, DataTypeHelper::filterFloat('1'));
|
||||
static::assertEquals(1.1, DataTypeHelper::filterFloat(1.1));
|
||||
static::assertEquals(1.1, DataTypeHelper::filterFloat('1.1'));
|
||||
static::assertNull(DataTypeHelper::filterFloat('1.1.3'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCheckTypeCase
|
||||
*/
|
||||
public function testFilterInt()
|
||||
{
|
||||
static::assertEquals(1, DataTypeHelper::filterInt(1, true));
|
||||
static::assertNull(DataTypeHelper::filterInt('1', true));
|
||||
|
||||
static::assertEquals(1, DataTypeHelper::filterInt(1));
|
||||
static::assertEquals(1, DataTypeHelper::filterInt('1'));
|
||||
static::assertNull(DataTypeHelper::filterInt('1.1'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCheckTypeCase
|
||||
*/
|
||||
public function testFilterScalar()
|
||||
{
|
||||
static::assertEquals('', DataTypeHelper::filterScalar('', true));
|
||||
static::assertEquals(1, DataTypeHelper::filterScalar(1, true));
|
||||
|
||||
static::assertNull(DataTypeHelper::filterScalar(null, true));
|
||||
static::assertNull(DataTypeHelper::filterScalar(fopen('php://memory', 'ab'), true));
|
||||
|
||||
static::assertEquals('', DataTypeHelper::filterScalar(''));
|
||||
static::assertEquals(1, DataTypeHelper::filterScalar(1));
|
||||
|
||||
static::assertNull(DataTypeHelper::filterScalar(null));
|
||||
static::assertNull(DataTypeHelper::filterScalar(fopen('php://memory', 'ab')));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCheckTypeCase
|
||||
*/
|
||||
public function testFilterString()
|
||||
{
|
||||
static::assertEquals('', DataTypeHelper::filterString('', true));
|
||||
static::assertEquals('1', DataTypeHelper::filterString('1', true));
|
||||
static::assertNull(DataTypeHelper::filterString(1, true));
|
||||
|
||||
static::assertEquals('', DataTypeHelper::filterString(''));
|
||||
static::assertEquals('1', DataTypeHelper::filterString('1'));
|
||||
static::assertEquals('1', DataTypeHelper::filterString(1));
|
||||
static::assertEquals('1', DataTypeHelper::filterString('1'));
|
||||
static::assertEquals('1.1', DataTypeHelper::filterString('1.1'));
|
||||
static::assertEquals('1.1', DataTypeHelper::filterString(1.1));
|
||||
|
||||
$value = new class () implements Stringable {
|
||||
public function __toString(): string
|
||||
{
|
||||
return 'foo';
|
||||
}
|
||||
};
|
||||
static::assertEquals('foo', DataTypeHelper::filterString($value));
|
||||
|
||||
$value = new class () {
|
||||
public function __toString(): string
|
||||
{
|
||||
return 'bar';
|
||||
}
|
||||
};
|
||||
static::assertEquals('bar', DataTypeHelper::filterString($value));
|
||||
|
||||
static::assertNull(DataTypeHelper::filterString([]));
|
||||
static::assertNull(DataTypeHelper::filterString((object)[]));
|
||||
}
|
||||
|
||||
public function testClassTypeCheckCase2()
|
||||
{
|
||||
$message = 'Argument $allowedTypes passed to humhub\helpers\DataTypeHelper::parseTypes must be one of string, string[], object[] - empty string given.';
|
||||
|
||||
$this->expectException(InvalidArgumentValueException::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
$this->expectExceptionCode(DataTypeHelper::TYPE_CHECK_INVALID_TYPE_PARAMETER + DataTypeHelper::TYPE_CHECK_VALUE_IS_EMPTY);
|
||||
|
||||
DataTypeHelper::matchClassType(null, '');
|
||||
}
|
||||
|
||||
public function testClassTypeCheckCase3()
|
||||
{
|
||||
$message = 'Argument $allowedTypes passed to humhub\helpers\DataTypeHelper::parseTypes must be one of string, string[], object[] - [] given.';
|
||||
|
||||
$this->expectException(InvalidArgumentValueException::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
$this->expectExceptionCode(DataTypeHelper::TYPE_CHECK_INVALID_TYPE_PARAMETER + DataTypeHelper::TYPE_CHECK_VALUE_IS_EMPTY);
|
||||
|
||||
DataTypeHelper::matchClassType(null, []);
|
||||
}
|
||||
|
||||
public function testClassTypeCheckCase4()
|
||||
{
|
||||
$message = 'Argument $allowedTypes passed to humhub\helpers\DataTypeHelper::parseTypes must be one of the following types: string, string[], object[], NULL - int given.';
|
||||
|
||||
$this->expectException(InvalidArgumentTypeException::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
$this->expectExceptionCode(DataTypeHelper::TYPE_CHECK_INVALID_TYPE_PARAMETER + DataTypeHelper::TYPE_CHECK_INVALID_TYPE);
|
||||
|
||||
DataTypeHelper::matchClassType(null, 0);
|
||||
}
|
||||
|
||||
public function testClassTypeCheckCase5()
|
||||
{
|
||||
$message = 'Argument $allowedTypes[0] passed to humhub\helpers\DataTypeHelper::parseTypes must be a valid class/interface/trait name or an object instance - \'0\' given.';
|
||||
|
||||
$this->expectException(InvalidArgumentValueException::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
$this->expectExceptionCode(DataTypeHelper::TYPE_CHECK_INVALID_TYPE_PARAMETER + DataTypeHelper::TYPE_CHECK_NON_EXISTING_CLASS);
|
||||
|
||||
DataTypeHelper::matchClassType(null, '0');
|
||||
}
|
||||
|
||||
|
||||
public function testClassTypeCheckCase6()
|
||||
{
|
||||
$message = 'Argument $allowedTypes[0] passed to humhub\helpers\DataTypeHelper::parseTypes must be a valid class/interface/trait name or an object instance - humhub\tests\codeception\unit\helpers\NonExistingClassName given.';
|
||||
|
||||
$this->expectException(InvalidArgumentValueException::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
$this->expectExceptionCode(DataTypeHelper::TYPE_CHECK_INVALID_TYPE_PARAMETER + DataTypeHelper::TYPE_CHECK_NON_EXISTING_CLASS);
|
||||
|
||||
/** @noinspection PhpUndefinedClassInspection */
|
||||
DataTypeHelper::matchClassType(null, NonExistingClassName::class);
|
||||
}
|
||||
|
||||
public function testClassTypeCheckCase7()
|
||||
{
|
||||
$message = 'Argument $allowedTypes[1] passed to humhub\helpers\DataTypeHelper::parseTypes must be a valid class/interface/trait name or an object instance - humhub\tests\codeception\unit\helpers\NonExistingClassName given.';
|
||||
|
||||
$this->expectException(InvalidArgumentValueException::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
$this->expectExceptionCode(DataTypeHelper::TYPE_CHECK_INVALID_TYPE_PARAMETER + DataTypeHelper::TYPE_CHECK_NON_EXISTING_CLASS);
|
||||
|
||||
/** @noinspection PhpUndefinedClassInspection */
|
||||
DataTypeHelper::matchClassType(null, [BaseObject::class, NonExistingClassName::class]);
|
||||
}
|
||||
|
||||
public function testClassTypeCheckCaseNull()
|
||||
{
|
||||
static::assertNull(
|
||||
DataTypeHelper::matchClassType(null, BaseObject::class)
|
||||
);
|
||||
|
||||
static::assertNull(
|
||||
DataTypeHelper::matchClassType(null, [BaseObject::class, null])
|
||||
);
|
||||
|
||||
$message = 'Argument $value passed to humhub\helpers\DataTypeHelper::matchClassType must be of type yii\base\BaseObject - NULL given.';
|
||||
|
||||
$this->expectException(InvalidArgumentTypeException::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
$this->expectExceptionCode(DataTypeHelper::TYPE_CHECK_INVALID_VALUE_PARAMETER + DataTypeHelper::TYPE_CHECK_VALUE_IS_EMPTY + DataTypeHelper::TYPE_CHECK_INVALID_TYPE + DataTypeHelper::TYPE_CHECK_VALUE_IS_NULL);
|
||||
|
||||
DataTypeHelper::ensureClassType(null, BaseObject::class);
|
||||
}
|
||||
|
||||
public function testClassTypeCheckCaseEmptyString()
|
||||
{
|
||||
static::assertNull(
|
||||
DataTypeHelper::matchClassType('', BaseObject::class)
|
||||
);
|
||||
|
||||
$message = 'Argument $value passed to humhub\helpers\DataTypeHelper::matchClassType must be of type yii\base\BaseObject - empty string given.';
|
||||
|
||||
$this->expectException(InvalidArgumentClassException::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
$this->expectExceptionCode(DataTypeHelper::TYPE_CHECK_INVALID_VALUE_PARAMETER + DataTypeHelper::TYPE_CHECK_VALUE_IS_EMPTY + DataTypeHelper::TYPE_CHECK_INVALID_TYPE + DataTypeHelper::TYPE_CHECK_TYPE_NOT_IN_LIST);
|
||||
|
||||
DataTypeHelper::ensureClassType('', BaseObject::class);
|
||||
}
|
||||
|
||||
public function testClassTypeCheckCaseString()
|
||||
{
|
||||
/** @noinspection PhpUndefinedClassInspection */
|
||||
static::assertNull(
|
||||
DataTypeHelper::matchClassType(NonExistingClassName::class, BaseObject::class, false)
|
||||
);
|
||||
|
||||
$message = 'Argument $value passed to humhub\helpers\DataTypeHelper::matchClassType must be a valid class name or an object instance - humhub\tests\codeception\unit\helpers\NonExistingClassName given.';
|
||||
|
||||
$this->expectException(InvalidArgumentValueException::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
$this->expectExceptionCode(DataTypeHelper::TYPE_CHECK_INVALID_VALUE_PARAMETER + DataTypeHelper::TYPE_CHECK_NON_EXISTING_CLASS);
|
||||
|
||||
/** @noinspection PhpUndefinedClassInspection */
|
||||
DataTypeHelper::ensureClassType(NonExistingClassName::class, BaseObject::class);
|
||||
}
|
||||
|
||||
public function testClassTypeCheckCaseWrongClass()
|
||||
{
|
||||
static::assertNull(
|
||||
DataTypeHelper::matchClassType(Exception::class, BaseObject::class)
|
||||
);
|
||||
|
||||
$message = 'Argument $value passed to humhub\helpers\DataTypeHelper::matchClassType must be of type yii\base\BaseObject - PHPUnit\Framework\Exception given.';
|
||||
|
||||
$this->expectException(InvalidArgumentClassException::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
$this->expectExceptionCode(DataTypeHelper::TYPE_CHECK_INVALID_VALUE_PARAMETER + DataTypeHelper::TYPE_CHECK_TYPE_NOT_IN_LIST);
|
||||
|
||||
DataTypeHelper::ensureClassType(Exception::class, BaseObject::class);
|
||||
}
|
||||
|
||||
public function testClassTypeCheckCaseWrongInstance()
|
||||
{
|
||||
static::assertNull(
|
||||
DataTypeHelper::matchClassType(new Exception('hello'), BaseObject::class)
|
||||
);
|
||||
|
||||
$message = 'Argument $value passed to humhub\helpers\DataTypeHelper::matchClassType must be of type yii\base\BaseObject - PHPUnit\Framework\Exception given.';
|
||||
|
||||
$this->expectException(InvalidArgumentClassException::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
$this->expectExceptionCode(DataTypeHelper::TYPE_CHECK_INVALID_VALUE_PARAMETER + DataTypeHelper::TYPE_CHECK_TYPE_NOT_IN_LIST + DataTypeHelper::TYPE_CHECK_VALUE_IS_INSTANCE);
|
||||
|
||||
DataTypeHelper::ensureClassType(new Exception('hello'), BaseObject::class);
|
||||
}
|
||||
|
||||
public function testClassTypeCheckCaseCorrectClass()
|
||||
{
|
||||
static::assertEquals(
|
||||
Exception::class,
|
||||
DataTypeHelper::matchClassType(Exception::class, Exception::class)
|
||||
);
|
||||
|
||||
static::assertEquals(
|
||||
Exception::class,
|
||||
DataTypeHelper::matchClassType(Exception::class, [new \Exception()])
|
||||
);
|
||||
|
||||
static::assertEquals(
|
||||
BaseObject::class,
|
||||
DataTypeHelper::matchClassType(BaseObject::class, Configurable::class)
|
||||
);
|
||||
|
||||
static::assertEquals(
|
||||
Model::class,
|
||||
DataTypeHelper::matchClassType(Model::class, ArrayableTrait::class)
|
||||
);
|
||||
|
||||
static::assertNull(
|
||||
DataTypeHelper::matchClassType('#%' . Exception::class, Exception::class)
|
||||
);
|
||||
|
||||
$message = 'Argument $value passed to humhub\helpers\DataTypeHelper::matchClassType must be a valid class name or an object instance - #%PHPUnit\Framework\Exception given.';
|
||||
|
||||
$this->expectException(InvalidArgumentValueException::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
$this->expectExceptionCode(DataTypeHelper::TYPE_CHECK_INVALID_VALUE_PARAMETER + DataTypeHelper::TYPE_CHECK_NON_EXISTING_CLASS);
|
||||
|
||||
DataTypeHelper::ensureClassType('#%' . Exception::class, Exception::class);
|
||||
}
|
||||
|
||||
public function testClassTypeCheckCaseCorrectInstance()
|
||||
{
|
||||
static::assertEquals(
|
||||
Exception::class,
|
||||
DataTypeHelper::matchClassType(new Exception('hello'), Exception::class)
|
||||
);
|
||||
|
||||
static::assertEquals(
|
||||
Exception::class,
|
||||
DataTypeHelper::matchClassType(new Exception('hello'), [new \Exception()])
|
||||
);
|
||||
|
||||
static::assertEquals(
|
||||
BaseObject::class,
|
||||
DataTypeHelper::matchClassType(new BaseObject(), Configurable::class)
|
||||
);
|
||||
|
||||
static::assertEquals(
|
||||
Model::class,
|
||||
DataTypeHelper::matchClassType(new Model(), ArrayableTrait::class)
|
||||
);
|
||||
}
|
||||
}
|
@ -1,260 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @link https://www.humhub.org/
|
||||
* @copyright Copyright (c) 2018 HumHub GmbH & Co. KG
|
||||
* @license https://www.humhub.com/licences
|
||||
*/
|
||||
|
||||
/**
|
||||
* @noinspection PhpIllegalPsrClassPathInspection
|
||||
*/
|
||||
|
||||
namespace humhub\tests\codeception\unit\libs;
|
||||
|
||||
use Codeception\Test\Unit;
|
||||
use humhub\exceptions\InvalidArgumentClassException;
|
||||
use humhub\exceptions\InvalidArgumentTypeException;
|
||||
use humhub\exceptions\InvalidArgumentValueException;
|
||||
use humhub\libs\Helpers;
|
||||
use PHPUnit\Framework\Exception;
|
||||
use yii\base\ArrayableTrait;
|
||||
use yii\base\BaseObject;
|
||||
use yii\base\Configurable;
|
||||
use yii\base\Model;
|
||||
|
||||
/**
|
||||
* Class MimeHelperTest
|
||||
*
|
||||
* @noinspection IdentifierGrammar
|
||||
*/
|
||||
class HelpersTest extends Unit
|
||||
{
|
||||
public function testClassTypeCheckCase1()
|
||||
{
|
||||
$message = 'Argument $type passed to humhub\libs\Helpers::checkClassType must be one of string, string[] - NULL given.';
|
||||
|
||||
$this->expectException(InvalidArgumentValueException::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
$this->expectExceptionCode(Helpers::CLASS_CHECK_INVALID_TYPE_PARAMETER + Helpers::CLASS_CHECK_VALUE_IS_EMPTY);
|
||||
|
||||
Helpers::checkClassType(null, null);
|
||||
}
|
||||
|
||||
public function testClassTypeCheckCase2()
|
||||
{
|
||||
$message = 'Argument $type passed to humhub\libs\Helpers::checkClassType must be one of string, string[] - empty string given.';
|
||||
|
||||
$this->expectException(InvalidArgumentValueException::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
$this->expectExceptionCode(Helpers::CLASS_CHECK_INVALID_TYPE_PARAMETER + Helpers::CLASS_CHECK_VALUE_IS_EMPTY);
|
||||
|
||||
Helpers::checkClassType(null, '');
|
||||
}
|
||||
|
||||
public function testClassTypeCheckCase3()
|
||||
{
|
||||
$message = 'Argument $type passed to humhub\libs\Helpers::checkClassType must be one of string, string[] - [] given.';
|
||||
|
||||
$this->expectException(InvalidArgumentValueException::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
$this->expectExceptionCode(Helpers::CLASS_CHECK_INVALID_TYPE_PARAMETER + Helpers::CLASS_CHECK_VALUE_IS_EMPTY);
|
||||
|
||||
Helpers::checkClassType(null, []);
|
||||
}
|
||||
|
||||
public function testClassTypeCheckCase4()
|
||||
{
|
||||
$message = 'Argument $type passed to humhub\libs\Helpers::checkClassType must be one of string, string[] - 0 given.';
|
||||
|
||||
$this->expectException(InvalidArgumentValueException::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
$this->expectExceptionCode(Helpers::CLASS_CHECK_INVALID_TYPE_PARAMETER + Helpers::CLASS_CHECK_VALUE_IS_EMPTY);
|
||||
|
||||
Helpers::checkClassType(null, 0);
|
||||
}
|
||||
|
||||
public function testClassTypeCheckCase5()
|
||||
{
|
||||
$message = 'Argument $type passed to humhub\libs\Helpers::checkClassType must be one of string, string[] - \'0\' given.';
|
||||
|
||||
$this->expectException(InvalidArgumentValueException::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
$this->expectExceptionCode(Helpers::CLASS_CHECK_INVALID_TYPE_PARAMETER + Helpers::CLASS_CHECK_VALUE_IS_EMPTY);
|
||||
|
||||
Helpers::checkClassType(null, '0');
|
||||
}
|
||||
|
||||
|
||||
public function testClassTypeCheckCase6()
|
||||
{
|
||||
$message = 'Argument $type[0] passed to humhub\libs\Helpers::checkClassType must be a valid class/interface/trait name or an object instance - humhub\tests\codeception\unit\libs\NonExistingClassName given.';
|
||||
|
||||
$this->expectException(InvalidArgumentValueException::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
$this->expectExceptionCode(Helpers::CLASS_CHECK_INVALID_TYPE_PARAMETER + Helpers::CLASS_CHECK_NON_EXISTING_CLASS);
|
||||
|
||||
/** @noinspection PhpUndefinedClassInspection */
|
||||
Helpers::checkClassType(null, NonExistingClassName::class);
|
||||
}
|
||||
|
||||
public function testClassTypeCheckCase7()
|
||||
{
|
||||
$message = 'Argument $type[1] passed to humhub\libs\Helpers::checkClassType must be a valid class/interface/trait name or an object instance - humhub\tests\codeception\unit\libs\NonExistingClassName given.';
|
||||
|
||||
$this->expectException(InvalidArgumentValueException::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
$this->expectExceptionCode(Helpers::CLASS_CHECK_INVALID_TYPE_PARAMETER + Helpers::CLASS_CHECK_NON_EXISTING_CLASS);
|
||||
|
||||
/** @noinspection PhpUndefinedClassInspection */
|
||||
Helpers::checkClassType(null, [BaseObject::class, NonExistingClassName::class]);
|
||||
}
|
||||
|
||||
public function testClassTypeCheckCaseNull()
|
||||
{
|
||||
static::assertNull(
|
||||
Helpers::checkClassType(null, BaseObject::class, false)
|
||||
);
|
||||
|
||||
static::assertNull(
|
||||
Helpers::checkClassType(null, [BaseObject::class, null])
|
||||
);
|
||||
|
||||
$message = 'Argument $className passed to humhub\libs\Helpers::checkClassType must be of type yii\base\BaseObject - NULL given.';
|
||||
|
||||
$this->expectException(InvalidArgumentTypeException::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
$this->expectExceptionCode(Helpers::CLASS_CHECK_INVALID_CLASSNAME_PARAMETER + Helpers::CLASS_CHECK_VALUE_IS_EMPTY + Helpers::CLASS_CHECK_INVALID_TYPE + Helpers::CLASS_CHECK_VALUE_IS_NULL);
|
||||
|
||||
Helpers::checkClassType(null, BaseObject::class);
|
||||
}
|
||||
|
||||
public function testClassTypeCheckCaseEmptyString()
|
||||
{
|
||||
static::assertNull(
|
||||
Helpers::checkClassType('', BaseObject::class, false)
|
||||
);
|
||||
|
||||
static::assertNull(
|
||||
Helpers::checkClassType('', [BaseObject::class, null], true, false)
|
||||
);
|
||||
|
||||
$message = 'Argument $className passed to humhub\libs\Helpers::checkClassType must be of type yii\base\BaseObject - empty string given.';
|
||||
|
||||
$this->expectException(InvalidArgumentClassException::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
$this->expectExceptionCode(Helpers::CLASS_CHECK_INVALID_CLASSNAME_PARAMETER + Helpers::CLASS_CHECK_VALUE_IS_EMPTY + Helpers::CLASS_CHECK_INVALID_TYPE + Helpers::CLASS_CHECK_TYPE_NOT_IN_LIST);
|
||||
|
||||
Helpers::checkClassType('', BaseObject::class);
|
||||
}
|
||||
|
||||
public function testClassTypeCheckCaseString()
|
||||
{
|
||||
/** @noinspection PhpUndefinedClassInspection */
|
||||
static::assertNull(
|
||||
Helpers::checkClassType(NonExistingClassName::class, BaseObject::class, false)
|
||||
);
|
||||
|
||||
$message = 'Argument $className passed to humhub\libs\Helpers::checkClassType must be a valid class name or an object instance - humhub\tests\codeception\unit\libs\NonExistingClassName given.';
|
||||
|
||||
$this->expectException(InvalidArgumentValueException::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
$this->expectExceptionCode(Helpers::CLASS_CHECK_INVALID_CLASSNAME_PARAMETER + Helpers::CLASS_CHECK_NON_EXISTING_CLASS);
|
||||
|
||||
/** @noinspection PhpUndefinedClassInspection */
|
||||
Helpers::checkClassType(NonExistingClassName::class, BaseObject::class);
|
||||
}
|
||||
|
||||
public function testClassTypeCheckCaseWrongClass()
|
||||
{
|
||||
static::assertNull(
|
||||
Helpers::checkClassType(Exception::class, BaseObject::class, false)
|
||||
);
|
||||
|
||||
$message = 'Argument $className passed to humhub\libs\Helpers::checkClassType must be of type yii\base\BaseObject - PHPUnit\Framework\Exception given.';
|
||||
|
||||
$this->expectException(InvalidArgumentClassException::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
$this->expectExceptionCode(Helpers::CLASS_CHECK_INVALID_CLASSNAME_PARAMETER + Helpers::CLASS_CHECK_TYPE_NOT_IN_LIST);
|
||||
|
||||
Helpers::checkClassType(Exception::class, BaseObject::class);
|
||||
}
|
||||
|
||||
public function testClassTypeCheckCaseWrongInstance()
|
||||
{
|
||||
static::assertNull(
|
||||
Helpers::checkClassType(new Exception('hello'), BaseObject::class, false)
|
||||
);
|
||||
|
||||
$message = 'Argument $className passed to humhub\libs\Helpers::checkClassType must be of type yii\base\BaseObject - PHPUnit\Framework\Exception given.';
|
||||
|
||||
$this->expectException(InvalidArgumentClassException::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
$this->expectExceptionCode(Helpers::CLASS_CHECK_INVALID_CLASSNAME_PARAMETER + Helpers::CLASS_CHECK_TYPE_NOT_IN_LIST + Helpers::CLASS_CHECK_VALUE_IS_INSTANCE);
|
||||
|
||||
Helpers::checkClassType(new Exception('hello'), BaseObject::class);
|
||||
}
|
||||
|
||||
public function testClassTypeCheckCaseCorrectClass()
|
||||
{
|
||||
static::assertEquals(
|
||||
Exception::class,
|
||||
Helpers::checkClassType(Exception::class, Exception::class)
|
||||
);
|
||||
|
||||
static::assertEquals(
|
||||
Exception::class,
|
||||
Helpers::checkClassType(Exception::class, [new \Exception()])
|
||||
);
|
||||
|
||||
static::assertEquals(
|
||||
BaseObject::class,
|
||||
Helpers::checkClassType(BaseObject::class, Configurable::class)
|
||||
);
|
||||
|
||||
static::assertEquals(
|
||||
Model::class,
|
||||
Helpers::checkClassType(Model::class, ArrayableTrait::class)
|
||||
);
|
||||
|
||||
static::assertEquals(
|
||||
Exception::class,
|
||||
Helpers::checkClassType('#%' . Exception::class, Exception::class, false, false)
|
||||
);
|
||||
|
||||
static::assertNull(
|
||||
Helpers::checkClassType('#%' . Exception::class, Exception::class, false, true)
|
||||
);
|
||||
|
||||
$message = 'Argument $className passed to humhub\libs\Helpers::checkClassType must be a valid class name or an object instance - #%PHPUnit\Framework\Exception given.';
|
||||
|
||||
$this->expectException(InvalidArgumentClassException::class);
|
||||
$this->expectExceptionMessage($message);
|
||||
$this->expectExceptionCode(Helpers::CLASS_CHECK_INVALID_CLASSNAME_PARAMETER);
|
||||
|
||||
Helpers::checkClassType('#%' . Exception::class, Exception::class);
|
||||
}
|
||||
|
||||
public function testClassTypeCheckCaseCorrectInstance()
|
||||
{
|
||||
static::assertEquals(
|
||||
Exception::class,
|
||||
Helpers::checkClassType(new Exception('hello'), Exception::class)
|
||||
);
|
||||
|
||||
static::assertEquals(
|
||||
Exception::class,
|
||||
Helpers::checkClassType(new Exception('hello'), [new \Exception()])
|
||||
);
|
||||
|
||||
static::assertEquals(
|
||||
BaseObject::class,
|
||||
Helpers::checkClassType(new BaseObject(), Configurable::class)
|
||||
);
|
||||
|
||||
static::assertEquals(
|
||||
Model::class,
|
||||
Helpers::checkClassType(new Model(), ArrayableTrait::class)
|
||||
);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user