efureev/php-support

View on GitHub
src/Global/base.php

Summary

Maintainability
B
6 hrs
Test Coverage
<?php

use Php\Support\Helpers\Arr;
use Php\Support\Structures\Collections\ReadableCollection;

if (!function_exists('value')) {
    /**
     * Return the default value of the given value.
     *
     * @param mixed $value
     * @param mixed ...$args
     *
     * @return mixed
     */
    function value(mixed $value, mixed ...$args): mixed
    {
        return $value instanceof Closure || (is_object($value) && is_callable($value))
            ? $value(...$args)
            : $value;
    }
}

if (!function_exists('dataGet')) {
    /**
     * Get an item from an array or object using "dot" notation.
     *
     * @param mixed $target
     * @param string|int|(string|int|null)[]|null $key
     * @param mixed $default
     * @return mixed
     */
    function dataGet(mixed $target, string|array|int|null $key, mixed $default = null): mixed
    {
        if ($key === null) {
            return $target;
        }

        $key = is_array($key) ? $key : explode('.', (string)$key);

        foreach ($key as $i => $segment) {
            unset($key[$i]);

            if ($segment === null) {
                return $target;
            }

            if ($segment === '*') {
                if ($target instanceof ReadableCollection) {
                    $target = $target->all();
                } elseif (!is_iterable($target)) {
                    return value($default);
                }

                $result = [];

                foreach ($target as $item) {
                    $result[] = dataGet($item, $key);
                }

                return in_array('*', $key) ? Arr::collapse($result) : $result;
            }

            if (Arr::accessible($target) && Arr::exists($target, $segment)) {
                $target = $target[$segment];
            } elseif (is_object($target) && isset($target->{$segment})) {
                $target = $target->{$segment};
            } else {
                return value($default);
            }
        }

        return $target;
    }
}


if (!function_exists('mapValue')) {
    function mapValue(callable $fn, iterable $collection, mixed ...$args): array
    {
        $result = [];

        foreach ($collection as $key => $value) {
            $result[$key] = $fn($value, $key, ...$args);
        }

        return $result;
    }
}

if (!function_exists('eachValue')) {
    function eachValue(callable $fn, iterable $collection, mixed ...$args): void
    {
        foreach ($collection as $key => $value) {
            $fn($value, $key, ...$args);
        }
    }
}

if (!function_exists('when')) {
    /**
     * Returns a value when a condition is truthy.
     *
     * @param mixed|bool|\Closure $condition
     * @param mixed|\Closure $value
     * @param mixed|\Closure|null $default
     *
     * @return mixed
     */
    function when($condition, $value, $default = null)
    {
        if ($result = value($condition)) {
            return $value instanceof Closure ? $value($result) : $value;
        }

        return value($default);
    }
}

if (!function_exists('classNamespace')) {
    /**
     * @param object|string $class
     *
     * @return string
     */
    function classNamespace($class): string
    {
        if (is_object($class)) {
            $class = get_class($class);
        }

        return implode('\\', array_slice(explode("\\", $class), 0, -1));
    }
}

if (!function_exists('isTrue')) {
    /**
     * Returns bool value of a value
     *
     * @param mixed $val
     * @param bool $return_null
     *
     * @return bool|null
     */
    function isTrue($val, bool $return_null = false): ?bool
    {
        if ($val === null && $return_null) {
            return null;
        }

        $boolVal = (is_string($val)
            ? filter_var($val, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)
            : (bool)$val);
        return ($boolVal === null && !$return_null ? false : $boolVal);
    }
}

if (!function_exists('instance')) {
    /**
     * @param string|object $instance
     * @param mixed ...$params
     *
     * @return mixed
     */
    function instance($instance, ...$params): mixed
    {
        if (is_object($instance)) {
            return $instance;
        }

        if (is_string($instance) && class_exists($instance)) {
            return new $instance(...$params);
        }

        return null;
    }
}

if (!function_exists('class_basename')) {
    /**
     * Get the class "basename" of the given object / class.
     *
     * @param string|object $class
     *
     * @return string
     */
    function class_basename($class)
    {
        $class = is_object($class) ? get_class($class) : $class;

        return basename(str_replace('\\', '/', $class));
    }
}

if (!function_exists('trait_uses_recursive')) {
    /**
     * Returns all traits used by a trait and its traits.
     *
     * @param string $trait
     *
     * @return array
     */
    function trait_uses_recursive(string $trait): array
    {
        if (!$traits = class_uses($trait)) {
            return [];
        }

        foreach ((array)$traits as $trt) {
            $traits += trait_uses_recursive($trt);
        }

        return $traits;
    }
}

if (!function_exists('does_trait_use')) {
    /**
     * @param string $class
     * @param string $trait
     *
     * @return bool
     */
    function does_trait_use(string $class, string $trait): bool
    {
        return isset(trait_uses_recursive($class)[$trait]);
    }
}

if (!function_exists('class_uses_recursive')) {
    /**
     * Returns all traits used by a class, its parent classes and trait of their traits.
     *
     * @param object|string $class
     *
     * @return array
     */
    function class_uses_recursive($class): array
    {
        if (is_object($class)) {
            $class = get_class($class);
        }

        $results = [];

        foreach (array_reverse((array)class_parents($class)) + [$class => $class] as $cls) {
            $results += trait_uses_recursive((string)$cls);
        }

        return array_unique($results);
    }
}


if (!function_exists('remoteStaticCall')) {
    /**
     * Returns result of an object's method if it exists in the object.
     *
     * @param string|object|null $class
     * @param string $method
     * @param mixed ...$params
     *
     * @return mixed
     */
    function remoteStaticCall(object|string|null $class, string $method, mixed ...$params): mixed
    {
        if (!$class) {
            return null;
        }

        if (
            (is_object($class) || (is_string($class) && class_exists($class))) &&
            method_exists($class, $method)
        ) {
            return $class::$method(...$params);
        }

        return null;
    }
}

if (!function_exists('remoteStaticCall')) {
    /**
     * Returns result of an object's method if it exists in the object or trow exception.
     *
     * @param string|object|null $class
     * @param string $method
     * @param mixed ...$params
     *
     * @return mixed
     */
    function remoteStaticCallOrTrow(object|string|null $class, string $method, mixed ...$params): mixed
    {
        if (!$class) {
            throw new RuntimeException('Target Class is absent');
        }

        if (
            (is_object($class) || (is_string($class) && class_exists($class))) &&
            method_exists($class, $method)
        ) {
            return $class::$method(...$params);
        }

        $strClass = is_object($class) ? $class::class : $class;
        throw new \Php\Support\Exceptions\MissingMethodException("$strClass::$method");
    }
}

if (!function_exists('remoteCall')) {
    /**
     * Returns result of an object's method if it exists in the object.
     *
     * @param object|null $class
     * @param string $method
     * @param mixed ...$params
     *
     * @return mixed
     */
    function remoteCall(?object $class, string $method, mixed ...$params): mixed
    {
        if (!$class) {
            return null;
        }

        if (method_exists($class, $method)) {
            return $class->$method(...$params);
        }

        return null;
    }
}