gnu-social/vendor/hoa/consistency/Consistency.php
Diogo Cordeiro ec32db2dd6 [CORE][COMPOSER] Add hoa/consistency
Renamed curry to callable_left_curry
2019-08-03 17:47:27 +01:00

364 lines
9.5 KiB
PHP

<?php
/**
* Hoa
*
*
* @license
*
* New BSD License
*
* Copyright © 2007-2017, Hoa community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the Hoa nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
namespace Hoa\Consistency
{
/**
* Class Hoa\Consistency\Consistency.
*
* This class is a collection of tools to ensure foreward and backward
* compatibility.
*
* @copyright Copyright © 2007-2017 Hoa community
* @license New BSD License
*/
class Consistency
{
/**
* Check if an entity exists (class, interface, trait…).
*
* @param string $entityName Entity name.
* @param bool $autoloader Run autoloader if necessary.
* @return bool
*/
public static function entityExists($entityName, $autoloader = false)
{
return
class_exists($entityName, $autoloader) ||
interface_exists($entityName, false) ||
trait_exists($entityName, false);
}
/**
* Get the shortest name for an entity.
*
* @param string $entityName Entity name.
* @return string
*/
public static function getEntityShortestName($entityName)
{
$parts = explode('\\', $entityName);
$count = count($parts);
if (1 >= $count) {
return $entityName;
}
if ($parts[$count - 2] === $parts[$count - 1]) {
return implode('\\', array_slice($parts, 0, -1));
}
return $entityName;
}
/**
* Declare a flex entity (for nested library).
*
* @param string $entityName Entity name.
* @return bool
*/
public static function flexEntity($entityName)
{
return class_alias(
$entityName,
static::getEntityShortestName($entityName),
false
);
}
/**
* Whether a word is reserved or not.
*
* @param string $word Word.
* @return bool
*/
public static function isKeyword($word)
{
static $_list = [
// PHP keywords.
'__halt_compiler',
'abstract',
'and',
'array',
'as',
'bool',
'break',
'callable',
'case',
'catch',
'class',
'clone',
'const',
'continue',
'declare',
'default',
'die',
'do',
'echo',
'else',
'elseif',
'empty',
'enddeclare',
'endfor',
'endforeach',
'endif',
'endswitch',
'endwhile',
'eval',
'exit',
'extends',
'false',
'final',
'float',
'for',
'foreach',
'function',
'global',
'goto',
'if',
'implements',
'include',
'include_once',
'instanceof',
'insteadof',
'int',
'interface',
'isset',
'list',
'mixed',
'namespace',
'new',
'null',
'numeric',
'object',
'or',
'print',
'private',
'protected',
'public',
'require',
'require_once',
'resource',
'return',
'static',
'string',
'switch',
'throw',
'trait',
'true',
'try',
'unset',
'use',
'var',
'void',
'while',
'xor',
'yield',
// Compile-time constants.
'__class__',
'__dir__',
'__file__',
'__function__',
'__line__',
'__method__',
'__namespace__',
'__trait__'
];
return in_array(strtolower($word), $_list);
}
/**
* Whether an ID is a valid PHP identifier.
*
* @param string $id ID.
* @return bool
*/
public static function isIdentifier($id)
{
return 0 !== preg_match(
'#^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x80-\xff]*$#',
$id
);
}
/**
* Register a register shutdown function.
* It may be analogous to a super static destructor.
*
* @param callable $callable Callable.
* @return bool
*/
public static function registerShutdownFunction($callable)
{
return register_shutdown_function($callable);
}
/**
* Get PHP executable.
*
* @return string
*/
public static function getPHPBinary()
{
if (defined('PHP_BINARY')) {
return PHP_BINARY;
}
if (isset($_SERVER['_'])) {
return $_SERVER['_'];
}
foreach (['', '.exe'] as $extension) {
if (file_exists($_ = PHP_BINDIR . DS . 'php' . $extension)) {
return realpath($_);
}
}
return null;
}
/**
* Generate an Universal Unique Identifier (UUID).
*
* @return string
*/
public static function uuid()
{
return sprintf(
'%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
mt_rand(0, 0x0fff) | 0x4000,
mt_rand(0, 0x3fff) | 0x8000,
mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
mt_rand(0, 0xffff)
);
}
}
}
namespace
{
if (70000 > PHP_VERSION_ID && false === interface_exists('Throwable', false)) {
/**
* Implement a fake Throwable class, introduced in PHP7.0.
*/
interface Throwable
{
public function getMessage();
public function getCode();
public function getFile();
public function getLine();
public function getTrace();
public function getPrevious();
public function getTraceAsString();
public function __toString();
}
}
/**
* Define TLSv* constants, introduced in PHP 5.5.
*/
if (50600 > PHP_VERSION_ID) {
$define = function ($constantName, $constantValue, $case = false) {
if (!defined($constantName)) {
return define($constantName, $constantValue, $case);
}
return false;
};
$define('STREAM_CRYPTO_METHOD_TLSv1_0_SERVER', 8);
$define('STREAM_CRYPTO_METHOD_TLSv1_1_SERVER', 16);
$define('STREAM_CRYPTO_METHOD_TLSv1_2_SERVER', 32);
$define('STREAM_CRYPTO_METHOD_ANY_SERVER', 62);
$define('STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT', 9);
$define('STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT', 17);
$define('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT', 33);
$define('STREAM_CRYPTO_METHOD_ANY_CLIENT', 63);
}
if (!function_exists('curry')) {
/**
* Curry.
* Example:
* $c = curry('str_replace', …, …, 'foobar');
* var_dump($c('foo', 'baz')); // bazbar
* $c = curry('str_replace', 'foo', 'baz', …);
* var_dump($c('foobarbaz')); // bazbarbaz
* Nested curries also work:
* $c1 = curry('str_replace', …, …, 'foobar');
* $c2 = curry($c1, 'foo', …);
* var_dump($c2('baz')); // bazbar
* Obviously, as the first argument is a callable, we can combine this with
* \Hoa\Consistency\Xcallable ;-).
* The “…” character is the HORIZONTAL ELLIPSIS Unicode character (Unicode:
* 2026, UTF-8: E2 80 A6).
*
* @param mixed $callable Callable (two parts).
* @param ... ... Arguments.
* @return \Closure
*/
function curry($callable)
{
$arguments = func_get_args();
array_shift($arguments);
$ii = array_keys($arguments, , true);
return function () use ($callable, $arguments, $ii) {
return call_user_func_array(
$callable,
array_replace($arguments, array_combine($ii, func_get_args()))
);
};
}
}
/**
* Flex entity.
*/
Hoa\Consistency\Consistency::flexEntity('Hoa\Consistency\Consistency');
}