Implement csv export for facebook ads
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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 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();
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+17
@@ -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
|
||||
],
|
||||
|
||||
@@ -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',
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
<h1>{reseller.name}</h1>
|
||||
<h2>Gesamtexport XML</h2>
|
||||
<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&Paste</h2>
|
||||
<ul>
|
||||
<f:for each="{products}" as="product">
|
||||
|
||||
@@ -170,6 +170,7 @@ $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl'] = [
|
||||
[
|
||||
'GETvar' => 'type',
|
||||
'valueMap' => [
|
||||
'csv' => 1979,
|
||||
'xml' => 1972,
|
||||
'excel' => 1984,
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user