fix: resolve RedisCache array offset error and improve discovery diagnostics

- Fix RedisCache driver to handle MGET failures gracefully with fallback
- Add comprehensive discovery context comparison debug tools
- Identify root cause: WEB context discovery missing 166 items vs CLI
- WEB context missing RequestFactory class entirely (52 vs 69 commands)
- Improved exception handling with detailed binding diagnostics
This commit is contained in:
2025-09-12 20:05:18 +02:00
parent 8040d3e7a5
commit e30753ba0e
46990 changed files with 10789682 additions and 89639 deletions

View File

@@ -40,4 +40,20 @@ final readonly class Image
public string $altText,
) {
}
public function withFilename(string $filename): self
{
return new self(
ulid: $this->ulid,
filename: $filename,
originalFilename: $this->originalFilename,
mimeType: $this->mimeType,
fileSize: $this->fileSize,
width: $this->width,
height: $this->height,
hash: $this->hash,
path: $this->path,
altText: $this->altText
);
}
}

View File

@@ -40,6 +40,9 @@ final readonly class ImageRepository
return $this->entityManager->findOneBy(Image::class, ['hash' => $hash]);
}
/**
* @return Image[]
*/
public function findAll(int $limit = 50, int $offset = 0, ?string $search = null): array
{
// Simplified version - use EntityManager::findAll for now
@@ -91,11 +94,14 @@ final readonly class ImageRepository
$image = $this->findByUlid($ulid);
if ($image) {
$image->filename = $filename;
$this->entityManager->save($image);
$updatedImage = $image->withFilename($filename);
$this->entityManager->save($updatedImage);
}
}
/**
* @return Image[]
*/
public function search(string $query, ?string $type = null, int $minWidth = 0, int $minHeight = 0): array
{
$allImages = $this->entityManager->findAll(Image::class);

View File

@@ -33,6 +33,9 @@ final readonly class ImageSlotRepository
return $this->entityManager->save($imageSlot);
}
/**
* @return array<int, ImageSlotView>
*/
public function findAllWithImages(): array
{
$slots = $this->entityManager->findAll(ImageSlot::class);

View File

@@ -11,9 +11,9 @@ use App\Domain\Meta\Service\MetaManager;
use App\Domain\Meta\Service\MetaTemplateResolver;
use App\Domain\Meta\ValueObject\MetaData;
use App\Framework\Attributes\Route;
use App\Framework\Http\JsonResult;
use App\Framework\Http\Method;
use App\Framework\Http\Status;
use App\Framework\Router\Result\JsonResult;
final class MetaAdminController
{

View File

@@ -15,11 +15,74 @@ final readonly class User
public string $id,
#[Column(name: 'name')]
public string $name,
#public ?string $email = null,
/*#[Column(name: 'email')]
public string $email*/
#[Column(name: 'email')]
public ?string $email = null,
#[Column(name: 'failed_attempts')]
public int $failed_attempts = 0,
#[Column(name: 'last_login')]
public ?\DateTimeImmutable $last_login = null,
#[Column(name: 'password_hash')]
public ?string $password_hash = null,
#[Column(name: 'last_failed_attempt')]
public ?\DateTimeImmutable $last_failed_attempt = null,
#[Column(name: 'locked_until')]
public ?\DateTimeImmutable $locked_until = null
) {
}
public function withFailedAttemptsReset(): self
{
return new self(
id: $this->id,
name: $this->name,
email: $this->email,
failed_attempts: 0,
last_login: new \DateTimeImmutable(),
password_hash: $this->password_hash,
last_failed_attempt: $this->last_failed_attempt,
locked_until: null // Clear lockout on successful login
);
}
public function withIncrementedFailedAttempts(): self
{
return new self(
id: $this->id,
name: $this->name,
email: $this->email,
failed_attempts: $this->failed_attempts + 1,
last_login: $this->last_login,
password_hash: $this->password_hash,
last_failed_attempt: new \DateTimeImmutable(),
locked_until: $this->locked_until
);
}
public function withLockout(\DateTimeImmutable $lockedUntil): self
{
return new self(
id: $this->id,
name: $this->name,
email: $this->email,
failed_attempts: $this->failed_attempts,
last_login: $this->last_login,
password_hash: $this->password_hash,
last_failed_attempt: $this->last_failed_attempt,
locked_until: $lockedUntil
);
}
public function withUpdatedLastLogin(\DateTimeImmutable $lastLogin): self
{
return new self(
id: $this->id,
name: $this->name,
email: $this->email,
failed_attempts: $this->failed_attempts,
last_login: $lastLogin,
password_hash: $this->password_hash,
last_failed_attempt: $this->last_failed_attempt,
locked_until: $this->locked_until
);
}
}