refactor: Cleanup git state - commit all staged changes
Major refactoring cleanup: - Add new controller architecture (class-controller-*.php) - Add new settings-v2 UI (views/settings-v2/) - Add new CSS architecture (agentic-sidebar.css, tokens) - Add esbuild build pipeline (scripts/build.js, package.json) - Add composer dependencies (vendor/) - Add frontend src directory (assets/js/src/index.jsx) - Add documentation files - Remove old/obsolete files (class-settings.php, old CSS) This commits all pending changes from previous refactoring efforts.
This commit is contained in:
19
vendor/doctrine/instantiator/LICENSE
vendored
Normal file
19
vendor/doctrine/instantiator/LICENSE
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2014 Doctrine Project
|
||||
|
||||
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.
|
||||
38
vendor/doctrine/instantiator/README.md
vendored
Normal file
38
vendor/doctrine/instantiator/README.md
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
# Doctrine Instantiator
|
||||
|
||||
This library provides a way of avoiding usage of constructors when instantiating PHP classes.
|
||||
|
||||
[](https://travis-ci.org/doctrine/instantiator)
|
||||
[](https://codecov.io/gh/doctrine/instantiator/branch/master)
|
||||
[](https://www.versioneye.com/package/php--doctrine--instantiator)
|
||||
|
||||
[](https://packagist.org/packages/doctrine/instantiator)
|
||||
[](https://packagist.org/packages/doctrine/instantiator)
|
||||
|
||||
## Installation
|
||||
|
||||
The suggested installation method is via [composer](https://getcomposer.org/):
|
||||
|
||||
```sh
|
||||
composer require doctrine/instantiator
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
The instantiator is able to create new instances of any class without using the constructor or any API of the class
|
||||
itself:
|
||||
|
||||
```php
|
||||
$instantiator = new \Doctrine\Instantiator\Instantiator();
|
||||
|
||||
$instance = $instantiator->instantiate(\My\ClassName\Here::class);
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Please read the [CONTRIBUTING.md](CONTRIBUTING.md) contents if you wish to help out!
|
||||
|
||||
## Credits
|
||||
|
||||
This library was migrated from [ocramius/instantiator](https://github.com/Ocramius/Instantiator), which
|
||||
has been donated to the doctrine organization, and which is now deprecated in favour of this package.
|
||||
47
vendor/doctrine/instantiator/composer.json
vendored
Normal file
47
vendor/doctrine/instantiator/composer.json
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"name": "doctrine/instantiator",
|
||||
"description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
|
||||
"type": "library",
|
||||
"license": "MIT",
|
||||
"homepage": "https://www.doctrine-project.org/projects/instantiator.html",
|
||||
"keywords": [
|
||||
"instantiate",
|
||||
"constructor"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Marco Pivetta",
|
||||
"email": "ocramius@gmail.com",
|
||||
"homepage": "https://ocramius.github.io/"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^8.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-phar": "*",
|
||||
"ext-pdo": "*",
|
||||
"doctrine/coding-standard": "^14",
|
||||
"phpbench/phpbench": "^1.2",
|
||||
"phpstan/phpstan": "^2.1",
|
||||
"phpstan/phpstan-phpunit": "^2.0",
|
||||
"phpunit/phpunit": "^10.5.58"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-0": {
|
||||
"DoctrineTest\\InstantiatorPerformance\\": "tests",
|
||||
"DoctrineTest\\InstantiatorTest\\": "tests",
|
||||
"DoctrineTest\\InstantiatorTestAsset\\": "tests"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": true
|
||||
}
|
||||
}
|
||||
}
|
||||
14
vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/ExceptionInterface.php
vendored
Normal file
14
vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/ExceptionInterface.php
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Instantiator\Exception;
|
||||
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Base exception marker interface for the instantiator component
|
||||
*/
|
||||
interface ExceptionInterface extends Throwable
|
||||
{
|
||||
}
|
||||
52
vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/InvalidArgumentException.php
vendored
Normal file
52
vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/InvalidArgumentException.php
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Instantiator\Exception;
|
||||
|
||||
use InvalidArgumentException as BaseInvalidArgumentException;
|
||||
use ReflectionClass;
|
||||
|
||||
use function interface_exists;
|
||||
use function sprintf;
|
||||
use function trait_exists;
|
||||
|
||||
/**
|
||||
* Exception for invalid arguments provided to the instantiator
|
||||
*/
|
||||
class InvalidArgumentException extends BaseInvalidArgumentException implements ExceptionInterface
|
||||
{
|
||||
public static function fromNonExistingClass(string $className): self
|
||||
{
|
||||
if (interface_exists($className)) {
|
||||
return new self(sprintf('The provided type "%s" is an interface, and cannot be instantiated', $className));
|
||||
}
|
||||
|
||||
if (trait_exists($className)) {
|
||||
return new self(sprintf('The provided type "%s" is a trait, and cannot be instantiated', $className));
|
||||
}
|
||||
|
||||
return new self(sprintf('The provided class "%s" does not exist', $className));
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param ReflectionClass<T> $reflectionClass
|
||||
*
|
||||
* @template T of object
|
||||
*/
|
||||
public static function fromAbstractClass(ReflectionClass $reflectionClass): self
|
||||
{
|
||||
return new self(sprintf(
|
||||
'The provided class "%s" is abstract, and cannot be instantiated',
|
||||
$reflectionClass->getName(),
|
||||
));
|
||||
}
|
||||
|
||||
public static function fromEnum(string $className): self
|
||||
{
|
||||
return new self(sprintf(
|
||||
'The provided class "%s" is an enum, and cannot be instantiated',
|
||||
$className,
|
||||
));
|
||||
}
|
||||
}
|
||||
61
vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/UnexpectedValueException.php
vendored
Normal file
61
vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/UnexpectedValueException.php
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Instantiator\Exception;
|
||||
|
||||
use Exception;
|
||||
use ReflectionClass;
|
||||
use UnexpectedValueException as BaseUnexpectedValueException;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
/**
|
||||
* Exception for given parameters causing invalid/unexpected state on instantiation
|
||||
*/
|
||||
class UnexpectedValueException extends BaseUnexpectedValueException implements ExceptionInterface
|
||||
{
|
||||
/**
|
||||
* @phpstan-param ReflectionClass<T> $reflectionClass
|
||||
*
|
||||
* @template T of object
|
||||
*/
|
||||
public static function fromSerializationTriggeredException(
|
||||
ReflectionClass $reflectionClass,
|
||||
Exception $exception,
|
||||
): self {
|
||||
return new self(
|
||||
sprintf(
|
||||
'An exception was raised while trying to instantiate an instance of "%s" via un-serialization',
|
||||
$reflectionClass->getName(),
|
||||
),
|
||||
0,
|
||||
$exception,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param ReflectionClass<T> $reflectionClass
|
||||
*
|
||||
* @template T of object
|
||||
*/
|
||||
public static function fromUncleanUnSerialization(
|
||||
ReflectionClass $reflectionClass,
|
||||
string $errorString,
|
||||
int $errorCode,
|
||||
string $errorFile,
|
||||
int $errorLine,
|
||||
): self {
|
||||
return new self(
|
||||
sprintf(
|
||||
'Could not produce an instance of "%s" via un-serialization, since an error was triggered '
|
||||
. 'in file "%s" at line "%d"',
|
||||
$reflectionClass->getName(),
|
||||
$errorFile,
|
||||
$errorLine,
|
||||
),
|
||||
0,
|
||||
new Exception($errorString, $errorCode),
|
||||
);
|
||||
}
|
||||
}
|
||||
253
vendor/doctrine/instantiator/src/Doctrine/Instantiator/Instantiator.php
vendored
Normal file
253
vendor/doctrine/instantiator/src/Doctrine/Instantiator/Instantiator.php
vendored
Normal file
@@ -0,0 +1,253 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Instantiator;
|
||||
|
||||
use ArrayIterator;
|
||||
use Doctrine\Instantiator\Exception\ExceptionInterface;
|
||||
use Doctrine\Instantiator\Exception\InvalidArgumentException;
|
||||
use Doctrine\Instantiator\Exception\UnexpectedValueException;
|
||||
use Exception;
|
||||
use ReflectionClass;
|
||||
use ReflectionException;
|
||||
use Serializable;
|
||||
|
||||
use function class_exists;
|
||||
use function enum_exists;
|
||||
use function is_subclass_of;
|
||||
use function restore_error_handler;
|
||||
use function set_error_handler;
|
||||
use function sprintf;
|
||||
use function strlen;
|
||||
use function unserialize;
|
||||
|
||||
final class Instantiator implements InstantiatorInterface
|
||||
{
|
||||
/**
|
||||
* Markers used internally by PHP to define whether {@see \unserialize} should invoke
|
||||
* the method {@see \Serializable::unserialize()} when dealing with classes implementing
|
||||
* the {@see \Serializable} interface.
|
||||
*/
|
||||
private const string SERIALIZATION_FORMAT_USE_UNSERIALIZER = 'C';
|
||||
private const string SERIALIZATION_FORMAT_AVOID_UNSERIALIZER = 'O';
|
||||
|
||||
/**
|
||||
* Used to instantiate specific classes, indexed by class name.
|
||||
*
|
||||
* @var array<class-string, callable(): object>
|
||||
*/
|
||||
private static array $cachedInstantiators = [];
|
||||
|
||||
/**
|
||||
* Array of objects that can directly be cloned, indexed by class name.
|
||||
*
|
||||
* @var object[]
|
||||
*/
|
||||
private static array $cachedCloneables = [];
|
||||
|
||||
/**
|
||||
* @phpstan-param class-string<T> $className
|
||||
*
|
||||
* @phpstan-return T
|
||||
*
|
||||
* @throws ExceptionInterface
|
||||
*
|
||||
* @template T of object
|
||||
*/
|
||||
public function instantiate(string $className): object
|
||||
{
|
||||
if (isset(self::$cachedCloneables[$className])) {
|
||||
/** @phpstan-var T */
|
||||
$cachedCloneable = self::$cachedCloneables[$className];
|
||||
|
||||
return clone $cachedCloneable;
|
||||
}
|
||||
|
||||
if (isset(self::$cachedInstantiators[$className])) {
|
||||
$factory = self::$cachedInstantiators[$className];
|
||||
|
||||
return $factory();
|
||||
}
|
||||
|
||||
return $this->buildAndCacheFromFactory($className);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the requested object and caches it in static properties for performance
|
||||
*
|
||||
* @phpstan-param class-string<T> $className
|
||||
*
|
||||
* @phpstan-return T
|
||||
*
|
||||
* @template T of object
|
||||
*/
|
||||
private function buildAndCacheFromFactory(string $className): object
|
||||
{
|
||||
$factory = self::$cachedInstantiators[$className] = $this->buildFactory($className);
|
||||
$instance = $factory();
|
||||
|
||||
if ($this->isSafeToClone(new ReflectionClass($instance))) {
|
||||
self::$cachedCloneables[$className] = clone $instance;
|
||||
}
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a callable capable of instantiating the given $className without
|
||||
* invoking its constructor.
|
||||
*
|
||||
* @phpstan-param class-string<T> $className
|
||||
*
|
||||
* @phpstan-return callable(): T
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
* @throws UnexpectedValueException
|
||||
* @throws ReflectionException
|
||||
*
|
||||
* @template T of object
|
||||
*/
|
||||
private function buildFactory(string $className): callable
|
||||
{
|
||||
$reflectionClass = $this->getReflectionClass($className);
|
||||
|
||||
if ($this->isInstantiableViaReflection($reflectionClass)) {
|
||||
return [$reflectionClass, 'newInstanceWithoutConstructor'];
|
||||
}
|
||||
|
||||
$serializedString = sprintf(
|
||||
'%s:%d:"%s":0:{}',
|
||||
is_subclass_of($className, Serializable::class) ? self::SERIALIZATION_FORMAT_USE_UNSERIALIZER : self::SERIALIZATION_FORMAT_AVOID_UNSERIALIZER,
|
||||
strlen($className),
|
||||
$className,
|
||||
);
|
||||
|
||||
$this->checkIfUnSerializationIsSupported($reflectionClass, $serializedString);
|
||||
|
||||
return static fn () => unserialize($serializedString);
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param class-string<T> $className
|
||||
*
|
||||
* @phpstan-return ReflectionClass<T>
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
* @throws ReflectionException
|
||||
*
|
||||
* @template T of object
|
||||
*/
|
||||
private function getReflectionClass(string $className): ReflectionClass
|
||||
{
|
||||
if (! class_exists($className)) {
|
||||
throw InvalidArgumentException::fromNonExistingClass($className);
|
||||
}
|
||||
|
||||
if (enum_exists($className, false)) {
|
||||
throw InvalidArgumentException::fromEnum($className);
|
||||
}
|
||||
|
||||
$reflection = new ReflectionClass($className);
|
||||
|
||||
if ($reflection->isAbstract()) {
|
||||
throw InvalidArgumentException::fromAbstractClass($reflection);
|
||||
}
|
||||
|
||||
return $reflection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param ReflectionClass<T> $reflectionClass
|
||||
*
|
||||
* @throws UnexpectedValueException
|
||||
*
|
||||
* @template T of object
|
||||
*/
|
||||
private function checkIfUnSerializationIsSupported(ReflectionClass $reflectionClass, string $serializedString): void
|
||||
{
|
||||
set_error_handler(static function (int $code, string $message, string $file, int $line) use ($reflectionClass, &$error): bool {
|
||||
$error = UnexpectedValueException::fromUncleanUnSerialization(
|
||||
$reflectionClass,
|
||||
$message,
|
||||
$code,
|
||||
$file,
|
||||
$line,
|
||||
);
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
try {
|
||||
$this->attemptInstantiationViaUnSerialization($reflectionClass, $serializedString);
|
||||
} finally {
|
||||
restore_error_handler();
|
||||
}
|
||||
|
||||
if ($error) {
|
||||
throw $error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param ReflectionClass<T> $reflectionClass
|
||||
*
|
||||
* @throws UnexpectedValueException
|
||||
*
|
||||
* @template T of object
|
||||
*/
|
||||
private function attemptInstantiationViaUnSerialization(ReflectionClass $reflectionClass, string $serializedString): void
|
||||
{
|
||||
try {
|
||||
unserialize($serializedString);
|
||||
} catch (Exception $exception) {
|
||||
throw UnexpectedValueException::fromSerializationTriggeredException($reflectionClass, $exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param ReflectionClass<T> $reflectionClass
|
||||
*
|
||||
* @template T of object
|
||||
*/
|
||||
private function isInstantiableViaReflection(ReflectionClass $reflectionClass): bool
|
||||
{
|
||||
return ! ($this->hasInternalAncestors($reflectionClass) && $reflectionClass->isFinal());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies whether the given class is to be considered internal
|
||||
*
|
||||
* @phpstan-param ReflectionClass<T> $reflectionClass
|
||||
*
|
||||
* @template T of object
|
||||
*/
|
||||
private function hasInternalAncestors(ReflectionClass $reflectionClass): bool
|
||||
{
|
||||
do {
|
||||
if ($reflectionClass->isInternal()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$reflectionClass = $reflectionClass->getParentClass();
|
||||
} while ($reflectionClass);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a class is cloneable
|
||||
*
|
||||
* Classes implementing `__clone` cannot be safely cloned, as that may cause side-effects.
|
||||
*
|
||||
* @phpstan-param ReflectionClass<T> $reflectionClass
|
||||
*
|
||||
* @template T of object
|
||||
*/
|
||||
private function isSafeToClone(ReflectionClass $reflectionClass): bool
|
||||
{
|
||||
return $reflectionClass->isCloneable()
|
||||
&& ! $reflectionClass->hasMethod('__clone')
|
||||
&& ! $reflectionClass->isSubclassOf(ArrayIterator::class);
|
||||
}
|
||||
}
|
||||
24
vendor/doctrine/instantiator/src/Doctrine/Instantiator/InstantiatorInterface.php
vendored
Normal file
24
vendor/doctrine/instantiator/src/Doctrine/Instantiator/InstantiatorInterface.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Instantiator;
|
||||
|
||||
use Doctrine\Instantiator\Exception\ExceptionInterface;
|
||||
|
||||
/**
|
||||
* Instantiator provides utility methods to build objects without invoking their constructors
|
||||
*/
|
||||
interface InstantiatorInterface
|
||||
{
|
||||
/**
|
||||
* @phpstan-param class-string<T> $className
|
||||
*
|
||||
* @phpstan-return T
|
||||
*
|
||||
* @throws ExceptionInterface
|
||||
*
|
||||
* @template T of object
|
||||
*/
|
||||
public function instantiate(string $className): object;
|
||||
}
|
||||
Reference in New Issue
Block a user