3030use App \Form \InfoProviderSystem \GlobalFieldMappingType ;
3131use App \Services \InfoProviderSystem \PartInfoRetriever ;
3232use App \Services \InfoProviderSystem \ExistingPartFinder ;
33+ use App \Services \InfoProviderSystem \ProviderRegistry ;
34+ use App \Services \InfoProviderSystem \Providers \LCSCProvider ;
3335use Doctrine \ORM \EntityManagerInterface ;
3436use Psr \Log \LoggerInterface ;
3537use Symfony \Bundle \FrameworkBundle \Controller \AbstractController ;
@@ -44,6 +46,7 @@ class BulkInfoProviderImportController extends AbstractController
4446{
4547 public function __construct (
4648 private readonly PartInfoRetriever $ infoRetriever ,
49+ private readonly LCSCProvider $ LCSCProvider ,
4750 private readonly ExistingPartFinder $ existingPartFinder ,
4851 private readonly EntityManagerInterface $ entityManager
4952 ) {
@@ -53,7 +56,7 @@ public function __construct(
5356 public function step1 (Request $ request , LoggerInterface $ exceptionLogger ): Response
5457 {
5558 $ this ->denyAccessUnlessGranted ('@info_providers.create_parts ' );
56-
59+
5760 // Increase execution time for bulk operations
5861 set_time_limit (600 ); // 10 minutes for large batches
5962
@@ -72,7 +75,7 @@ public function step1(Request $request, LoggerInterface $exceptionLogger): Respo
7275 $ this ->addFlash ('error ' , 'No valid parts found for bulk import ' );
7376 return $ this ->redirectToRoute ('homepage ' );
7477 }
75-
78+
7679 // Warn about large batches
7780 if (count ($ parts ) > 50 ) {
7881 $ this ->addFlash ('warning ' , 'Processing ' . count ($ parts ) . ' parts may take several minutes and could timeout. Consider processing smaller batches. ' );
@@ -110,7 +113,7 @@ public function step1(Request $request, LoggerInterface $exceptionLogger): Respo
110113 $ formData = $ form ->getData ();
111114 $ fieldMappings = $ formData ['field_mappings ' ];
112115 $ prefetchDetails = $ formData ['prefetch_details ' ] ?? false ;
113-
116+
114117 // Debug logging
115118 $ exceptionLogger ->info ('Form data received ' , [
116119 'prefetch_details ' => $ prefetchDetails ,
@@ -143,13 +146,13 @@ public function step1(Request $request, LoggerInterface $exceptionLogger): Respo
143146 // Optimize: Use batch async requests for LCSC provider
144147 $ lcscKeywords = [];
145148 $ keywordToPartField = [];
146-
149+
147150 // First, collect all LCSC keywords for batch processing
148151 foreach ($ parts as $ part ) {
149152 foreach ($ fieldMappings as $ mapping ) {
150153 $ field = $ mapping ['field ' ];
151154 $ providers = $ mapping ['providers ' ] ?? [];
152-
155+
153156 if (in_array ('lcsc ' , $ providers , true )) {
154157 $ keyword = $ this ->getKeywordFromField ($ part , $ field );
155158 if ($ keyword ) {
@@ -291,11 +294,11 @@ function ($dto) use ($dtoMetadata) {
291294 'job_id ' => $ job ->getId (),
292295 'parts_count ' => count ($ parts )
293296 ]);
294-
297+
295298 // Delete the job since it has no useful results
296299 $ this ->entityManager ->remove ($ job );
297300 $ this ->entityManager ->flush ();
298-
301+
299302 $ this ->addFlash ('error ' , 'No search results found for any of the selected parts. Please check your field mappings and provider selections. ' );
300303 return $ this ->redirectToRoute ('bulk_info_provider_step1 ' , ['ids ' => implode (', ' , $ partIds )]);
301304 }
@@ -304,18 +307,18 @@ function ($dto) use ($dtoMetadata) {
304307 $ job ->setSearchResults ($ this ->serializeSearchResults ($ searchResults ));
305308 $ job ->markAsInProgress ();
306309 $ this ->entityManager ->flush ();
307-
310+
308311 } catch (\Exception $ e ) {
309312 $ exceptionLogger ->error ('Critical error during bulk import search ' , [
310313 'job_id ' => $ job ->getId (),
311314 'error ' => $ e ->getMessage (),
312315 'exception ' => $ e
313316 ]);
314-
317+
315318 // Delete the job on critical failure
316319 $ this ->entityManager ->remove ($ job );
317320 $ this ->entityManager ->flush ();
318-
321+
319322 $ this ->addFlash ('error ' , 'Search failed due to an error: ' . $ e ->getMessage ());
320323 return $ this ->redirectToRoute ('bulk_info_provider_step1 ' , ['ids ' => implode (', ' , $ partIds )]);
321324 }
@@ -356,19 +359,19 @@ public function manageBulkJobs(): Response
356359 // Also clean up jobs with no results (failed searches)
357360 $ updatedJobs = false ;
358361 $ jobsToDelete = [];
359-
362+
360363 foreach ($ allJobs as $ job ) {
361364 if ($ job ->isAllPartsCompleted () && !$ job ->isCompleted ()) {
362365 $ job ->markAsCompleted ();
363366 $ updatedJobs = true ;
364367 }
365-
368+
366369 // Mark jobs with no results for deletion (failed searches)
367370 if ($ job ->getResultCount () === 0 && $ job ->isInProgress ()) {
368371 $ jobsToDelete [] = $ job ;
369372 }
370373 }
371-
374+
372375 // Delete failed jobs
373376 foreach ($ jobsToDelete as $ job ) {
374377 $ this ->entityManager ->remove ($ job );
@@ -378,7 +381,7 @@ public function manageBulkJobs(): Response
378381 // Flush changes if any jobs were updated
379382 if ($ updatedJobs ) {
380383 $ this ->entityManager ->flush ();
381-
384+
382385 if (!empty ($ jobsToDelete )) {
383386 $ this ->addFlash ('info ' , 'Cleaned up ' . count ($ jobsToDelete ) . ' failed job(s) with no results. ' );
384387 }
@@ -619,18 +622,7 @@ private function deserializeSearchResults(array $serializedResults, array $parts
619622 */
620623 private function searchLcscBatch (array $ keywords ): array
621624 {
622- // Get LCSC provider through reflection since PartInfoRetriever doesn't expose it
623- $ reflection = new \ReflectionClass ($ this ->infoRetriever );
624- $ registryProp = $ reflection ->getProperty ('provider_registry ' );
625- $ registryProp ->setAccessible (true );
626- $ registry = $ registryProp ->getValue ($ this ->infoRetriever );
627-
628- $ lcscProvider = $ registry ->getProviderByKey ('lcsc ' );
629- if ($ lcscProvider && method_exists ($ lcscProvider , 'searchByKeywordsBatch ' )) {
630- return $ lcscProvider ->searchByKeywordsBatch ($ keywords );
631- }
632-
633- return [];
625+ return $ this ->LCSCProvider ->searchByKeywordsBatch ($ keywords );
634626 }
635627
636628 #[Route('/job/{jobId}/part/{partId}/mark-completed ' , name: 'bulk_info_provider_mark_completed ' , methods: ['POST ' ])]
@@ -710,4 +702,4 @@ public function markPartPending(int $jobId, int $partId): Response
710702 'job_completed ' => $ job ->isCompleted ()
711703 ]);
712704 }
713- }
705+ }
0 commit comments