<?php declare(strict_types=1);
/**
* gb media
* All Rights Reserved.
*
* Unauthorized copying of this file, via any medium is strictly prohibited.
* The content of this file is proprietary and confidential.
*
* @category Shopware
* @package Shopware_Plugins
* @subpackage GbmedDocumentBarcode
* @copyright Copyright (c) 2019, gb media
* @license proprietary
* @author Giuseppe Bottino
* @link http://www.gb-media.biz
*/
namespace Gbmed\DocumentBarcode\Core\Checkout\Document;
use Gbmed\DocumentBarcode\Core\Framework\Struct\StructDocument;
use Gbmed\DocumentBarcode\Installer\ConfigInstaller;
use Gbmed\DocumentBarcode\Services\Logger;
use Shopware\Core\Checkout\Document\Event\DocumentTemplateRendererParameterEvent;
use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemEntity;
use Shopware\Core\Checkout\Order\OrderEntity;
use Shopware\Core\Content\Product\ProductEntity;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Zend\Barcode\Barcode;
use Zend\Stdlib\ErrorHandler;
class DocumentTemplateRenderer implements EventSubscriberInterface
{
/**
* @var SystemConfigService
*/
private $systemConfigService;
/**
* @var string
*/
private $codeType;
/**
* @var string
*/
private $useCode;
/**
* @var bool
*/
private $drawText;
/**
* @var string
*/
private $barcodeLayout;
/**
* @var string
*/
private $barcodeImageWidth;
/**
* @var array
*/
private $showBarcodeAt;
/**
* @var array
*/
private $showBarcodeType;
/**
* @var Logger
*/
private $logger;
/**
* Product constructor.
* @param SystemConfigService $systemConfigService
* @param Logger $logger
*/
public function __construct(
SystemConfigService $systemConfigService,
Logger $logger
) {
$this->systemConfigService = $systemConfigService;
$this->logger = $logger;
}
/**
* subscribe events
*
* @return array
*/
public static function getSubscribedEvents(): array
{
return [
DocumentTemplateRendererParameterEvent::class => 'DocumentTemplateRendererParameter'
];
}
/**
* add extensions into document parameters
*
* @param DocumentTemplateRendererParameterEvent $event
*/
public function DocumentTemplateRendererParameter(DocumentTemplateRendererParameterEvent $event): void
{
$this->getConfig();
$params = $event->getParameters();
if (!isset($params['order'])) {
return;
}
/** @var OrderEntity $order */
$order = $params['order'];
$orderNumber = $order->getOrderNumber();
$lineItems = $order->getLineItems();
$customer = $order->getOrderCustomer();
$customerNumber = $customer->getCustomerNumber();
$documentNumber = $params['config']['documentNumber'];
$documentName = $params['config']['id'];
// lineItems
if ($this->show('lineItems', $documentName)) {
/** @var OrderLineItemEntity $lineItem */
foreach ($lineItems->getElements() as $index => $lineItem) {
$lineItem->addExtension(
'GbmedDocumentBarcode',
$this->getStructDocument(
$this->getBarcodeText($lineItem),
$lineItem->getProduct()
)
);
}
}
// default settings
$event->addExtension(
'GbmedDocumentBarcode',
$this->getStructDocument()
);
// documentNumber
if ($this->show('documentNumber', $documentName)) {
$event->addExtension(
'GbmedDocumentBarcodeDocumentNumber',
$this->getStructDocument($documentNumber)
);
}
// customerNumber
if ($this->show('customerNumber', $documentName)) {
$event->addExtension(
'GbmedDocumentBarcodeCustomerNumber',
$this->getStructDocument($customerNumber)
);
}
// orderNumber
if ($this->show('orderNumber', $documentName)) {
$event->addExtension(
'GbmedDocumentBarcodeOrderNumber',
$this->getStructDocument($orderNumber)
);
}
}
/**
* return formated structure
*
* @param string|null $text
* @param ProductEntity|null $product
* @return StructDocument
*/
public function getStructDocument($text = null, ?ProductEntity $product = null): StructDocument
{
$struct = new StructDocument();
$struct->setCodeType($this->codeType)
->setUseCode($this->useCode)
->setDrawText($this->drawText)
->setBarcodeLayout($this->barcodeLayout)
->setBarcodeImageWidth($this->barcodeImageWidth)
->setShowBarcodeAt($this->showBarcodeAt);
if ($text) {
$struct->setImage(
$this->draw(
[
'text' => $text,
'drawText' => $this->drawText
],
$this->codeType,
$product
)
);
}
return $struct;
}
/**
* @param OrderLineItemEntity $lineItem
*
* @return string|null
*/
private function getBarcodeText(OrderLineItemEntity $lineItem)
{
/** @var ProductEntity $product */
$product = $lineItem->getProduct();
if (!$product) {
return null;
}
$customFields = $product->getCustomFields();
$text = $this->useCode === 'eannumber' ? $product->getEan() : $product->getProductNumber();
if ($this->useCode === 'alternativebarcode') {
$text = !isset($customFields['gbmed_document_barcode_useCode']) || empty($customFields['gbmed_document_barcode_useCode'])
? null
: $customFields['gbmed_document_barcode_useCode'];
} else {
if ($this->useCode === 'alternativebarcode_eannumber') {
$text = $customFields['gbmed_document_barcode_useCode'] ?? null;
if (!$text) {
$text = $product->getEan();
}
} else {
if ($this->useCode === 'alternativebarcode_productnumber') {
$text = $customFields['gbmed_document_barcode_useCode'] ?? null;
if (!$text) {
$text = $product->getProductNumber();
}
}
}
}
return $this->prepareText($text);
}
/**
* helper to prepare text
*
* @param string|null $text
* @return string|null
*/
private function prepareText(?string $text = null)
{
if ($text !== null && $this->codeType === 'ean13') {
$text = substr($text, 0, 12);
}
return $text;
}
/**
* helper to draw barcode
*
* @param array $renderer
* @param string $codeType
* @param ProductEntity|null $product
* @return string|null
* @noinspection PhpComposerExtensionStubsInspection
*/
private function draw($renderer = [], $codeType = 'code128', ?ProductEntity $product = null): ?string
{
try {
/** @var \Zend\Barcode\Renderer\Image $barcode */
$barcode = Barcode::factory($codeType, 'image', $renderer, []);
$image = $barcode->drawOrThrowException();
} catch (\Exception $e) {
$this->logger->setProduct($product)
->error(
$e->getMessage(),
[
'codeType' => $codeType,
'text' => $renderer['text']
]
);
$image = null;
}
if ($image === null) {
return null;
}
ob_start();
imagepng($image);
$contents = ob_get_clean();
return 'data:image/png;base64,' . base64_encode($contents);
}
/**
* get plugin configurations
*/
private function getConfig(): void
{
$this->codeType = $this->systemConfigService->get(ConfigInstaller::getConfigKey('codeType'));
$this->useCode = $this->systemConfigService->get(ConfigInstaller::getConfigKey('useCode'));
$this->drawText = (bool)$this->systemConfigService->get(ConfigInstaller::getConfigKey('drawText'));
$this->barcodeLayout = $this->systemConfigService->get(ConfigInstaller::getConfigKey('barcodeLayout'));
$this->barcodeImageWidth = $this->systemConfigService->get(ConfigInstaller::getConfigKey('barcodeImageWidth'));
$this->showBarcodeAt = (array)$this->systemConfigService->get(ConfigInstaller::getConfigKey('showBarcodeAtDocumentBase'));
$this->showBarcodeType = (array)$this->systemConfigService->get(ConfigInstaller::getConfigKey('showBarcodeType'));
}
/**
* check if we can show barcode
*
* @param $type
* @param $at
* @return bool
*/
private function show($type, $at): bool
{
return (in_array($type, $this->showBarcodeType) && in_array($at, $this->showBarcodeAt));
}
}