diff --git a/src/Model/FileSupport/BuyRequest/CustomizableOptionDataProvider.php b/src/Model/FileSupport/BuyRequest/CustomizableOptionDataProvider.php new file mode 100644 index 0000000..404289f --- /dev/null +++ b/src/Model/FileSupport/BuyRequest/CustomizableOptionDataProvider.php @@ -0,0 +1,188 @@ +mediaPath = $filesystem->getDirectoryRead(DirectoryList::MEDIA)->getAbsolutePath(); + } + + /** + * @inheritdoc + * + * @phpcs:disable Magento2.Functions.DiscouragedFunction + */ + public function execute(WishlistItem $wishlistItemData, ?int $productId): array + { + $customizableOptionsData = []; + foreach ($wishlistItemData->getSelectedOptions() as $optionData) { + $optionData = \explode('/', base64_decode($optionData->getId())); + + if ($this->isProviderApplicable($optionData) === false) { + continue; + } + + [$optionType, $optionId, $optionValue] = $optionData; + + if ($optionType == self::PROVIDER_OPTION_TYPE) { + $customizableOptionsData[$optionId][] = $optionValue; + } + } + + foreach ($wishlistItemData->getEnteredOptions() as $option) { + $optionData = \explode('/', base64_decode($option->getUid())); + + if ($this->isProviderApplicable($optionData) === false) { + continue; + } + + [$optionType, $optionId] = $optionData; + + // -- File Upload Support -- + $fileData = $this->getFileData($option->getUid(), $option->getValue()); + if ($optionType == self::PROVIDER_OPTION_TYPE) { + if ($fileData !== false) { + $this->createFileAndFolder($option->getUid(), $fileData['raw'], $fileData['title']); + unset($fileData['raw']); + $customizableOptionsData[$optionId][] = $fileData; + // -- End of Support -- + } else { + $customizableOptionsData[$optionId][] = $option->getValue(); + } + } + } + + if (empty($customizableOptionsData)) { + return $customizableOptionsData; + } + + $result = ['options' => $this->flattenOptionValues($customizableOptionsData)]; + + if ($productId) { + $result += ['product' => $productId]; + } + + return $result; + } + + protected function getFileData($uid, $optionData) { + try { + $data = json_decode($optionData, true); + + if (!is_array($data)) { + return false; + } + + $filename = $data['file_name']; + $filedata = $data['file_data']; + + $insidePath = $uid . '/_/' . $filename; + + if (!$filename || !$filedata) { + return false; + } + + return [ + 'type' => 'application/octet-stream', + 'title' => $filename, + 'quote_path' => self::QUOTE_MEDIA_PATH . $insidePath, + 'order_path' => self::ORDER_MEDIA_PATH . $insidePath, + 'fullpath' => $this->mediaPath . self::QUOTE_MEDIA_PATH . $insidePath, + 'secret_key' => $filename, + 'raw' => $filedata + ]; + } catch(\Exception $e) { + return false; + } + + return false; + } + + /** + * @param $quoteId + * @param $value + * @param $filename + */ + public function createFileAndFolder($uid, $value, $filename) + { + $directory = sprintf( + '%s%s%s/_', + $this->mediaPath, + self::QUOTE_MEDIA_PATH, + $uid + ); + + if (!is_dir($directory)) { + mkdir($directory, 0777, true); + } + + file_put_contents( + sprintf('%s/%s', $directory, $filename), + base64_decode(substr($value, strpos($value, ',') + 1 )) + ); + } + + /** + * Flatten option values for non-multiselect customizable options + * + * @param array $customizableOptionsData + * + * @return array + */ + protected function flattenOptionValues(array $customizableOptionsData): array + { + foreach ($customizableOptionsData as $optionId => $optionValue) { + if (count($optionValue) === 1) { + $customizableOptionsData[$optionId] = $optionValue[0]; + } + } + + return $customizableOptionsData; + } + + /** + * Checks whether this provider is applicable for the current option + * + * @param array $optionData + * @return bool + */ + protected function isProviderApplicable(array $optionData): bool + { + return $optionData[0] === self::PROVIDER_OPTION_TYPE; + } +} diff --git a/src/Model/Resolver/WishlistItemsResolver.php b/src/Model/Resolver/WishlistItemsResolver.php index de1b6c8..26e77b4 100755 --- a/src/Model/Resolver/WishlistItemsResolver.php +++ b/src/Model/Resolver/WishlistItemsResolver.php @@ -250,7 +250,16 @@ protected function getItemOptions($item, $type) $options = $this->downloadableOptions->getOptions($item); break; default: - return $this->productOptions->getOptions($item); + $options = $this->productOptions->getOptions($item); + + // Magento produce HTML markup as label for files. We need plain name of the file instead. + foreach ($options as $index => $option){ + if($option['option_type'] === 'file'){ + $options[$index]['value'] = $option['print_value']; + } + } + + return $options; } $output = []; diff --git a/src/etc/graphql/di.xml b/src/etc/graphql/di.xml new file mode 100644 index 0000000..063d310 --- /dev/null +++ b/src/etc/graphql/di.xml @@ -0,0 +1,16 @@ + + + + + + + ScandiPWA\WishlistGraphQl\Model\FileSupport\BuyRequest\CustomizableOptionDataProvider + + + +