Merge branch 'csvexport'

This commit is contained in:
Björn Fromme
2018-09-24 16:01:17 +02:00
10 changed files with 147 additions and 70 deletions
@@ -29,7 +29,6 @@ namespace EP\EpProducts\Controller;
use EP\EpProducts\Domain\Model\Product; use EP\EpProducts\Domain\Model\Product;
use EP\EpProducts\Domain\Model\Reseller; use EP\EpProducts\Domain\Model\Reseller;
use EP\EpProducts\Service\ExcelService;
use EP\EpProducts\Service\ResellerService; use EP\EpProducts\Service\ResellerService;
use Symfony\Component\Serializer\Encoder\XmlEncoder; use Symfony\Component\Serializer\Encoder\XmlEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
@@ -44,20 +43,13 @@ class ResellerController extends ActionController
*/ */
protected $resellerService; protected $resellerService;
/**
* @var ExcelService
*/
protected $excelService;
/** /**
* @param ResellerService $resellerService * @param ResellerService $resellerService
* @param ExcelService $excelService
*/ */
public function __construct(ResellerService $resellerService, ExcelService $excelService) public function __construct(ResellerService $resellerService)
{ {
parent::__construct(); parent::__construct();
$this->resellerService = $resellerService; $this->resellerService = $resellerService;
$this->excelService = $excelService;
} }
/** /**
@@ -112,4 +104,53 @@ class ResellerController extends ActionController
return false; 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();
}
} }
@@ -34,9 +34,14 @@ class Product
{ {
/** /**
* @param \EP\EpProducts\Domain\Model\Product $entity * @param \EP\EpProducts\Domain\Model\Product $entity
* @param array $imageProcessingInstructions
* @return array * @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 = [ $product = [
'concept' => [], 'concept' => [],
@@ -59,8 +64,10 @@ class Product
$product['concept']['description'] = SerializationUtility::sanitizeText($entity->getConcept()->getDescription()); $product['concept']['description'] = SerializationUtility::sanitizeText($entity->getConcept()->getDescription());
$product['board'] = SerializationUtility::sanitizeText($entity->getBoardDescription()); $product['board'] = SerializationUtility::sanitizeText($entity->getBoardDescription());
$product['programme'] = SerializationUtility::sanitizeText($entity->getProgrammeDescription()); $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['video'] = $entity->getVideo();
$product['link'] = SerializationUtility::generateLink($entity->getDetailPage());
$product['region'] = Region::fromEntity($entity->getRegion()); $product['region'] = Region::fromEntity($entity->getRegion());
$product['city'] = City::fromEntity($entity->getCity()); $product['city'] = City::fromEntity($entity->getCity());
@@ -1,41 +0,0 @@
<?php
namespace EP\EpProducts\Service;
/***************************************************************
*
* Copyright notice
*
* (c) 2018 Björn Fromme <[email protected]>, 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()
{}
}
@@ -55,9 +55,10 @@ class ResellerService implements SingletonInterface
/** /**
* @param Reseller $reseller * @param Reseller $reseller
* @param array $imageProcessingInstructions
* @return array * @return array
*/ */
public function preprocessAll(Reseller $reseller) public function preprocessAll(Reseller $reseller, array $imageProcessingInstructions = null)
{ {
$data = []; $data = [];
$products = $reseller->getProducts(); $products = $reseller->getProducts();
@@ -65,7 +66,7 @@ class ResellerService implements SingletonInterface
foreach ($products as $product) foreach ($products as $product)
{ {
/** @var Product $product */ /** @var Product $product */
$data['product'][] = $this->preprocessSingle($product, $reseller); $data['product'][] = $this->preprocessSingle($product, $reseller, $imageProcessingInstructions);
} }
return $data; return $data;
@@ -74,11 +75,12 @@ class ResellerService implements SingletonInterface
/** /**
* @param Product $product * @param Product $product
* @param Reseller $reseller * @param Reseller $reseller
* @param array $imageProcessingInstructions
* @return array * @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(); $hotels = $product->getHotels();
$paCode = $reseller->getPaCode(); $paCode = $reseller->getPaCode();
@@ -85,7 +85,7 @@ trait ImageServiceTrait
* @param array $images * @param array $images
* @return array * @return array
*/ */
protected function generateResizedImages($images) public function generateResizedImages($images)
{ {
$resized = []; $resized = [];
foreach ($this->imageSizes as $version => $instructions) foreach ($this->imageSizes as $version => $instructions)
@@ -27,22 +27,31 @@ namespace EP\EpProducts\Utility;
* This copyright notice MUST APPEAR in all copies of the script! * 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\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\Persistence\ObjectStorage;
use TYPO3\CMS\Extbase\Service\ImageService;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
class SerializationUtility class SerializationUtility
{ {
/**
* @var ImageService
*/
protected static $imageService;
/**
* @var ContentObjectRenderer
*/
protected static $contentObject;
/** /**
* @param $text * @param $text
* @return string * @return string
*/ */
public static function sanitizeText($text) 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('&nbsp;', ' ', $text); $text = str_replace('&nbsp;', ' ', $text);
return trim($text); return trim($text);
@@ -50,20 +59,59 @@ class SerializationUtility
/** /**
* @param ObjectStorage $images * @param ObjectStorage $images
* @param array $processingInstructions
* @return array * @return array
*/ */
public static function preprocessImages(ObjectStorage $images) public static function preprocessImages(ObjectStorage $images, array $processingInstructions = null)
{ {
$hostname = GeneralUtility::getHostname();
$data = []; $data = [];
foreach ($images as $image) foreach ($images as $file)
{ {
/** @var FileReference $image $image = $file->getOriginalResource();
*/ if (!\is_array($processingInstructions)) {
$data[] = 'https://' . $hostname . '/' . $image->getOriginalResource()->getOriginalFile()->getPublicUrl(); $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; 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;
}
} }
@@ -513,6 +513,23 @@ return [
--palette--;;filePalette', --palette--;;filePalette',
], ],
], ],
'columns' => [
'crop' => [
'config' => [
'cropVariants' => [
'facebook' => [
'title' => 'Facebook',
'allowedAspectRatios' => [
'ad' => [
'title' => 'Single product ad',
'value' => 1.91,
]
]
]
],
],
],
],
], ],
'maxitems' => 10 'maxitems' => 10
], ],
@@ -301,10 +301,10 @@ $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks'][\EP\EpProducts\T
'EP.' . $_EXTKEY, 'EP.' . $_EXTKEY,
'reseller', 'reseller',
[ [
'Reseller' => 'list,xml,copypaste', 'Reseller' => 'list,xml,copypaste,csv',
], ],
[ [
'Reseller' => 'list,xml,copypaste', 'Reseller' => 'list,xml,copypaste,csv',
] ]
); );
@@ -12,6 +12,8 @@
<h1>{reseller.name}</h1> <h1>{reseller.name}</h1>
<h2>Gesamtexport XML</h2> <h2>Gesamtexport XML</h2>
<f:link.action arguments="{reseller: reseller}" pageType="1972" target="_blank">Export XML</f:link.action> <f:link.action arguments="{reseller: reseller}" pageType="1972" target="_blank">Export XML</f:link.action>
<h2>Gesamtexport CSV (Facebook)</h2>
<f:link.action action="csv" arguments="{reseller: reseller}" target="_blank">Export CSV</f:link.action>
<h2>Einzelexport für Copy&amp;Paste</h2> <h2>Einzelexport für Copy&amp;Paste</h2>
<ul> <ul>
<f:for each="{products}" as="product"> <f:for each="{products}" as="product">
+1
View File
@@ -170,6 +170,7 @@ $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl'] = [
[ [
'GETvar' => 'type', 'GETvar' => 'type',
'valueMap' => [ 'valueMap' => [
'csv' => 1979,
'xml' => 1972, 'xml' => 1972,
'excel' => 1984, 'excel' => 1984,
], ],