Browse code

Optimize API functions and CLI commands

Benjamin Roth authored on21/10/2024 15:41:50
Showing3 changed files
... ...
@@ -15,6 +15,7 @@ namespace vonRotenberg\ShopwareApiBundle\API;
15 15
 use Contao\System;
16 16
 use Symfony\Component\Serializer\SerializerInterface;
17 17
 use Symfony\Contracts\HttpClient\HttpClientInterface;
18
+use Symfony\Contracts\HttpClient\ResponseInterface;
18 19
 
19 20
 class Shopware
20 21
 {
... ...
@@ -61,7 +62,14 @@ class Shopware
61 62
 
62 63
         $relEndpoint = '/' . ltrim($relEndpoint,'/');
63 64
 
64
-        return $this->httpClient->request($method,$this->getApiEndpoint().$relEndpoint,$options);
65
+        $request = $this->httpClient->request($method,$this->getApiEndpoint().$relEndpoint,$options);
66
+
67
+        if ($request->getStatusCode() == 401)
68
+        {
69
+            throw new \RuntimeException('Unauthorized');
70
+        }
71
+
72
+        return $request;
65 73
     }
66 74
 
67 75
     protected function getAccessToken()
... ...
@@ -84,20 +92,16 @@ class Shopware
84 92
             return json_decode($content);
85 93
         }
86 94
 
87
-        return null;
95
+        throw new \RuntimeException('Can\'t retrieve access token. Check credentials.');
88 96
     }
89 97
 
90 98
     protected function getAuthentication()
91 99
     {
92
-        if (($Token = $this->getAccessToken()) !== null)
93
-        {
94
-            return 'Authorization: ' . $Token->token_type . ' ' . $Token->access_token;
95
-        }
96
-
97
-        return null;
100
+        $Token = $this->getAccessToken();
101
+        return 'Authorization: ' . $Token->token_type . ' ' . $Token->access_token;
98 102
     }
99 103
 
100
-    public function isShopwareRunning()
104
+    public function isShopwareRunning(): bool
101 105
     {
102 106
         $options = [
103 107
             'headers' => [
... ...
@@ -117,10 +121,8 @@ class Shopware
117 121
         return false;
118 122
     }
119 123
 
120
-    public function getProductsForSku(string $strSku, bool $blnWildcardSearch=false, bool $blnShort=false)
124
+    public function getProductsForSku(string $strSku, bool $blnWildcardSearch=false, bool $blnShort=false): ResponseInterface
121 125
     {
122
-
123
-
124 126
         $options = [
125 127
             'headers' => [
126 128
                 $this->getAuthentication(),
... ...
@@ -159,13 +161,28 @@ class Shopware
159 161
             );
160 162
         }
161 163
 
162
-        $response = $this->sendRequest('search/product',$options,'POST');
164
+        return $this->sendRequest('search/product',$options,'POST');
165
+    }
163 166
 
164
-        if ($response->getStatusCode() == 200)
167
+    public function queryAPI(string $strUrlFragment, ?string $strBody, string $strMethod = 'GET', bool $blnAuthenticate=true): ResponseInterface
168
+    {
169
+        $options = [
170
+            'headers' => [
171
+                'Content-Type: application/json',
172
+                'Accept: application/json'
173
+            ]
174
+        ];
175
+
176
+        if ($blnAuthenticate)
165 177
         {
166
-            return json_decode($response->getContent());
178
+            $options['headers'][] = $this->getAuthentication();
167 179
         }
168 180
 
169
-        return false;
181
+        if ($strBody !== null)
182
+        {
183
+            $options['body'] = $strBody;
184
+        }
185
+
186
+        return $this->sendRequest($strUrlFragment,$options,$strMethod);
170 187
     }
171 188
 }
172 189
new file mode 100644
... ...
@@ -0,0 +1,84 @@
1
+<?php
2
+
3
+declare(strict_types=1);
4
+
5
+/*
6
+ * This file is part of vonRotenberg Shopware API Bundle.
7
+ *
8
+ * (c) vonRotenberg
9
+ *
10
+ * @license proprietary
11
+ */
12
+
13
+namespace vonRotenberg\ShopwareApiBundle\Command;
14
+
15
+use Contao\CoreBundle\Framework\ContaoFramework;
16
+use Contao\System;
17
+use Symfony\Component\Console\Command\Command;
18
+use Symfony\Component\Console\Input\InputArgument;
19
+use Symfony\Component\Console\Input\InputInterface;
20
+use Symfony\Component\Console\Input\InputOption;
21
+use Symfony\Component\Console\Output\OutputInterface;
22
+use Symfony\Component\Console\Style\SymfonyStyle;
23
+use Symfony\Component\VarDumper\Cloner\VarCloner;
24
+use Symfony\Component\VarDumper\Dumper\CliDumper;
25
+use vonRotenberg\ShopwareApiBundle\API\Shopware;
26
+
27
+class ShopwareApiTester extends Command
28
+{
29
+    protected static $defaultName = 'shopware:api-test';
30
+
31
+    protected $framework;
32
+
33
+    public function __construct(ContaoFramework $framework)
34
+    {
35
+        $this->framework = $framework;
36
+
37
+        parent::__construct();
38
+    }
39
+
40
+    protected function configure(): void
41
+    {
42
+        $this
43
+            ->setName(self::$defaultName)
44
+            ->setDescription('Query the Shopware API')
45
+            ->addOption('authenticate','a',InputOption::VALUE_NONE, 'Use Token authentication with request')
46
+        ;
47
+    }
48
+    protected function execute(InputInterface $input, OutputInterface $output): int
49
+    {
50
+        $this->framework->initialize();
51
+        $cloner = new VarCloner();
52
+        $dumper = new CliDumper();
53
+
54
+        $io = new SymfonyStyle($input, $output);
55
+        $io->title('Shopware API Tester');
56
+        $strUrlFragment = $io->ask('Enter URL fragment');
57
+        $strMethod = $io->choice('Request type',['GET','POST','PUT','DELETE','PATCH'], 'GET');
58
+        $strBody = $io->ask('Enter request body (JSON)', null, function ($strBody) {
59
+            if ($strBody !== null && !json_validate($strBody)) {
60
+                throw new \RuntimeException('Invalid JSON body');
61
+            }
62
+
63
+            return $strBody;
64
+        });
65
+
66
+        /** @var Shopware $Shopware */
67
+        $Shopware = System::getContainer()->get(Shopware::class);
68
+
69
+        $Result = $Shopware->queryAPI($strUrlFragment,$strBody, $strMethod, (bool)$input->getOption('authenticate'));
70
+
71
+        if ($Result->getStatusCode() === 200)
72
+        {
73
+            $dumper->dump(($cloner->cloneVar(json_validate($Result->getContent()) ? json_decode($Result->getContent(), true) : $Result)));
74
+
75
+            $io->success('Successful response');
76
+
77
+            return self::SUCCESS;
78
+        }
79
+
80
+        $io->error(sprintf('Error when querying the Shopware API. HTTP Status returned: %s',$Result->getStatusCode()));
81
+
82
+        return self::FAILURE;
83
+    }
84
+}
... ...
@@ -48,6 +48,8 @@ class ShopwareGetProductsBySku extends Command
48 48
     protected function execute(InputInterface $input, OutputInterface $output): int
49 49
     {
50 50
         $this->framework->initialize();
51
+        $cloner = new VarCloner();
52
+        $dumper = new CliDumper();
51 53
 
52 54
         $io = new SymfonyStyle($input, $output);
53 55
         $io->title('Shopware products search by SKU');
... ...
@@ -56,21 +58,22 @@ class ShopwareGetProductsBySku extends Command
56 58
         /** @var Shopware $Shopware */
57 59
         $Shopware = System::getContainer()->get(Shopware::class);
58 60
 
59
-        if (($Products = $Shopware->getProductsForSku($strSku,true, $input->getOption('short') ? true : false)) !== false)
61
+        $Result = $Shopware->getProductsForSku($strSku,true, $input->getOption('short') ? true : false);
62
+
63
+        if ($Result->getStatusCode() === 200)
60 64
         {
61
-            $cloner = new VarCloner();
62
-            $dumper = new CliDumper();
65
+            $Content = json_validate($Result->getContent()) ? json_decode($Result->getContent(), true) : $Result;
63 66
 
64
-            if ($Products->total)
67
+            if ($Content['total'])
65 68
             {
66
-                $dumper->dump(($cloner->cloneVar($Products->data)));
69
+                $dumper->dump(($cloner->cloneVar($Content['data'])));
67 70
             }
68
-            $io->success(sprintf('Found %s product(s)',$Products->total));
71
+            $io->success(sprintf('Found %s product(s)',$Content['total']));
69 72
 
70 73
             return self::SUCCESS;
71 74
         }
75
+        $io->error(sprintf('Could not retrieve products by SKU. HTTP Status returned: %s',$Result->getStatusCode()));
72 76
 
73
-        $io->error('Could not retrieve products by SKU');
74 77
         return self::FAILURE;
75 78
     }
76 79
 }