datatable.directory codebase
				https://datatable.directory/
			
			
		
			You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							388 lines
						
					
					
						
							8.6 KiB
						
					
					
				
			
		
		
	
	
							388 lines
						
					
					
						
							8.6 KiB
						
					
					
				<?php
 | 
						|
 | 
						|
/*
 | 
						|
|--------------------------------------------------------------------------
 | 
						|
| Global helper functions
 | 
						|
|--------------------------------------------------------------------------
 | 
						|
|
 | 
						|
| Functions defined here are available anywhere in the application.
 | 
						|
|
 | 
						|
*/
 | 
						|
 | 
						|
use MightyPork\Utils\ObjCollection;
 | 
						|
use MightyPork\Utils\Profiler;
 | 
						|
use MightyPork\Utils\Str;
 | 
						|
use MightyPork\Utils\Utils;
 | 
						|
 | 
						|
#region Defines
 | 
						|
 | 
						|
define('IDENTIFIER_PATTERN', '/^[a-z][a-z0-9_]*$/i');
 | 
						|
define('USERNAME_PATTERN', '/^[a-z0-9_-]+$/i');
 | 
						|
 | 
						|
#endregion
 | 
						|
 | 
						|
#region View helpers
 | 
						|
 | 
						|
/** to bool 01 */
 | 
						|
function bool01($x)
 | 
						|
{
 | 
						|
	return Utils::parseBool01($x);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Conditional helper for view (same as: A ? B : '')
 | 
						|
 *
 | 
						|
 * @param bool   $cond   Condition to check
 | 
						|
 * @param string $then Value to use if condition is true, otherwise empty string.
 | 
						|
 * @param string $else   False value
 | 
						|
 * @return string result for the view.
 | 
						|
 */
 | 
						|
function when($cond, $then, $else = '')
 | 
						|
{
 | 
						|
	return $cond ? $then : $else;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Conditional helper for view, opposite of when()
 | 
						|
 *
 | 
						|
 * @param bool   $cond   Condition to check
 | 
						|
 * @param string $then Value to use if condition is false, otherwise empty string.
 | 
						|
 * @param string $else   True value
 | 
						|
 * @return string result for the view.
 | 
						|
 */
 | 
						|
function unless($cond, $then, $else = '')
 | 
						|
{
 | 
						|
	return $cond ? $else : $then;
 | 
						|
}
 | 
						|
 | 
						|
#endregion
 | 
						|
 | 
						|
#region General purpose helpers
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * Wrapper for nested arrays or objects.
 | 
						|
 * - Undefined keys are returned as null.
 | 
						|
 * - array and object values are wrapped in objBag when returned.
 | 
						|
 */
 | 
						|
class objBag implements JsonSerializable, ArrayAccess, \Illuminate\Contracts\Support\Arrayable
 | 
						|
{
 | 
						|
    /** @var object */
 | 
						|
    private $wrapped;
 | 
						|
    private $recursive;
 | 
						|
 | 
						|
    /**
 | 
						|
     * objBag constructor.
 | 
						|
     * @param mixed $wrapped - wrapped object/array/class
 | 
						|
     * @param bool $recursive - return array/object values as objBags too
 | 
						|
     */
 | 
						|
    public function __construct($wrapped, $recursive = true)
 | 
						|
    {
 | 
						|
        $this->wrapped = (object)$wrapped;
 | 
						|
        $this->recursive = $recursive;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @param $name
 | 
						|
     * @return null|objBag|mixed
 | 
						|
     */
 | 
						|
    public function __get($name)
 | 
						|
    {
 | 
						|
        if ($this->wrapped) {
 | 
						|
            if (isset($this->wrapped->$name)) {
 | 
						|
                $x = $this->wrapped->$name;
 | 
						|
 | 
						|
                if ($this->recursive && (is_array($x) || is_object($x))) {
 | 
						|
                    return objBag($x);
 | 
						|
                }
 | 
						|
 | 
						|
                return $x;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        return null;
 | 
						|
    }
 | 
						|
 | 
						|
    public function __set($name, $value)
 | 
						|
    {
 | 
						|
        if ($this->wrapped) {
 | 
						|
            $this->wrapped->$name = $value;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    public function __unset($name)
 | 
						|
    {
 | 
						|
        if ($this->wrapped) {
 | 
						|
            unset($this->wrapped->$name);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    public function __isset($name)
 | 
						|
    {
 | 
						|
        return isset($this->wrapped->$name);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @param $name
 | 
						|
     * @param null $def
 | 
						|
     * @return null|array|mixed
 | 
						|
     */
 | 
						|
    public function get($name, $def = null)
 | 
						|
    {
 | 
						|
        if (!isset($this->$name)) return $def;
 | 
						|
        return $this->$name;
 | 
						|
    }
 | 
						|
 | 
						|
    public function has($name)
 | 
						|
    {
 | 
						|
        return isset($this->$name) && $this->$name !== null;
 | 
						|
    }
 | 
						|
 | 
						|
    public function unpack()
 | 
						|
    {
 | 
						|
        return $this->wrapped;
 | 
						|
    }
 | 
						|
 | 
						|
    public function toArray()
 | 
						|
    {
 | 
						|
        return (array)$this->wrapped;
 | 
						|
    }
 | 
						|
 | 
						|
    public function all()
 | 
						|
    {
 | 
						|
        return $this->toArray();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Specify data which should be serialized to JSON
 | 
						|
     *
 | 
						|
     * @link  http://php.net/manual/en/jsonserializable.jsonserialize.php
 | 
						|
     * @return mixed data which can be serialized by <b>json_encode</b>,
 | 
						|
     * which is a value of any type other than a resource.
 | 
						|
     * @since 5.4.0
 | 
						|
     */
 | 
						|
    public function jsonSerialize()
 | 
						|
    {
 | 
						|
        return $this->wrapped;
 | 
						|
    }
 | 
						|
 | 
						|
    public function offsetExists($offset)
 | 
						|
    {
 | 
						|
        return isset($this->$offset);
 | 
						|
    }
 | 
						|
 | 
						|
    public function offsetGet($offset)
 | 
						|
    {
 | 
						|
        return $this->$offset;
 | 
						|
    }
 | 
						|
 | 
						|
    public function offsetSet($offset, $value)
 | 
						|
    {
 | 
						|
        $this->$offset = $value;
 | 
						|
    }
 | 
						|
 | 
						|
    public function offsetUnset($offset)
 | 
						|
    {
 | 
						|
        unset($this->$offset);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * @param $obj
 | 
						|
 * @param bool $recursive - whether the bag should be recursive
 | 
						|
 * @return objBag
 | 
						|
 */
 | 
						|
function objBag($obj, $recursive=true) {
 | 
						|
	return new \objBag($obj, $recursive);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Helper to check if model exists.
 | 
						|
 *
 | 
						|
 * Related to https://github.com/laravel/framework/issues/13988
 | 
						|
 *
 | 
						|
 * @param \Illuminate\Database\Eloquent\Model|null $model
 | 
						|
 * @return bool
 | 
						|
 */
 | 
						|
function model_exists(Illuminate\Database\Eloquent\Model $model = null) {
 | 
						|
	return $model !== null && $model->exists;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Get a data array or value from the config data array
 | 
						|
 *
 | 
						|
 * @param string $key     key in dot notation
 | 
						|
 * @param null   $default default value if not defined
 | 
						|
 * @return mixed
 | 
						|
 */
 | 
						|
function data($key, $default = null)
 | 
						|
{
 | 
						|
	return config("data.$key", $default);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Wrap the argument in an array, if not an array already.
 | 
						|
 * Null becomes an empty array, array stays an array.
 | 
						|
 * Collection is converted to an array.
 | 
						|
 *
 | 
						|
 * @param mixed|mixed[]|null $oneOrMany
 | 
						|
 * @return array
 | 
						|
 */
 | 
						|
function arr($oneOrMany)
 | 
						|
{
 | 
						|
	if (is_null($oneOrMany)) {
 | 
						|
		return [];
 | 
						|
	}
 | 
						|
 | 
						|
	if (is_array($oneOrMany)) {
 | 
						|
		return $oneOrMany;
 | 
						|
	} else if ($oneOrMany instanceof \Illuminate\Support\Collection) {
 | 
						|
		return $oneOrMany->toArray();
 | 
						|
	} else {
 | 
						|
		return [$oneOrMany];
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Clamp value to given bounds
 | 
						|
 *
 | 
						|
 * @param float $value input
 | 
						|
 * @param float $min   lower bound - included
 | 
						|
 * @param float $max   upper bound - included
 | 
						|
 * @return float result
 | 
						|
 */
 | 
						|
function clamp($value, $min, $max)
 | 
						|
{
 | 
						|
	return Utils::clamp($value, $min, $max);
 | 
						|
}
 | 
						|
 | 
						|
function objCollect($value = null)
 | 
						|
{
 | 
						|
	return new ObjCollection($value);
 | 
						|
}
 | 
						|
 | 
						|
function mb_ucfirst($str) {
 | 
						|
	return Str::ucfirst($str);
 | 
						|
}
 | 
						|
 | 
						|
// "pipe sort" is like normal sort, but returns the sorted array
 | 
						|
 | 
						|
/** "pipe sort" */
 | 
						|
function sorted($arr) {
 | 
						|
	sort($arr);
 | 
						|
	return $arr;
 | 
						|
}
 | 
						|
 | 
						|
/** natural "pipe sort" */
 | 
						|
function natsorted($arr, $cs=false) {
 | 
						|
	return collect($arr)->natSort($cs)->all();
 | 
						|
}
 | 
						|
 | 
						|
/** natural "pipe sort" by prop or retriever */
 | 
						|
function natsorted_by($arr, $prop, $cs=false) {
 | 
						|
	return collect($arr)->natSortBy($prop, $cs)->all();
 | 
						|
}
 | 
						|
 | 
						|
/** Preg match that returns the array */
 | 
						|
function preg_matched($pattern, $subject) {
 | 
						|
	$ar = [];
 | 
						|
	preg_match($pattern, $subject, $ar);
 | 
						|
	return $ar;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Format a string using the {} syntax
 | 
						|
 *
 | 
						|
 * @param  string $format
 | 
						|
 * @param array   ...$replacements
 | 
						|
 * @return string
 | 
						|
 */
 | 
						|
function fmt($format, ...$replacements)
 | 
						|
{
 | 
						|
	return Str::format($format, ...$replacements);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Sleep milliseconds (complementary to sleep & usleep)
 | 
						|
 *
 | 
						|
 * @param int $millis ms to sleep
 | 
						|
 */
 | 
						|
function msleep($millis)
 | 
						|
{
 | 
						|
	usleep(1000 * $millis);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Sleep with a log message
 | 
						|
 *
 | 
						|
 * @param int $millis ms to sleep
 | 
						|
 */
 | 
						|
function log_msleep($millis)
 | 
						|
{
 | 
						|
	Log::debug("Sleeping $millis ms");
 | 
						|
	usleep(1000 * $millis);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Sleep with a log message
 | 
						|
 *
 | 
						|
 * @param int $secs ms to sleep
 | 
						|
 */
 | 
						|
function log_sleep($secs)
 | 
						|
{
 | 
						|
	Log::debug("Sleeping $secs s");
 | 
						|
	sleep($secs);
 | 
						|
}
 | 
						|
 | 
						|
#endregion
 | 
						|
 | 
						|
#region Profiling
 | 
						|
/**
 | 
						|
 * Start profiling
 | 
						|
 *
 | 
						|
 * @return float start time (token)
 | 
						|
 */
 | 
						|
function prof_start()
 | 
						|
{
 | 
						|
	return Profiler::start();
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * End profiling
 | 
						|
 *
 | 
						|
 * @param float $token start time (from profiler_start())
 | 
						|
 * @return float time elapsed
 | 
						|
 */
 | 
						|
function prof_end($token)
 | 
						|
{
 | 
						|
	return Profiler::end($token);
 | 
						|
}
 | 
						|
 | 
						|
#endregion
 | 
						|
 | 
						|
/**
 | 
						|
 * Simple (but not exhaustive) transliteration for natural sort etc.
 | 
						|
 *
 | 
						|
 * @param $string
 | 
						|
 * @return string
 | 
						|
 */
 | 
						|
function simple_translit($string) {
 | 
						|
	static $table = [
 | 
						|
		'Á' => 'A', 'á' => 'a', 'Č' => 'C', 'č' => 'c', 'Ď' => 'D', 'ď' => 'd', 'É' => 'E',
 | 
						|
		'é' => 'e', 'Ě' => 'E', 'ě' => 'e', 'Í' => 'I', 'í' => 'i', 'Ň' => 'N', 'ň' => 'n',
 | 
						|
		'Ó' => 'O', 'ó' => 'o', 'Ř' => 'R', 'ř' => 'r', 'Š' => 'S', 'š' => 's', 'Ť' => 'T',
 | 
						|
		'ť' => 't', 'Ú' => 'U', 'ú' => 'u', 'Ů' => 'U', 'ů' => 'u', 'Ý' => 'Y', 'ý' => 'y',
 | 
						|
		'Ž' => 'Z', 'ž' => 'z', 'ß' => 'ss', 'А' => 'a', 'а' => 'a', 'Б' => 'b', 'б' => 'b',
 | 
						|
		'В' => 'v', 'в' => 'v', 'Г' => 'g', 'г' => 'g', 'Д' => 'd', 'д' => 'd', 'Е' => 'e',
 | 
						|
		'е' => 'e', 'Ё' => 'e', 'ё' => 'e', 'Ж' => 'z', 'ж' => 'z', 'З' => 'z', 'з' => 'z',
 | 
						|
		'И' => 'i', 'и' => 'i', 'Й' => 'j', 'й' => 'j', 'К' => 'k', 'к' => 'k', 'Л' => 'l',
 | 
						|
		'л' => 'l', 'М' => 'm', 'м' => 'm', 'Н' => 'n', 'н' => 'n', 'О' => 'o', 'о' => 'o',
 | 
						|
		'П' => 'p', 'п' => 'p', 'Р' => 'r', 'р' => 'r', 'С' => 's', 'с' => 's', 'Т' => 't',
 | 
						|
		'т' => 't', 'У' => 'u', 'у' => 'u', 'Ф' => 'f', 'ф' => 'f', 'Х' => 'x', 'х' => 'x',
 | 
						|
		'Ц' => 'c', 'ц' => 'c', 'Ч' => 'ch', 'ч' => 'ch', 'Ш' => 'sh', 'ш' => 'sh', 'Щ' => 'shch',
 | 
						|
		'щ' => 'shch', 'Ы' => 'y', 'ы' => 'y', 'Э' => 'e', 'э' => 'e', 'Ю' => 'ju', 'ю' => 'ju',
 | 
						|
		'Я' => 'ja', 'я' => 'ja',
 | 
						|
	];
 | 
						|
 | 
						|
	return strtr($string, $table);
 | 
						|
}
 | 
						|
 |