Files
michaelschiemer/src/Framework/Search/SearchableMappingRegistry.php
Michael Schiemer 55a330b223 Enable Discovery debug logging for production troubleshooting
- Add DISCOVERY_LOG_LEVEL=debug
- Add DISCOVERY_SHOW_PROGRESS=true
- Temporary changes for debugging InitializerProcessor fixes on production
2025-08-11 20:13:26 +02:00

127 lines
3.8 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Framework\Search;
/**
* Central registry for searchable entity mappings
*/
final class SearchableMappingRegistry
{
/** @var array<string, SearchableMapping> */
private array $mappingsByEntityType = [];
/** @var array<string, SearchableMapping> */
private array $mappingsByEntityClass = [];
public function register(SearchableMapping $mapping): void
{
$this->mappingsByEntityType[$mapping->entityType] = $mapping;
$this->mappingsByEntityClass[$mapping->entityClass] = $mapping;
}
public function getByEntityType(string $entityType): ?SearchableMapping
{
return $this->mappingsByEntityType[$entityType] ?? null;
}
public function getByEntityClass(string $entityClass): ?SearchableMapping
{
return $this->mappingsByEntityClass[$entityClass] ?? null;
}
public function hasMapping(string $entityTypeOrClass): bool
{
return isset($this->mappingsByEntityType[$entityTypeOrClass])
|| isset($this->mappingsByEntityClass[$entityTypeOrClass]);
}
public function getAllMappings(): array
{
return array_values($this->mappingsByEntityType);
}
public function getEntityTypes(): array
{
return array_keys($this->mappingsByEntityType);
}
/**
* Create adapter for entity
*/
public function createAdapter(object $entity): ?SearchableAdapter
{
$entityClass = get_class($entity);
$mapping = $this->getByEntityClass($entityClass);
if (! $mapping || ! $mapping->enabled) {
return null;
}
return new SearchableAdapter($entity, $mapping);
}
/**
* Check if entity is searchable
*/
public function isSearchable(object|string $entityOrClass): bool
{
$entityClass = is_object($entityOrClass) ? get_class($entityOrClass) : $entityOrClass;
$mapping = $this->getByEntityClass($entityClass);
return $mapping && $mapping->enabled;
}
/**
* Bulk register mappings from configuration
*/
public function registerFromConfig(array $config): void
{
foreach ($config as $entityClass => $mappingConfig) {
$builder = SearchableMapping::for($entityClass);
if (isset($mappingConfig['entity_type'])) {
$builder->entityType($mappingConfig['entity_type']);
}
if (isset($mappingConfig['id_field'])) {
$builder->idField($mappingConfig['id_field']);
}
if (isset($mappingConfig['auto_index'])) {
$builder->autoIndex($mappingConfig['auto_index']);
}
if (isset($mappingConfig['enabled'])) {
$builder->enabled($mappingConfig['enabled']);
}
// Add field mappings
foreach ($mappingConfig['fields'] ?? [] as $searchField => $fieldConfig) {
if (is_string($fieldConfig)) {
// Simple mapping: 'title' => 'name'
$builder->field($searchField, $fieldConfig);
} elseif (is_array($fieldConfig)) {
// Complex mapping with transformer
$entityField = $fieldConfig['field'];
$transformer = $fieldConfig['transformer'] ?? null;
if ($transformer && is_string($transformer) && function_exists($transformer)) {
$transformer = $transformer(...);
}
$builder->field($searchField, $entityField, $transformer);
}
}
// Add boosts
foreach ($mappingConfig['boosts'] ?? [] as $field => $boost) {
$builder->boost($field, (float) $boost);
}
$this->register($builder->build());
}
}
}