- 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)
141 lines
4.5 KiB
PHP
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()
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|