Implement csv export for facebook ads

This commit is contained in:
Björn Fromme
2018-09-24 16:00:58 +02:00
parent f081305c33
commit cae985638d
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\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('&nbsp;', ' ', $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;
}
}
@@ -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&amp;Paste</h2>
<ul>
<f:for each="{products}" as="product">
+1
View File
@@ -170,6 +170,7 @@ $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl'] = [
[
'GETvar' => 'type',
'valueMap' => [
'csv' => 1979,
'xml' => 1972,
'excel' => 1984,
],