Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
3a06f71
Enforce PHPStan level 7 compliance for App package
armanist Mar 27, 2026
913adda
Enforce PHPStan level 7 compliance for Archive package
armanist Mar 27, 2026
8082b4e
Enforce PHPStan level 7 compliance for Asset package and remove redun…
armanist Mar 27, 2026
5159f7d
Refactor Auth package with strict types and clean Factory patterns fo…
armanist Mar 27, 2026
2310de5
Code cleanup and cs fix for Auth package
armanist Mar 27, 2026
13e1223
Refactor Cache package for PHPStan level 7: extract CacheTrait, add p…
armanist Mar 28, 2026
ad968d4
Enforce PHPStan level 7 compliance for Captcha package
armanist Mar 28, 2026
93a0354
Fix type safety in Console package for PHPStan level 7 and add unit t…
armanist Mar 28, 2026
aa7ab22
Enforce PHPStan level 7 compliance for Cron package
armanist Mar 28, 2026
575479e
Enforce PHPStan level 7 compliance for Csrf package
armanist Mar 28, 2026
22e9a42
Fix type safety in Database package for PHPStan level 7 and add unser…
armanist Mar 28, 2026
72d2d1c
Enforce PHPStan level 7 compliance for Di package
armanist Mar 28, 2026
31012dd
Enforce PHPStan level 7 compliance for Encryption package
armanist Mar 28, 2026
e79dcdf
Enforce PHPStan level 7 compliance for Environment package
armanist Mar 28, 2026
a630873
Fix type safety in Http package for PHPStan level 7 and add precise r…
armanist Mar 28, 2026
acec496
Enforce PHPStan level 7 compliance for HttpClient package
armanist Mar 28, 2026
ff37ec6
Enforce PHPStan level 7 compliance for Lang package
armanist Mar 28, 2026
e50a9f1
Enforce PHPStan level 7 compliance for Loader package
armanist Mar 28, 2026
60d47be
Enforce PHPStan level 7 compliance for Logger package
armanist Mar 28, 2026
0e3cbf3
Refactor Mailer package for PHPStan level 7: replace conditional logi…
armanist Mar 28, 2026
502da2f
Enforce PHPStan level 7 compliance for Migration package: make TableF…
armanist Mar 28, 2026
da94a88
Enforce PHPStan level 7 compliance for Model package
armanist Mar 28, 2026
c161145
Enforce PHPStan level 7 compliance for Module package
armanist Mar 28, 2026
8d0504d
Enforce PHPStan level 7 compliance for Paginator package
armanist Mar 28, 2026
697538e
Enforce PHPStan level 7 compliance for Renderer package
armanist Mar 28, 2026
7187bc9
Enforce PHPStan level 7 compliance for ResourceCache package
armanist Mar 28, 2026
10110e1
Enforce PHPStan level 7 compliance for Router package
armanist Mar 30, 2026
d452073
Enforce PHPStan level 7 compliance for Session package
armanist Mar 30, 2026
1a76966
Enforce PHPStan level 7 compliance for Storage package
armanist Mar 30, 2026
a39156f
Enforce PHPStan level 7 compliance for Tracer package
armanist Mar 30, 2026
4dfad6a
Enforce PHPStan level 7 compliance for Validator package
armanist Mar 30, 2026
513ab7f
Enforce PHPStan level 7 compliance for View package
armanist Mar 30, 2026
cd7a406
The PHPStan configuration was updated to increase the analysis level …
armanist Mar 30, 2026
cb04108
Adding unit tests for commands
armanist Mar 30, 2026
4d74963
Refactor Database SleekDB adapter and update KeyGenerateCommand test
armanist Mar 31, 2026
5ee7f77
Fix nullable configs passed to Twig Environment constructor for PHP 8…
armanist Mar 31, 2026
713a871
refactor: improve error handling, type safety, and test stability acr…
armanist Mar 31, 2026
860029c
Removing and ignoring temp generated files for test
armanist Mar 31, 2026
b210553
Adding unit tests for coverage patch
armanist Mar 31, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Thumbs.db
# Test & Runtime artifacts
# =========================
/tests/_root/shared/store/*
/tests/_root/cron-tests/
/coverage/
*.log

Expand Down
2 changes: 1 addition & 1 deletion phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
parameters:
phpVersion: 70400
level: 6
level: 7

paths:
- src
Expand Down
12 changes: 6 additions & 6 deletions src/App/Adapters/ConsoleAppAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class ConsoleAppAdapter extends AppAdapter

protected ConsoleOutput $output;

protected ?Application $application = null;
protected Application $application;

public function __construct()
{
Expand All @@ -59,6 +59,11 @@ public function __construct()
$this->loadEnvironment();
$this->loadAppConfig();
}

$this->application = $this->createApplication(
config()->get('app.name', 'UNKNOWN'),
config()->get('app.version', 'UNKNOWN')
);
}

/**
Expand All @@ -72,11 +77,6 @@ public function __construct()
public function start(): ?int
{
try {
$this->application = $this->createApplication(
config()->get('app.name', 'UNKNOWN'),
config()->get('app.version', 'UNKNOWN')
);

$this->loadLanguage();

$this->registerCoreCommands();
Expand Down
2 changes: 1 addition & 1 deletion src/App/Adapters/WebAppAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ public function start(): ?int

$viewCache = $this->setupViewCache();

if ($viewCache->serveCachedView(route_uri(), $this->response)) {
if ($viewCache->serveCachedView(route_uri() ?? '', $this->response)) {
stop();
}

Expand Down
5 changes: 5 additions & 0 deletions src/App/App.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use Quantum\App\Exceptions\BaseException;
use Quantum\App\Exceptions\AppException;
use Quantum\App\Contracts\AppInterface;
use RuntimeException;

/**
* Class App
Expand All @@ -42,6 +43,10 @@ public static function setBaseDir(string $baseDir): void

public static function getBaseDir(): string
{
if (self::$baseDir === null || self::$baseDir === '') {
throw new RuntimeException('Base directory is not initialized.');
}

return self::$baseDir;
}

Expand Down
2 changes: 1 addition & 1 deletion src/App/Exceptions/StopExecutionException.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public static function executionTerminated(?int $code): self
{
return new self(
ExceptionMessages::EXECUTION_TERMINATED,
$code
$code ?? 0
);
}
}
8 changes: 4 additions & 4 deletions src/App/Helpers/misc.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ function _message(string $subject, $params): string
if (is_array($params)) {
return preg_replace_callback('/{%\d+}/', function () use (&$params) {
return array_shift($params);
}, $subject);
}, $subject) ?? $subject;
} else {
return preg_replace('/{%\d+}/', $params, $subject);
return preg_replace('/{%\d+}/', $params, $subject) ?? $subject;
}
}

Expand Down Expand Up @@ -62,8 +62,8 @@ function random_number(int $length = 10): int
function slugify(string $text): string
{
$text = trim($text, ' ');
$text = preg_replace('/[^\p{L}\p{N}]/u', ' ', $text);
$text = preg_replace('/\s+/', '-', $text);
$text = preg_replace('/[^\p{L}\p{N}]/u', ' ', $text) ?? $text;
$text = preg_replace('/\s+/', '-', $text) ?? $text;
$text = trim($text, '-');
$text = mb_strtolower($text);

Expand Down
4 changes: 3 additions & 1 deletion src/App/Traits/AppTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ protected function loadComponentHelperFunctions(): void

$srcDir = dirname(__DIR__, 2);

foreach (glob($srcDir . DS . '*', GLOB_ONLYDIR) as $componentDir) {
$componentDirs = glob($srcDir . DS . '*', GLOB_ONLYDIR);

foreach (is_array($componentDirs) ? $componentDirs : [] as $componentDir) {
$helperPath = $componentDir . DS . 'Helpers';
if (is_dir($helperPath)) {
$loader->loadDir($helperPath);
Expand Down
8 changes: 6 additions & 2 deletions src/App/Traits/ConsoleAppTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
namespace Quantum\App\Traits;

use Quantum\Environment\Exceptions\EnvException;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Application;
use Quantum\App\Exceptions\BaseException;
use Quantum\Di\Exceptions\DiException;
Expand Down Expand Up @@ -80,7 +81,10 @@ private function registerCommands(string $directory, string $namespace): void
$commands = CommandDiscovery::discover($directory, $namespace);

foreach ($commands as $command) {
$this->application->add(new $command['class']());
$instance = new $command['class']();
if ($instance instanceof Command) {
$this->application->add($instance);
}
}
}

Expand All @@ -91,7 +95,7 @@ private function validateCommand(): void
{
$commandName = $this->input->getFirstArgument();

if (!$this->application->has($commandName)) {
if ($commandName === null || !$this->application->has($commandName)) {
throw new Exception("Command `$commandName` is not defined");
}
}
Expand Down
6 changes: 5 additions & 1 deletion src/Archive/Adapters/PharAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,9 @@ public function addFile(string $filePath, ?string $entryName = null): bool
}

try {
$this->archive->addFile($filePath, $entryName);
$entryName !== null
? $this->archive->addFile($filePath, $entryName)
: $this->archive->addFile($filePath);
return true;
} catch (Exception $e) {
return false;
Expand Down Expand Up @@ -213,6 +215,8 @@ public function deleteMultipleFiles(array $fileNames): bool

/**
* @throws ArchiveException
* @phpstan-assert Phar $this->archive
* @phpstan-assert string $this->archiveName
*/
private function ensureArchiveOpen(): void
{
Expand Down
5 changes: 4 additions & 1 deletion src/Archive/Adapters/ZipAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,9 @@ public function addFile(string $filePath, ?string $entryName = null): bool
throw ArchiveException::fileNotFound($filePath);
}

$result = $this->archive->addFile($filePath, $entryName);
$result = $entryName !== null
? $this->archive->addFile($filePath, $entryName)
: $this->archive->addFile($filePath);
$this->requiresReopen = true;

return $result;
Expand Down Expand Up @@ -195,6 +197,7 @@ public function deleteMultipleFiles(array $fileNames): bool

/**
* @throws ArchiveException
* @phpstan-assert ZipArchive $this->archive
*/
private function ensureArchiveOpen(): void
{
Expand Down
10 changes: 5 additions & 5 deletions src/Asset/Asset.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class Asset
*/
private ?array $attributes;

private ?int $position;
private int $position;

/**
* Asset templates
Expand All @@ -58,7 +58,7 @@ class Asset
* Asset constructor
* @param array<string>|null $attributes
*/
public function __construct(int $type, string $path, ?string $name = null, ?int $position = -1, ?array $attributes = [])
public function __construct(int $type, string $path, ?string $name = null, int $position = -1, ?array $attributes = [])
{
$this->type = $type;
$this->path = $path;
Expand All @@ -76,7 +76,7 @@ public function getType(): int
}

/**
* Gets asset path
* Gets an asset path
*/
public function getPath(): string
{
Expand All @@ -94,7 +94,7 @@ public function getName(): ?string
/**
* Gets asset position
*/
public function getPosition(): ?int
public function getPosition(): int
{
return $this->position;
}
Expand Down Expand Up @@ -127,7 +127,7 @@ public function tag(): string
{
return _message(
$this->templates[$this->type],
[$this->url(), implode(' ', $this->attributes)]
[$this->url(), implode(' ', $this->attributes ?? [])]
) . PHP_EOL;
}
}
4 changes: 2 additions & 2 deletions src/Asset/AssetManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ private function setPriorityAssets(): void
$position = $asset->getPosition();
$type = $asset->getType();

if ($position != -1) {
if ($position !== -1) {
if (isset($this->published[$type][$position])) {
throw AssetException::positionInUse($position, $asset->getPath());
}
Expand All @@ -185,7 +185,7 @@ private function setPriorityAssets(): void
private function setRegularAssets(): void
{
foreach ($this->store as $asset) {
if ($asset->getPosition() == -1) {
if ($asset->getPosition() === -1) {
$this->setPosition($asset, 0);
}
}
Expand Down
9 changes: 6 additions & 3 deletions src/Auth/Adapters/JwtAuthAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,12 @@ class JwtAuthAdapter implements AuthenticatableInterface
{
use AuthTrait;

protected JwtToken $jwt;

/**
* @throws AuthException
*/
public function __construct(AuthServiceInterface $authService, Mailer $mailer, Hasher $hasher, ?JwtToken $jwt = null)
public function __construct(AuthServiceInterface $authService, Mailer $mailer, Hasher $hasher, JwtToken $jwt)
{
$this->authService = $authService;
$this->mailer = $mailer;
Expand Down Expand Up @@ -138,11 +140,12 @@ public function verifyOtp(int $otp, string $otpToken): array

/**
* Get Updated Tokens
* @throws JwtException
* @return array<string, string>
* @throws JwtException
*/
protected function getUpdatedTokens(User $user): array
{

return [
$this->keyFields[AuthKeys::REFRESH_TOKEN] => $this->generateToken(),
$this->keyFields[AuthKeys::ACCESS_TOKEN] => base64_encode($this->jwt->setData($this->getVisibleFields($user))->compose()),
Expand All @@ -151,8 +154,8 @@ protected function getUpdatedTokens(User $user): array

/**
* Set Updated Tokens
* @throws JwtException
* @return array<string, string>
* @throws JwtException
*/
protected function setUpdatedTokens(User $user): array
{
Expand Down
26 changes: 17 additions & 9 deletions src/Auth/Factories/AuthFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@

namespace Quantum\Auth\Factories;

use Quantum\Auth\Contracts\AuthenticatableInterface;
use Quantum\Auth\Contracts\AuthServiceInterface;
use Quantum\Service\Exceptions\ServiceException;
use Quantum\Config\Exceptions\ConfigException;
use Quantum\Service\Factories\ServiceFactory;
use Quantum\Auth\Adapters\SessionAuthAdapter;
use Quantum\Auth\Exceptions\AuthException;
use Quantum\Auth\Adapters\JwtAuthAdapter;
use Quantum\App\Exceptions\BaseException;
use Quantum\Auth\Adapters\JwtAuthAdapter;
use Quantum\Di\Exceptions\DiException;
use Quantum\Auth\Enums\AuthType;
use Quantum\Service\QtService;
Expand Down Expand Up @@ -87,12 +88,17 @@ public static function get(?string $adapter = null): Auth
*/
private static function createInstance(string $adapterClass, string $adapter): Auth
{
return new Auth(new $adapterClass(
self::createAuthService($adapter),
mailer(),
new Hasher(),
self::createJwtInstance($adapter)
));
$authService = self::createAuthService($adapter);

$adapterInstance = $adapter === AuthType::JWT
? new $adapterClass($authService, mailer(), new Hasher(), self::createJwtInstance())
: new $adapterClass($authService, mailer(), new Hasher());

if (!$adapterInstance instanceof AuthenticatableInterface) {
throw AuthException::adapterNotSupported($adapter);
}

return new Auth($adapterInstance);
}

/**
Expand Down Expand Up @@ -127,8 +133,10 @@ private static function createAuthService(string $adapter): AuthServiceInterface
return $authService;
}

private static function createJwtInstance(string $adapter): ?JwtToken
private static function createJwtInstance(): JwtToken
{
return $adapter === AuthType::JWT ? (new JwtToken())->setLeeway(1)->setClaims((array) config()->get('auth.claims')) : null;
return (new JwtToken())
->setLeeway(1)
->setClaims((array) config()->get('auth.' . AuthType::JWT . '.claims'));
}
}
Loading
Loading