浏览代码

Http functional moved in abstract class SearchDummyJson

Alexander Musikhin 1 年之前
父节点
当前提交
85def13110
共有 2 个文件被更改,包括 106 次插入56 次删除
  1. 79 0
      app/Console/Commands/SearchDummyJson.php
  2. 27 56
      app/Console/Commands/SearchProducts.php

+ 79 - 0
app/Console/Commands/SearchDummyJson.php

@@ -0,0 +1,79 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Models\Tag;
+use Illuminate\Console\Command;
+use Illuminate\Http\Client\ConnectionException;
+use Illuminate\Support\Facades\Http;
+use Illuminate\Support\Str;
+
+abstract class SearchDummyJson extends Command
+{
+    /**
+     * Limit fetching data per iteration
+     *
+     * @var int
+     */
+    protected int $limit = 5;
+
+    /**
+     * Get or create tags ids from Tag model
+     *
+     * @param $tags
+     * @return array
+     */
+    protected function getTagsIds($tags):array
+    {
+        $ids = [];
+        foreach ($tags as $tag){
+            $t = Tag::query()->firstOrCreate(['name' => $tag]);
+            $ids[] = $t->id;
+        }
+        return $ids;
+    }
+
+    /**
+     * Convert array keys from camelCase to snake_case
+     *
+     * @param $arr
+     * @return array
+     */
+    protected function arrayKeysCamelToSnake($arr): array
+    {
+        $ret = [];
+        foreach ($arr as $k => $v)
+            $ret[Str::snake($k)] = $v;
+        return $ret;
+    }
+
+    /**
+     * Get data from DummyJSON by name
+     *
+     * @param $name
+     * @param $q
+     * @return array
+     * @throws ConnectionException
+     */
+    protected function getJson($name, $q): array
+    {
+        $skip = $total = 0;
+        $data = [];
+        do{
+            $response = Http::retry(10, 15)
+                ->get('https://dummyjson.com/' . $name . '/search', ['q' => $q, 'limit' => $this->limit, 'skip' => $skip]);
+
+            if($response->successful()){
+                $data = array_merge($data, $response->json($name));
+                $skip = $response->json('skip');
+                $total = $response->json('total');
+                $skip += $this->limit;
+                $this->info('Received ' . count($data) . ' / ' . $total);
+            } else {
+                $this->error('Error on HTTP request!');
+            }
+        } while($skip < $total);
+
+        return $data;
+    }
+}

+ 27 - 56
app/Console/Commands/GetProducts.php → app/Console/Commands/SearchProducts.php

@@ -5,12 +5,9 @@ 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;
+use Illuminate\Http\Client\ConnectionException;
 
-class GetProducts extends Command
+class SearchProducts extends SearchDummyJson
 {
     /**
      * The name and signature of the console command.
@@ -29,51 +26,43 @@ class GetProducts extends Command
     /**
      * Execute the console command.
      */
-    public function handle()
+    public function handle(): void
     {
-        $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);
+        try {
+            $products = $this->getJson('products', 'iPhone');
+            $this->upsertProducts($products);
+            $this->info('Done!');
+        } catch (ConnectionException $e) {
+            $this->error('Error fetching data!');
+            dump($e);
+        }
     }
 
-    protected function upsertProducts($products):void
+    /**
+     * Prepare data and update or insert into DB
+     * todo: need validation
+     *
+     * @param $products
+     * @return void
+     */
+    protected function upsertProducts($products): void
     {
-        foreach ($products as $product){
+        foreach ($products as $product) {
 
+            // remember foreign tables data
             $tags = $product['tags'];
             $reviews = $product['reviews'];
             $images = $product['images'];
 
+            // move some subarray elements to root
             $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'] );
-
+            // remove extra data
+            unset($product['tags'], $product['reviews'], $product['images'], $product['dimensions'], $product['meta']);
 
             $product = $this->arrayKeysCamelToSnake($product);
             Product::query()->updateOrInsert(['id' => $product['id']], $product);
@@ -85,35 +74,17 @@ class GetProducts extends Command
 
             // delete all reviews and create from received
             ProductReview::query()->where('product_id', '=', $p->id)->delete();
-            foreach ($reviews as $review){
+            foreach ($reviews as $review) {
                 $review['product_id'] = $p->id;
                 ProductReview::query()->create($this->arrayKeysCamelToSnake($review));
             }
 
+            // delete all images and create from received
             ProductImage::query()->where('product_id', '=', $p->id)->delete();
-            foreach ($images as $image){
+            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;
-    }
 }