info('Fetching: ' . $url); $response = Http::timeout(30)->acceptJson()->get($url); if (!$response->ok()) { $this->error('Failed to fetch data: ' . $response->status()); return self::FAILURE; } $data = $response->json(); if (!is_array($data)) { $this->error('Unexpected response format'); return self::FAILURE; } $countCategories = 0; $countPoses = 0; foreach ($data as $cat) { $extId = (int) ($cat['id'] ?? 0); if ($extId <= 0) { continue; } $category = YogaCategory::updateOrCreate( ['external_id' => $extId], [ 'name' => (string) ($cat['category_name'] ?? 'Category ' . $extId), 'description' => (string) ($cat['category_description'] ?? ''), ] ); $countCategories++; $poses = $cat['poses'] ?? []; if (!is_array($poses)) { $poses = []; } foreach ($poses as $pose) { $pExt = (int) ($pose['id'] ?? 0); if ($pExt <= 0) { continue; } $payload = [ 'category_id' => $category->id, 'english_name' => (string) ($pose['english_name'] ?? ''), 'sanskrit_name_adapted' => (string) ($pose['sanskrit_name_adapted'] ?? ''), 'sanskrit_name' => (string) ($pose['sanskrit_name'] ?? ''), 'translation_name' => (string) ($pose['translation_name'] ?? ''), 'description' => (string) ($pose['pose_description'] ?? ''), 'benefits' => (string) ($pose['pose_benefits'] ?? ''), 'url_svg' => (string) ($pose['url_svg'] ?? ''), 'url_png' => (string) ($pose['url_png'] ?? ''), 'url_svg_alt' => (string) ($pose['url_svg_alt'] ?? ''), ]; $model = YogaPose::updateOrCreate( ['external_id' => $pExt], $payload + [ // slug may be regenerated with --force 'slug' => $this->makeSlug($payload['english_name'], $pExt, $category->name), ] ); if ($this->option('force')) { $model->slug = $this->makeSlug($payload['english_name'], $pExt, $category->name, true); $model->save(); } $countPoses++; } } $this->info("Imported {$countCategories} categories, {$countPoses} poses."); return self::SUCCESS; } protected function makeSlug(string $englishName, int $externalId, string $categoryName = '', bool $force = false): string { $base = Str::slug($englishName !== '' ? $englishName : ('pose-' . $externalId)); if ($base === '') { $base = 'pose-' . $externalId; } $slug = $base; $i = 1; while (YogaPose::where('slug', $slug)->exists()) { // If force-regenerating we allow different category-based suffix to reduce collisions $suffix = $force && $categoryName ? '-' . Str::slug($categoryName) : ''; $slug = $base . $suffix . '-' . (++$i); } return $slug; } }