From cae985638dfe85800b8ec9b3b950430678d94e5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bjo=CC=88rn=20Fromme?= Date: Fri, 21 Sep 2018 16:38:41 +0200 Subject: [PATCH] Implement csv export for facebook ads --- .../Classes/Controller/ResellerController.php | 59 +++++++++++++--- .../Classes/Domain/Serialization/Product.php | 11 ++- .../Classes/Service/ExcelService.php | 41 ----------- .../Classes/Service/ResellerService.php | 10 +-- .../Classes/Traits/ImageServiceTrait.php | 2 +- .../Classes/Utility/SerializationUtility.php | 70 ++++++++++++++++--- .../tx_epproducts_domain_model_product.php | 17 +++++ .../ext/ep_products/ext_localconf.php | 4 +- .../Private/Templates/Reseller/List.html | 2 + web/typo3conf/realurl_conf.php | 1 + 10 files changed, 147 insertions(+), 70 deletions(-) delete mode 100644 web/typo3conf/ext/ep_products/Classes/Service/ExcelService.php diff --git a/web/typo3conf/ext/ep_products/Classes/Controller/ResellerController.php b/web/typo3conf/ext/ep_products/Classes/Controller/ResellerController.php index 6ff8607f..bdfe7c1b 100644 --- a/web/typo3conf/ext/ep_products/Classes/Controller/ResellerController.php +++ b/web/typo3conf/ext/ep_products/Classes/Controller/ResellerController.php @@ -29,7 +29,6 @@ namespace EP\EpProducts\Controller; use EP\EpProducts\Domain\Model\Product; use EP\EpProducts\Domain\Model\Reseller; -use EP\EpProducts\Service\ExcelService; use EP\EpProducts\Service\ResellerService; use Symfony\Component\Serializer\Encoder\XmlEncoder; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; @@ -44,20 +43,13 @@ class ResellerController extends ActionController */ protected $resellerService; - /** - * @var ExcelService - */ - protected $excelService; - /** * @param ResellerService $resellerService - * @param ExcelService $excelService */ - public function __construct(ResellerService $resellerService, ExcelService $excelService) + public function __construct(ResellerService $resellerService) { parent::__construct(); $this->resellerService = $resellerService; - $this->excelService = $excelService; } /** @@ -112,4 +104,53 @@ class ResellerController extends ActionController return false; } + /** + * @param Reseller $reseller + * @return bool + */ + public function csvAction(Reseller $reseller) + { + $data = $this->resellerService->preprocessAll($reseller, [ 'width' => '1200', 'maxHeight' => '630', 'cropVariant' => 'facebook' ]); + + header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); + header('Content-Description: File Transfer'); + header('Content-type: text/csv'); + header('Content-Disposition: attachment; filename=export.csv'); + header('Expires: 0'); + header('Pragma: public'); + + $fileHandle = fopen('php://output', 'wb'); + + foreach ($data['product'] as $product) + { + $minPrice = null; + + foreach ($product['hotels']['hotel'] as $hotel) + { + foreach ($hotel['dates']['date'] as $date) + { + if ($minPrice === null || $date['minprice'] < $minPrice) { + $minPrice = $date['minprice']; + } + } + } + + fputcsv($fileHandle, [ + $product['@id'], + 'in stock', + 'new', + $product['description'], + $product['images']['image'][0], + $product['link'], + $product['name'], + $minPrice . ' EUR', + 'brand-epreisen' + ]); + } + + fclose($fileHandle); + + exit(); + } + } diff --git a/web/typo3conf/ext/ep_products/Classes/Domain/Serialization/Product.php b/web/typo3conf/ext/ep_products/Classes/Domain/Serialization/Product.php index 9a9f1cc8..d596f2aa 100644 --- a/web/typo3conf/ext/ep_products/Classes/Domain/Serialization/Product.php +++ b/web/typo3conf/ext/ep_products/Classes/Domain/Serialization/Product.php @@ -34,9 +34,14 @@ class Product { /** * @param \EP\EpProducts\Domain\Model\Product $entity + * @param array $imageProcessingInstructions * @return array */ - public static function fromEntity(\EP\EpProducts\Domain\Model\Product $entity) + public static function fromEntity + ( + \EP\EpProducts\Domain\Model\Product $entity, + array $imageProcessingInstructions = null + ) { $product = [ 'concept' => [], @@ -59,8 +64,10 @@ class Product $product['concept']['description'] = SerializationUtility::sanitizeText($entity->getConcept()->getDescription()); $product['board'] = SerializationUtility::sanitizeText($entity->getBoardDescription()); $product['programme'] = SerializationUtility::sanitizeText($entity->getProgrammeDescription()); - $product['images']['image'] = SerializationUtility::preprocessImages($entity->getResellerImages()); + $product['description'] = SerializationUtility::sanitizeText($entity->getConceptDescription()); + $product['images']['image'] = SerializationUtility::preprocessImages($entity->getResellerImages(), $imageProcessingInstructions); $product['video'] = $entity->getVideo(); + $product['link'] = SerializationUtility::generateLink($entity->getDetailPage()); $product['region'] = Region::fromEntity($entity->getRegion()); $product['city'] = City::fromEntity($entity->getCity()); diff --git a/web/typo3conf/ext/ep_products/Classes/Service/ExcelService.php b/web/typo3conf/ext/ep_products/Classes/Service/ExcelService.php deleted file mode 100644 index 7faea68c..00000000 --- a/web/typo3conf/ext/ep_products/Classes/Service/ExcelService.php +++ /dev/null @@ -1,41 +0,0 @@ -, dreipunktnull - * - * All rights reserved - * - * This script is part of the TYPO3 project. The TYPO3 project is - * free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * The GNU General Public License can be found at - * http://www.gnu.org/copyleft/gpl.html. - * - * This script is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This copyright notice MUST APPEAR in all copies of the script! - ***************************************************************/ - -use TYPO3\CMS\Core\SingletonInterface; - -class ExcelService implements SingletonInterface -{ - public function createDocument() - {} - - public function addWorksheet() - {} - - public function renderDocument() - {} -} diff --git a/web/typo3conf/ext/ep_products/Classes/Service/ResellerService.php b/web/typo3conf/ext/ep_products/Classes/Service/ResellerService.php index 636559b6..4557e779 100644 --- a/web/typo3conf/ext/ep_products/Classes/Service/ResellerService.php +++ b/web/typo3conf/ext/ep_products/Classes/Service/ResellerService.php @@ -55,9 +55,10 @@ class ResellerService implements SingletonInterface /** * @param Reseller $reseller + * @param array $imageProcessingInstructions * @return array */ - public function preprocessAll(Reseller $reseller) + public function preprocessAll(Reseller $reseller, array $imageProcessingInstructions = null) { $data = []; $products = $reseller->getProducts(); @@ -65,7 +66,7 @@ class ResellerService implements SingletonInterface foreach ($products as $product) { /** @var Product $product */ - $data['product'][] = $this->preprocessSingle($product, $reseller); + $data['product'][] = $this->preprocessSingle($product, $reseller, $imageProcessingInstructions); } return $data; @@ -74,11 +75,12 @@ class ResellerService implements SingletonInterface /** * @param Product $product * @param Reseller $reseller + * @param array $imageProcessingInstructions * @return array */ - public function preprocessSingle(Product $product, Reseller $reseller) + public function preprocessSingle(Product $product, Reseller $reseller, array $imageProcessingInstructions = null) { - $data = \EP\EpProducts\Domain\Serialization\Product::fromEntity($product); + $data = \EP\EpProducts\Domain\Serialization\Product::fromEntity($product, $imageProcessingInstructions); $hotels = $product->getHotels(); $paCode = $reseller->getPaCode(); diff --git a/web/typo3conf/ext/ep_products/Classes/Traits/ImageServiceTrait.php b/web/typo3conf/ext/ep_products/Classes/Traits/ImageServiceTrait.php index 968129f9..6b6f6cff 100644 --- a/web/typo3conf/ext/ep_products/Classes/Traits/ImageServiceTrait.php +++ b/web/typo3conf/ext/ep_products/Classes/Traits/ImageServiceTrait.php @@ -85,7 +85,7 @@ trait ImageServiceTrait * @param array $images * @return array */ - protected function generateResizedImages($images) + public function generateResizedImages($images) { $resized = []; foreach ($this->imageSizes as $version => $instructions) diff --git a/web/typo3conf/ext/ep_products/Classes/Utility/SerializationUtility.php b/web/typo3conf/ext/ep_products/Classes/Utility/SerializationUtility.php index 25433351..0260e1a4 100644 --- a/web/typo3conf/ext/ep_products/Classes/Utility/SerializationUtility.php +++ b/web/typo3conf/ext/ep_products/Classes/Utility/SerializationUtility.php @@ -27,22 +27,31 @@ namespace EP\EpProducts\Utility; * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ +use TYPO3\CMS\Core\Imaging\ImageManipulation\CropVariantCollection; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Extbase\Domain\Model\FileReference; +use TYPO3\CMS\Extbase\Object\ObjectManager; use TYPO3\CMS\Extbase\Persistence\ObjectStorage; +use TYPO3\CMS\Extbase\Service\ImageService; +use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; class SerializationUtility { + /** + * @var ImageService + */ + protected static $imageService; + + /** + * @var ContentObjectRenderer + */ + protected static $contentObject; + /** * @param $text * @return string */ public static function sanitizeText($text) { - //$text = html_entity_decode($text, null, 'utf-8'); - //$text = strip_tags($text); - //$text = htmlspecialchars($text); - //$text = nl2br($text); $text = str_replace(' ', ' ', $text); return trim($text); @@ -50,20 +59,59 @@ class SerializationUtility /** * @param ObjectStorage $images + * @param array $processingInstructions * @return array */ - public static function preprocessImages(ObjectStorage $images) + public static function preprocessImages(ObjectStorage $images, array $processingInstructions = null) { - $hostname = GeneralUtility::getHostname(); $data = []; - foreach ($images as $image) + foreach ($images as $file) { - /** @var FileReference $image - */ - $data[] = 'https://' . $hostname . '/' . $image->getOriginalResource()->getOriginalFile()->getPublicUrl(); + $image = $file->getOriginalResource(); + if (!\is_array($processingInstructions)) { + $hostname = GeneralUtility::getHostname(); + $data[] = 'https://' . $hostname . '/' . $image->getOriginalFile()->getPublicUrl(); + } else { + $imageService = static::getImageService(); + $cropString = $image->getProperty('crop'); + $cropVariantCollection = CropVariantCollection::create($cropString); + $cropVariant = $processingInstructions['cropVariant'] ?: 'default'; + $cropArea = $cropVariantCollection->getCropArea($cropVariant); + $processingInstructions['crop'] = $cropArea->isEmpty() ? null : $cropArea->makeAbsoluteBasedOnFile($image); + $processedImage = $imageService->applyProcessingInstructions($image, $processingInstructions); + $data[] = $imageService->getImageUri($processedImage, true); + } } return $data; } + /** + * @param string $parameter + * @return string + */ + public static function generateLink($parameter) + { + if (static::$contentObject === null) { + /** @var ContentObjectRenderer $contentObject */ + static::$contentObject = GeneralUtility::makeInstance(ContentObjectRenderer::class); + } + + return static::$contentObject->typoLink_URL([ 'parameter' => $parameter, 'forceAbsoluteUrl' => true ]); + } + + /** + * @return ImageService + */ + protected static function getImageService() + { + if (static::$imageService === null) { + /** @var ObjectManager $objectManager */ + $objectManager = GeneralUtility::makeInstance(ObjectManager::class); + static::$imageService = $objectManager->get(ImageService::class); + } + + return static::$imageService; + } + } diff --git a/web/typo3conf/ext/ep_products/Configuration/TCA/tx_epproducts_domain_model_product.php b/web/typo3conf/ext/ep_products/Configuration/TCA/tx_epproducts_domain_model_product.php index f536bf65..f9d82597 100644 --- a/web/typo3conf/ext/ep_products/Configuration/TCA/tx_epproducts_domain_model_product.php +++ b/web/typo3conf/ext/ep_products/Configuration/TCA/tx_epproducts_domain_model_product.php @@ -513,6 +513,23 @@ return [ --palette--;;filePalette', ], ], + 'columns' => [ + 'crop' => [ + 'config' => [ + 'cropVariants' => [ + 'facebook' => [ + 'title' => 'Facebook', + 'allowedAspectRatios' => [ + 'ad' => [ + 'title' => 'Single product ad', + 'value' => 1.91, + ] + ] + ] + ], + ], + ], + ], ], 'maxitems' => 10 ], diff --git a/web/typo3conf/ext/ep_products/ext_localconf.php b/web/typo3conf/ext/ep_products/ext_localconf.php index acc42748..e415be68 100644 --- a/web/typo3conf/ext/ep_products/ext_localconf.php +++ b/web/typo3conf/ext/ep_products/ext_localconf.php @@ -301,10 +301,10 @@ $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks'][\EP\EpProducts\T 'EP.' . $_EXTKEY, 'reseller', [ - 'Reseller' => 'list,xml,copypaste', + 'Reseller' => 'list,xml,copypaste,csv', ], [ - 'Reseller' => 'list,xml,copypaste', + 'Reseller' => 'list,xml,copypaste,csv', ] ); diff --git a/web/typo3conf/ext/ep_theme/Resources/Private/Templates/Reseller/List.html b/web/typo3conf/ext/ep_theme/Resources/Private/Templates/Reseller/List.html index faae3c41..2f3bcc79 100644 --- a/web/typo3conf/ext/ep_theme/Resources/Private/Templates/Reseller/List.html +++ b/web/typo3conf/ext/ep_theme/Resources/Private/Templates/Reseller/List.html @@ -12,6 +12,8 @@

{reseller.name}

Gesamtexport XML

Export XML +

Gesamtexport CSV (Facebook)

+ Export CSV

Einzelexport für Copy&Paste