GetProducts.php 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. <?php
  2. namespace App\Console\Commands;
  3. use App\Models\Product;
  4. use App\Models\ProductImage;
  5. use App\Models\ProductReview;
  6. use App\Models\Tag;
  7. use Illuminate\Console\Command;
  8. use Illuminate\Support\Facades\Http;
  9. use Illuminate\Support\Str;
  10. class GetProducts extends Command
  11. {
  12. /**
  13. * The name and signature of the console command.
  14. *
  15. * @var string
  16. */
  17. protected $signature = 'app:get-products';
  18. /**
  19. * The console command description.
  20. *
  21. * @var string
  22. */
  23. protected $description = 'Get products from DummyJSON';
  24. /**
  25. * Execute the console command.
  26. */
  27. public function handle()
  28. {
  29. $url = 'https://dummyjson.com/products/search';
  30. $limit = 5;
  31. $skip = 0;
  32. $total = 0;
  33. do{
  34. $response = Http::retry(10, 15)
  35. ->get($url, ['q' => 'iphone', 'limit' => $limit, 'skip' => $skip]);
  36. if($response->successful()){
  37. $json = $response->json();
  38. $products = $response->json('products');
  39. $skip = $response->json('skip');
  40. $total = $response->json('total');
  41. $this->upsertProducts($products);
  42. $skip += $limit;
  43. $this->info('Received ' . count($products) . ' records');
  44. } else {
  45. $this->error('Error on HTTP request!');
  46. }
  47. } while($skip < $total);
  48. $this->info('Total: ' . $total);
  49. }
  50. protected function upsertProducts($products):void
  51. {
  52. foreach ($products as $product){
  53. $tags = $product['tags'];
  54. $reviews = $product['reviews'];
  55. $images = $product['images'];
  56. $product['width'] = $product['dimensions']['width'];
  57. $product['height'] = $product['dimensions']['height'];
  58. $product['depth'] = $product['dimensions']['depth'];
  59. $product['barcode'] = $product['meta']['barcode'];
  60. $product['qr_code'] = $product['meta']['qrCode'];
  61. unset($product['tags'], $product['reviews'], $product['images'], $product['dimensions'], $product['meta'] );
  62. $product = $this->arrayKeysCamelToSnake($product);
  63. Product::query()->updateOrInsert(['id' => $product['id']], $product);
  64. $p = Product::find($product['id']);
  65. // detach all tags and attach received
  66. $p->tags()->detach();
  67. $p->tags()->attach($this->getTagsIds($tags));
  68. // delete all reviews and create from received
  69. ProductReview::query()->where('product_id', '=', $p->id)->delete();
  70. foreach ($reviews as $review){
  71. $review['product_id'] = $p->id;
  72. ProductReview::query()->create($this->arrayKeysCamelToSnake($review));
  73. }
  74. ProductImage::query()->where('product_id', '=', $p->id)->delete();
  75. foreach ($images as $image){
  76. ProductImage::create(['product_id' => $p->id, 'url' => $image]);
  77. }
  78. }
  79. }
  80. protected function getTagsIds($tags):array
  81. {
  82. $ids = [];
  83. foreach ($tags as $tag){
  84. $t = Tag::query()->firstOrCreate(['name' => $tag]);
  85. $ids[] = $t->id;
  86. }
  87. return $ids;
  88. }
  89. protected function arrayKeysCamelToSnake($arr): array
  90. {
  91. $ret = [];
  92. foreach ($arr as $k => $v)
  93. $ret[Str::snake($k)] = $v;
  94. return $ret;
  95. }
  96. }