37 changed files with 17330 additions and 323 deletions
@ -0,0 +1,25 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// autoload.php @generated by Composer |
||||
|
|
||||
|
if (PHP_VERSION_ID < 50600) { |
||||
|
if (!headers_sent()) { |
||||
|
header('HTTP/1.1 500 Internal Server Error'); |
||||
|
} |
||||
|
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL; |
||||
|
if (!ini_get('display_errors')) { |
||||
|
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { |
||||
|
fwrite(STDERR, $err); |
||||
|
} elseif (!headers_sent()) { |
||||
|
echo $err; |
||||
|
} |
||||
|
} |
||||
|
trigger_error( |
||||
|
$err, |
||||
|
E_USER_ERROR |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
require_once __DIR__ . '/composer/autoload_real.php'; |
||||
|
|
||||
|
return ComposerAutoloaderInitc1a2ef5635fca26e353737c00247f58a::getLoader(); |
@ -0,0 +1,579 @@ |
|||||
|
<?php |
||||
|
|
||||
|
/* |
||||
|
* This file is part of Composer. |
||||
|
* |
||||
|
* (c) Nils Adermann <naderman@naderman.de> |
||||
|
* Jordi Boggiano <j.boggiano@seld.be> |
||||
|
* |
||||
|
* For the full copyright and license information, please view the LICENSE |
||||
|
* file that was distributed with this source code. |
||||
|
*/ |
||||
|
|
||||
|
namespace Composer\Autoload; |
||||
|
|
||||
|
/** |
||||
|
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader. |
||||
|
* |
||||
|
* $loader = new \Composer\Autoload\ClassLoader(); |
||||
|
* |
||||
|
* // register classes with namespaces |
||||
|
* $loader->add('Symfony\Component', __DIR__.'/component'); |
||||
|
* $loader->add('Symfony', __DIR__.'/framework'); |
||||
|
* |
||||
|
* // activate the autoloader |
||||
|
* $loader->register(); |
||||
|
* |
||||
|
* // to enable searching the include path (eg. for PEAR packages) |
||||
|
* $loader->setUseIncludePath(true); |
||||
|
* |
||||
|
* In this example, if you try to use a class in the Symfony\Component |
||||
|
* namespace or one of its children (Symfony\Component\Console for instance), |
||||
|
* the autoloader will first look for the class under the component/ |
||||
|
* directory, and it will then fallback to the framework/ directory if not |
||||
|
* found before giving up. |
||||
|
* |
||||
|
* This class is loosely based on the Symfony UniversalClassLoader. |
||||
|
* |
||||
|
* @author Fabien Potencier <fabien@symfony.com> |
||||
|
* @author Jordi Boggiano <j.boggiano@seld.be> |
||||
|
* @see https://www.php-fig.org/psr/psr-0/ |
||||
|
* @see https://www.php-fig.org/psr/psr-4/ |
||||
|
*/ |
||||
|
class ClassLoader |
||||
|
{ |
||||
|
/** @var \Closure(string):void */ |
||||
|
private static $includeFile; |
||||
|
|
||||
|
/** @var string|null */ |
||||
|
private $vendorDir; |
||||
|
|
||||
|
// PSR-4 |
||||
|
/** |
||||
|
* @var array<string, array<string, int>> |
||||
|
*/ |
||||
|
private $prefixLengthsPsr4 = array(); |
||||
|
/** |
||||
|
* @var array<string, list<string>> |
||||
|
*/ |
||||
|
private $prefixDirsPsr4 = array(); |
||||
|
/** |
||||
|
* @var list<string> |
||||
|
*/ |
||||
|
private $fallbackDirsPsr4 = array(); |
||||
|
|
||||
|
// PSR-0 |
||||
|
/** |
||||
|
* List of PSR-0 prefixes |
||||
|
* |
||||
|
* Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2'))) |
||||
|
* |
||||
|
* @var array<string, array<string, list<string>>> |
||||
|
*/ |
||||
|
private $prefixesPsr0 = array(); |
||||
|
/** |
||||
|
* @var list<string> |
||||
|
*/ |
||||
|
private $fallbackDirsPsr0 = array(); |
||||
|
|
||||
|
/** @var bool */ |
||||
|
private $useIncludePath = false; |
||||
|
|
||||
|
/** |
||||
|
* @var array<string, string> |
||||
|
*/ |
||||
|
private $classMap = array(); |
||||
|
|
||||
|
/** @var bool */ |
||||
|
private $classMapAuthoritative = false; |
||||
|
|
||||
|
/** |
||||
|
* @var array<string, bool> |
||||
|
*/ |
||||
|
private $missingClasses = array(); |
||||
|
|
||||
|
/** @var string|null */ |
||||
|
private $apcuPrefix; |
||||
|
|
||||
|
/** |
||||
|
* @var array<string, self> |
||||
|
*/ |
||||
|
private static $registeredLoaders = array(); |
||||
|
|
||||
|
/** |
||||
|
* @param string|null $vendorDir |
||||
|
*/ |
||||
|
public function __construct($vendorDir = null) |
||||
|
{ |
||||
|
$this->vendorDir = $vendorDir; |
||||
|
self::initializeIncludeClosure(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return array<string, list<string>> |
||||
|
*/ |
||||
|
public function getPrefixes() |
||||
|
{ |
||||
|
if (!empty($this->prefixesPsr0)) { |
||||
|
return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); |
||||
|
} |
||||
|
|
||||
|
return array(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return array<string, list<string>> |
||||
|
*/ |
||||
|
public function getPrefixesPsr4() |
||||
|
{ |
||||
|
return $this->prefixDirsPsr4; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return list<string> |
||||
|
*/ |
||||
|
public function getFallbackDirs() |
||||
|
{ |
||||
|
return $this->fallbackDirsPsr0; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return list<string> |
||||
|
*/ |
||||
|
public function getFallbackDirsPsr4() |
||||
|
{ |
||||
|
return $this->fallbackDirsPsr4; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return array<string, string> Array of classname => path |
||||
|
*/ |
||||
|
public function getClassMap() |
||||
|
{ |
||||
|
return $this->classMap; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param array<string, string> $classMap Class to filename map |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function addClassMap(array $classMap) |
||||
|
{ |
||||
|
if ($this->classMap) { |
||||
|
$this->classMap = array_merge($this->classMap, $classMap); |
||||
|
} else { |
||||
|
$this->classMap = $classMap; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Registers a set of PSR-0 directories for a given prefix, either |
||||
|
* appending or prepending to the ones previously set for this prefix. |
||||
|
* |
||||
|
* @param string $prefix The prefix |
||||
|
* @param list<string>|string $paths The PSR-0 root directories |
||||
|
* @param bool $prepend Whether to prepend the directories |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function add($prefix, $paths, $prepend = false) |
||||
|
{ |
||||
|
$paths = (array) $paths; |
||||
|
if (!$prefix) { |
||||
|
if ($prepend) { |
||||
|
$this->fallbackDirsPsr0 = array_merge( |
||||
|
$paths, |
||||
|
$this->fallbackDirsPsr0 |
||||
|
); |
||||
|
} else { |
||||
|
$this->fallbackDirsPsr0 = array_merge( |
||||
|
$this->fallbackDirsPsr0, |
||||
|
$paths |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
$first = $prefix[0]; |
||||
|
if (!isset($this->prefixesPsr0[$first][$prefix])) { |
||||
|
$this->prefixesPsr0[$first][$prefix] = $paths; |
||||
|
|
||||
|
return; |
||||
|
} |
||||
|
if ($prepend) { |
||||
|
$this->prefixesPsr0[$first][$prefix] = array_merge( |
||||
|
$paths, |
||||
|
$this->prefixesPsr0[$first][$prefix] |
||||
|
); |
||||
|
} else { |
||||
|
$this->prefixesPsr0[$first][$prefix] = array_merge( |
||||
|
$this->prefixesPsr0[$first][$prefix], |
||||
|
$paths |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Registers a set of PSR-4 directories for a given namespace, either |
||||
|
* appending or prepending to the ones previously set for this namespace. |
||||
|
* |
||||
|
* @param string $prefix The prefix/namespace, with trailing '\\' |
||||
|
* @param list<string>|string $paths The PSR-4 base directories |
||||
|
* @param bool $prepend Whether to prepend the directories |
||||
|
* |
||||
|
* @throws \InvalidArgumentException |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function addPsr4($prefix, $paths, $prepend = false) |
||||
|
{ |
||||
|
$paths = (array) $paths; |
||||
|
if (!$prefix) { |
||||
|
// Register directories for the root namespace. |
||||
|
if ($prepend) { |
||||
|
$this->fallbackDirsPsr4 = array_merge( |
||||
|
$paths, |
||||
|
$this->fallbackDirsPsr4 |
||||
|
); |
||||
|
} else { |
||||
|
$this->fallbackDirsPsr4 = array_merge( |
||||
|
$this->fallbackDirsPsr4, |
||||
|
$paths |
||||
|
); |
||||
|
} |
||||
|
} elseif (!isset($this->prefixDirsPsr4[$prefix])) { |
||||
|
// Register directories for a new namespace. |
||||
|
$length = strlen($prefix); |
||||
|
if ('\\' !== $prefix[$length - 1]) { |
||||
|
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); |
||||
|
} |
||||
|
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; |
||||
|
$this->prefixDirsPsr4[$prefix] = $paths; |
||||
|
} elseif ($prepend) { |
||||
|
// Prepend directories for an already registered namespace. |
||||
|
$this->prefixDirsPsr4[$prefix] = array_merge( |
||||
|
$paths, |
||||
|
$this->prefixDirsPsr4[$prefix] |
||||
|
); |
||||
|
} else { |
||||
|
// Append directories for an already registered namespace. |
||||
|
$this->prefixDirsPsr4[$prefix] = array_merge( |
||||
|
$this->prefixDirsPsr4[$prefix], |
||||
|
$paths |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Registers a set of PSR-0 directories for a given prefix, |
||||
|
* replacing any others previously set for this prefix. |
||||
|
* |
||||
|
* @param string $prefix The prefix |
||||
|
* @param list<string>|string $paths The PSR-0 base directories |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function set($prefix, $paths) |
||||
|
{ |
||||
|
if (!$prefix) { |
||||
|
$this->fallbackDirsPsr0 = (array) $paths; |
||||
|
} else { |
||||
|
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Registers a set of PSR-4 directories for a given namespace, |
||||
|
* replacing any others previously set for this namespace. |
||||
|
* |
||||
|
* @param string $prefix The prefix/namespace, with trailing '\\' |
||||
|
* @param list<string>|string $paths The PSR-4 base directories |
||||
|
* |
||||
|
* @throws \InvalidArgumentException |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function setPsr4($prefix, $paths) |
||||
|
{ |
||||
|
if (!$prefix) { |
||||
|
$this->fallbackDirsPsr4 = (array) $paths; |
||||
|
} else { |
||||
|
$length = strlen($prefix); |
||||
|
if ('\\' !== $prefix[$length - 1]) { |
||||
|
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); |
||||
|
} |
||||
|
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; |
||||
|
$this->prefixDirsPsr4[$prefix] = (array) $paths; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Turns on searching the include path for class files. |
||||
|
* |
||||
|
* @param bool $useIncludePath |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function setUseIncludePath($useIncludePath) |
||||
|
{ |
||||
|
$this->useIncludePath = $useIncludePath; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Can be used to check if the autoloader uses the include path to check |
||||
|
* for classes. |
||||
|
* |
||||
|
* @return bool |
||||
|
*/ |
||||
|
public function getUseIncludePath() |
||||
|
{ |
||||
|
return $this->useIncludePath; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Turns off searching the prefix and fallback directories for classes |
||||
|
* that have not been registered with the class map. |
||||
|
* |
||||
|
* @param bool $classMapAuthoritative |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function setClassMapAuthoritative($classMapAuthoritative) |
||||
|
{ |
||||
|
$this->classMapAuthoritative = $classMapAuthoritative; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Should class lookup fail if not found in the current class map? |
||||
|
* |
||||
|
* @return bool |
||||
|
*/ |
||||
|
public function isClassMapAuthoritative() |
||||
|
{ |
||||
|
return $this->classMapAuthoritative; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* APCu prefix to use to cache found/not-found classes, if the extension is enabled. |
||||
|
* |
||||
|
* @param string|null $apcuPrefix |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function setApcuPrefix($apcuPrefix) |
||||
|
{ |
||||
|
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* The APCu prefix in use, or null if APCu caching is not enabled. |
||||
|
* |
||||
|
* @return string|null |
||||
|
*/ |
||||
|
public function getApcuPrefix() |
||||
|
{ |
||||
|
return $this->apcuPrefix; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Registers this instance as an autoloader. |
||||
|
* |
||||
|
* @param bool $prepend Whether to prepend the autoloader or not |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function register($prepend = false) |
||||
|
{ |
||||
|
spl_autoload_register(array($this, 'loadClass'), true, $prepend); |
||||
|
|
||||
|
if (null === $this->vendorDir) { |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if ($prepend) { |
||||
|
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; |
||||
|
} else { |
||||
|
unset(self::$registeredLoaders[$this->vendorDir]); |
||||
|
self::$registeredLoaders[$this->vendorDir] = $this; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Unregisters this instance as an autoloader. |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function unregister() |
||||
|
{ |
||||
|
spl_autoload_unregister(array($this, 'loadClass')); |
||||
|
|
||||
|
if (null !== $this->vendorDir) { |
||||
|
unset(self::$registeredLoaders[$this->vendorDir]); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Loads the given class or interface. |
||||
|
* |
||||
|
* @param string $class The name of the class |
||||
|
* @return true|null True if loaded, null otherwise |
||||
|
*/ |
||||
|
public function loadClass($class) |
||||
|
{ |
||||
|
if ($file = $this->findFile($class)) { |
||||
|
$includeFile = self::$includeFile; |
||||
|
$includeFile($file); |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Finds the path to the file where the class is defined. |
||||
|
* |
||||
|
* @param string $class The name of the class |
||||
|
* |
||||
|
* @return string|false The path if found, false otherwise |
||||
|
*/ |
||||
|
public function findFile($class) |
||||
|
{ |
||||
|
// class map lookup |
||||
|
if (isset($this->classMap[$class])) { |
||||
|
return $this->classMap[$class]; |
||||
|
} |
||||
|
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { |
||||
|
return false; |
||||
|
} |
||||
|
if (null !== $this->apcuPrefix) { |
||||
|
$file = apcu_fetch($this->apcuPrefix.$class, $hit); |
||||
|
if ($hit) { |
||||
|
return $file; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
$file = $this->findFileWithExtension($class, '.php'); |
||||
|
|
||||
|
// Search for Hack files if we are running on HHVM |
||||
|
if (false === $file && defined('HHVM_VERSION')) { |
||||
|
$file = $this->findFileWithExtension($class, '.hh'); |
||||
|
} |
||||
|
|
||||
|
if (null !== $this->apcuPrefix) { |
||||
|
apcu_add($this->apcuPrefix.$class, $file); |
||||
|
} |
||||
|
|
||||
|
if (false === $file) { |
||||
|
// Remember that this class does not exist. |
||||
|
$this->missingClasses[$class] = true; |
||||
|
} |
||||
|
|
||||
|
return $file; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Returns the currently registered loaders keyed by their corresponding vendor directories. |
||||
|
* |
||||
|
* @return array<string, self> |
||||
|
*/ |
||||
|
public static function getRegisteredLoaders() |
||||
|
{ |
||||
|
return self::$registeredLoaders; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param string $class |
||||
|
* @param string $ext |
||||
|
* @return string|false |
||||
|
*/ |
||||
|
private function findFileWithExtension($class, $ext) |
||||
|
{ |
||||
|
// PSR-4 lookup |
||||
|
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; |
||||
|
|
||||
|
$first = $class[0]; |
||||
|
if (isset($this->prefixLengthsPsr4[$first])) { |
||||
|
$subPath = $class; |
||||
|
while (false !== $lastPos = strrpos($subPath, '\\')) { |
||||
|
$subPath = substr($subPath, 0, $lastPos); |
||||
|
$search = $subPath . '\\'; |
||||
|
if (isset($this->prefixDirsPsr4[$search])) { |
||||
|
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); |
||||
|
foreach ($this->prefixDirsPsr4[$search] as $dir) { |
||||
|
if (file_exists($file = $dir . $pathEnd)) { |
||||
|
return $file; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// PSR-4 fallback dirs |
||||
|
foreach ($this->fallbackDirsPsr4 as $dir) { |
||||
|
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { |
||||
|
return $file; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// PSR-0 lookup |
||||
|
if (false !== $pos = strrpos($class, '\\')) { |
||||
|
// namespaced class name |
||||
|
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) |
||||
|
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); |
||||
|
} else { |
||||
|
// PEAR-like class name |
||||
|
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; |
||||
|
} |
||||
|
|
||||
|
if (isset($this->prefixesPsr0[$first])) { |
||||
|
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { |
||||
|
if (0 === strpos($class, $prefix)) { |
||||
|
foreach ($dirs as $dir) { |
||||
|
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { |
||||
|
return $file; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// PSR-0 fallback dirs |
||||
|
foreach ($this->fallbackDirsPsr0 as $dir) { |
||||
|
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { |
||||
|
return $file; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// PSR-0 include paths. |
||||
|
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { |
||||
|
return $file; |
||||
|
} |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return void |
||||
|
*/ |
||||
|
private static function initializeIncludeClosure() |
||||
|
{ |
||||
|
if (self::$includeFile !== null) { |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Scope isolated include. |
||||
|
* |
||||
|
* Prevents access to $this/self from included files. |
||||
|
* |
||||
|
* @param string $file |
||||
|
* @return void |
||||
|
*/ |
||||
|
self::$includeFile = \Closure::bind(static function($file) { |
||||
|
include $file; |
||||
|
}, null, null); |
||||
|
} |
||||
|
} |
@ -0,0 +1,359 @@ |
|||||
|
<?php |
||||
|
|
||||
|
/* |
||||
|
* This file is part of Composer. |
||||
|
* |
||||
|
* (c) Nils Adermann <naderman@naderman.de> |
||||
|
* Jordi Boggiano <j.boggiano@seld.be> |
||||
|
* |
||||
|
* For the full copyright and license information, please view the LICENSE |
||||
|
* file that was distributed with this source code. |
||||
|
*/ |
||||
|
|
||||
|
namespace Composer; |
||||
|
|
||||
|
use Composer\Autoload\ClassLoader; |
||||
|
use Composer\Semver\VersionParser; |
||||
|
|
||||
|
/** |
||||
|
* This class is copied in every Composer installed project and available to all |
||||
|
* |
||||
|
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions |
||||
|
* |
||||
|
* To require its presence, you can require `composer-runtime-api ^2.0` |
||||
|
* |
||||
|
* @final |
||||
|
*/ |
||||
|
class InstalledVersions |
||||
|
{ |
||||
|
/** |
||||
|
* @var mixed[]|null |
||||
|
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null |
||||
|
*/ |
||||
|
private static $installed; |
||||
|
|
||||
|
/** |
||||
|
* @var bool|null |
||||
|
*/ |
||||
|
private static $canGetVendors; |
||||
|
|
||||
|
/** |
||||
|
* @var array[] |
||||
|
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}> |
||||
|
*/ |
||||
|
private static $installedByVendor = array(); |
||||
|
|
||||
|
/** |
||||
|
* Returns a list of all package names which are present, either by being installed, replaced or provided |
||||
|
* |
||||
|
* @return string[] |
||||
|
* @psalm-return list<string> |
||||
|
*/ |
||||
|
public static function getInstalledPackages() |
||||
|
{ |
||||
|
$packages = array(); |
||||
|
foreach (self::getInstalled() as $installed) { |
||||
|
$packages[] = array_keys($installed['versions']); |
||||
|
} |
||||
|
|
||||
|
if (1 === \count($packages)) { |
||||
|
return $packages[0]; |
||||
|
} |
||||
|
|
||||
|
return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Returns a list of all package names with a specific type e.g. 'library' |
||||
|
* |
||||
|
* @param string $type |
||||
|
* @return string[] |
||||
|
* @psalm-return list<string> |
||||
|
*/ |
||||
|
public static function getInstalledPackagesByType($type) |
||||
|
{ |
||||
|
$packagesByType = array(); |
||||
|
|
||||
|
foreach (self::getInstalled() as $installed) { |
||||
|
foreach ($installed['versions'] as $name => $package) { |
||||
|
if (isset($package['type']) && $package['type'] === $type) { |
||||
|
$packagesByType[] = $name; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return $packagesByType; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Checks whether the given package is installed |
||||
|
* |
||||
|
* This also returns true if the package name is provided or replaced by another package |
||||
|
* |
||||
|
* @param string $packageName |
||||
|
* @param bool $includeDevRequirements |
||||
|
* @return bool |
||||
|
*/ |
||||
|
public static function isInstalled($packageName, $includeDevRequirements = true) |
||||
|
{ |
||||
|
foreach (self::getInstalled() as $installed) { |
||||
|
if (isset($installed['versions'][$packageName])) { |
||||
|
return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Checks whether the given package satisfies a version constraint |
||||
|
* |
||||
|
* e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call: |
||||
|
* |
||||
|
* Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3') |
||||
|
* |
||||
|
* @param VersionParser $parser Install composer/semver to have access to this class and functionality |
||||
|
* @param string $packageName |
||||
|
* @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package |
||||
|
* @return bool |
||||
|
*/ |
||||
|
public static function satisfies(VersionParser $parser, $packageName, $constraint) |
||||
|
{ |
||||
|
$constraint = $parser->parseConstraints((string) $constraint); |
||||
|
$provided = $parser->parseConstraints(self::getVersionRanges($packageName)); |
||||
|
|
||||
|
return $provided->matches($constraint); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Returns a version constraint representing all the range(s) which are installed for a given package |
||||
|
* |
||||
|
* It is easier to use this via isInstalled() with the $constraint argument if you need to check |
||||
|
* whether a given version of a package is installed, and not just whether it exists |
||||
|
* |
||||
|
* @param string $packageName |
||||
|
* @return string Version constraint usable with composer/semver |
||||
|
*/ |
||||
|
public static function getVersionRanges($packageName) |
||||
|
{ |
||||
|
foreach (self::getInstalled() as $installed) { |
||||
|
if (!isset($installed['versions'][$packageName])) { |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
$ranges = array(); |
||||
|
if (isset($installed['versions'][$packageName]['pretty_version'])) { |
||||
|
$ranges[] = $installed['versions'][$packageName]['pretty_version']; |
||||
|
} |
||||
|
if (array_key_exists('aliases', $installed['versions'][$packageName])) { |
||||
|
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); |
||||
|
} |
||||
|
if (array_key_exists('replaced', $installed['versions'][$packageName])) { |
||||
|
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); |
||||
|
} |
||||
|
if (array_key_exists('provided', $installed['versions'][$packageName])) { |
||||
|
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); |
||||
|
} |
||||
|
|
||||
|
return implode(' || ', $ranges); |
||||
|
} |
||||
|
|
||||
|
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param string $packageName |
||||
|
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present |
||||
|
*/ |
||||
|
public static function getVersion($packageName) |
||||
|
{ |
||||
|
foreach (self::getInstalled() as $installed) { |
||||
|
if (!isset($installed['versions'][$packageName])) { |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
if (!isset($installed['versions'][$packageName]['version'])) { |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
return $installed['versions'][$packageName]['version']; |
||||
|
} |
||||
|
|
||||
|
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param string $packageName |
||||
|
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present |
||||
|
*/ |
||||
|
public static function getPrettyVersion($packageName) |
||||
|
{ |
||||
|
foreach (self::getInstalled() as $installed) { |
||||
|
if (!isset($installed['versions'][$packageName])) { |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
if (!isset($installed['versions'][$packageName]['pretty_version'])) { |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
return $installed['versions'][$packageName]['pretty_version']; |
||||
|
} |
||||
|
|
||||
|
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param string $packageName |
||||
|
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference |
||||
|
*/ |
||||
|
public static function getReference($packageName) |
||||
|
{ |
||||
|
foreach (self::getInstalled() as $installed) { |
||||
|
if (!isset($installed['versions'][$packageName])) { |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
if (!isset($installed['versions'][$packageName]['reference'])) { |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
return $installed['versions'][$packageName]['reference']; |
||||
|
} |
||||
|
|
||||
|
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param string $packageName |
||||
|
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path. |
||||
|
*/ |
||||
|
public static function getInstallPath($packageName) |
||||
|
{ |
||||
|
foreach (self::getInstalled() as $installed) { |
||||
|
if (!isset($installed['versions'][$packageName])) { |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null; |
||||
|
} |
||||
|
|
||||
|
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return array |
||||
|
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool} |
||||
|
*/ |
||||
|
public static function getRootPackage() |
||||
|
{ |
||||
|
$installed = self::getInstalled(); |
||||
|
|
||||
|
return $installed[0]['root']; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Returns the raw installed.php data for custom implementations |
||||
|
* |
||||
|
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. |
||||
|
* @return array[] |
||||
|
* @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} |
||||
|
*/ |
||||
|
public static function getRawData() |
||||
|
{ |
||||
|
@trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED); |
||||
|
|
||||
|
if (null === self::$installed) { |
||||
|
// only require the installed.php file if this file is loaded from its dumped location, |
||||
|
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 |
||||
|
if (substr(__DIR__, -8, 1) !== 'C') { |
||||
|
self::$installed = include __DIR__ . '/installed.php'; |
||||
|
} else { |
||||
|
self::$installed = array(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return self::$installed; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Returns the raw data of all installed.php which are currently loaded for custom implementations |
||||
|
* |
||||
|
* @return array[] |
||||
|
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}> |
||||
|
*/ |
||||
|
public static function getAllRawData() |
||||
|
{ |
||||
|
return self::getInstalled(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Lets you reload the static array from another file |
||||
|
* |
||||
|
* This is only useful for complex integrations in which a project needs to use |
||||
|
* this class but then also needs to execute another project's autoloader in process, |
||||
|
* and wants to ensure both projects have access to their version of installed.php. |
||||
|
* |
||||
|
* A typical case would be PHPUnit, where it would need to make sure it reads all |
||||
|
* the data it needs from this class, then call reload() with |
||||
|
* `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure |
||||
|
* the project in which it runs can then also use this class safely, without |
||||
|
* interference between PHPUnit's dependencies and the project's dependencies. |
||||
|
* |
||||
|
* @param array[] $data A vendor/composer/installed.php data set |
||||
|
* @return void |
||||
|
* |
||||
|
* @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data |
||||
|
*/ |
||||
|
public static function reload($data) |
||||
|
{ |
||||
|
self::$installed = $data; |
||||
|
self::$installedByVendor = array(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return array[] |
||||
|
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}> |
||||
|
*/ |
||||
|
private static function getInstalled() |
||||
|
{ |
||||
|
if (null === self::$canGetVendors) { |
||||
|
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); |
||||
|
} |
||||
|
|
||||
|
$installed = array(); |
||||
|
|
||||
|
if (self::$canGetVendors) { |
||||
|
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { |
||||
|
if (isset(self::$installedByVendor[$vendorDir])) { |
||||
|
$installed[] = self::$installedByVendor[$vendorDir]; |
||||
|
} elseif (is_file($vendorDir.'/composer/installed.php')) { |
||||
|
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */ |
||||
|
$required = require $vendorDir.'/composer/installed.php'; |
||||
|
$installed[] = self::$installedByVendor[$vendorDir] = $required; |
||||
|
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { |
||||
|
self::$installed = $installed[count($installed) - 1]; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (null === self::$installed) { |
||||
|
// only require the installed.php file if this file is loaded from its dumped location, |
||||
|
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 |
||||
|
if (substr(__DIR__, -8, 1) !== 'C') { |
||||
|
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */ |
||||
|
$required = require __DIR__ . '/installed.php'; |
||||
|
self::$installed = $required; |
||||
|
} else { |
||||
|
self::$installed = array(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (self::$installed !== array()) { |
||||
|
$installed[] = self::$installed; |
||||
|
} |
||||
|
|
||||
|
return $installed; |
||||
|
} |
||||
|
} |
@ -0,0 +1,21 @@ |
|||||
|
|
||||
|
Copyright (c) Nils Adermann, Jordi Boggiano |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
|
of this software and associated documentation files (the "Software"), to deal |
||||
|
in the Software without restriction, including without limitation the rights |
||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
copies of the Software, and to permit persons to whom the Software is furnished |
||||
|
to do so, subject to the following conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be included in all |
||||
|
copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||
|
THE SOFTWARE. |
||||
|
|
@ -0,0 +1,10 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// autoload_classmap.php @generated by Composer |
||||
|
|
||||
|
$vendorDir = dirname(__DIR__); |
||||
|
$baseDir = dirname($vendorDir); |
||||
|
|
||||
|
return array( |
||||
|
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', |
||||
|
); |
@ -0,0 +1,9 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// autoload_namespaces.php @generated by Composer |
||||
|
|
||||
|
$vendorDir = dirname(__DIR__); |
||||
|
$baseDir = dirname($vendorDir); |
||||
|
|
||||
|
return array( |
||||
|
); |
@ -0,0 +1,10 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// autoload_psr4.php @generated by Composer |
||||
|
|
||||
|
$vendorDir = dirname(__DIR__); |
||||
|
$baseDir = dirname($vendorDir); |
||||
|
|
||||
|
return array( |
||||
|
'sqhlib\\Hanzi\\' => array($vendorDir . '/sqhlib/hanzi-convert/src'), |
||||
|
); |
@ -0,0 +1,36 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// autoload_real.php @generated by Composer |
||||
|
|
||||
|
class ComposerAutoloaderInitc1a2ef5635fca26e353737c00247f58a |
||||
|
{ |
||||
|
private static $loader; |
||||
|
|
||||
|
public static function loadClassLoader($class) |
||||
|
{ |
||||
|
if ('Composer\Autoload\ClassLoader' === $class) { |
||||
|
require __DIR__ . '/ClassLoader.php'; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return \Composer\Autoload\ClassLoader |
||||
|
*/ |
||||
|
public static function getLoader() |
||||
|
{ |
||||
|
if (null !== self::$loader) { |
||||
|
return self::$loader; |
||||
|
} |
||||
|
|
||||
|
spl_autoload_register(array('ComposerAutoloaderInitc1a2ef5635fca26e353737c00247f58a', 'loadClassLoader'), true, true); |
||||
|
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); |
||||
|
spl_autoload_unregister(array('ComposerAutoloaderInitc1a2ef5635fca26e353737c00247f58a', 'loadClassLoader')); |
||||
|
|
||||
|
require __DIR__ . '/autoload_static.php'; |
||||
|
call_user_func(\Composer\Autoload\ComposerStaticInitc1a2ef5635fca26e353737c00247f58a::getInitializer($loader)); |
||||
|
|
||||
|
$loader->register(true); |
||||
|
|
||||
|
return $loader; |
||||
|
} |
||||
|
} |
@ -0,0 +1,36 @@ |
|||||
|
<?php |
||||
|
|
||||
|
// autoload_static.php @generated by Composer |
||||
|
|
||||
|
namespace Composer\Autoload; |
||||
|
|
||||
|
class ComposerStaticInitc1a2ef5635fca26e353737c00247f58a |
||||
|
{ |
||||
|
public static $prefixLengthsPsr4 = array ( |
||||
|
's' => |
||||
|
array ( |
||||
|
'sqhlib\\Hanzi\\' => 13, |
||||
|
), |
||||
|
); |
||||
|
|
||||
|
public static $prefixDirsPsr4 = array ( |
||||
|
'sqhlib\\Hanzi\\' => |
||||
|
array ( |
||||
|
0 => __DIR__ . '/..' . '/sqhlib/hanzi-convert/src', |
||||
|
), |
||||
|
); |
||||
|
|
||||
|
public static $classMap = array ( |
||||
|
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', |
||||
|
); |
||||
|
|
||||
|
public static function getInitializer(ClassLoader $loader) |
||||
|
{ |
||||
|
return \Closure::bind(function () use ($loader) { |
||||
|
$loader->prefixLengthsPsr4 = ComposerStaticInitc1a2ef5635fca26e353737c00247f58a::$prefixLengthsPsr4; |
||||
|
$loader->prefixDirsPsr4 = ComposerStaticInitc1a2ef5635fca26e353737c00247f58a::$prefixDirsPsr4; |
||||
|
$loader->classMap = ComposerStaticInitc1a2ef5635fca26e353737c00247f58a::$classMap; |
||||
|
|
||||
|
}, null, ClassLoader::class); |
||||
|
} |
||||
|
} |
@ -0,0 +1,45 @@ |
|||||
|
{ |
||||
|
"packages": [ |
||||
|
{ |
||||
|
"name": "sqhlib/hanzi-convert", |
||||
|
"version": "1.1", |
||||
|
"version_normalized": "1.1.0.0", |
||||
|
"source": { |
||||
|
"type": "git", |
||||
|
"url": "https://github.com/uutool/hanzi-convert.git", |
||||
|
"reference": "ec3afe9ec3fd3af965291ec9cd3f7f1955010da1" |
||||
|
}, |
||||
|
"dist": { |
||||
|
"type": "zip", |
||||
|
"url": "https://api.github.com/repos/uutool/hanzi-convert/zipball/ec3afe9ec3fd3af965291ec9cd3f7f1955010da1", |
||||
|
"reference": "ec3afe9ec3fd3af965291ec9cd3f7f1955010da1", |
||||
|
"shasum": "" |
||||
|
}, |
||||
|
"time": "2018-06-29T07:56:45+00:00", |
||||
|
"type": "library", |
||||
|
"installation-source": "dist", |
||||
|
"autoload": { |
||||
|
"psr-4": { |
||||
|
"sqhlib\\Hanzi\\": "src" |
||||
|
} |
||||
|
}, |
||||
|
"notification-url": "https://packagist.org/downloads/", |
||||
|
"license": [ |
||||
|
"MIT" |
||||
|
], |
||||
|
"authors": [ |
||||
|
{ |
||||
|
"name": "sqh" |
||||
|
} |
||||
|
], |
||||
|
"description": "PHP中文繁简体字转换程序,支持繁体转简体或简体转繁体", |
||||
|
"support": { |
||||
|
"issues": "https://github.com/uutool/hanzi-convert/issues", |
||||
|
"source": "https://github.com/uutool/hanzi-convert/tree/1.1" |
||||
|
}, |
||||
|
"install-path": "../sqhlib/hanzi-convert" |
||||
|
} |
||||
|
], |
||||
|
"dev": true, |
||||
|
"dev-package-names": [] |
||||
|
} |
@ -0,0 +1,32 @@ |
|||||
|
<?php return array( |
||||
|
'root' => array( |
||||
|
'name' => '__root__', |
||||
|
'pretty_version' => '1.0.0+no-version-set', |
||||
|
'version' => '1.0.0.0', |
||||
|
'reference' => null, |
||||
|
'type' => 'library', |
||||
|
'install_path' => __DIR__ . '/../../', |
||||
|
'aliases' => array(), |
||||
|
'dev' => true, |
||||
|
), |
||||
|
'versions' => array( |
||||
|
'__root__' => array( |
||||
|
'pretty_version' => '1.0.0+no-version-set', |
||||
|
'version' => '1.0.0.0', |
||||
|
'reference' => null, |
||||
|
'type' => 'library', |
||||
|
'install_path' => __DIR__ . '/../../', |
||||
|
'aliases' => array(), |
||||
|
'dev_requirement' => false, |
||||
|
), |
||||
|
'sqhlib/hanzi-convert' => array( |
||||
|
'pretty_version' => '1.1', |
||||
|
'version' => '1.1.0.0', |
||||
|
'reference' => 'ec3afe9ec3fd3af965291ec9cd3f7f1955010da1', |
||||
|
'type' => 'library', |
||||
|
'install_path' => __DIR__ . '/../sqhlib/hanzi-convert', |
||||
|
'aliases' => array(), |
||||
|
'dev_requirement' => false, |
||||
|
), |
||||
|
), |
||||
|
); |
@ -0,0 +1,3 @@ |
|||||
|
/vendor/ |
||||
|
*.lock |
||||
|
/.idea/ |
@ -0,0 +1,29 @@ |
|||||
|
# PHP 中文繁简体字转换 |
||||
|
汉字中文繁简体转换,繁体转简体,简体转繁体,最全字库,共15356个 |
||||
|
|
||||
|
## 关于字库 |
||||
|
之前使用过几个繁简体转换程序,发现其内置的字库都是日常生活常用字,对于一些古诗之类的有比较多繁体字的字符串,很多繁体字无法转换,故网络收集整理了这份相对比较全的字库,共收录了15356个繁体字,能够比较好的满足有较多生僻繁体字转换的需求。 |
||||
|
|
||||
|
|
||||
|
## 使用方法 |
||||
|
|
||||
|
``` |
||||
|
use sqhlib\Hanzi\HanziConvert; |
||||
|
|
||||
|
//繁体转简体 |
||||
|
$str = '平時已秉班揚筆,暇處不妨甘石經。吾里忻傳日邊信,君言頻中斗杓星。會稽夫子餘詩禮,巴蜀君平舊典型。歷歷周天三百度,更參璿玉到虞廷。'; |
||||
|
echo HanziConvert::convert($str); |
||||
|
|
||||
|
//简体转繁体 |
||||
|
$str = '平时已秉班扬笔,暇处不妨甘石经。吾里忻传日边信,君言频中斗杓星。会稽夫子余诗礼,巴蜀君平旧典型。歷歷周天三百度,更参璇玉到虞廷。'; |
||||
|
echo HanziConvert::convert($str,1); |
||||
|
|
||||
|
``` |
||||
|
|
||||
|
## 注意事项 |
||||
|
由于在中文中,一个简体字有的有多个繁体字写法,因此不能保证从繁体转成简体后再转成繁体和之前字形一样。 |
||||
|
|
||||
|
|
||||
|
## 完善代码 |
||||
|
期望大家一起参与进来,共同完善词库~ |
||||
|
|
@ -0,0 +1,16 @@ |
|||||
|
{ |
||||
|
"name": "sqhlib/hanzi-convert", |
||||
|
"description": "PHP中文繁简体字转换程序,支持繁体转简体或简体转繁体", |
||||
|
"license": "MIT", |
||||
|
"authors": [ |
||||
|
{ |
||||
|
"name": "sqh" |
||||
|
} |
||||
|
], |
||||
|
"require": {}, |
||||
|
"autoload": { |
||||
|
"psr-4": { |
||||
|
"sqhlib\\Hanzi\\": "src" |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,21 @@ |
|||||
|
<?php |
||||
|
/** |
||||
|
* PHP转换程序示例代码 |
||||
|
* |
||||
|
*/ |
||||
|
|
||||
|
use sqhlib\Hanzi\HanziConvert; |
||||
|
|
||||
|
include "vendor/autoload.php"; |
||||
|
|
||||
|
//繁体转简体 |
||||
|
echo '繁体转简体:<br/>'; |
||||
|
$str = '平時已秉班揚筆,暇處不妨甘石經。吾里忻傳日邊信,君言頻中斗杓星。會稽夫子餘詩禮,巴蜀君平舊典型。歷歷周天三百度,更參璿玉到虞廷。'; |
||||
|
echo HanziConvert::convert($str); |
||||
|
|
||||
|
echo "<br/><br/>"; |
||||
|
|
||||
|
//简体转繁体 |
||||
|
echo '简体转繁体:<br/>'; |
||||
|
$str = '平时已秉班扬笔,暇处不妨甘石经。吾里忻传日边信,君言频中斗杓星。会稽夫子余诗礼,巴蜀君平旧典型。歷歷周天三百度,更参璇玉到虞廷。'; |
||||
|
echo HanziConvert::convert($str,1); |
@ -0,0 +1,65 @@ |
|||||
|
<?php |
||||
|
namespace sqhlib\Hanzi; |
||||
|
|
||||
|
/** |
||||
|
* 汉字转换,繁体转简体或简体转繁体 |
||||
|
* |
||||
|
* 如需还有未收录的字库,请打开HanziDict.php文件添加 |
||||
|
* |
||||
|
*/ |
||||
|
class HanziConvert |
||||
|
{ |
||||
|
private static $hanziDict;//繁体->简体数组 |
||||
|
private static $hanziReverseDict;//简体->繁体数组 |
||||
|
|
||||
|
/** |
||||
|
* 执行文字转换 |
||||
|
* |
||||
|
* @param string $str 需要转换的字符串 |
||||
|
* @param boolean $isSc2tc 是否是简体转繁体 |
||||
|
* @return string 转换后的字符串 |
||||
|
*/ |
||||
|
public static function convert($str, $isSc2tc = false) |
||||
|
{ |
||||
|
//检查输入参数 |
||||
|
if (empty($str)) { |
||||
|
return $str; |
||||
|
} |
||||
|
|
||||
|
//初始化字库 |
||||
|
self::initConvert($isSc2tc); |
||||
|
|
||||
|
//开始处理 |
||||
|
$strArr = preg_split('/(?<!^)(?!$)/u', $str);//将字符串转成数组 |
||||
|
array_walk($strArr, function (&$value) use ($isSc2tc) {//循环处理字符 |
||||
|
if ($isSc2tc) {//如果是简体转繁体 |
||||
|
$value = isset(self::$hanziReverseDict[$value]) ? self::$hanziReverseDict[$value] : $value; |
||||
|
} else { |
||||
|
$value = isset(self::$hanziDict[$value]) ? self::$hanziDict[$value] : $value; |
||||
|
} |
||||
|
}); |
||||
|
return implode('', $strArr);//将数组合并成字符串 |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 初始化中文转换 |
||||
|
* |
||||
|
* @param boolean $isSC2tc 是否是简体转繁体 |
||||
|
* |
||||
|
*/ |
||||
|
public static function initConvert($isSC2tc = false) |
||||
|
{ |
||||
|
if ($isSC2tc) { |
||||
|
if (empty(self::$hanziReverseDict)) { |
||||
|
self::$hanziReverseDict = require('HanziDict.php'); |
||||
|
self::$hanziReverseDict = array_flip(self::$hanziReverseDict);//繁简体数组翻转 |
||||
|
} |
||||
|
} else { |
||||
|
if (empty(self::$hanziDict)) { |
||||
|
self::$hanziDict = require('HanziDict.php'); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
File diff suppressed because it is too large
@ -1,323 +1,15 @@ |
|||||
<?php |
<?php |
||||
|
require_once __DIR__ . '/class/vendor/autoload.php'; |
||||
|
|
||||
// 数据库连接信息 |
use sqhlib\Hanzi\HanziConvert; |
||||
$servername = "localhost"; |
|
||||
$username = "masadaroot"; |
|
||||
$password = 'x6h5E5p#u8y'; // 数据库密码 |
|
||||
$database = 'appwms'; // 数据库名称 |
|
||||
|
|
||||
// 建立数据库连接 |
|
||||
$conn = new mysqli($servername, $username, $password, $database); |
|
||||
|
|
||||
// 检查连接是否成功 |
// $str = '平時已秉班揚筆,暇處不妨甘石經。吾里忻傳日邊信,君言頻中斗杓星。會稽夫子餘詩禮,巴蜀君平舊典型。歷歷周天三百度,更參璿玉到虞廷。'; |
||||
if ($conn->connect_error) { |
// echo HanziConvert::convert($str);//默认是繁体转简体 |
||||
die("连接失败: " . $conn->connect_error); |
|
||||
} |
|
||||
|
|
||||
// 指定要查询的 facilityno |
//简体转繁体 |
||||
$facilitynos = array( |
echo $str = '平时已秉班扬笔,暇处不妨甘石经。吾里忻传日边信,君言频中斗杓星。会稽夫子余诗礼,巴蜀君平旧典型。歷歷周天三百度,更参璇玉到虞廷。'; |
||||
'3TX19201', |
|
||||
'3TX19202', |
|
||||
'3TX19203', |
|
||||
'3JX06604', |
|
||||
'3JX08605', |
|
||||
'3TX19206', |
|
||||
'3TX00401', |
|
||||
'3TX00301', |
|
||||
'3TX01401', |
|
||||
'3JX07401', |
|
||||
'3JX05101', |
|
||||
'3JX05102', |
|
||||
'3JX05104', |
|
||||
'3JX05103', |
|
||||
'3JX05105', |
|
||||
'3JX05106', |
|
||||
'3JX02501', |
|
||||
'3JX02512', |
|
||||
'3JX02505', |
|
||||
'3JX02504', |
|
||||
'3JX02502', |
|
||||
'3JX02506', |
|
||||
'3JX02507', |
|
||||
'3JX02508', |
|
||||
'3JX02509', |
|
||||
'3JX02510', |
|
||||
'3JX02511', |
|
||||
'3JX02503', |
|
||||
'3JX05701', |
|
||||
'3JX05702', |
|
||||
'3TX38002', |
|
||||
'3TX38003', |
|
||||
'3TX38004', |
|
||||
'3TX38005', |
|
||||
'3TX38006', |
|
||||
'3TX38001', |
|
||||
'3TX23101', |
|
||||
'3TX41501', |
|
||||
'3TX27001', |
|
||||
'3TX27002', |
|
||||
'3TX40301', |
|
||||
'3TZ41701', |
|
||||
'3JX08505', |
|
||||
'3JX08504', |
|
||||
'3JX08503', |
|
||||
'3JX08502', |
|
||||
'3JX08501', |
|
||||
'3TX45701', |
|
||||
'3TX47401', |
|
||||
'3MH00111', |
|
||||
'3MH00205', |
|
||||
'3MH00206', |
|
||||
'3MH00002', |
|
||||
'4JX00601', |
|
||||
'4JX00602', |
|
||||
'4JX00603', |
|
||||
'4JX00604', |
|
||||
'4JX00605', |
|
||||
'4JX00606', |
|
||||
'4JX00607', |
|
||||
'4TX00401', |
|
||||
'4TW02601', |
|
||||
'4TW03101', |
|
||||
'4TW04901', |
|
||||
'4TW05001', |
|
||||
'4TH00601', |
|
||||
'4TH00701', |
|
||||
'4TX00501', |
|
||||
'3TX52701', |
|
||||
'3TX42901', |
|
||||
'3TH44501', |
|
||||
'2MX00029', |
|
||||
'2MX00030', |
|
||||
'2MX00031', |
|
||||
'2MX00032', |
|
||||
'2MX00033', |
|
||||
'2MX00034', |
|
||||
'2MX00035', |
|
||||
'2MX00036', |
|
||||
'2MX00037', |
|
||||
'3TX01303', |
|
||||
'3TX01304', |
|
||||
'3TX01301', |
|
||||
'3TX01302', |
|
||||
'3TX08501', |
|
||||
'3TX08504', |
|
||||
'3TX08503', |
|
||||
'3TX08502', |
|
||||
'3TX20601', |
|
||||
'3TX20602', |
|
||||
'3TX20603', |
|
||||
'3TX20604', |
|
||||
'3TX20605', |
|
||||
'3TX20606', |
|
||||
'3TX20607', |
|
||||
'3JX05501', |
|
||||
'3TX22101', |
|
||||
'3TX37101', |
|
||||
'3TX37102', |
|
||||
'3TX37103', |
|
||||
'3TX37104', |
|
||||
'3TX37105', |
|
||||
'3TX45801', |
|
||||
'3TX45901', |
|
||||
'2MW00027', |
|
||||
'4JX01001', |
|
||||
'4JX01002', |
|
||||
'4JX01003', |
|
||||
'4JX01004', |
|
||||
'4JX01005', |
|
||||
'4JX01201', |
|
||||
'4JX01202', |
|
||||
'4JX01203', |
|
||||
'4JX01204', |
|
||||
'4JX01205', |
|
||||
'4JX01206', |
|
||||
'4JX01207', |
|
||||
'4JX01208', |
|
||||
'4JX01209', |
|
||||
'4JX01210', |
|
||||
'4JX00401', |
|
||||
'4JX00402', |
|
||||
'4JX00403', |
|
||||
'4JX00404', |
|
||||
'4JX00405', |
|
||||
'4JX00406', |
|
||||
'4JX00407', |
|
||||
'4TW02301', |
|
||||
'4JX01302', |
|
||||
'4JX01301', |
|
||||
'4JX01801', |
|
||||
'4JX01802', |
|
||||
'3TX47901', |
|
||||
'3TX52601', |
|
||||
'3TX24501', |
|
||||
'3TX25401', |
|
||||
'3TX15501', |
|
||||
'3TX15502', |
|
||||
'3TX01201', |
|
||||
'22TX0002704', |
|
||||
'22TX0002705', |
|
||||
'22TX0002706', |
|
||||
'22TX0002707', |
|
||||
'22TX0002708', |
|
||||
'22TX0002709', |
|
||||
'22TX0002710', |
|
||||
'22TX0002711', |
|
||||
'22TX0002701', |
|
||||
'22TX0002702', |
|
||||
'22TX0002703', |
|
||||
'3TX01501', |
|
||||
'3TH06501', |
|
||||
'3JX00301', |
|
||||
'3JX00302', |
|
||||
'3TW14601', |
|
||||
'3TX07301', |
|
||||
'3TX07401', |
|
||||
'3TX07701', |
|
||||
'3TX37603', |
|
||||
'3TX37602', |
|
||||
'3TX37601', |
|
||||
'3TX37604', |
|
||||
'3TX37201', |
|
||||
'3JX06401', |
|
||||
'3TX43001', |
|
||||
'3TX43002', |
|
||||
'3TX43003', |
|
||||
'3TX43004', |
|
||||
'3TX43005', |
|
||||
'3TX43006', |
|
||||
'3TX43007', |
|
||||
'3TX43008', |
|
||||
'3TX43009', |
|
||||
'3TX43010', |
|
||||
'3TX43011', |
|
||||
'3TX43012', |
|
||||
'3TX43013', |
|
||||
'3JX07301', |
|
||||
'3JX07302', |
|
||||
'3JX08001', |
|
||||
'3JX08002', |
|
||||
'3JX08003', |
|
||||
'3JX08004', |
|
||||
'3JX08005', |
|
||||
'3JX08006', |
|
||||
'3JX08007', |
|
||||
'3JX08008', |
|
||||
'3JX08009', |
|
||||
'3TX47001', |
|
||||
'3TX47901', |
|
||||
'3TX48001', |
|
||||
'3TX47801', |
|
||||
'3TX54201', |
|
||||
'4JX00801', |
|
||||
'4JX00802', |
|
||||
'4JX00803', |
|
||||
'4JX00804', |
|
||||
'4JX00805', |
|
||||
'4JX00701', |
|
||||
'4JX00702', |
|
||||
'4JX00703', |
|
||||
'4JX00704', |
|
||||
'4JX00705', |
|
||||
'4JX00706', |
|
||||
'3MH00540', |
|
||||
'4TH07101', |
|
||||
'4TH06901', |
|
||||
'4TW06801', |
|
||||
'3JX01601', |
|
||||
'3MH00513', |
|
||||
'4TH06701', |
|
||||
'3TX26501', |
|
||||
'3JX07001', |
|
||||
'3JX07002', |
|
||||
'3JX07003', |
|
||||
'3JX07004', |
|
||||
'3JX07005', |
|
||||
'3JX07006', |
|
||||
'3JX07007', |
|
||||
'3JX07008', |
|
||||
'3JX07009', |
|
||||
'3JX07010', |
|
||||
'3JX07011', |
|
||||
'3JX07012', |
|
||||
'3JX07013', |
|
||||
'3JX07014', |
|
||||
'3JX07015', |
|
||||
'3JX07016', |
|
||||
'3JX07017', |
|
||||
'3JX07018', |
|
||||
'3JX07019', |
|
||||
'3JX07020', |
|
||||
'3JX07021', |
|
||||
'3JX07022', |
|
||||
'3JX07023', |
|
||||
'3JX07024', |
|
||||
'3JX07025', |
|
||||
'3JX07026', |
|
||||
'3JX07027', |
|
||||
'3JX07028', |
|
||||
'3JX07029', |
|
||||
'3JX07030', |
|
||||
'3JX07031', |
|
||||
'3JX07032', |
|
||||
'3JX07033', |
|
||||
'3JX07034', |
|
||||
'3JX07035', |
|
||||
'3JX07036', |
|
||||
'3JX07037', |
|
||||
'3JX07038', |
|
||||
'3JX07039', |
|
||||
'3JX07040', |
|
||||
'3JX00901', |
|
||||
'3JX00902', |
|
||||
'3JX00903', |
|
||||
'3JX04501', |
|
||||
'3JX04502', |
|
||||
'3JX04503', |
|
||||
'3JX04504', |
|
||||
'3TX40401', |
|
||||
'3TX40402', |
|
||||
'3JX08201', |
|
||||
'3JX08202', |
|
||||
'3MH00036', |
|
||||
'3TX54101', |
|
||||
'4TW04301', |
|
||||
'4JX00901', |
|
||||
'4JX00902', |
|
||||
'4JX00903', |
|
||||
'3TX22001', |
|
||||
'3TX22001', |
|
||||
'3TX20701' |
|
||||
); |
|
||||
$facilityno_tmp = []; |
|
||||
// 循环遍历 facilityno |
|
||||
foreach ($facilitynos as $facilityno) { |
|
||||
// 准备查询语句 |
|
||||
$sql = "SELECT COUNT(*) AS count FROM schedule WHERE facilityno = '$facilityno'"; |
|
||||
|
|
||||
// 执行查询 |
|
||||
$result = $conn->query($sql); |
|
||||
|
|
||||
// 检查是否找到记录 |
|
||||
if ($result && $result->num_rows > 0) { |
|
||||
$row = $result->fetch_assoc(); |
|
||||
$count = $row['count']; |
|
||||
|
|
||||
// 如果记录不存在,则记录到另一个表中 |
|
||||
if ($count == 0) { |
|
||||
// 准备插入语句 |
|
||||
array_push($facilityno_tmp, $facilityno); |
|
||||
} |
|
||||
} else { |
|
||||
echo "查询 $facilityno 时出错: " . $conn->error . "\n"; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
// 关闭连接 |
echo "<br/>"; |
||||
$conn->close(); |
|
||||
$i = 1; |
|
||||
foreach($facilityno_tmp as $row){ |
|
||||
echo $i++.":".$row."<br/>"; |
|
||||
} |
|
||||
|
|
||||
?> |
echo HanziConvert::convert($str,true);//第二个参数传入布尔真则是简体转繁体 |
||||
|
@ -0,0 +1,85 @@ |
|||||
|
<?php |
||||
|
require_once('../conn.php'); |
||||
|
require dirname(dirname(dirname(__DIR__))) . '/common/composer/vendor/autoload.php'; |
||||
|
header("Content-Type: application/json"); |
||||
|
|
||||
|
use PhpOffice\PhpSpreadsheet\Spreadsheet; |
||||
|
use PhpOffice\PhpSpreadsheet\Writer\Xlsx; |
||||
|
use PhpOffice\PhpSpreadsheet\Style\Fill; |
||||
|
|
||||
|
//數字轉英文(0=>A、1=>B、26=>AA...以此類推) |
||||
|
function num2alpha($n) |
||||
|
{ |
||||
|
for ($r = ""; $n >= 0; $n = intval($n / 26) - 1) |
||||
|
$r = chr($n % 26 + 0x41) . $r; |
||||
|
return $r; |
||||
|
} |
||||
|
|
||||
|
//英文轉數字(A=>0、B=>1、AA=>26...以此類推) |
||||
|
function alpha2num($a) |
||||
|
{ |
||||
|
$l = strlen($a); |
||||
|
$n = 0; |
||||
|
for ($i = 0; $i < $l; $i++) |
||||
|
$n = $n * 26 + ord($a[$i]) - 0x40; |
||||
|
return $n - 1; |
||||
|
} |
||||
|
|
||||
|
try { |
||||
|
$create_at_start = isset($_REQUEST['create_at_start']) ? $_REQUEST['create_at_start'] : ''; |
||||
|
$create_at_end = isset($_REQUEST['create_at_end']) ? $_REQUEST['create_at_end'] : ''; |
||||
|
if (!empty($create_at_start) && !empty($create_at_end)) { |
||||
|
$sql_str = "SELECT * |
||||
|
FROM sanlien_log |
||||
|
WHERE SUBSTR(create_at, 1, 10) |
||||
|
BETWEEN :create_at_start AND :create_at_end |
||||
|
"; |
||||
|
$stmt = $conn->prepare($sql_str); |
||||
|
$stmt->bindParam(':create_at_start', $create_at_start); |
||||
|
$stmt->bindParam(':create_at_end', $create_at_end); |
||||
|
} else { |
||||
|
$sql_str = "SELECT * FROM sanlien_log "; |
||||
|
$stmt = $conn->prepare($sql_str); |
||||
|
} |
||||
|
$stmt->execute(); |
||||
|
|
||||
|
$spreadsheet = new Spreadsheet(); |
||||
|
$sheet = $spreadsheet->getActiveSheet(); |
||||
|
$sheet->setTitle('三連地震數據'); |
||||
|
|
||||
|
// 設定標題 |
||||
|
$colTitleArr = []; |
||||
|
for ($i = 0; $i < $stmt->columnCount(); $i++) { |
||||
|
$columnMeta = $stmt->getColumnMeta($i); |
||||
|
$colTitleArr[] = $columnMeta['name']; |
||||
|
} |
||||
|
// 標題寫入 excel 第一列 |
||||
|
for ($i = 0; $i < count($colTitleArr); $i++) |
||||
|
$sheet->setCellValue(num2alpha($i) . '1', $colTitleArr[$i]); |
||||
|
|
||||
|
// 設定內容 |
||||
|
$data = $stmt->fetchAll(PDO::FETCH_NUM); |
||||
|
$i = 2; |
||||
|
foreach ($data as $row) { |
||||
|
for ($j = 0; $j < count($row); $j++) { |
||||
|
$sheet->setCellValue(num2alpha($j) . $i, $row[$j]); |
||||
|
} |
||||
|
$i++; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
$writer = new Xlsx($spreadsheet); |
||||
|
$file_path = dirname(dirname(dirname(__DIR__))) . '/wms/excel/' . 'sanlien.xlsx'; |
||||
|
|
||||
|
$writer->save($file_path); |
||||
|
try { |
||||
|
$writer->save($file_path); |
||||
|
// 回傳檔案路徑給 JavaScript |
||||
|
echo json_encode(['data' => $file_path]); |
||||
|
} catch (Exception $e) { |
||||
|
echo 'Error: ' . $e->getMessage(); |
||||
|
} |
||||
|
exit(); |
||||
|
} catch (PDOException $e) { |
||||
|
die("ERROR!!!: " . $e->getMessage()); |
||||
|
} |
@ -0,0 +1,39 @@ |
|||||
|
<?php |
||||
|
|
||||
|
if ($_SERVER["REQUEST_METHOD"] == "POST") { |
||||
|
require_once('../conn.php'); |
||||
|
header("Content-Type: application/json"); |
||||
|
$d = new Department(); |
||||
|
echo $d->getDepartment(); |
||||
|
} |
||||
|
|
||||
|
class Department |
||||
|
{ |
||||
|
public function getDepartment() |
||||
|
{ |
||||
|
global $conn; |
||||
|
|
||||
|
$sql_str = " |
||||
|
SELECT |
||||
|
* FROM( |
||||
|
SELECT |
||||
|
'0' AS value, |
||||
|
'全部' AS text |
||||
|
FROM department |
||||
|
|
||||
|
UNION |
||||
|
|
||||
|
SELECT |
||||
|
DISTINCT |
||||
|
department_id AS value, |
||||
|
name AS text |
||||
|
FROM department |
||||
|
)AS tmp |
||||
|
ORDER BY tmp.value |
||||
|
"; |
||||
|
$stmt = $conn->prepare($sql_str); |
||||
|
$stmt->execute(); |
||||
|
$data = $stmt->fetchAll(PDO::FETCH_ASSOC); |
||||
|
return json_encode($data, JSON_UNESCAPED_UNICODE); |
||||
|
} |
||||
|
} |
@ -0,0 +1,131 @@ |
|||||
|
<?php |
||||
|
|
||||
|
if ($_SERVER["REQUEST_METHOD"] == "POST") { |
||||
|
require_once('../conn.php'); |
||||
|
header("Content-Type: application/json; charset=UTF-8"); |
||||
|
$signDetails = new signDetails(); |
||||
|
echo $signDetails->getSingDetails(); |
||||
|
} |
||||
|
|
||||
|
class signDetails |
||||
|
{ |
||||
|
|
||||
|
public function getSingDetails() |
||||
|
{ |
||||
|
global $conn; |
||||
|
|
||||
|
$system_name = !empty($_POST['system_name']) ? $_POST['system_name'] : ''; |
||||
|
$department_id = !empty($_POST['department_id']) ? $_POST['department_id'] : ''; |
||||
|
$user_id = !empty($_POST['user_id']) ? $_POST['user_id'] : ''; |
||||
|
|
||||
|
$sql_str = " |
||||
|
SELECT |
||||
|
sm.system_name, |
||||
|
fm.flow_name, |
||||
|
f.form_key, |
||||
|
sf.current_assigner, |
||||
|
a.name AS user_name, |
||||
|
d.department_id, |
||||
|
d.depart_name AS depart_name, |
||||
|
sf.update_date |
||||
|
FROM flow AS f |
||||
|
LEFT JOIN system_main as sm |
||||
|
ON f.system_id = sm.system_id |
||||
|
LEFT JOIN flow_main as fm |
||||
|
ON f.flow_id = fm.flow_id |
||||
|
LEFT JOIN ( |
||||
|
SELECT |
||||
|
form_key, |
||||
|
current_assigner, |
||||
|
IF(update_date IS NULL,create_date,update_date) AS update_date, |
||||
|
MAX(seq) AS seq |
||||
|
FROM subflow |
||||
|
WHERE 1 = 1 |
||||
|
GROUP BY form_key, current_assigner, update_date |
||||
|
) AS sf |
||||
|
ON f.form_key = sf.form_key |
||||
|
LEFT JOIN account AS a |
||||
|
ON sf.current_assigner = a.accountid |
||||
|
LEFT JOIN ( |
||||
|
SELECT DISTINCT |
||||
|
department_id, |
||||
|
name AS depart_name |
||||
|
FROM department |
||||
|
) AS d |
||||
|
ON a.department_id = d.department_id |
||||
|
WHERE 1 =1 |
||||
|
AND f.flow_code != 'Z' |
||||
|
AND sf.form_key != '' |
||||
|
AND sf.form_key IS NOT NULL |
||||
|
AND sf.current_assigner != '' |
||||
|
AND sf.current_assigner IS NOT NULL |
||||
|
"; |
||||
|
if(!empty($department_id)){ |
||||
|
$sql_str .= " AND d.department_id = :department_id "; |
||||
|
} |
||||
|
if(!empty($user_id)){ |
||||
|
$sql_str .= " AND sf.current_assigner = :user_id "; |
||||
|
} |
||||
|
$stmt = $conn->prepare($sql_str); |
||||
|
if(!empty($department_id)){ |
||||
|
$stmt->bindParam(':department_id', $department_id); |
||||
|
} |
||||
|
if(!empty($user_id)){ |
||||
|
$stmt->bindParam(':user_id', $user_id); |
||||
|
} |
||||
|
$stmt->execute(); |
||||
|
$data = $stmt->fetchAll(PDO::FETCH_ASSOC); |
||||
|
return json_encode($data, JSON_UNESCAPED_UNICODE); |
||||
|
} |
||||
|
|
||||
|
public function getSingDetailsAllCount() |
||||
|
{ |
||||
|
global $conn; |
||||
|
$sql_str = " |
||||
|
SELECT |
||||
|
sm.system_name, |
||||
|
fm.flow_name, |
||||
|
f.form_key, |
||||
|
sf.current_assigner, |
||||
|
a.name AS user_name, |
||||
|
d.department_id, |
||||
|
d.depart_name AS depart_name, |
||||
|
-- d.name AS depart_name, |
||||
|
sf.update_date |
||||
|
FROM flow AS f |
||||
|
LEFT JOIN system_main as sm |
||||
|
ON f.system_id = sm.system_id |
||||
|
LEFT JOIN flow_main as fm |
||||
|
ON f.flow_id = fm.flow_id |
||||
|
LEFT JOIN ( |
||||
|
SELECT |
||||
|
form_key, |
||||
|
current_assigner, |
||||
|
IF(update_date IS NULL,create_date,update_date) AS update_date, |
||||
|
MAX(seq) AS seq |
||||
|
FROM subflow |
||||
|
WHERE 1 = 1 |
||||
|
GROUP BY form_key, current_assigner, update_date |
||||
|
) AS sf |
||||
|
ON f.form_key = sf.form_key |
||||
|
LEFT JOIN account AS a |
||||
|
ON sf.current_assigner = a.accountid |
||||
|
LEFT JOIN ( |
||||
|
SELECT DISTINCT |
||||
|
department_id, |
||||
|
name AS depart_name |
||||
|
FROM department |
||||
|
) AS d |
||||
|
ON a.department_id = d.department_id |
||||
|
WHERE 1 =1 |
||||
|
AND f.flow_code != 'Z' |
||||
|
AND sf.form_key != '' |
||||
|
AND sf.form_key IS NOT NULL |
||||
|
AND sf.current_assigner != '' |
||||
|
AND sf.current_assigner IS NOT NULL |
||||
|
"; |
||||
|
$stmt = $conn->prepare($sql_str); |
||||
|
$stmt->execute(); |
||||
|
return $stmt->rowCount(); |
||||
|
} |
||||
|
} |
@ -0,0 +1,49 @@ |
|||||
|
<?php |
||||
|
|
||||
|
if ($_SERVER["REQUEST_METHOD"] == "POST") { |
||||
|
require_once('../conn.php'); |
||||
|
header("Content-Type: application/json"); |
||||
|
$department_id = isset($_POST['department_id']) ? $_POST['department_id'] : null; |
||||
|
$u = new User(); |
||||
|
echo $u->getUser($department_id); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
class User |
||||
|
{ |
||||
|
public function getUser($department_id) |
||||
|
{ |
||||
|
global $conn; |
||||
|
|
||||
|
$sql_str = " |
||||
|
SELECT |
||||
|
* |
||||
|
FROM( |
||||
|
SELECT |
||||
|
'' AS value, |
||||
|
'全部' AS text |
||||
|
FROM account |
||||
|
|
||||
|
UNION |
||||
|
|
||||
|
SELECT |
||||
|
DISTINCT |
||||
|
accountid AS value, |
||||
|
name AS text |
||||
|
FROM account |
||||
|
WHERE accounttype IN ('B','M','W','E') |
||||
|
"; |
||||
|
$sql_str .= !empty($department_id) ? " AND department_id = :department_id" : ''; |
||||
|
$sql_str .= " |
||||
|
)AS tmp |
||||
|
ORDER BY tmp.value |
||||
|
"; |
||||
|
$stmt = $conn->prepare($sql_str); |
||||
|
if (!empty($department_id)) { |
||||
|
$stmt->bindParam(':department_id', $department_id); |
||||
|
} |
||||
|
$stmt->execute(); |
||||
|
$data = $stmt->fetchAll(PDO::FETCH_ASSOC); |
||||
|
return json_encode($data, JSON_UNESCAPED_UNICODE); |
||||
|
} |
||||
|
} |
@ -0,0 +1,47 @@ |
|||||
|
<?php |
||||
|
$envFile = dirname(dirname(dirname(__file__))) . '/.env'; // .env 文件的路径 |
||||
|
|
||||
|
if (file_exists($envFile)) { |
||||
|
$lines = file($envFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); |
||||
|
if ($lines !== false) { |
||||
|
foreach ($lines as $line) { |
||||
|
list($key, $value) = explode('=', $line, 2); |
||||
|
$key = trim($key); |
||||
|
$value = trim($value); |
||||
|
// 设置环境变量 |
||||
|
putenv("$key=$value"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
$db_hostname = getenv('DB_HOST'); //資料庫主機名稱 |
||||
|
$db_username = getenv('DB_USERNAME'); //登入資料庫的管理者的帳號 |
||||
|
$db_password = getenv('DB_PASSWORD'); //登入密碼 |
||||
|
$db_name = getenv('DB_DATABASE'); //使用的資料庫 |
||||
|
$db_charset = 'utf8'; //設定字元編碼 |
||||
|
|
||||
|
//建立PDO的指定工作 |
||||
|
$dsn = "mysql:host=$db_hostname;dbname=$db_name;charset=$db_charset"; |
||||
|
|
||||
|
try { |
||||
|
//使用PDO連接到MySQL資料庫,建立PDO物件 |
||||
|
$conn = new PDO($dsn, $db_username, $db_password); |
||||
|
|
||||
|
//當錯誤發生時會將錯誤資訊放到一個類物件裡(PDOException) |
||||
|
//PDO異常處理,PDO::ATTR_ERRMODE,有以下三種值的設定 |
||||
|
//PDO::ERRMODE_SILENT: 預設模式,不主動報錯,需要以$conn->errorInfo()的形式獲取錯誤資訊 |
||||
|
//PDO::ERRMODE_WARNING: 引發 E_WARNING 錯誤,主動報錯 |
||||
|
//PDO::ERRMODE_EXCEPTION: 主動抛出 exceptions 異常,需要以try{}cath(){}輸出錯誤資訊。 |
||||
|
//設定主動以警告的形式報錯 |
||||
|
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); |
||||
|
|
||||
|
// $connT8 = new PDO("sqlsrv:Server=220.130.203.251;Database=T8TEST", "M0117", "IFFCUFM="); |
||||
|
// if ($connT8) { |
||||
|
// $connT8->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); |
||||
|
// } |
||||
|
//如果連接錯誤,將抛出一個PDOException異常對象 |
||||
|
} catch (PDOException $e) { |
||||
|
//如果連結資料庫失敗則顯示錯誤訊並停止本頁的工作 |
||||
|
die("ERROR!!!: " . $e->getMessage()); |
||||
|
} |
||||
|
|
||||
|
//$conn = null; //關閉資料庫的連線 |
@ -0,0 +1,67 @@ |
|||||
|
const signed_overdue_date_data = () => { |
||||
|
return { |
||||
|
init() { |
||||
|
this.$watch('data.department_id', () => { |
||||
|
this.changeDepartment() |
||||
|
}) |
||||
|
}, data: { |
||||
|
system_name_options: [{ |
||||
|
text: '全部', |
||||
|
value: '' |
||||
|
}, { |
||||
|
text: 'BPM', |
||||
|
value: 'bpm' |
||||
|
}, { |
||||
|
text: 'WMS', |
||||
|
value: 'wms' |
||||
|
}], |
||||
|
deparetment_options: deparetment_options, |
||||
|
signDetails: signDetails, |
||||
|
user_options: user_options, |
||||
|
system_name: '', |
||||
|
department_id: '', |
||||
|
user_id: '', |
||||
|
}, |
||||
|
table_details: [], |
||||
|
searchLoading: false, |
||||
|
downloadLoading: false, |
||||
|
search() { |
||||
|
this.ssearchLoading = true; |
||||
|
const form = new FormData(); |
||||
|
form.append('system_name', this.data.system_name); |
||||
|
form.append('department_id', this.data.department_id); |
||||
|
form.append('user_id', this.data.user_id); |
||||
|
axios.post('./api/getSingedDetails.php', form).then(res => { |
||||
|
this.data.signDetails = res.data; |
||||
|
this.searchLoading = false; |
||||
|
}).catch(error => { |
||||
|
console.log(error.response.data) |
||||
|
this.searchLoading = false |
||||
|
}) |
||||
|
}, getDepartment() { |
||||
|
axios.post('./api/getDepartment.php').then(res => { |
||||
|
this.data.deparetment_options = res.data |
||||
|
}).catch(error => { |
||||
|
console.log(error.response.data) |
||||
|
this.downloadLoading = false |
||||
|
}) |
||||
|
}, getUser() { |
||||
|
axios.post('./api/getUser.php').then(res => { |
||||
|
this.data.user_options = res.data |
||||
|
}).catch(error => { |
||||
|
console.log(error.response.data) |
||||
|
this.downloadLoading = false |
||||
|
}) |
||||
|
}, changeDepartment() { |
||||
|
const form = new FormData(); |
||||
|
form.append('department_id', this.data.department_id); |
||||
|
axios.post('./api/getUser.php', form).then(res => { |
||||
|
this.data.user_options = res.data |
||||
|
}).catch(error => { |
||||
|
console.log(error.response.data) |
||||
|
this.downloadLoading = false |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,25 @@ |
|||||
|
|
||||
|
const axiosClient = axios.create({ |
||||
|
baseURL : `${import.meta.env.VITE_API_BASE_URL}/api`, |
||||
|
}); |
||||
|
|
||||
|
|
||||
|
axiosClient.interceptors.request.use( (config)=> { |
||||
|
config.headers.Authorization = `Bearer ${store.state.user.token}` |
||||
|
return config; |
||||
|
}, (error)=> { |
||||
|
return Promise.reject(error); |
||||
|
}); |
||||
|
|
||||
|
axiosClient.interceptors.response.use( (response)=> { |
||||
|
return response; |
||||
|
}, (error)=>{ |
||||
|
if(error.response.status === 401){ |
||||
|
store.commit('setToken', null) |
||||
|
sessionStorage.removeItem('TOKEN') |
||||
|
router.push({name:'login'}) |
||||
|
} |
||||
|
throw error; |
||||
|
}); |
||||
|
|
||||
|
export default axiosClient; |
File diff suppressed because one or more lines are too long
@ -0,0 +1,48 @@ |
|||||
|
export default { |
||||
|
data() { |
||||
|
return { |
||||
|
options: [], |
||||
|
value: [], |
||||
|
list: [], |
||||
|
loading: false, |
||||
|
states: ["Alabama", "Alaska", "Arizona", |
||||
|
"Arkansas", "California", "Colorado", |
||||
|
"Connecticut", "Delaware", "Florida", |
||||
|
"Georgia", "Hawaii", "Idaho", "Illinois", |
||||
|
"Indiana", "Iowa", "Kansas", "Kentucky", |
||||
|
"Louisiana", "Maine", "Maryland", |
||||
|
"Massachusetts", "Michigan", "Minnesota", |
||||
|
"Mississippi", "Missouri", "Montana", |
||||
|
"Nebraska", "Nevada", "New Hampshire", |
||||
|
"New Jersey", "New Mexico", "New York", |
||||
|
"North Carolina", "North Dakota", "Ohio", |
||||
|
"Oklahoma", "Oregon", "Pennsylvania", |
||||
|
"Rhode Island", "South Carolina", |
||||
|
"South Dakota", "Tennessee", "Texas", |
||||
|
"Utah", "Vermont", "Virginia", |
||||
|
"Washington", "West Virginia", "Wisconsin", |
||||
|
"Wyoming"] |
||||
|
} |
||||
|
}, |
||||
|
mounted() { |
||||
|
this.list = this.states.map(item => { |
||||
|
return { value: `value:${item}`, label: `label:${item}` }; |
||||
|
}); |
||||
|
}, |
||||
|
methods: { |
||||
|
remoteMethod(query) { |
||||
|
if (query !== '') { |
||||
|
this.loading = true; |
||||
|
setTimeout(() => { |
||||
|
this.loading = false; |
||||
|
this.options = this.list.filter(item => { |
||||
|
return item.label.toLowerCase() |
||||
|
.indexOf(query.toLowerCase()) > -1; |
||||
|
}); |
||||
|
}, 200); |
||||
|
} else { |
||||
|
this.options = []; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
File diff suppressed because one or more lines are too long
@ -0,0 +1,126 @@ |
|||||
|
<?php |
||||
|
include_once("../header.php"); |
||||
|
require_once("./conn.php"); |
||||
|
|
||||
|
include("./api/getSingedDetails.php"); |
||||
|
include("./api/getDepartment.php"); |
||||
|
include("./api/getUser.php"); |
||||
|
|
||||
|
$sd = new signDetails(); |
||||
|
$d = new Department(); |
||||
|
$u = new User(); |
||||
|
|
||||
|
|
||||
|
$details_all_count = $sd->getSingDetailsAllCount(); |
||||
|
$signDetails = $sd->getSingDetails(); |
||||
|
$deparetment_options = $d->getDepartment(); |
||||
|
$user_options = $u->getUser(null); |
||||
|
|
||||
|
?> |
||||
|
<link rel="stylesheet" href="./styles/style.css?id=<?php echo date("YmdHis"); ?>"> |
||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" integrity="sha512-z3gLpd7yknf1YoNbCzqRKc4qyor8gaKU1qmn+CShxbuBusANI9QpRohGBreCFkKxLhei6S9CQXFEbbKuqLg0DA==" crossorigin="anonymous" referrerpolicy="no-referrer" /> |
||||
|
<script defer src="./js/alpinejs/cdn.min.js"></script> |
||||
|
<script src="./js/axios/axios.min.js"></script> |
||||
|
|
||||
|
<div class="form" method="post" x-data="signed_overdue_date_data"> |
||||
|
<table class="table table-bordered query-table table-striped table-bordered display compact" style="width:99%;margin-left:.5%"> |
||||
|
<thead> |
||||
|
<tr> |
||||
|
<td colspan="8"> |
||||
|
<h3 style='text-align:center'>部門逾期待簽查詢</h3> |
||||
|
</td> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
<tbody style="font-weight: bolder;margin-bottom: 20px"> |
||||
|
<tr> |
||||
|
<td style="vertical-align: middle">系統名稱</td> |
||||
|
<td> |
||||
|
<select class="form-control" x-model="data.system_name"> |
||||
|
<template x-for="option in data.system_name_options"> |
||||
|
<option :selected="option.value == data.system_name" :value="option.value" x-text="option.text"></option> |
||||
|
</template> |
||||
|
</select> |
||||
|
</td> |
||||
|
<td style="vertical-align: middle">部門名稱</td> |
||||
|
<td> |
||||
|
<select class="form-control" x-model="data.department_id"> |
||||
|
<template x-for="option in data.deparetment_options"> |
||||
|
<option :selected="option.value == data.depart_name" :value="option.value" x-text="option.text"></option> |
||||
|
</template> |
||||
|
</select> |
||||
|
</td> |
||||
|
<td style="vertical-align: middle">人員名稱</td> |
||||
|
<td> |
||||
|
<select class="form-control" x-model="data.user_id"> |
||||
|
<template x-for="option in data.user_options"> |
||||
|
<option :selected="option.value == data.depart_name" :value="option.value" x-text="option.text"></option> |
||||
|
</template> |
||||
|
</select> |
||||
|
</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td colspan="6" style="text-align: center"> |
||||
|
<button @click="search()" :disabled="searchLoading" type="button" class="btn btn-primary btn-sm savebtn"> |
||||
|
<template x-if="!searchLoading"> |
||||
|
<span>查詢</span> |
||||
|
</template> |
||||
|
<template x-if="searchLoading"> |
||||
|
<div class="loader"></div> |
||||
|
</template> |
||||
|
</button> |
||||
|
<button @click="download()" :disabled="downloadLoading" type="button" class="btn btn-primary btn-sm savebtn"> |
||||
|
<template x-if="!downloadLoading"> |
||||
|
<span>下載</span> |
||||
|
</template> |
||||
|
<template x-if="downloadLoading"> |
||||
|
<div class="loader"></div> |
||||
|
</template> |
||||
|
</button> |
||||
|
</td> |
||||
|
</tr> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
|
||||
|
<table class="table table-bordered query-table table-striped table-bordered display compact" style="width:99%;margin-left:.5%"> |
||||
|
<thead> |
||||
|
<!-- <tr> |
||||
|
<th> |
||||
|
<label>顯示</label> |
||||
|
<input type='number' min="1" max="100" x-model="datatable_ini.show_num" style="width: 40px" /> |
||||
|
</th> |
||||
|
</tr> --> |
||||
|
<tr> |
||||
|
<th>序號</th> |
||||
|
<th>系統名稱</th> |
||||
|
<th>流程名稱</th> |
||||
|
<th>接受日期</th> |
||||
|
<th>當前簽核者</th> |
||||
|
<th>姓名</th> |
||||
|
<th>所屬部門</th> |
||||
|
<th>逾期天數</th> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
<template x-for="(user, index) in data.signDetails" :key="index"> |
||||
|
<tbody> |
||||
|
<tr> |
||||
|
<td x-text="user.form_key"></td> |
||||
|
<td x-text="user.system_name"></td> |
||||
|
<td x-text="user.flow_name"></td> |
||||
|
<td x-text="user.update_date"></td> |
||||
|
<td x-text="user.current_assigner"></td> |
||||
|
<td x-text="user.user_name"></td> |
||||
|
<td x-text="user.depart_name"></td> |
||||
|
<td x-text="user.update_date"></td> |
||||
|
</tr> |
||||
|
</tbody> |
||||
|
</template> |
||||
|
</table> |
||||
|
</div> |
||||
|
|
||||
|
<script src="./js/alpine.js?id=<?php echo date("YmdHis"); ?>"></script> |
||||
|
|
||||
|
<script> |
||||
|
const signDetails = [...<?php echo $signDetails; ?>]; |
||||
|
const deparetment_options = [...<?php echo $deparetment_options; ?>]; |
||||
|
const user_options = [...<?php echo $user_options; ?>]; |
||||
|
</script> |
@ -0,0 +1,8 @@ |
|||||
|
.loader { |
||||
|
border: 4px solid #f3f3f3; /* Light grey */ |
||||
|
border-top: 4px solid #999; /* Blue */ |
||||
|
border-radius: 50%; |
||||
|
width: 20px; |
||||
|
height: 20px; |
||||
|
animation: spin 2s linear infinite; |
||||
|
} |
Loading…
Reference in new issue