serializer = $serializer; $this->httpClient = $httpClient; $this->clientId = System::getContainer()->getParameter('vonrotenberg_shopware_api.credentials.client_id'); $this->clientSecret = System::getContainer()->getParameter('vonrotenberg_shopware_api.credentials.client_secret'); $this->apiEndpoint = System::getContainer()->getParameter('vonrotenberg_shopware_api.credentials.api_endpoint'); } protected function getClientId() { return $this->clientId; } protected function getClientSecret() { return $this->clientSecret; } protected function getApiEndpoint() { return rtrim($this->apiEndpoint,'/'); } protected function sendRequest(string $relEndpoint, array $options, string $method = 'GET',bool $blnFQDNEndpoint=false) { if ($blnFQDNEndpoint) { return $this->httpClient->request($method,$relEndpoint,$options); } $relEndpoint = '/' . ltrim($relEndpoint,'/'); $request = $this->httpClient->request($method,$this->getApiEndpoint().$relEndpoint,$options); if ($request->getStatusCode() == 401) { throw new \RuntimeException('Unauthorized'); } return $request; } protected function getAccessToken() { $options = [ 'body' => json_encode([ 'grant_type' => 'client_credentials', 'client_id' => $this->clientId, 'client_secret' => $this->clientSecret ]), 'headers' => ['Content-Type: application/json', 'Accept: application/json'], ]; $response = $this->sendRequest('oauth/token',$options,'POST'); if ($response->getStatusCode() == 200) { $content = $response->getContent(); return json_decode($content); } throw new \RuntimeException('Can\'t retrieve access token. Check credentials.'); } protected function getAuthentication() { $Token = $this->getAccessToken(); return 'Authorization: ' . $Token->token_type . ' ' . $Token->access_token; } public function isShopwareRunning(): bool { $options = [ 'headers' => [ $this->getAuthentication(), 'Content-Type: application/json', 'Accept: application/json' ], ]; $response = $this->sendRequest('_info/health-check',$options,'GET'); if ($response->getStatusCode() == 200) { return true; } return false; } public function getProductsForSku(string $strSku, bool $blnWildcardSearch=false, bool $blnShort=false): ResponseInterface { $options = [ 'headers' => [ $this->getAuthentication(), 'Content-Type: application/json', 'Accept: application/json' ], 'body' => json_encode([ 'filter' => [ [ 'type' => !$blnWildcardSearch ? 'equals' : 'contains', 'field' => 'productNumber', 'value' => $strSku ] ], 'sort' => [ [ 'field' => 'productNumber', 'order' => 'ASC', 'naturalSorting' => true ] ] ]) ]; if ($blnShort) { $options['body'] = json_encode( array_merge( json_decode($options['body'],true), [ 'fields' => [ 'name' ] ] ) ); } return $this->sendRequest('search/product',$options,'POST'); } public function queryAPI(string $strUrlFragment, ?string $strBody, string $strMethod = 'GET', bool $blnAuthenticate=true): ResponseInterface { $options = [ 'headers' => [ 'Content-Type: application/json', 'Accept: application/json' ] ]; if ($blnAuthenticate) { $options['headers'][] = $this->getAuthentication(); } if ($strBody !== null) { $options['body'] = $strBody; } return $this->sendRequest($strUrlFragment,$options,$strMethod); } protected function checkBySkuIfExists(string $strSku): bool { $Result = $this->getProductsForSku($strSku,false,true); if ($Result->getStatusCode() == 200) { $Content = json_decode($Result->getContent()); if ($Content->total) { return true; } } return false; } public function addOrUpdateProductBySku(string $strSku, array $arrData): bool { $blnInsert = true; // Update or insert check if (($searchResponse = $this->getProductsForSku($strSku))->getStatusCode() == 200) { $Product = json_decode($searchResponse->getContent()); if ($Product->total) { $blnInsert = false; } } // Prepare product data $arrData = array_merge([ 'id' => $blnInsert ? $this->createUuid() : $Product->data[0]->id ], $arrData); $options = [ 'headers' => [ $this->getAuthentication(), 'Content-Type: application/json', 'Accept: application/json' ], 'body' => json_encode($arrData) ]; if ($blnInsert) { $response = $this->sendRequest('product',$options,'POST'); } else { $response = $this->sendRequest('product/'.$Product->data[0]->id,$options,'PATCH'); } return in_array($response->getStatusCode(),[200,201,202,203,204]); } public function truncatePropertiesForProductBySku(string $strSku, string|array|null $groupIds = null): bool { if ($groupIds !== null && !is_array($groupIds)) { $groupIds = (array) $groupIds; } // Look for product if (($searchResponse = $this->getProductsForSku($strSku))->getStatusCode() == 200) { $Product = json_decode($searchResponse->getContent()); if (!$Product->total) { return false; } // Get property ids $arrPropertiesPayload = []; foreach (System::getContainer()->getParameter('vonrotenberg_shopware_api.mappings.properties') as $groupId => $properties) { if ($groupIds !== null && !in_array($groupId,$groupIds)) { continue; } foreach (array_keys($properties) as $propertyId) { $arrPropertiesPayload[] = [ 'productId' => $Product->data[0]->id, 'optionId' => $propertyId ]; } } // Build request data $arrData = [ [ 'entity' => 'product_property', 'action' => 'delete', 'payload' => $arrPropertiesPayload ] ]; $options = [ 'headers' => [ $this->getAuthentication(), 'Content-Type: application/json', 'Accept: application/json', 'fail-on-error: false' ], 'body' => json_encode($arrData) ]; // Send request $response = $this->sendRequest('_action/sync',$options,'POST'); return in_array($response->getStatusCode(),[200]); } return false; } protected function createUuid($data = null) { // Generate 16 bytes (128 bits) of random data or use the data passed into the function. $data = $data ?? random_bytes(16); assert(strlen($data) == 16); // Set version to 0100 $data[6] = chr(ord($data[6]) & 0x0f | 0x40); // Set bits 6-7 to 10 $data[8] = chr(ord($data[8]) & 0x3f | 0x80); // Output the 36 character UUID. return bin2hex($data); } }