Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 08:43:17 +08:00
commit 8967d326a7
30 changed files with 5154 additions and 0 deletions

View File

@@ -0,0 +1,348 @@
# AI Agent Development Guide
**Project:** rte_ckeditor_image - TYPO3 CKEditor 5 Image Extension
**Type:** TYPO3 CMS Extension (PHP 8.2+ + JavaScript/ES6)
**License:** GPL-2.0-or-later
## 📋 Documentation Structure
This project uses a three-tier documentation system:
- **[claudedocs/](claudedocs/)** - AI session context (Markdown, gitignored, temporary)
- **[Documentation/](Documentation/)** - Official TYPO3 docs (RST, published, permanent)
- **Root** - Project essentials (README, CONTRIBUTING, SECURITY, LICENSE)
See **[claudedocs/INDEX.md](claudedocs/INDEX.md)** for AI context navigation and **[Documentation/AGENTS.md](Documentation/AGENTS.md)** for TYPO3 documentation system guide.
## 🎯 Quick Start
```bash
# First time setup
composer install
make help # See all available targets
# Development workflow
make lint # Run all linters
make format # Fix code style
make test # Run tests
make ci # Full CI check (pre-commit)
# Composer shortcuts (if make unavailable)
composer ci:test:php:lint # PHP syntax check
composer ci:test:php:phpstan # Static analysis
composer ci:test:php:cgl # Code style check
composer ci:cgl # Fix code style
```
## 🏗️ Setup
### Prerequisites
- **PHP:** 8.2-8.9 with extensions: dom, libxml
- **Composer:** Latest stable
- **TYPO3:** 13.4+ (cms-core, cms-backend, cms-frontend, cms-rte-ckeditor)
- **direnv:** Optional but recommended
### Installation
```bash
# Clone and install
git clone https://github.com/netresearch/t3x-rte_ckeditor_image.git
cd t3x-rte_ckeditor_image
composer install
# Enable direnv (optional)
direnv allow
```
## 🔧 Build & Test Commands
### Fast Quality Checks (Pre-commit)
```bash
make lint # PHP lint + PHPStan + style check
make format # Auto-fix code style
make typecheck # PHPStan static analysis
```
### Full CI Suite
```bash
make ci # Complete CI pipeline
make test # All tests (when available)
```
### Individual Commands
```bash
# PHP Linting
composer ci:test:php:lint
# Static Analysis
composer ci:test:php:phpstan
# Code Style Check
composer ci:test:php:cgl
# Code Style Fix
composer ci:cgl
# Rector (PHP Modernization)
composer ci:test:php:rector
composer ci:rector # Apply changes
```
## 📝 Code Style
### PHP Standards
- **Base:** PSR-12 + PER-CS 2.0
- **Strict types:** Required in all files (`declare(strict_types=1);`)
- **Header comments:** Auto-managed by PHP-CS-Fixer
- **Config:** `Build/.php-cs-fixer.dist.php`
### Key Rules
```php
<?php
declare(strict_types=1);
/**
* This file is part of the package netresearch/rte-ckeditor-image.
*
* For the full copyright and license information, please read the
* LICENSE file that was distributed with this source code.
*/
namespace Netresearch\RteCKEditorImage\Controller;
// Imports: Classes, constants, functions
use TYPO3\CMS\Core\Utility\GeneralUtility;
// Alignment on = and =>
$config = [
'short' => 'value',
'longer' => 'another',
];
```
### JavaScript Standards
- **ES6 modules:** CKEditor 5 plugin format
- **No npm tooling:** TYPO3-managed assets
- **Style:** Follow CKEditor 5 conventions
- **Location:** `Resources/Public/JavaScript/`
## 🔒 Security
- **No secrets in VCS:** Use TYPO3's environment configuration
- **Dependency scanning:** Renovate enabled (see `renovate.json`)
- **Static analysis:** PHPStan with strict rules
- **TYPO3 security:** Follow TYPO3 Security Guidelines
- **File uploads:** Use FAL (File Abstraction Layer)
- **XSS prevention:** All output escaped via Fluid templates
## ✅ PR/Commit Checklist
Before committing:
1.**Lint passed:** `make lint` or `composer ci:test:php:lint`
2.**Style fixed:** `make format` or `composer ci:cgl`
3.**Static analysis:** `composer ci:test:php:phpstan` (no new errors)
4.**Rector check:** `composer ci:test:php:rector` (no suggestions)
5.**Docs updated:** Update relevant docs/ files if API changed
6.**CHANGELOG:** Add entry if user-facing change
7.**Conventional Commits:** Use format: `type(scope): message`
8.**Small PRs:** Keep ≤300 net LOC changed
### Commit Format
```
<type>(<scope>): <subject>
[optional body]
[optional footer]
```
**Types:** `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`
**Scopes:** `backend`, `frontend`, `config`, `docs`, `build`
**Examples:**
```
feat(backend): add image processing hook for WebP
fix(frontend): resolve style drop-down disabled for typo3image
docs(api): update DataHandling API reference
```
## 🎓 Good vs Bad Examples
### ✅ Good: TYPO3 Pattern
```php
<?php
declare(strict_types=1);
namespace Netresearch\RteCKEditorImage\Controller;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Core\Resource\ResourceFactory;
final class SelectImageController
{
public function __construct(
private readonly ResourceFactory $resourceFactory
) {
}
public function infoAction(ServerRequestInterface $request): ResponseInterface
{
$fileUid = (int)($request->getQueryParams()['fileId'] ?? 0);
// Implementation...
}
}
```
### ❌ Bad: Missing strict types, no DI
```php
<?php
namespace Netresearch\RteCKEditorImage\Controller;
class SelectImageController
{
public function infoAction($request)
{
$fileUid = $_GET['fileId']; // Direct superglobal access
$factory = new ResourceFactory(); // No DI
}
}
```
### ✅ Good: CKEditor 5 Plugin
```javascript
export default class Typo3Image extends Core.Plugin {
static get requires() {
return ['StyleUtils', 'GeneralHtmlSupport'];
}
init() {
const editor = this.editor;
this.listenTo(styleUtils, 'isStyleEnabledForBlock', (event, [style]) => {
// Event handling...
});
}
}
```
### ❌ Bad: Missing dependencies
```javascript
class Typo3Image extends Core.Plugin {
// Missing requires() - breaks style integration
init() {
// Implementation...
}
}
```
## 🆘 When Stuck
1. **AI Context:** Start with [claudedocs/INDEX.md](claudedocs/INDEX.md) for project navigation
2. **Architecture:** Review [claudedocs/ARCHITECTURE.md](claudedocs/ARCHITECTURE.md)
3. **Security:** Check [claudedocs/SECURITY.md](claudedocs/SECURITY.md)
4. **API Reference:** See [claudedocs/API_REFERENCE.md](claudedocs/API_REFERENCE.md)
5. **Development Guide:** Follow [claudedocs/DEVELOPMENT_GUIDE.md](claudedocs/DEVELOPMENT_GUIDE.md)
6. **TYPO3 Docs Guide:** Read [Documentation/AGENTS.md](Documentation/AGENTS.md)
7. **Published Manual:** https://docs.typo3.org/p/netresearch/rte-ckeditor-image/main/en-us/
8. **TYPO3 Core Docs:** https://docs.typo3.org/
9. **Issues:** https://github.com/netresearch/t3x-rte_ckeditor_image/issues
### Common Issues
- **Style drop-down disabled:** Missing `GeneralHtmlSupport` dependency (v13.0.0+)
- **Images not in frontend:** Missing static template include
- **PHPStan errors:** Run `composer ci:test:php:phpstan:baseline` to update baseline
- **Code style fails:** Run `composer ci:cgl` to auto-fix
## 📐 House Rules
### Commits & PRs
- **Atomic commits:** One logical change per commit
- **Conventional Commits:** Required format (see checklist)
- **Small PRs:** Target ≤300 net LOC changed
- **Branch naming:** `feature/short-description`, `fix/issue-123`
### Design Principles
- **SOLID:** Single responsibility, Open/closed, Liskov, Interface segregation, Dependency inversion
- **KISS:** Keep it simple, stupid
- **DRY:** Don't repeat yourself
- **YAGNI:** You aren't gonna need it
- **Composition > Inheritance:** Prefer composition
- **Law of Demeter:** Minimize coupling
### Dependencies
- **Latest stable:** Use current TYPO3 13.4+ versions
- **Renovate:** Auto-updates enabled
- **Major updates:** Require changelog review + migration notes
- **Composer:** Lock file committed
### API & Versioning
- **SemVer:** Semantic versioning (MAJOR.MINOR.PATCH)
- **TYPO3 compatibility:** Follow TYPO3 versioning
- **Breaking changes:** Increment major version
- **Deprecations:** Add `@deprecated` tag + removal plan
### Testing
- **TYPO3 Testing Framework:** Use `typo3/testing-framework`
- **Functional tests:** For database/integration scenarios
- **Unit tests:** For isolated logic
- **Test location:** `Tests/Functional/`, `Tests/Unit/`
### Licensing
- **License:** AGPL-3.0-or-later
- **SPDX:** Use SPDX identifiers
- **Headers:** Auto-managed by PHP-CS-Fixer
- **Third-party:** Document in CHANGELOG
## 🔗 Related Files
**Root Documentation:**
- **[README.md](README.md)** - Project overview and quick links
- **[CONTRIBUTING.md](CONTRIBUTING.md)** - Contribution guidelines
- **[SECURITY.md](SECURITY.md)** - Security policy
- **[LICENSE](LICENSE)** - GPL-2.0-or-later license
**AI Session Context (gitignored):**
- **[claudedocs/INDEX.md](claudedocs/INDEX.md)** - Navigation hub
- **[claudedocs/PROJECT_OVERVIEW.md](claudedocs/PROJECT_OVERVIEW.md)** - Project summary
- **[claudedocs/ARCHITECTURE.md](claudedocs/ARCHITECTURE.md)** - System design
- **[claudedocs/DEVELOPMENT_GUIDE.md](claudedocs/DEVELOPMENT_GUIDE.md)** - Development workflow
- **[claudedocs/API_REFERENCE.md](claudedocs/API_REFERENCE.md)** - PHP API docs
- **[claudedocs/SECURITY.md](claudedocs/SECURITY.md)** - Security analysis
**Official TYPO3 Documentation:**
- **[Documentation/](Documentation/)** - RST documentation (published)
- **[Documentation/AGENTS.md](Documentation/AGENTS.md)** - TYPO3 docs system guide
**Configuration:**
- **[composer.json](composer.json)** - Dependencies & scripts
- **[Build/](Build/)** - Development tools configuration
## 📚 Additional Resources
- **Repository:** https://github.com/netresearch/t3x-rte_ckeditor_image
- **Packagist:** https://packagist.org/packages/netresearch/rte-ckeditor-image
- **TYPO3 Ext:** https://extensions.typo3.org/extension/rte_ckeditor_image
- **TYPO3 Docs:** https://docs.typo3.org/
- **CKEditor 5:** https://ckeditor.com/docs/ckeditor5/

View File

@@ -0,0 +1,392 @@
# Classes/AGENTS.md
<!-- Managed by agent: keep sections & order; edit content, not structure. Last updated: 2025-10-15 -->
**Scope:** PHP backend components (Controllers, EventListeners, DataHandling, Utils)
**Parent:** [../AGENTS.md](../AGENTS.md)
## 📋 Overview
PHP backend implementation for TYPO3 CKEditor Image extension. Components:
### Controllers
- **SelectImageController** - Image browser wizard, file selection, image info API
- **ImageRenderingController** - Image rendering and processing for frontend
- **ImageLinkRenderingController** - Link-wrapped image rendering
### EventListeners
- **RteConfigurationListener** - PSR-14 event for RTE configuration injection
### DataHandling
- **RteImagesDbHook** - Database hooks for image magic reference handling
- **RteImageSoftReferenceParser** - Soft reference parsing for RTE images
### Backend Components
- **RteImagePreviewRenderer** - Backend preview rendering
### Utilities
- **ProcessedFilesHandler** - File processing and manipulation utilities
## 🏗️ Architecture Patterns
### TYPO3 Patterns
- **FAL (File Abstraction Layer):** All file operations via ResourceFactory
- **PSR-7 Request/Response:** HTTP message interfaces for controllers
- **PSR-14 Events:** Event-driven configuration and hooks
- **Dependency Injection:** Constructor-based DI (TYPO3 v13+)
- **Service Configuration:** `Configuration/Services.yaml` for DI registration
### File Structure
```
Classes/
├── Backend/
│ └── Preview/
│ └── RteImagePreviewRenderer.php
├── Controller/
│ ├── ImageLinkRenderingController.php
│ ├── ImageRenderingController.php
│ └── SelectImageController.php
├── DataHandling/
│ └── SoftReference/
│ └── RteImageSoftReferenceParser.php
├── Database/
│ └── RteImagesDbHook.php
├── EventListener/
│ └── RteConfigurationListener.php
└── Utils/
└── ProcessedFilesHandler.php
```
## 🔧 Build & Tests
```bash
# PHP-specific quality checks
make lint # All linters (syntax + PHPStan + Rector + style)
composer ci:test:php:lint # PHP syntax check
composer ci:test:php:phpstan # Static analysis
composer ci:test:php:rector # Rector modernization check
composer ci:test:php:cgl # Code style check
# Fixes
make format # Auto-fix code style
composer ci:cgl # Alternative: fix style
composer ci:rector # Apply Rector changes
# Full CI
make ci # Complete pipeline
```
## 📝 Code Style
### Required Patterns
**1. Strict Types (Always First)**
```php
<?php
declare(strict_types=1);
```
**2. File Header (Auto-managed by PHP-CS-Fixer)**
```php
/**
* This file is part of the package netresearch/rte-ckeditor-image.
*
* For the full copyright and license information, please read the
* LICENSE file that was distributed with this source code.
*/
```
**3. Import Order**
- Classes first
- Functions second
- Constants third
- One blank line before namespace
**4. Type Hints**
- All parameters must have type hints
- All return types must be declared
- Use nullable types `?Type` when appropriate
- Use union types `Type1|Type2` for PHP 8+
**5. Property Types**
```php
private ResourceFactory $resourceFactory; // Required type declaration
private readonly ResourceFactory $factory; // Readonly for immutability
```
**6. Alignment**
```php
$config = [
'short' => 'value', // Align on =>
'longer' => 'another',
];
```
## 🔒 Security
### FAL (File Abstraction Layer)
- **Always use FAL:** Never direct file system access
- **ResourceFactory:** For retrieving files by UID
- **File validation:** Check isDeleted(), isMissing()
- **ProcessedFile:** Use process() for image manipulation
```php
// ✅ Good: FAL usage
$file = $this->resourceFactory->getFileObject($id);
if ($file->isDeleted() || $file->isMissing()) {
throw new \Exception('File not found');
}
// ❌ Bad: Direct file access
$file = file_get_contents('/var/www/uploads/' . $filename);
```
### Input Validation
- **Type cast superglobals:** `(int)($request->getQueryParams()['id'] ?? 0)`
- **Validate before use:** Check ranges, formats, existence
- **Exit on error:** Use HTTP status codes with `HttpUtility::HTTP_STATUS_*`
### XSS Prevention
- **Fluid templates:** Auto-escaping enabled by default
- **JSON responses:** Use `JsonResponse` class
- **Localization:** Via `LocalizationUtility::translate()`
## ✅ PR/Commit Checklist
### PHP-Specific Checks
1.**Strict types:** `declare(strict_types=1);` in all files
2.**Type hints:** All parameters and return types declared
3.**PHPStan:** Zero errors (`composer ci:test:php:phpstan`)
4.**Code style:** PSR-12/PER-CS2.0 compliant (`make format`)
5.**Rector:** No modernization suggestions (`composer ci:test:php:rector`)
6.**FAL usage:** No direct file system access
7.**DI pattern:** Constructor injection, no `new ClassName()`
8.**PSR-7:** Request/Response for controllers
9.**Documentation:** PHPDoc for public methods
## 🎓 Good vs Bad Examples
### ✅ Good: Controller Pattern
```php
<?php
declare(strict_types=1);
namespace Netresearch\RteCKEditorImage\Controller;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Core\Http\JsonResponse;
use TYPO3\CMS\Core\Resource\ResourceFactory;
final class SelectImageController
{
public function __construct(
private readonly ResourceFactory $resourceFactory
) {
}
public function infoAction(ServerRequestInterface $request): ResponseInterface
{
$fileUid = (int)($request->getQueryParams()['fileId'] ?? 0);
if ($fileUid <= 0) {
return new JsonResponse(['error' => 'Invalid file ID'], 400);
}
$file = $this->resourceFactory->getFileObject($fileUid);
return new JsonResponse([
'uid' => $file->getUid(),
'width' => $file->getProperty('width'),
'height' => $file->getProperty('height'),
]);
}
}
```
### ❌ Bad: Anti-patterns
```php
<?php
// ❌ Missing strict types
namespace Netresearch\RteCKEditorImage\Controller;
// ❌ Missing PSR-7 types
class SelectImageController
{
// ❌ No constructor DI
public function infoAction($request)
{
// ❌ Direct superglobal access
$fileUid = $_GET['fileId'];
// ❌ No DI - manual instantiation
$factory = new ResourceFactory();
// ❌ No type safety, no validation
$file = $factory->getFileObject($fileUid);
// ❌ Manual JSON encoding
header('Content-Type: application/json');
echo json_encode(['uid' => $file->getUid()]);
exit;
}
}
```
### ✅ Good: EventListener Pattern
```php
<?php
declare(strict_types=1);
namespace Netresearch\RteCKEditorImage\EventListener;
use TYPO3\CMS\Backend\Routing\UriBuilder;
use TYPO3\CMS\RteCKEditor\Form\Element\Event\AfterPrepareConfigurationForEditorEvent;
final class RteConfigurationListener
{
public function __construct(
private readonly UriBuilder $uriBuilder
) {
}
public function __invoke(AfterPrepareConfigurationForEditorEvent $event): void
{
$configuration = $event->getConfiguration();
$configuration['style']['typo3image'] = [
'routeUrl' => (string)$this->uriBuilder->buildUriFromRoute('rteckeditorimage_wizard_select_image'),
];
$event->setConfiguration($configuration);
}
}
```
### ❌ Bad: EventListener Anti-pattern
```php
<?php
namespace Netresearch\RteCKEditorImage\EventListener;
class RteConfigurationListener
{
// ❌ Wrong signature - not invokable
public function handle($event)
{
// ❌ Manual instantiation instead of DI
$uriBuilder = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(UriBuilder::class);
// ❌ Array access without type safety
$config = $event->getConfiguration();
$config['style']['typo3image']['routeUrl'] = $uriBuilder->buildUriFromRoute('rteckeditorimage_wizard_select_image');
$event->setConfiguration($config);
}
}
```
### ✅ Good: FAL Usage
```php
protected function getImage(int $id): File
{
try {
$file = $this->resourceFactory->getFileObject($id);
if ($file->isDeleted() || $file->isMissing()) {
throw new FileNotFoundException('File not found or deleted', 1234567890);
}
} catch (\Exception $e) {
throw new FileNotFoundException('Could not load file', 1234567891, $e);
}
return $file;
}
```
### ❌ Bad: Direct File Access
```php
// ❌ Multiple issues
protected function getImage($id) // Missing return type, no type hint
{
// ❌ Direct file system access, bypassing FAL
$path = '/var/www/html/fileadmin/' . $id;
// ❌ No validation, no error handling
if (file_exists($path)) {
return file_get_contents($path);
}
return null; // ❌ Should throw exception or return typed null
}
```
## 🆘 When Stuck
### Documentation
- **API Reference:** [docs/API/Controllers.md](../docs/API/Controllers.md) - Controller APIs
- **Event Listeners:** [docs/API/EventListeners.md](../docs/API/EventListeners.md) - PSR-14 events
- **Data Handling:** [docs/API/DataHandling.md](../docs/API/DataHandling.md) - Database hooks
- **Architecture:** [docs/Architecture/Overview.md](../docs/Architecture/Overview.md) - System design
### TYPO3 Resources
- **FAL Documentation:** https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ApiOverview/Fal/Index.html
- **PSR-14 Events:** https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ApiOverview/Events/Index.html
- **Dependency Injection:** https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ApiOverview/DependencyInjection/Index.html
- **Controllers:** https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ApiOverview/Backend/Controllers/Index.html
### Common Issues
- **ResourceFactory errors:** Check file exists, not deleted, proper UID
- **DI not working:** Verify `Configuration/Services.yaml` registration
- **PHPStan errors:** Update baseline: `composer ci:test:php:phpstan:baseline`
- **Type errors:** Enable strict_types, add all type hints
## 📐 House Rules
### Controllers
- **Extend framework controllers:** ElementBrowserController for browsers
- **Final by default:** Use `final class` unless inheritance required
- **PSR-7 types:** ServerRequestInterface → ResponseInterface
- **JSON responses:** Use `JsonResponse` class
- **Validation first:** Validate all input parameters at method start
### EventListeners
- **Invokable:** Use `__invoke()` method signature
- **Event type hints:** Type-hint specific event classes
- **Immutability aware:** Get, modify, set configuration/state
- **Final classes:** Event listeners should be final
### DataHandling
- **Soft references:** Implement soft reference parsing for data integrity
- **Database hooks:** Use for maintaining referential integrity
- **Transaction safety:** Consider rollback scenarios
### Dependencies
- **Constructor injection:** All dependencies via constructor
- **Readonly properties:** Use `readonly` for immutable dependencies
- **Interface over implementation:** Depend on interfaces when available
- **GeneralUtility::makeInstance:** Only for factories or when DI unavailable
### Error Handling
- **Type-specific exceptions:** Use TYPO3 exception hierarchy
- **HTTP status codes:** Via HttpUtility constants
- **Meaningful messages:** Include context in exception messages
- **Log important errors:** Use TYPO3 logging framework
### Testing
- **Functional tests:** For controllers, database operations
- **Unit tests:** For utilities, isolated logic
- **Mock FAL:** Use TYPO3 testing framework FAL mocks
- **Test location:** `Tests/Functional/` and `Tests/Unit/`
## 🔗 Related
- **[Resources/AGENTS.md](../Resources/AGENTS.md)** - JavaScript/CKEditor integration
- **[Tests/AGENTS.md](../Tests/AGENTS.md)** - Testing patterns
- **[Configuration/Services.yaml](../Configuration/Services.yaml)** - DI container configuration
- **[docs/API/](../docs/API/)** - Complete API documentation