| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- <?php
- namespace App\Console\Commands;
- use App\Models\Product;
- use App\Models\ProductImage;
- use App\Models\ProductReview;
- use App\Models\Tag;
- use Illuminate\Console\Command;
- use Illuminate\Support\Facades\Http;
- use Illuminate\Support\Str;
- class GetProducts extends Command
- {
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
- protected $signature = 'app:get-products';
- /**
- * The console command description.
- *
- * @var string
- */
- protected $description = 'Get products from DummyJSON';
- /**
- * Execute the console command.
- */
- public function handle()
- {
- $url = 'https://dummyjson.com/products/search';
- $limit = 5;
- $skip = 0;
- $total = 0;
- do{
- $response = Http::retry(10, 15)
- ->get($url, ['q' => 'iphone', 'limit' => $limit, 'skip' => $skip]);
- if($response->successful()){
- $json = $response->json();
- $products = $response->json('products');
- $skip = $response->json('skip');
- $total = $response->json('total');
- $this->upsertProducts($products);
- $skip += $limit;
- $this->info('Received ' . count($products) . ' records');
- } else {
- $this->error('Error on HTTP request!');
- }
- } while($skip < $total);
- $this->info('Total: ' . $total);
- }
- protected function upsertProducts($products):void
- {
- foreach ($products as $product){
- $tags = $product['tags'];
- $reviews = $product['reviews'];
- $images = $product['images'];
- $product['width'] = $product['dimensions']['width'];
- $product['height'] = $product['dimensions']['height'];
- $product['depth'] = $product['dimensions']['depth'];
- $product['barcode'] = $product['meta']['barcode'];
- $product['qr_code'] = $product['meta']['qrCode'];
- unset($product['tags'], $product['reviews'], $product['images'], $product['dimensions'], $product['meta'] );
- $product = $this->arrayKeysCamelToSnake($product);
- Product::query()->updateOrInsert(['id' => $product['id']], $product);
- $p = Product::find($product['id']);
- // detach all tags and attach received
- $p->tags()->detach();
- $p->tags()->attach($this->getTagsIds($tags));
- // delete all reviews and create from received
- ProductReview::query()->where('product_id', '=', $p->id)->delete();
- foreach ($reviews as $review){
- $review['product_id'] = $p->id;
- ProductReview::query()->create($this->arrayKeysCamelToSnake($review));
- }
- ProductImage::query()->where('product_id', '=', $p->id)->delete();
- foreach ($images as $image){
- ProductImage::create(['product_id' => $p->id, 'url' => $image]);
- }
- }
- }
- protected function getTagsIds($tags):array
- {
- $ids = [];
- foreach ($tags as $tag){
- $t = Tag::query()->firstOrCreate(['name' => $tag]);
- $ids[] = $t->id;
- }
- return $ids;
- }
- protected function arrayKeysCamelToSnake($arr): array
- {
- $ret = [];
- foreach ($arr as $k => $v)
- $ret[Str::snake($k)] = $v;
- return $ret;
- }
- }
|