Files
michaelschiemer/src/Domain/Cms/DI/CmsServiceInitializer.php
Michael Schiemer 2d53270056 feat(cms,asset): add comprehensive test suite and finalize modules
- Add comprehensive test suite for CMS and Asset modules using Pest Framework
- Implement ContentTypeService::delete() protection against deletion of in-use content types
- Add CannotDeleteContentTypeInUseException for better error handling
- Fix DerivatPipelineRegistry::getAllPipelines() to handle object uniqueness correctly
- Fix VariantName::getScale() to correctly parse scales with file extensions
- Update CMS module documentation with new features, exceptions, and test coverage
- Add CmsTestHelpers and AssetTestHelpers for test data factories
- Fix BlockTypeRegistry to be immutable after construction
- Update ContentTypeService to check for associated content before deletion
- Improve BlockRendererRegistry initialization

Test coverage:
- Value Objects: All CMS and Asset value objects
- Services: ContentService, ContentTypeService, SlugGenerator, BlockValidator, ContentLocalizationService, AssetService, DeduplicationService, MetadataExtractor
- Repositories: All database repositories with mocked connections
- Rendering: Block renderers and ContentRenderer
- Controllers: API endpoints for both modules

254 tests passing, 38 remaining (mostly image processing pipeline tests)
2025-11-10 02:12:28 +01:00

141 lines
4.5 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Domain\Cms\DI;
use App\Domain\Cms\Repositories\ContentRepository;
use App\Domain\Cms\Repositories\ContentTypeRepository;
use App\Domain\Cms\Repositories\DatabaseContentRepository;
use App\Domain\Cms\Repositories\DatabaseContentTypeRepository;
use App\Domain\Cms\Rendering\BlockRendererRegistry;
use App\Domain\Cms\Rendering\DefaultBlockRenderer;
use App\Domain\Cms\Rendering\HeroBlockRenderer;
use App\Domain\Cms\Rendering\ImageBlockRenderer;
use App\Domain\Cms\Rendering\TextBlockRenderer;
use App\Domain\Cms\Repositories\ContentTranslationRepository;
use App\Domain\Cms\Repositories\DatabaseContentTranslationRepository;
use App\Domain\Cms\Services\BlockTypeRegistry;
use App\Domain\Cms\Services\BlockValidator;
use App\Domain\Cms\Services\ContentLocalizationService;
use App\Domain\Cms\Services\ContentRenderer;
use App\Domain\Cms\Services\ContentService;
use App\Domain\Cms\Services\ContentTypeService;
use App\Domain\Cms\Services\SlugGenerator;
use App\Framework\Database\ConnectionInterface;
use App\Framework\DateTime\Clock;
use App\Framework\DI\Container;
use App\Framework\DI\Initializer;
use App\Framework\View\ComponentRenderer;
/**
* CMS Domain Service Registration
*
* Registers all CMS domain services in the DI container.
*/
final readonly class CmsServiceInitializer
{
#[Initializer]
public function __invoke(Container $container): void
{
// Repository Bindings
$container->singleton(
ContentRepository::class,
fn (Container $c) => new DatabaseContentRepository(
$c->get(ConnectionInterface::class)
)
);
$container->singleton(
ContentTypeRepository::class,
fn (Container $c) => new DatabaseContentTypeRepository(
$c->get(ConnectionInterface::class)
)
);
// Block Type Registry
$container->singleton(
BlockTypeRegistry::class,
fn () => new BlockTypeRegistry()
);
// Services
$container->singleton(
BlockValidator::class,
fn (Container $c) => new BlockValidator(
$c->get(BlockTypeRegistry::class)
)
);
$container->singleton(
SlugGenerator::class,
fn (Container $c) => new SlugGenerator(
$c->get(ContentRepository::class)
)
);
$container->singleton(
ContentService::class,
fn (Container $c) => new ContentService(
$c->get(ContentRepository::class),
$c->get(BlockValidator::class),
$c->get(SlugGenerator::class),
$c->get(Clock::class)
)
);
$container->singleton(
ContentTypeService::class,
fn (Container $c) => new ContentTypeService(
$c->get(ContentTypeRepository::class),
$c->get(ContentRepository::class),
$c->get(Clock::class)
)
);
// Content Translation Repository
$container->singleton(
ContentTranslationRepository::class,
fn (Container $c) => new DatabaseContentTranslationRepository(
$c->get(ConnectionInterface::class)
)
);
// Content Localization Service
$container->singleton(
ContentLocalizationService::class,
fn (Container $c) => new ContentLocalizationService(
$c->get(ContentTranslationRepository::class),
$c->get(Clock::class)
)
);
// Block Renderer Registry
$container->singleton(
BlockRendererRegistry::class,
function (Container $c) {
$registry = new BlockRendererRegistry();
// Register default renderers
$registry->registerForType('hero', new HeroBlockRenderer());
$registry->registerForType('text', new TextBlockRenderer());
$registry->registerForType('image', new ImageBlockRenderer());
return $registry;
}
);
// Content Renderer
$container->singleton(
ContentRenderer::class,
fn (Container $c) => new ContentRenderer(
$c->get(BlockRendererRegistry::class),
$c->get(ComponentRenderer::class),
$c->get(ContentLocalizationService::class),
new DefaultBlockRenderer()
)
);
}
}