diff --git a/src/Controller/BulkInfoProviderImportController.php b/src/Controller/BulkInfoProviderImportController.php index ee8658e6..905df42d 100644 --- a/src/Controller/BulkInfoProviderImportController.php +++ b/src/Controller/BulkInfoProviderImportController.php @@ -30,8 +30,8 @@ use App\Entity\Parts\Supplier; use App\Form\InfoProviderSystem\GlobalFieldMappingType; use App\Services\InfoProviderSystem\BulkInfoProviderService; use App\Services\InfoProviderSystem\DTOs\BulkSearchResponseDTO; -use App\Services\InfoProviderSystem\DTOs\FieldMappingDTO; -use App\Services\InfoProviderSystem\DTOs\PartSearchResultsDTO; +use App\Services\InfoProviderSystem\DTOs\BulkSearchFieldMappingDTO; +use App\Services\InfoProviderSystem\DTOs\BulkSearchPartResultsDTO; use Doctrine\ORM\EntityManagerInterface; use Psr\Log\LoggerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; @@ -60,13 +60,13 @@ class BulkInfoProviderImportController extends AbstractController * Convert field mappings from array format to FieldMappingDTO[]. * * @param array $fieldMappings Array of field mapping arrays - * @return FieldMappingDTO[] Array of FieldMappingDTO objects + * @return BulkSearchFieldMappingDTO[] Array of FieldMappingDTO objects */ private function convertFieldMappingsToDto(array $fieldMappings): array { $dtos = []; foreach ($fieldMappings as $mapping) { - $dtos[] = new FieldMappingDTO(field: $mapping['field'], providers: $mapping['providers'], priority: $mapping['priority'] ?? 1); + $dtos[] = new BulkSearchFieldMappingDTO(field: $mapping['field'], providers: $mapping['providers'], priority: $mapping['priority'] ?? 1); } return $dtos; } @@ -101,7 +101,7 @@ class BulkInfoProviderImportController extends AbstractController return $job; } - private function updatePartSearchResults(BulkInfoProviderImportJob $job, int $partId, ?PartSearchResultsDTO $newResults): void + private function updatePartSearchResults(BulkInfoProviderImportJob $job, int $partId, ?BulkSearchPartResultsDTO $newResults): void { if ($newResults === null) { return; diff --git a/src/Entity/BulkInfoProviderImportJob.php b/src/Entity/BulkInfoProviderImportJob.php index 69570690..936438fd 100644 --- a/src/Entity/BulkInfoProviderImportJob.php +++ b/src/Entity/BulkInfoProviderImportJob.php @@ -26,7 +26,7 @@ use App\Entity\Base\AbstractDBElement; use App\Entity\Parts\Part; use App\Entity\UserSystem\User; use App\Services\InfoProviderSystem\DTOs\BulkSearchResponseDTO; -use App\Services\InfoProviderSystem\DTOs\FieldMappingDTO; +use App\Services\InfoProviderSystem\DTOs\BulkSearchFieldMappingDTO; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\DBAL\Types\Types; @@ -44,7 +44,7 @@ class BulkInfoProviderImportJob extends AbstractDBElement private array $fieldMappings = []; /** - * @var FieldMappingDTO[] The deserialized field mappings DTOs, cached for performance + * @var BulkSearchFieldMappingDTO[] The deserialized field mappings DTOs, cached for performance */ private ?array $fieldMappingsDTO = null; @@ -156,14 +156,14 @@ class BulkInfoProviderImportJob extends AbstractDBElement } /** - * @return FieldMappingDTO[] The deserialized field mappings + * @return BulkSearchFieldMappingDTO[] The deserialized field mappings */ public function getFieldMappings(): array { if ($this->fieldMappingsDTO === null) { // Lazy load the DTOs from the raw JSON data $this->fieldMappingsDTO = array_map( - static fn($data) => FieldMappingDTO::fromSerializableArray($data), + static fn($data) => BulkSearchFieldMappingDTO::fromSerializableArray($data), $this->fieldMappings ); } @@ -172,20 +172,20 @@ class BulkInfoProviderImportJob extends AbstractDBElement } /** - * @param FieldMappingDTO[] $fieldMappings + * @param BulkSearchFieldMappingDTO[] $fieldMappings * @return $this */ public function setFieldMappings(array $fieldMappings): self { //Ensure that we are dealing with the objects here - if (count($fieldMappings) > 0 && !$fieldMappings[0] instanceof FieldMappingDTO) { + if (count($fieldMappings) > 0 && !$fieldMappings[0] instanceof BulkSearchFieldMappingDTO) { throw new \InvalidArgumentException('Expected an array of FieldMappingDTO objects'); } $this->fieldMappingsDTO = $fieldMappings; $this->fieldMappings = array_map( - static fn(FieldMappingDTO $dto) => $dto->toSerializableArray(), + static fn(BulkSearchFieldMappingDTO $dto) => $dto->toSerializableArray(), $fieldMappings ); return $this; diff --git a/src/Services/InfoProviderSystem/BulkInfoProviderService.php b/src/Services/InfoProviderSystem/BulkInfoProviderService.php index dec62f25..586fb873 100644 --- a/src/Services/InfoProviderSystem/BulkInfoProviderService.php +++ b/src/Services/InfoProviderSystem/BulkInfoProviderService.php @@ -6,10 +6,10 @@ namespace App\Services\InfoProviderSystem; use App\Entity\Parts\Part; use App\Entity\Parts\Supplier; -use App\Services\InfoProviderSystem\DTOs\BulkSearchResultDTO; +use App\Services\InfoProviderSystem\DTOs\BulkSearchPartResultDTO; use App\Services\InfoProviderSystem\DTOs\BulkSearchResponseDTO; -use App\Services\InfoProviderSystem\DTOs\FieldMappingDTO; -use App\Services\InfoProviderSystem\DTOs\PartSearchResultsDTO; +use App\Services\InfoProviderSystem\DTOs\BulkSearchFieldMappingDTO; +use App\Services\InfoProviderSystem\DTOs\BulkSearchPartResultsDTO; use App\Services\InfoProviderSystem\Providers\BatchInfoProviderInterface; use App\Services\InfoProviderSystem\Providers\InfoProviderInterface; use Doctrine\ORM\EntityManagerInterface; @@ -33,7 +33,7 @@ final class BulkInfoProviderService * Perform bulk search across multiple parts and providers. * * @param Part[] $parts Array of parts to search for - * @param FieldMappingDTO[] $fieldMappings Array of field mappings defining search strategy + * @param BulkSearchFieldMappingDTO[] $fieldMappings Array of field mappings defining search strategy * @param bool $prefetchDetails Whether to prefetch detailed information for results * @return BulkSearchResponseDTO Structured response containing all search results * @throws \InvalidArgumentException If no valid parts provided @@ -92,7 +92,7 @@ final class BulkInfoProviderService $searchResults = $this->formatSearchResults($allResults); } - $partResults[] = new PartSearchResultsDTO( + $partResults[] = new BulkSearchPartResultsDTO( part: $part, searchResults: $searchResults, errors: [] @@ -117,9 +117,9 @@ final class BulkInfoProviderService * Process parts using batch-capable info providers. * * @param Part[] $parts Array of parts to search for - * @param FieldMappingDTO[] $fieldMappings Array of field mapping configurations + * @param BulkSearchFieldMappingDTO[] $fieldMappings Array of field mapping configurations * @param array $batchProviders Batch providers indexed by key - * @return array Results indexed by part ID + * @return array Results indexed by part ID */ private function processBatchProviders(array $parts, array $fieldMappings, array $batchProviders): array { @@ -145,7 +145,7 @@ final class BulkInfoProviderService $keyword = $this->getKeywordFromField($part, $mapping->field); if ($keyword && isset($providerResults[$keyword])) { foreach ($providerResults[$keyword] as $dto) { - $batchResults[$part->getId()][] = new BulkSearchResultDTO( + $batchResults[$part->getId()][] = new BulkSearchPartResultDTO( searchResult: $dto, sourceField: $mapping->field, sourceKeyword: $keyword, @@ -171,10 +171,10 @@ final class BulkInfoProviderService * Process parts using regular (non-batch) info providers. * * @param Part[] $parts Array of parts to search for - * @param FieldMappingDTO[] $fieldMappings Array of field mapping configurations + * @param BulkSearchFieldMappingDTO[] $fieldMappings Array of field mapping configurations * @param array $regularProviders Regular providers indexed by key - * @param array $excludeResults Results to exclude (from batch processing) - * @return array Results indexed by part ID + * @param array $excludeResults Results to exclude (from batch processing) + * @return array Results indexed by part ID */ private function processRegularProviders(array $parts, array $fieldMappings, array $regularProviders, array $excludeResults): array { @@ -204,7 +204,7 @@ final class BulkInfoProviderService $dtos = $this->infoRetriever->searchByKeyword($keyword, $providers); foreach ($dtos as $dto) { - $regularResults[$part->getId()][] = new BulkSearchResultDTO( + $regularResults[$part->getId()][] = new BulkSearchPartResultDTO( searchResult: $dto, sourceField: $mapping->field, sourceKeyword: $keyword, @@ -229,7 +229,7 @@ final class BulkInfoProviderService * Collect unique keywords for a specific provider from all parts and field mappings. * * @param Part[] $parts Array of parts to collect keywords from - * @param FieldMappingDTO[] $fieldMappings Array of field mapping configurations + * @param BulkSearchFieldMappingDTO[] $fieldMappings Array of field mapping configurations * @param string $providerKey The provider key to collect keywords for * @return string[] Array of unique keywords */ @@ -326,8 +326,8 @@ final class BulkInfoProviderService /** * Format and deduplicate search results. * - * @param BulkSearchResultDTO[] $bulkResults Array of bulk search results - * @return BulkSearchResultDTO[] Array of formatted search results with metadata + * @param BulkSearchPartResultDTO[] $bulkResults Array of bulk search results + * @return BulkSearchPartResultDTO[] Array of formatted search results with metadata */ private function formatSearchResults(array $bulkResults): array { diff --git a/src/Services/InfoProviderSystem/DTOs/FieldMappingDTO.php b/src/Services/InfoProviderSystem/DTOs/BulkSearchFieldMappingDTO.php similarity index 95% rename from src/Services/InfoProviderSystem/DTOs/FieldMappingDTO.php rename to src/Services/InfoProviderSystem/DTOs/BulkSearchFieldMappingDTO.php index ec51ebb2..50b7f4cf 100644 --- a/src/Services/InfoProviderSystem/DTOs/FieldMappingDTO.php +++ b/src/Services/InfoProviderSystem/DTOs/BulkSearchFieldMappingDTO.php @@ -24,9 +24,8 @@ namespace App\Services\InfoProviderSystem\DTOs; /** * Represents a mapping between a part field and the info providers that should search in that field. - * This DTO provides type safety and better structure than raw arrays for field mapping configuration. */ -readonly class FieldMappingDTO +readonly class BulkSearchFieldMappingDTO { /** * @param string $field The field to search in (e.g., 'mpn', 'name', or supplier-specific fields like 'digikey_spn') diff --git a/src/Services/InfoProviderSystem/DTOs/BulkSearchResultDTO.php b/src/Services/InfoProviderSystem/DTOs/BulkSearchPartResultDTO.php similarity index 90% rename from src/Services/InfoProviderSystem/DTOs/BulkSearchResultDTO.php rename to src/Services/InfoProviderSystem/DTOs/BulkSearchPartResultDTO.php index 04c41a64..d46624d4 100644 --- a/src/Services/InfoProviderSystem/DTOs/BulkSearchResultDTO.php +++ b/src/Services/InfoProviderSystem/DTOs/BulkSearchPartResultDTO.php @@ -25,9 +25,9 @@ namespace App\Services\InfoProviderSystem\DTOs; use App\Entity\Parts\Part; /** - * Represents a search result from bulk search with additional context information, like how the part was found. + * Represents a single search result from bulk search with additional context information, like how the part was found. */ -readonly class BulkSearchResultDTO +readonly class BulkSearchPartResultDTO { public function __construct( /** The base search result DTO containing provider data */ diff --git a/src/Services/InfoProviderSystem/DTOs/PartSearchResultsDTO.php b/src/Services/InfoProviderSystem/DTOs/BulkSearchPartResultsDTO.php similarity index 85% rename from src/Services/InfoProviderSystem/DTOs/PartSearchResultsDTO.php rename to src/Services/InfoProviderSystem/DTOs/BulkSearchPartResultsDTO.php index ae414a04..8614f4ec 100644 --- a/src/Services/InfoProviderSystem/DTOs/PartSearchResultsDTO.php +++ b/src/Services/InfoProviderSystem/DTOs/BulkSearchPartResultsDTO.php @@ -26,13 +26,13 @@ use App\Entity\Parts\Part; /** * Represents the search results for a single part from bulk info provider search. - * This DTO provides type safety and clear structure for part search results. + * It contains multiple search results, that match the part. */ -readonly class PartSearchResultsDTO +readonly class BulkSearchPartResultsDTO { /** * @param Part $part The part that was searched for - * @param BulkSearchResultDTO[] $searchResults Array of search results found for this part + * @param BulkSearchPartResultDTO[] $searchResults Array of search results found for this part * @param string[] $errors Array of error messages encountered during search */ public function __construct( @@ -72,12 +72,12 @@ readonly class PartSearchResultsDTO /** * Get search results sorted by priority (ascending). - * @return BulkSearchResultDTO[] + * @return BulkSearchPartResultDTO[] */ public function getResultsSortedByPriority(): array { $results = $this->searchResults; - usort($results, static fn(BulkSearchResultDTO $a, BulkSearchResultDTO $b) => $a->priority <=> $b->priority); + usort($results, static fn(BulkSearchPartResultDTO $a, BulkSearchPartResultDTO $b) => $a->priority <=> $b->priority); return $results; } } diff --git a/src/Services/InfoProviderSystem/DTOs/BulkSearchResponseDTO.php b/src/Services/InfoProviderSystem/DTOs/BulkSearchResponseDTO.php index 0e630d04..dd9ee7ac 100644 --- a/src/Services/InfoProviderSystem/DTOs/BulkSearchResponseDTO.php +++ b/src/Services/InfoProviderSystem/DTOs/BulkSearchResponseDTO.php @@ -32,7 +32,7 @@ use Doctrine\ORM\EntityManagerInterface; readonly class BulkSearchResponseDTO implements \ArrayAccess { /** - * @param PartSearchResultsDTO[] $partResults Array of search results for each part + * @param BulkSearchPartResultsDTO[] $partResults Array of search results for each part */ public function __construct( public array $partResults @@ -41,10 +41,10 @@ readonly class BulkSearchResponseDTO implements \ArrayAccess /** * Replaces the search results for a specific part, and returns a new instance. * @param Part|int $part - * @param PartSearchResultsDTO $new_results + * @param BulkSearchPartResultsDTO $new_results * @return BulkSearchResponseDTO */ - public function replaceResultsForPart(Part|int $part, PartSearchResultsDTO $new_results): self + public function replaceResultsForPart(Part|int $part, BulkSearchPartResultsDTO $new_results): self { $array = $this->partResults; foreach ($array as $index => $partResult) { @@ -85,7 +85,7 @@ readonly class BulkSearchResponseDTO implements \ArrayAccess /** * Get all parts that have search results. - * @return PartSearchResultsDTO[] + * @return BulkSearchPartResultsDTO[] */ public function getPartsWithResults(): array { @@ -94,7 +94,7 @@ readonly class BulkSearchResponseDTO implements \ArrayAccess /** * Get all parts that have errors. - * @return PartSearchResultsDTO[] + * @return BulkSearchPartResultsDTO[] */ public function getPartsWithErrors(): array { @@ -175,9 +175,9 @@ readonly class BulkSearchResponseDTO implements \ArrayAccess { $partResults = []; foreach ($data as $partData) { - $partResults[] = new PartSearchResultsDTO( + $partResults[] = new BulkSearchPartResultsDTO( part: $entityManager->getReference(Part::class, $partData['part_id']), - searchResults: array_map(fn($result) => new BulkSearchResultDTO( + searchResults: array_map(fn($result) => new BulkSearchPartResultDTO( searchResult: SearchResultDTO::fromNormalizedSearchResultArray($result['dto']), sourceField: $result['source_field'] ?? null, sourceKeyword: $result['source_keyword'] ?? null, @@ -199,7 +199,7 @@ readonly class BulkSearchResponseDTO implements \ArrayAccess return isset($this->partResults[$offset]); } - public function offsetGet(mixed $offset): ?PartSearchResultsDTO + public function offsetGet(mixed $offset): ?BulkSearchPartResultsDTO { if (!is_int($offset)) { throw new \InvalidArgumentException("Offset must be an integer."); diff --git a/tests/Controller/BulkInfoProviderImportControllerTest.php b/tests/Controller/BulkInfoProviderImportControllerTest.php index f6986dbc..02cdacda 100644 --- a/tests/Controller/BulkInfoProviderImportControllerTest.php +++ b/tests/Controller/BulkInfoProviderImportControllerTest.php @@ -659,8 +659,8 @@ class BulkInfoProviderImportControllerTest extends WebTestCase // Create field mappings to verify the service works $fieldMappings = [ - new \App\Services\InfoProviderSystem\DTOs\FieldMappingDTO('name', ['test'], 1), - new \App\Services\InfoProviderSystem\DTOs\FieldMappingDTO('mpn', ['test'], 2) + new \App\Services\InfoProviderSystem\DTOs\BulkSearchFieldMappingDTO('name', ['test'], 1), + new \App\Services\InfoProviderSystem\DTOs\BulkSearchFieldMappingDTO('mpn', ['test'], 2) ]; // The service may return an empty result or throw when no results are found @@ -790,8 +790,8 @@ class BulkInfoProviderImportControllerTest extends WebTestCase // Create field mappings with supplier SPN field mapping $fieldMappings = [ - new \App\Services\InfoProviderSystem\DTOs\FieldMappingDTO('invalid_field', ['test'], 1), - new \App\Services\InfoProviderSystem\DTOs\FieldMappingDTO('test_supplier_spn', ['test'], 2) + new \App\Services\InfoProviderSystem\DTOs\BulkSearchFieldMappingDTO('invalid_field', ['test'], 1), + new \App\Services\InfoProviderSystem\DTOs\BulkSearchFieldMappingDTO('test_supplier_spn', ['test'], 2) ]; // The service should be able to process the request and throw an exception when no results are found @@ -821,7 +821,7 @@ class BulkInfoProviderImportControllerTest extends WebTestCase // Create field mappings with multiple keywords $fieldMappings = [ - new \App\Services\InfoProviderSystem\DTOs\FieldMappingDTO('name', ['lcsc'], 1) + new \App\Services\InfoProviderSystem\DTOs\BulkSearchFieldMappingDTO('name', ['lcsc'], 1) ]; // The service should be able to process the request and throw an exception when no results are found diff --git a/tests/Services/InfoProviderSystem/DTOs/BulkSearchResponseDTOTest.php b/tests/Services/InfoProviderSystem/DTOs/BulkSearchResponseDTOTest.php index bc33de3d..b1951e09 100644 --- a/tests/Services/InfoProviderSystem/DTOs/BulkSearchResponseDTOTest.php +++ b/tests/Services/InfoProviderSystem/DTOs/BulkSearchResponseDTOTest.php @@ -23,8 +23,8 @@ namespace App\Tests\Services\InfoProviderSystem\DTOs; use App\Doctrine\Types\BulkSearchResponseDTOType; use App\Entity\Parts\Part; use App\Services\InfoProviderSystem\DTOs\BulkSearchResponseDTO; -use App\Services\InfoProviderSystem\DTOs\BulkSearchResultDTO; -use App\Services\InfoProviderSystem\DTOs\PartSearchResultsDTO; +use App\Services\InfoProviderSystem\DTOs\BulkSearchPartResultDTO; +use App\Services\InfoProviderSystem\DTOs\BulkSearchPartResultsDTO; use App\Services\InfoProviderSystem\DTOs\SearchResultDTO; use Doctrine\ORM\EntityManagerInterface; use PHPUnit\Framework\TestCase; @@ -45,14 +45,14 @@ class BulkSearchResponseDTOTest extends KernelTestCase $this->dummyEmpty = new BulkSearchResponseDTO(partResults: []); $this->dummy = new BulkSearchResponseDTO(partResults: [ - new PartSearchResultsDTO( + new BulkSearchPartResultsDTO( part: $this->entityManager->find(Part::class, 1), searchResults: [ - new BulkSearchResultDTO( + new BulkSearchPartResultDTO( searchResult: new SearchResultDTO(provider_key: "dummy", provider_id: "1234", name: "Test Part", description: "A part for testing"), sourceField: "mpn", sourceKeyword: "1234", priority: 1 ), - new BulkSearchResultDTO( + new BulkSearchPartResultDTO( searchResult: new SearchResultDTO(provider_key: "test", provider_id: "test", name: "Test Part2", description: "A part for testing"), sourceField: "name", sourceKeyword: "1234", localPart: $this->entityManager->find(Part::class, 2), priority: 2,