$categoryIds * @return array */ public function resolve(array $categoryIds): array { if (empty($categoryIds)) { return []; } $categories = []; $missingIds = []; // Step 1: Check memory cache foreach ($categoryIds as $id) { $cached = Cache::get(self::MEMORY_CACHE_PREFIX.$id); if ($cached !== null) { $categories[$id] = $cached; } else { $missingIds[] = $id; } } if (empty($missingIds)) { return $categories; } // Step 2: Check database cache $dbCategories = SettingsCatalogCategory::whereIn('category_id', $missingIds)->get(); foreach ($dbCategories as $dbCat) { $metadata = [ 'displayName' => $dbCat->display_name, 'description' => $dbCat->description, ]; $categories[$dbCat->category_id] = $metadata; // Cache in memory Cache::put( self::MEMORY_CACHE_PREFIX.$dbCat->category_id, $metadata, now()->addSeconds(self::CACHE_TTL) ); $missingIds = array_diff($missingIds, [$dbCat->category_id]); } if (empty($missingIds)) { return $categories; } // Step 3: Fetch from Graph API try { $graphCategories = $this->fetchFromGraph($missingIds); foreach ($graphCategories as $categoryId => $metadata) { // Store in database SettingsCatalogCategory::updateOrCreate( ['category_id' => $categoryId], [ 'display_name' => $metadata['displayName'], 'description' => $metadata['description'], ] ); // Cache in memory Cache::put( self::MEMORY_CACHE_PREFIX.$categoryId, $metadata, now()->addSeconds(self::CACHE_TTL) ); $categories[$categoryId] = $metadata; } } catch (\Exception $e) { Log::error('Failed to fetch categories from Graph API', [ 'category_ids' => $missingIds, 'error' => $e->getMessage(), ]); } // Step 4: Fallback for still missing categories foreach ($missingIds as $id) { if (! isset($categories[$id])) { $fallback = [ 'displayName' => 'Category', 'description' => null, ]; $categories[$id] = $fallback; // Cache fallback in memory too (short TTL) Cache::put( self::MEMORY_CACHE_PREFIX.$id, $fallback, now()->addMinutes(5) ); } } return $categories; } /** * Resolve a single category ID. */ public function resolveOne(string $categoryId): ?array { $result = $this->resolve([$categoryId]); return $result[$categoryId] ?? null; } /** * Fetch categories from Graph API. */ private function fetchFromGraph(array $categoryIds): array { $categories = []; // Fetch each category individually // Endpoint: /deviceManagement/configurationCategories/{categoryId} foreach ($categoryIds as $categoryId) { try { $response = $this->graphClient->request( 'GET', "/deviceManagement/configurationCategories/{$categoryId}" ); if ($response->successful() && isset($response->data)) { $item = $response->data; $categories[$categoryId] = [ 'displayName' => $item['displayName'] ?? 'Category', 'description' => $item['description'] ?? null, ]; } } catch (\Exception $e) { Log::warning('Failed to fetch category from Graph API', [ 'categoryId' => $categoryId, 'error' => $e->getMessage(), ]); // Continue with other categories } } return $categories; } }