diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index c5f6005..eeba8df 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -24,7 +24,7 @@ jobs:
strategy:
matrix:
- php: [7.3, 7.4, '8.0', 8.1]
+ php: [7.4, '8.0', 8.1]
lib:
- { laravel: ^9.0 }
- { laravel: ^8.0 }
@@ -36,7 +36,11 @@ jobs:
- { php: 8.1, lib: { laravel: ^6.0 } }
- { php: 8.1, lib: { laravel: ^6.0, flags: --prefer-lowest } }
- { php: 7.4, lib: { laravel: ^9.0 } }
- - { php: 7.3, lib: { laravel: ^9.0 } }
+ include:
+ - { php: 8.1, lib: { laravel: ^9.0 }, phpstan: '1' }
+ - { php: 8.1, lib: { laravel: ^8.0 }, phpstan: '1' }
+ - { php: '8.0', lib: { laravel: ^9.0 }, phpstan: '1' }
+ - { php: '8.0', lib: { laravel: ^8.0 }, phpstan: '1' }
steps:
- uses: actions/checkout@v2
@@ -51,6 +55,10 @@ jobs:
run: |
composer require "laravel/framework:${{ matrix.lib.laravel }}" --dev ${{ matrix.lib.flags }}
+ - name: PHPStan
+ if: ${{ matrix.phpstan }}
+ run: composer phpstan
+
- run: mkdir -p build/logs
- run: vendor/bin/phpunit --coverage-clover build/logs/clover.xml
diff --git a/.gitignore b/.gitignore
index 475b6ea..a2363fe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
composer.lock
+/.idea/
/vendor/
/build/logs/
.php_cs.cache
diff --git a/.scrutinizer.yml b/.scrutinizer.yml
index 67d9421..a40aeee 100644
--- a/.scrutinizer.yml
+++ b/.scrutinizer.yml
@@ -4,6 +4,7 @@ checks:
filter:
excluded_paths:
+ - phpstan/*
- tests/*
- vendor/*
@@ -14,12 +15,6 @@ build:
tests:
override:
- php-scrutinizer-run
-
- environment:
- php: '7.4'
- docker: true
-
- nodes:
custom-nodes:
services:
custom-mysql:
@@ -32,6 +27,10 @@ build:
ports:
- 3306
+ environment:
+ php: '7.4'
+ docker: true
+
dependencies:
before:
- composer install
diff --git a/README.md b/README.md
index f31e761..a5c59b3 100644
--- a/README.md
+++ b/README.md
@@ -4,8 +4,11 @@ A tiny extension of `MySqlConnection` that manages **session** system variables
## Requirements
-- PHP: `^7.3 || ^8.0`
-- Laravel: `^6.0 || ^7.0 || ^8.0 || ^9.0`
+| Package | Version | Mandatory |
+|:---|:---|:---:|
+| PHP | ^7.4 || ^8.0
| ✅ |
+| Laravel | ^6.0 || ^7.0 || ^8.0 || ^9.0
| ✅ |
+| PHPStan | >=1.1
| |
## Installing
diff --git a/_ide_helper.php b/_ide_helper.php
new file mode 100644
index 0000000..0159066
--- /dev/null
+++ b/_ide_helper.php
@@ -0,0 +1,165 @@
+=6.6",
- "phpunit/phpunit": ">=9.5"
+ "phpunit/phpunit": ">=9.5",
+ "phpstan/phpstan": ">=1.1",
+ "phpstan/extension-installer": ">=1.1",
+ "nunomaduro/larastan": "^1.0"
+ },
+ "scripts": {
+ "test": "vendor/bin/phpunit",
+ "phpstan": "vendor/bin/phpstan analyse src tests phpstan"
},
"minimum-stability": "dev",
- "prefer-stable": true
+ "prefer-stable": true,
+ "extra": {
+ "phpstan": {
+ "includes": [
+ "extension.neon"
+ ]
+ }
+ }
}
diff --git a/extension.neon b/extension.neon
new file mode 100644
index 0000000..a4ac342
--- /dev/null
+++ b/extension.neon
@@ -0,0 +1,13 @@
+services:
+ -
+ class: Mpyw\LaravelMySqlSystemVariableManager\PHPStan\ConnectionClassExtension
+ tags:
+ - phpstan.broker.methodsClassReflectionExtension
+ -
+ class: Mpyw\LaravelMySqlSystemVariableManager\PHPStan\CallableReturnTypeExtension
+ tags:
+ - phpstan.broker.dynamicMethodReturnTypeExtension
+ -
+ class: Mpyw\LaravelMySqlSystemVariableManager\PHPStan\CallableFacadeReturnTypeExtension
+ tags:
+ - phpstan.broker.dynamicStaticMethodReturnTypeExtension
diff --git a/phpstan.neon b/phpstan.neon
new file mode 100644
index 0000000..2a71b8d
--- /dev/null
+++ b/phpstan.neon
@@ -0,0 +1,10 @@
+includes:
+ - ./extension.neon
+
+parameters:
+ level: 9
+ checkMissingIterableValueType: false
+ reportUnmatchedIgnoredErrors: false
+ ignoreErrors:
+ - message: '#Cannot access property \$value on mixed#'
+ path: tests
diff --git a/phpstan/CallableArgumentParameter.php b/phpstan/CallableArgumentParameter.php
new file mode 100644
index 0000000..6c9092d
--- /dev/null
+++ b/phpstan/CallableArgumentParameter.php
@@ -0,0 +1,41 @@
+getName(), $methods, true);
+ }
+
+ public function getTypeFromStaticMethodCall(MethodReflection $methodReflection, StaticCall $methodCall, Scope $scope): \PHPStan\Type\Type
+ {
+ if ($methodReflection->getName()[0] === 's') {
+ return new ObjectType(Connection::class);
+ }
+
+ $offset = $methodReflection->getName()[\strlen($methodReflection->getName()) - 1] === 's' ? 1 : 2;
+
+ if (\count($methodCall->getArgs()) > $offset) {
+ $type = $scope->getType($methodCall->getArgs()[$offset]->value);
+
+ if ($type instanceof ParametersAcceptor) {
+ return $type->getReturnType();
+ }
+ }
+
+ return new MixedType();
+ }
+}
diff --git a/phpstan/CallableParameter.php b/phpstan/CallableParameter.php
new file mode 100644
index 0000000..e432187
--- /dev/null
+++ b/phpstan/CallableParameter.php
@@ -0,0 +1,54 @@
+argumentParameters = $argumentParameters;
+ }
+
+ public function getName(): string
+ {
+ return 'callback';
+ }
+
+ public function isOptional(): bool
+ {
+ return false;
+ }
+
+ public function getType(): Type
+ {
+ return new CallableType($this->argumentParameters);
+ }
+
+ public function passedByReference(): PassedByReference
+ {
+ return PassedByReference::createNo();
+ }
+
+ public function isVariadic(): bool
+ {
+ return false;
+ }
+
+ public function getDefaultValue(): ?Type
+ {
+ return null;
+ }
+}
diff --git a/phpstan/CallableReturnTypeExtension.php b/phpstan/CallableReturnTypeExtension.php
new file mode 100644
index 0000000..9306e2d
--- /dev/null
+++ b/phpstan/CallableReturnTypeExtension.php
@@ -0,0 +1,52 @@
+getName(), $methods, true);
+ }
+
+ public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): Type
+ {
+ if ($methodReflection->getName()[0] === 's') {
+ return new ThisType($methodReflection->getDeclaringClass());
+ }
+
+ $offset = $methodReflection->getName()[\strlen($methodReflection->getName()) - 1] === 's' ? 1 : 2;
+
+ if (\count($methodCall->getArgs()) > $offset) {
+ $type = $scope->getType($methodCall->getArgs()[$offset]->value);
+
+ if ($type instanceof ParametersAcceptor) {
+ return $type->getReturnType();
+ }
+ }
+
+ return new MixedType();
+ }
+}
diff --git a/phpstan/ConnectionClassExtension.php b/phpstan/ConnectionClassExtension.php
new file mode 100644
index 0000000..841a23d
--- /dev/null
+++ b/phpstan/ConnectionClassExtension.php
@@ -0,0 +1,29 @@
+getName(), ConnectionInterface::class, true);
+ }
+
+ public function getMethod(ClassReflection $classReflection, string $methodName): MethodReflection
+ {
+ return new SystemVariablesMethod($classReflection, $methodName);
+ }
+}
diff --git a/phpstan/KeyParameter.php b/phpstan/KeyParameter.php
new file mode 100644
index 0000000..4ce858c
--- /dev/null
+++ b/phpstan/KeyParameter.php
@@ -0,0 +1,41 @@
+class = $classReflection;
+ $this->name = $methodName;
+ }
+
+ public function getDeclaringClass(): ClassReflection
+ {
+ return $this->class;
+ }
+
+ public function isStatic(): bool
+ {
+ return false;
+ }
+
+ public function isPrivate(): bool
+ {
+ return false;
+ }
+
+ public function isPublic(): bool
+ {
+ return true;
+ }
+
+ public function getDocComment(): ?string
+ {
+ return null;
+ }
+
+ public function getName(): string
+ {
+ return $this->name;
+ }
+
+ public function getPrototype(): ClassMemberReflection
+ {
+ return $this;
+ }
+
+ public function getVariants(): array
+ {
+ return $this->getName()[0] === 's'
+ ? $this->getSetVariants()
+ : $this->getUsingVariants();
+ }
+
+ private function getSetVariants(): array
+ {
+ return [new FunctionVariant(
+ TemplateTypeMap::createEmpty(),
+ null,
+ $this->getName()[\strlen($this->getName()) - 1] === 's'
+ ? [
+ new ValuesParameter(),
+ new MemoizeParameter(),
+ ]
+ : [
+ new KeyParameter(),
+ new ValueParameter(),
+ new MemoizeParameter(),
+ ],
+ false,
+ new ThisType($this->class),
+ )];
+ }
+
+ private function getUsingVariants(): array
+ {
+ $baseArgs = $this->getName()[\strlen($this->getName()) - 1] === 's'
+ ? [
+ new ValuesParameter(),
+ ]
+ : [
+ new KeyParameter(),
+ new ValueParameter(),
+ ];
+
+ $variants = [];
+
+ for ($i = 0; $i < 10; ++$i) {
+ $argumentParameters = [];
+ for ($j = 0; $j < $i; ++$j) {
+ $argumentParameters[] = new CallableArgumentParameter();
+ }
+
+ $variants[] = new FunctionVariant(
+ TemplateTypeMap::createEmpty(),
+ null,
+ [
+ ...$baseArgs,
+ new CallableParameter($argumentParameters),
+ ...$argumentParameters,
+ ],
+ false,
+ new MixedType(),
+ );
+ }
+
+ return $variants;
+ }
+
+ public function isDeprecated(): TrinaryLogic
+ {
+ return TrinaryLogic::createNo();
+ }
+
+ public function getDeprecatedDescription(): ?string
+ {
+ return null;
+ }
+
+ public function isFinal(): TrinaryLogic
+ {
+ return TrinaryLogic::createNo();
+ }
+
+ public function isInternal(): TrinaryLogic
+ {
+ return TrinaryLogic::createNo();
+ }
+
+ public function getThrowType(): ?Type
+ {
+ return new ObjectType(QueryException::class);
+ }
+
+ public function hasSideEffects(): TrinaryLogic
+ {
+ return TrinaryLogic::createMaybe();
+ }
+}
diff --git a/phpstan/ValueParameter.php b/phpstan/ValueParameter.php
new file mode 100644
index 0000000..e8bf8a7
--- /dev/null
+++ b/phpstan/ValueParameter.php
@@ -0,0 +1,41 @@
+pdos = array_filter($pdos);
+ $this->pdos = \array_filter($pdos);
}
/**
@@ -47,8 +47,7 @@ public function assign(array $values)
/**
* Configure PDO using query and parameters temporarily enabling PDO::ATTR_EMULATE_PREPARES.
*
- * @param string $query
- * @param array $values
+ * @param array $values
* @return $this
*/
protected function withEmulatedStatement(string $query, array $values = [])
@@ -67,10 +66,7 @@ protected function withEmulatedStatement(string $query, array $values = [])
}
/**
- * @param \PDO $pdo
- * @param string $query
- * @param array $values
- * @return \PDO
+ * @param array $values
*/
protected static function withEmulatedStatementFor(PDO $pdo, string $query, array $values): PDO
{
@@ -83,14 +79,11 @@ protected static function withEmulatedStatementFor(PDO $pdo, string $query, arra
}
/**
- * @param \PDO $pdo
- * @param string $query
- * @param array $values
- * @return \PDO
+ * @param array $values
*/
protected static function withStatementFor(PDO $pdo, string $query, array $values): PDO
{
- $expressions = array_map([Value::class, 'wrap'], $values);
+ $expressions = \array_map([Value::class, 'wrap'], $values);
$original = static::selectOriginalVariablesForReplacer($pdo, $expressions);
$statement = $pdo->prepare($query);
@@ -104,13 +97,12 @@ protected static function withStatementFor(PDO $pdo, string $query, array $value
}
/**
- * @param \PDO $pdo
* @param \Mpyw\LaravelMySqlSystemVariableManager\ExpressionInterface[] $expressions
* @return \Mpyw\LaravelMySqlSystemVariableManager\ValueInterface[]
*/
protected static function selectOriginalVariablesForReplacer(PDO $pdo, array $expressions): array
{
- $replacers = array_filter($expressions, function ($value) {
+ $replacers = \array_filter($expressions, function ($value) {
return $value instanceof IntegerReplacerInterface
|| $value instanceof BooleanReplacerInterface
|| $value instanceof FloatReplacerInterface
@@ -120,12 +112,6 @@ protected static function selectOriginalVariablesForReplacer(PDO $pdo, array $ex
return SystemVariableSelector::selectOriginalVariables($pdo, $replacers);
}
- /**
- * @param \PDOStatement $statement
- * @param int $parameter
- * @param \Mpyw\LaravelMySqlSystemVariableManager\ExpressionInterface $expression
- * @param null|\Mpyw\LaravelMySqlSystemVariableManager\ValueInterface $original
- */
protected static function bindValue(PDOStatement $statement, int $parameter, ExpressionInterface $expression, ?ValueInterface $original = null): void
{
if ($expression instanceof ValueInterface) {
@@ -133,13 +119,23 @@ protected static function bindValue(PDOStatement $statement, int $parameter, Exp
return;
}
- if (($expression instanceof IntegerReplacerInterface
- || $expression instanceof BooleanReplacerInterface
- || $expression instanceof FloatReplacerInterface
- || $expression instanceof StringReplacerInterface
- ) && $original) {
- $statement->bindValue($parameter, $expression->replace($original->getValue()), $expression->getParamType());
- return;
+ if ($original) {
+ if ($expression instanceof IntegerReplacerInterface) {
+ $statement->bindValue($parameter, $expression->replace((int)$original->getValue()), $expression->getParamType());
+ return;
+ }
+ if ($expression instanceof BooleanReplacerInterface) {
+ $statement->bindValue($parameter, $expression->replace((bool)$original->getValue()), $expression->getParamType());
+ return;
+ }
+ if ($expression instanceof FloatReplacerInterface) {
+ $statement->bindValue($parameter, $expression->replace((float)$original->getValue()), $expression->getParamType());
+ return;
+ }
+ if ($expression instanceof StringReplacerInterface) {
+ $statement->bindValue($parameter, $expression->replace((string)$original->getValue()), $expression->getParamType());
+ return;
+ }
}
// @codeCoverageIgnoreStart
diff --git a/src/SystemVariableAwareReconnector.php b/src/SystemVariableAwareReconnector.php
index 72cf33f..b184bc3 100644
--- a/src/SystemVariableAwareReconnector.php
+++ b/src/SystemVariableAwareReconnector.php
@@ -13,7 +13,7 @@ class SystemVariableAwareReconnector
/**
* @var array
*/
- protected $memoizedSystemVariables = [];
+ protected array $memoizedSystemVariables = [];
/**
* @var null|callable
@@ -22,8 +22,6 @@ class SystemVariableAwareReconnector
/**
* SystemVariableAwareReconnector constructor.
- *
- * @param null|callable $reconnector
*/
public function __construct(?callable $reconnector = null)
{
@@ -36,17 +34,16 @@ public function __construct(?callable $reconnector = null)
*/
public function memoizeSystemVariables(array $values)
{
- $this->memoizedSystemVariables = array_replace($this->memoizedSystemVariables, $values);
+ $this->memoizedSystemVariables = \array_replace($this->memoizedSystemVariables, $values);
return $this;
}
/**
- * @param \Illuminate\Database\ConnectionInterface|\Mpyw\LaravelMySqlSystemVariableManager\ManagesSystemVariables $connection
* @return mixed
*/
public function __invoke(ConnectionInterface $connection)
{
- if (is_callable($this->reconnector)) {
+ if (\is_callable($this->reconnector) && \method_exists($connection, 'setSystemVariables')) {
$result = ($this->reconnector)($connection);
$connection->setSystemVariables($this->memoizedSystemVariables, true);
return $result;
diff --git a/src/SystemVariableGrammar.php b/src/SystemVariableGrammar.php
index 034b0e2..1ad161b 100644
--- a/src/SystemVariableGrammar.php
+++ b/src/SystemVariableGrammar.php
@@ -5,34 +5,32 @@
class SystemVariableGrammar
{
/**
- * @param string[] $variables
- * @return string
+ * @param string[] $variables
*/
public static function selectStatement(array $variables): string
{
- return 'select ' . implode(', ', static::variableExpressions($variables));
+ return 'select ' . \implode(', ', static::variableExpressions($variables));
}
/**
- * @param string[] $variables
+ * @param string[] $variables
* @return string[]
*/
public static function variableExpressions(array $variables): array
{
$expressions = [];
foreach ($variables as $variable) {
- $expressions[] = sprintf('@@%1$s as %1$s', static::escapeIdentifier($variable));
+ $expressions[] = \sprintf('@@%1$s as %1$s', static::escapeIdentifier($variable));
}
return $expressions;
}
/**
- * @param array $values
- * @return string
+ * @param array $values
*/
public static function assignmentStatement(array $values): string
{
- return 'set session ' . implode(', ', static::assignmentExpressions($values));
+ return 'set session ' . \implode(', ', static::assignmentExpressions($values));
}
/**
@@ -48,12 +46,8 @@ public static function assignmentExpressions(array $values): array
return $expressions;
}
- /**
- * @param string $identifier
- * @return string
- */
public static function escapeIdentifier(string $identifier): string
{
- return '`' . str_replace('`', '``', $identifier) . '`';
+ return '`' . \str_replace('`', '``', $identifier) . '`';
}
}
diff --git a/src/SystemVariableMemoizedAssigner.php b/src/SystemVariableMemoizedAssigner.php
index fb70db6..63d5321 100644
--- a/src/SystemVariableMemoizedAssigner.php
+++ b/src/SystemVariableMemoizedAssigner.php
@@ -4,15 +4,12 @@
class SystemVariableMemoizedAssigner
{
- /**
- * @var \Mpyw\LaravelMySqlSystemVariableManager\SystemVariableAwareReconnector
- */
- protected $reconnector;
+ protected SystemVariableAwareReconnector $reconnector;
/**
* @var \Closure[]|\PDO[]
*/
- protected $pdos;
+ protected array $pdos;
/**
* SystemVariableMemoizedAssigner constructor.
@@ -26,14 +23,13 @@ public function __construct(&$reconnector, &...$pdos)
? new SystemVariableAwareReconnector($reconnector)
: $reconnector;
- $this->pdos = array_filter($pdos);
+ $this->pdos = \array_filter($pdos);
}
/**
* Set MySQL system variables for PDO.
*
* @param array $values
- * @param bool $memoizeForReconnect
* @return $this
*/
public function assign(array $values, bool $memoizeForReconnect = true)
diff --git a/src/SystemVariableSelector.php b/src/SystemVariableSelector.php
index 31aa07a..5ec8790 100644
--- a/src/SystemVariableSelector.php
+++ b/src/SystemVariableSelector.php
@@ -9,7 +9,6 @@ class SystemVariableSelector
/**
* Select current MySQL system variable values.
*
- * @param \PDO $pdo
* @param array $newValues
* @return \Mpyw\LaravelMySqlSystemVariableManager\ValueInterface[]
*/
@@ -19,9 +18,17 @@ public static function selectOriginalVariables(PDO $pdo, array $newValues): arra
return [];
}
- $original = $pdo
- ->query(SystemVariableGrammar::selectStatement(array_keys($newValues)))
- ->fetch(PDO::FETCH_ASSOC);
+ $stmt = $pdo->query(SystemVariableGrammar::selectStatement(\array_keys($newValues)));
+
+ if (!$stmt) {
+ // @codeCoverageIgnoreStart
+ return [];
+ // @codeCoverageIgnoreEnd
+ }
+
+ $original = $stmt->fetch(PDO::FETCH_ASSOC);
+
+ \assert(\is_array($original));
foreach ($original as $key => $value) {
$original[$key] = Value::as(Value::wrap($newValues[$key])->getType(), $value);
diff --git a/src/SystemVariableTemporaryAssigner.php b/src/SystemVariableTemporaryAssigner.php
index 912bb10..bcf8767 100644
--- a/src/SystemVariableTemporaryAssigner.php
+++ b/src/SystemVariableTemporaryAssigner.php
@@ -10,7 +10,7 @@ class SystemVariableTemporaryAssigner
/**
* @var \Closure[]|\PDO[]
*/
- protected $pdos;
+ protected array $pdos;
/**
* SystemVariableAssigner constructor.
@@ -19,15 +19,14 @@ class SystemVariableTemporaryAssigner
*/
public function __construct(&...$pdos)
{
- $this->pdos = array_filter($pdos);
+ $this->pdos = \array_filter($pdos);
}
/**
* Temporarily set MySQL system variables for PDO.
*
- * @param array $using
- * @param callable $callback
- * @param array $args
+ * @param array $using
+ * @param mixed ...$args
* @return $this
*/
public function using(array $using, callable $callback, ...$args)
diff --git a/src/Value.php b/src/Value.php
index 12162bf..3a43b2c 100644
--- a/src/Value.php
+++ b/src/Value.php
@@ -5,25 +5,22 @@
use Closure;
use InvalidArgumentException;
use ReflectionFunction;
+use ReflectionNamedType;
class Value implements ValueInterface
{
use ExpressionTrait;
/**
- * @var mixed
+ * @var bool|float|int|string
*/
protected $value;
- /**
- * @var string
- */
- protected $type;
+ protected string $type;
/**
* Create new int value for MySQL system variable.
*
- * @param int $value
* @return static
*/
public static function int(int $value)
@@ -34,7 +31,6 @@ public static function int(int $value)
/**
* Create new bool value for MySQL system variable.
*
- * @param bool $value
* @return static
*/
public static function bool(bool $value)
@@ -45,7 +41,6 @@ public static function bool(bool $value)
/**
* Create new float value for MySQL system variable.
*
- * @param float $value
* @return static
*/
public static function float(float $value)
@@ -56,7 +51,6 @@ public static function float(float $value)
/**
* Create new string value for MySQL system variable.
*
- * @param string $value
* @return static
*/
public static function str(string $value)
@@ -67,21 +61,19 @@ public static function str(string $value)
/**
* Create new typed value for MySQL system variable.
*
- * @param string $type
- * @param bool|float|int|string $value
- * @return \Mpyw\LaravelMySqlSystemVariableManager\ExpressionInterface
+ * @param bool|float|int|string $value
*/
public static function as(string $type, $value): ExpressionInterface
{
switch ($type) {
case static::TYPE_INTEGER:
- return static::int($value);
+ return static::int((int)$value);
case static::TYPE_BOOLEAN:
- return static::bool($value);
+ return static::bool((bool)$value);
case static::TYPE_FLOAT:
- return static::float($value);
+ return static::float((float)$value);
case static::TYPE_STRING:
- return static::str($value);
+ return static::str((string)$value);
default:
throw new InvalidArgumentException('The type must be one of "integer", "boolean", "double" or "string".');
}
@@ -92,8 +84,7 @@ public static function as(string $type, $value): ExpressionInterface
/**
* Automatically wrap a non-null value.
*
- * @param mixed $value
- * @return \Mpyw\LaravelMySqlSystemVariableManager\ExpressionInterface
+ * @param mixed $value
*/
public static function wrap($value): ExpressionInterface
{
@@ -101,16 +92,17 @@ public static function wrap($value): ExpressionInterface
return $value;
}
- if (is_scalar($value)) {
+ if (\is_scalar($value)) {
return static::as(gettype($value), $value);
}
if ($value instanceof Closure) {
/* @noinspection PhpUnhandledExceptionInspection */
$reflector = new ReflectionFunction($value);
- if ($reflector->hasReturnType()) {
- $returnType = $reflector->getReturnType();
- if (!$returnType->allowsNull() && $type = ExpressionInterface::GRAMMATICAL_TYPE_TO_STRING_TYPE[$returnType->getName()] ?? null) {
+ $returnType = $reflector->getReturnType();
+ if ($returnType instanceof ReflectionNamedType && !$returnType->allowsNull()) {
+ $type = ExpressionInterface::GRAMMATICAL_TYPE_TO_STRING_TYPE[$returnType->getName()] ?? null;
+ if ($type) {
return Replacer::as($type, $value);
}
}
@@ -122,10 +114,9 @@ public static function wrap($value): ExpressionInterface
/**
* Value constructor.
*
- * @param mixed $value
- * @param string $type
+ * @param bool|float|int|string $value
*/
- protected function __construct($value, string $type)
+ final protected function __construct($value, string $type)
{
$this->value = $value;
$this->type = $type;
diff --git a/tests/BasicVariableAssignmentTest.php b/tests/BasicVariableAssignmentTest.php
index 10b2efb..217b492 100644
--- a/tests/BasicVariableAssignmentTest.php
+++ b/tests/BasicVariableAssignmentTest.php
@@ -11,8 +11,6 @@ class BasicVariableAssignmentTest extends TestCase
{
/**
* @test
- * @param string $variableName
- * @param bool $emulated
* @param mixed $expectedOriginal
* @param mixed $newValue
* @param mixed $expectedChanged
@@ -29,8 +27,6 @@ public function testAssignments(string $variableName, bool $emulated, $expectedO
/**
* @test
- * @param string $variableName
- * @param bool $emulated
* @param mixed $expectedOriginal
* @param mixed $newValue
* @param mixed $expectedChanged
diff --git a/tests/TestCase.php b/tests/TestCase.php
index 670139b..4ebad34 100644
--- a/tests/TestCase.php
+++ b/tests/TestCase.php
@@ -7,15 +7,16 @@
use Mpyw\LaravelMySqlSystemVariableManager\MySqlConnectionServiceProvider;
use Orchestra\Testbench\TestCase as BaseTestCase;
use PDO;
+use ReflectionProperty;
class TestCase extends BaseTestCase
{
/**
* @param \Illuminate\Foundation\Application $app
*/
- protected function getEnvironmentSetUp($app)
+ protected function getEnvironmentSetUp($app): void
{
- $host = \gethostbyname('mysql') !== 'mysql' // Is "mysql" valid hostname?
+ $host = gethostbyname('mysql') !== 'mysql' // Is "mysql" valid hostname?
? 'mysql' // Local
: '127.0.0.1'; // CI
@@ -41,9 +42,9 @@ protected function getEnvironmentSetUp($app)
/**
* @param \Illuminate\Foundation\Application $app
- * @return array
+ * @return string[]
*/
- protected function getPackageProviders($app)
+ protected function getPackageProviders($app): array
{
return [
MySqlConnectionServiceProvider::class,
@@ -64,20 +65,24 @@ protected function onEmulatedConnection(callable $callback): void
* @param string $property
* @return \Closure|\PDO
*/
- protected function getConnectionPropertyValue(string $connection, string $property)
+ protected function getConnectionPropertyValue(?string $connection, string $property)
{
$db = DB::connection($connection);
- $rp = new \ReflectionProperty($db, $property);
+ $rp = new ReflectionProperty($db, $property);
$rp->setAccessible(true);
- return $rp->getValue($db);
+ $value = $rp->getValue($db);
+
+ assert($value instanceof Closure || $value instanceof PDO);
+
+ return $value;
}
- protected function assertPdoResolved(string $connection): void
+ protected function assertPdoResolved(?string $connection): void
{
$this->assertInstanceOf(PDO::class, $this->getConnectionPropertyValue($connection, 'pdo'));
}
- protected function assertPdoNotResolved(string $connection): void
+ protected function assertPdoNotResolved(?string $connection): void
{
$this->assertInstanceOf(Closure::class, $this->getConnectionPropertyValue($connection, 'pdo'));
}