mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
[wip] add different steps to handle request
This commit is contained in:
parent
b40b85527a
commit
e1a9ad1612
@ -25,6 +25,11 @@ namespace Chill\MainBundle\Controller;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Chill\MainBundle\Form\Type\Export\ExportType;
|
||||
use Chill\MainBundle\Form\Type\Export\PickFormatterType;
|
||||
use Chill\MainBundle\Form\Type\Export\FormatterType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
|
||||
|
||||
|
||||
/**
|
||||
@ -44,20 +49,53 @@ class ExportController extends Controller
|
||||
));
|
||||
}
|
||||
|
||||
public function newAction($alias)
|
||||
/**
|
||||
* Render the form required to generate data for the export.
|
||||
*
|
||||
* This action has two steps :
|
||||
*
|
||||
* - 'export', for the export form
|
||||
* - 'formatter', for the formatter form
|
||||
*
|
||||
* @param string $alias
|
||||
* @param Request $request
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function newAction(Request $request, $alias)
|
||||
{
|
||||
$step = $request->query->getAlpha('step', 'export');
|
||||
|
||||
switch ($step) {
|
||||
case 'export':
|
||||
return $this->renderExportForm($alias);
|
||||
break;
|
||||
case 'formatter':
|
||||
return $this->renderFormatterStep($request, $alias);
|
||||
break;
|
||||
default:
|
||||
throw $this->createNotFoundException("The given step '$step' is invalid");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the export form
|
||||
*
|
||||
* @param string $alias
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
protected function renderExportForm($alias)
|
||||
{
|
||||
$exportManager = $this->get('chill.main.export_manager');
|
||||
|
||||
$export = $exportManager->getExport($alias);
|
||||
|
||||
$form = $this->createCreateForm($alias);
|
||||
|
||||
$form = $this->createCreateFormExport($alias);
|
||||
|
||||
return $this->render('ChillMainBundle:Export:new.html.twig', array(
|
||||
'form' => $form->createView(),
|
||||
'export_alias' => $alias,
|
||||
'export' => $export
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -65,30 +103,150 @@ class ExportController extends Controller
|
||||
* @param string $alias
|
||||
* @return \Symfony\Component\Form\Form
|
||||
*/
|
||||
protected function createCreateForm($alias)
|
||||
protected function createCreateFormExport($alias)
|
||||
{
|
||||
$form = $this->createForm(ExportType::class, array(), array(
|
||||
$builder = $this->get('form.factory')
|
||||
->createNamedBuilder(null, FormType::class, array(), array(
|
||||
'method' => 'GET',
|
||||
'csrf_protection' => false,
|
||||
'action' => $this->generateUrl('chill_main_export_new', array(
|
||||
'alias' => $alias
|
||||
))
|
||||
));
|
||||
|
||||
$builder->add('export', ExportType::class, array(
|
||||
'export_alias' => $alias,
|
||||
'method' => 'GET',
|
||||
'action' => $this->generateUrl('chill_main_export_generate', array(
|
||||
'alias' => $alias
|
||||
))
|
||||
|
||||
));
|
||||
|
||||
$form->add('submit', 'submit', array(
|
||||
$builder->add('submit', 'submit', array(
|
||||
'label' => 'Generate'
|
||||
));
|
||||
$builder->add('step', 'hidden', array(
|
||||
'data' => 'formatter'
|
||||
));
|
||||
|
||||
return $builder->getForm();
|
||||
}
|
||||
|
||||
protected function renderFormatterStep(Request $request, $alias)
|
||||
{
|
||||
$export = $this->get('chill.main.export_manager')->getExport($alias);
|
||||
|
||||
$exportForm = $this->createCreateFormExport($alias);
|
||||
$exportForm->handleRequest($request);
|
||||
$data = $exportForm->getData();
|
||||
|
||||
$form = $this->createCreateFormFormatter($request,
|
||||
$alias, array(), $data['export']['formatter']['alias']);
|
||||
|
||||
return $this->render('ChillMainBundle:Export:new_formatter_step.html.twig',
|
||||
array(
|
||||
'form' => $form->createView(),
|
||||
'export' => $export
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Request $request
|
||||
* @param type $formatterAlias
|
||||
* @return \Symfony\Component\Form\Form
|
||||
*/
|
||||
protected function createCreateFormFormatter(Request $request,
|
||||
$exportAlias, $aggregatorAliases, $formatterAlias = null)
|
||||
{
|
||||
var_dump($request->query->all());
|
||||
$builder = $this->get('form.factory')
|
||||
->createNamedBuilder(null, FormType::class, array(), array(
|
||||
'method' => 'GET',
|
||||
'csrf_protection' => false,
|
||||
'action' => $this->generateUrl('chill_main_export_generate', array(
|
||||
'alias' => $exportAlias
|
||||
))
|
||||
));
|
||||
|
||||
$builder->add('formatter', FormatterType::class, array(
|
||||
'formatter_alias' => $formatterAlias,
|
||||
'export_alias' => $exportAlias,
|
||||
'aggregator_aliases' => $aggregatorAliases
|
||||
));
|
||||
|
||||
// re-add the export type under hidden fields
|
||||
$builderExport = $builder->create('export', FormType::class, array());
|
||||
$data = $request->query->all();
|
||||
foreach($data['export'] as $key => $value) {
|
||||
$this->recursiveAddHiddenFieldsToForm($builderExport, $key, $value);
|
||||
}
|
||||
$builder->add($builderExport);
|
||||
|
||||
//add the formatter alias
|
||||
$builder->add('formatter', HiddenType::class, array(
|
||||
'data' => $formatterAlias
|
||||
));
|
||||
|
||||
$builder->add('submit', 'submit', array(
|
||||
'label' => 'Generate'
|
||||
));
|
||||
|
||||
return $form;
|
||||
return $builder->getForm();
|
||||
|
||||
}
|
||||
|
||||
public function generateAction(Request $request, $alias)
|
||||
{
|
||||
$exportManager = $this->get('chill.main.export_manager');
|
||||
|
||||
$form = $this->createCreateForm($alias);
|
||||
$form = $this->createCreateFormGenerate($request, $alias);
|
||||
$form->handleRequest($request);
|
||||
$data = $form->getData();
|
||||
|
||||
return $exportManager->generate($alias, $form->getData());
|
||||
return $exportManager->generate($alias, $data['export']);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Request $request
|
||||
* @param string $alias
|
||||
* @return \Symfony\Component\Form\Form
|
||||
*/
|
||||
public function createCreateFormGenerate(Request $request, $alias,
|
||||
$aggregatorAliases, $formatterAlias)
|
||||
{
|
||||
$builder = $this->get('form.factory')
|
||||
->createNamedBuilder(null, FormType::class, array(), array(
|
||||
'method' => 'GET',
|
||||
'csrf_protection' => false,
|
||||
'action' => $this->generateUrl('chill_main_export_generate', array(
|
||||
'alias' => $alias
|
||||
))
|
||||
));
|
||||
|
||||
$builder->add('formatter', FormatterType::class, array(
|
||||
'formatter_alias' => $formatterAlias,
|
||||
'export_alias' => $exportAlias,
|
||||
'aggregator_aliases' => $aggregatorAliases
|
||||
));
|
||||
|
||||
$builder->add('export', ExportType::class, array(
|
||||
'export_alias' => $alias,
|
||||
));
|
||||
|
||||
return $builder->getForm();
|
||||
}
|
||||
|
||||
protected function recursiveAddHiddenFieldsToForm(FormBuilderInterface $builder, $key, $data)
|
||||
{
|
||||
if (is_array($data)) {
|
||||
foreach($data as $subKey => $value) {
|
||||
$subBuilder = $builder->create($subKey, FormType::class);
|
||||
$this->recursiveAddHiddenFieldsToForm($subBuilder, $subKey, $value);
|
||||
$builder->add($subBuilder);
|
||||
}
|
||||
} else {
|
||||
$builder->add($key, 'hidden', array(
|
||||
'data' => $data
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,6 +52,7 @@ class ExportsCompilerPass implements CompilerPassInterface
|
||||
$this->compileExports($chillManagerDefinition, $container);
|
||||
$this->compileFilters($chillManagerDefinition, $container);
|
||||
$this->compileAggregators($chillManagerDefinition, $container);
|
||||
$this->compileFormatters($chillManagerDefinition, $container);
|
||||
}
|
||||
|
||||
private function compileExports(Definition $chillManagerDefinition,
|
||||
@ -143,5 +144,35 @@ class ExportsCompilerPass implements CompilerPassInterface
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function compileFormatters(Definition $chillManagerDefinition,
|
||||
ContainerBuilder $container)
|
||||
{
|
||||
$taggedServices = $container->findTaggedServiceIds(
|
||||
'chill.export_formatter'
|
||||
);
|
||||
|
||||
$knownAliases = array();
|
||||
|
||||
foreach ($taggedServices as $id => $tagAttributes) {
|
||||
foreach ($tagAttributes as $attributes) {
|
||||
if (!isset($attributes["alias"])) {
|
||||
throw new \LogicException("the 'alias' attribute is missing in your ".
|
||||
"service '$id' definition");
|
||||
}
|
||||
|
||||
if (array_search($attributes["alias"], $knownAliases)) {
|
||||
throw new \LogicException("There is already a chill.export_formatter service with alias "
|
||||
.$attributes["alias"].". Choose another alias.");
|
||||
}
|
||||
$knownAliases[] = $attributes["alias"];
|
||||
|
||||
$chillManagerDefinition->addMethodCall(
|
||||
'addFormatter',
|
||||
array(new Reference($id), $attributes["alias"])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -94,9 +94,9 @@ class ExportManager
|
||||
$this->exports[$alias] = $export;
|
||||
}
|
||||
|
||||
public function addFormatter(FormatterInterface $formatter)
|
||||
public function addFormatter(FormatterInterface $formatter, $alias)
|
||||
{
|
||||
array_push($this->formatters, $formatter);
|
||||
$this->formatters[$alias] = $formatter;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -157,6 +157,13 @@ class ExportManager
|
||||
return $this->filters[$alias];
|
||||
}
|
||||
|
||||
public function getFilters(array $aliases)
|
||||
{
|
||||
foreach($aliases as $alias) {
|
||||
yield $alias => $this->getFilter($alias);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $alias
|
||||
@ -172,6 +179,31 @@ class ExportManager
|
||||
return $this->aggregators[$alias];
|
||||
}
|
||||
|
||||
public function getAggregators(array $aliases)
|
||||
{
|
||||
foreach ($aliases as $alias) {
|
||||
yield $alias => $this->getAggregator($alias);
|
||||
}
|
||||
}
|
||||
|
||||
public function getFormatter($alias)
|
||||
{
|
||||
if (!array_key_exists($alias, $this->formatters)) {
|
||||
throw new \RuntimeException("The formatter with alias $alias is not known.");
|
||||
}
|
||||
|
||||
return $this->formatters[$alias];
|
||||
}
|
||||
|
||||
public function getFormattersByTypes(array $types)
|
||||
{
|
||||
foreach ($this->formatters as $alias => $formatter) {
|
||||
if (in_array($formatter->getType(), $types)) {
|
||||
yield $alias => $formatter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a \Generator containing filter which support type
|
||||
@ -242,11 +274,18 @@ class ExportManager
|
||||
'class' => self::class, 'function' => __FUNCTION__
|
||||
));
|
||||
|
||||
$results = $qb->getQuery()->getResult(\Doctrine\ORM\Query::HYDRATE_SCALAR);
|
||||
$result = $export->getResult($qb, array());
|
||||
|
||||
var_dump($results);
|
||||
/* @var $formatter Formatter\CSVFormatter */
|
||||
$formatter = $this->getFormatter('csv');
|
||||
$filters = array();
|
||||
$aggregators = iterator_to_array($this->retrieveUsedAggregators($data['aggregators']));
|
||||
$aggregatorsData = array_combine(array_keys($data['aggregators']),
|
||||
array_map(function($data) { return $data['form']; }, $data['aggregators'])
|
||||
);
|
||||
|
||||
return new Response('everything is fine !');
|
||||
return $formatter->getResponse($result, array(), $export,
|
||||
$filters, $aggregators, array(), $data['filters'], $aggregatorsData);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -257,12 +296,10 @@ class ExportManager
|
||||
*/
|
||||
private function retrieveUsedModifiers($data)
|
||||
{
|
||||
$usedTypes = array();
|
||||
|
||||
// used filters
|
||||
$this->retrieveUsedFilters($data, $usedTypes);
|
||||
// used aggregators
|
||||
$this->retrieveUsedAggregators($data, $usedTypes);
|
||||
$usedTypes = array_merge(
|
||||
$this->retrieveUsedFiltersType($data['filters']),
|
||||
$this->retrieveUsedAggregatorsType($data['aggregators'])
|
||||
);
|
||||
|
||||
$this->logger->debug('Required types are '.implode(', ', $usedTypes),
|
||||
array('class' => self::class, 'function' => __FUNCTION__));
|
||||
@ -270,9 +307,10 @@ class ExportManager
|
||||
return $usedTypes;
|
||||
}
|
||||
|
||||
private function retrieveUsedFilters($data, &$usedTypes)
|
||||
private function retrieveUsedFiltersType($data)
|
||||
{
|
||||
foreach($data['filters'] as $alias => $filterData) {
|
||||
$usedTypes = array();
|
||||
foreach($data as $alias => $filterData) {
|
||||
if ($filterData['enabled'] == true){
|
||||
$filter = $this->getFilter($alias);
|
||||
if (!in_array($filter->applyOn(), $usedTypes)) {
|
||||
@ -280,16 +318,37 @@ class ExportManager
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $usedTypes;
|
||||
}
|
||||
|
||||
private function retrieveUsedAggregators($data, &$usedTypes)
|
||||
/**
|
||||
*
|
||||
* @param mixed $data
|
||||
* @return string[]
|
||||
*/
|
||||
private function retrieveUsedAggregatorsType($data)
|
||||
{
|
||||
foreach($data['aggregators'] as $alias => $aggregatorData) {
|
||||
$usedTypes = array();
|
||||
foreach($this->retrieveUsedAggregators($data) as $alias => $aggregator) {
|
||||
if (!in_array($aggregator->applyOn(), $usedTypes)) {
|
||||
array_push($usedTypes, $aggregator->applyOn());
|
||||
}
|
||||
}
|
||||
|
||||
return $usedTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param mixed $data
|
||||
* @return AggregatorInterface[]
|
||||
*/
|
||||
private function retrieveUsedAggregators($data)
|
||||
{
|
||||
foreach($data as $alias => $aggregatorData) {
|
||||
if ($aggregatorData['order']> 0){
|
||||
$aggregator = $this->getAggregator($alias);
|
||||
if (!in_array($aggregator->applyOn(), $usedTypes)) {
|
||||
array_push($usedTypes, $aggregator->applyOn());
|
||||
}
|
||||
yield $alias => $this->getAggregator($alias);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
247
Export/Formatter/CSVFormatter.php
Normal file
247
Export/Formatter/CSVFormatter.php
Normal file
@ -0,0 +1,247 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 Champs-Libres <info@champs-libres.coop>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Export\Formatter;
|
||||
|
||||
use Chill\MainBundle\Export\ExportInterface;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Chill\MainBundle\Export\FormatterInterface;
|
||||
use Symfony\Component\Translation\TranslatorInterface;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
// command to get the report with curl : curl --user "center a_social:password" "http://localhost:8000/fr/exports/generate/count_person?export[filters][person_gender_filter][enabled]=&export[filters][person_nationality_filter][enabled]=&export[filters][person_nationality_filter][form][nationalities]=&export[aggregators][person_nationality_aggregator][order]=1&export[aggregators][person_nationality_aggregator][form][group_by_level]=country&export[submit]=&export[_token]=RHpjHl389GrK-bd6iY5NsEqrD5UKOTHH40QKE9J1edU" --globoff
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
class CSVFormatter implements FormatterInterface
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @var TranslatorInterface
|
||||
*/
|
||||
protected $translator;
|
||||
|
||||
protected $result;
|
||||
|
||||
protected $formatterData;
|
||||
|
||||
protected $export;
|
||||
|
||||
protected $filters;
|
||||
|
||||
protected $aggregators;
|
||||
|
||||
protected $exportData;
|
||||
|
||||
protected $filterData;
|
||||
|
||||
protected $aggregatorsData;
|
||||
|
||||
|
||||
public function __construct(TranslatorInterface $translator)
|
||||
{
|
||||
$this->translator = $translator;
|
||||
}
|
||||
|
||||
public function getType()
|
||||
{
|
||||
return 'tabular';
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'CSV';
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, $exportAlias, array $aggregatorAliases)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param mixed $result
|
||||
* @param mixed $data
|
||||
* @param \Chill\MainBundle\Export\ExportInterface $export
|
||||
* @param \Chill\MainBundle\Export\FilterInterface[] $filters
|
||||
* @param \Chill\MainBundle\Export\AggregatorInterface[] $aggregators
|
||||
*/
|
||||
public function getResponse($result, $formatterData, ExportInterface $export, $filters,
|
||||
$aggregators, $exportData, $filterData, $aggregatorsData)
|
||||
{
|
||||
$this->result = $result;
|
||||
$this->formatterData = $formatterData;
|
||||
$this->export = $export;
|
||||
$this->filters = $filters;
|
||||
$this->aggregators = $aggregators;
|
||||
$this->exportData = $exportData;
|
||||
$this->filterData = $filterData;
|
||||
$this->aggregatorsData = $aggregatorsData;
|
||||
|
||||
$response = new Response();
|
||||
$response->setStatusCode(200);
|
||||
$response->headers->set('Content-Type', 'text/csv; charset=utf-8');
|
||||
//$response->headers->set('Content-Disposition','attachment; filename="export.csv"');
|
||||
|
||||
$response->setContent($this->generateContent());
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
protected function generateContent()
|
||||
{
|
||||
$labels = $this->gatherLabels();
|
||||
$horizontalHeadersKeys = $this->getHorizontalHeaders();
|
||||
$resultsKeys = $this->export->getQueryKeys($this->exportData);
|
||||
|
||||
|
||||
// create a file pointer connected to the output stream
|
||||
$output = fopen('php://output', 'w');
|
||||
|
||||
//title
|
||||
fputcsv($output, array($this->translator->trans($this->export->getTitle())));
|
||||
//blank line
|
||||
fputcsv($output, array(""));
|
||||
|
||||
//headers
|
||||
$headerLine = array();
|
||||
foreach($horizontalHeadersKeys as $headerKey) {
|
||||
$headerLine[] = array_key_exists('_header', $labels[$headerKey]) ?
|
||||
$labels[$headerKey]['_header'] : '';
|
||||
}
|
||||
foreach($resultsKeys as $key) {
|
||||
$headerLine[] = array_key_exists('_header', $labels[$key]) ?
|
||||
$labels[$key]['_header'] : '';
|
||||
}
|
||||
fputcsv($output, $headerLine);
|
||||
unset($headerLine); //free memory
|
||||
|
||||
$content = array();
|
||||
foreach($this->result as $row) {
|
||||
$line = array();
|
||||
//set horizontal headers
|
||||
foreach($horizontalHeadersKeys as $headerKey) {
|
||||
|
||||
if (!array_key_exists($row[$headerKey], $labels[$headerKey])) {
|
||||
throw new \LogicException("The value '".$row[$headerKey]."' "
|
||||
. "is not available from the labels defined by aggregators. "
|
||||
. "The key name was $headerKey");
|
||||
}
|
||||
|
||||
$line[] = $labels[$headerKey][$row[$headerKey]];
|
||||
}
|
||||
//append result
|
||||
foreach($resultsKeys as $key) {
|
||||
$line[] = $labels[$key][$row[$key]];
|
||||
}
|
||||
// append to content
|
||||
$content[] = $line;
|
||||
}
|
||||
|
||||
//ordering content
|
||||
array_multisort($content);
|
||||
|
||||
//generate CSV
|
||||
foreach($content as $line) {
|
||||
fputcsv($output, $line);
|
||||
}
|
||||
|
||||
$text = stream_get_contents($output);
|
||||
fclose($output);
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
|
||||
protected function getHorizontalHeaders()
|
||||
{
|
||||
$headers = array();
|
||||
/* @var $aggregator AggregatorInterface */
|
||||
foreach($this->aggregators as $alias => $aggregator) {
|
||||
$headers = array_merge($headers, $aggregator->getQueryKeys($this->aggregatorsData[$alias]));
|
||||
}
|
||||
return $headers;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param mixed $result
|
||||
* @param \Chill\MainBundle\Export\AggregatorInterface[] $aggregators
|
||||
*/
|
||||
protected function gatherLabels()
|
||||
{
|
||||
return array_merge(
|
||||
$this->gatherLabelsFromAggregators(),
|
||||
$this->gatherLabelsFromExport()
|
||||
);
|
||||
}
|
||||
|
||||
protected function gatherLabelsFromAggregators()
|
||||
{
|
||||
$labels = array();
|
||||
/* @var $aggretator \Chill\MainBundle\Export\AggregatorInterface */
|
||||
foreach ($this->aggregators as $alias => $aggregator) {
|
||||
$keys = $aggregator->getQueryKeys($this->aggregatorsData[$alias]);
|
||||
|
||||
// gather data in an array
|
||||
foreach($keys as $key) {
|
||||
$values = array_map(function($row) use ($key, $alias) {
|
||||
if (!array_key_exists($key, $row)) {
|
||||
throw new \LogicException("the key '".$key."' is declared by "
|
||||
. "the aggregator with alias '".$alias."' but is not "
|
||||
. "present in results");
|
||||
}
|
||||
|
||||
return $row[$key];
|
||||
}, $this->result);
|
||||
$labels[$key] = $aggregator->getLabels($key, array_unique($values),
|
||||
$this->aggregatorsData[$alias]);
|
||||
}
|
||||
}
|
||||
|
||||
return $labels;
|
||||
}
|
||||
|
||||
protected function gatherLabelsFromExport()
|
||||
{
|
||||
$labels = array();
|
||||
$export = $this->export;
|
||||
$keys = $this->export->getQueryKeys($this->exportData);
|
||||
|
||||
foreach($keys as $key) {
|
||||
$values = array_map(function($row) use ($key, $export) {
|
||||
if (!array_key_exists($key, $row)) {
|
||||
throw new \LogicException("the key '".$key."' is declared by "
|
||||
. "the export with title '".$export->getTitle()."' but is not "
|
||||
. "present in results");
|
||||
}
|
||||
|
||||
return $row[$key];
|
||||
}, $this->result);
|
||||
$labels[$key] = $this->export->getLabels($key, array_unique($values),
|
||||
$this->exportData);
|
||||
}
|
||||
|
||||
return $labels;
|
||||
}
|
||||
|
||||
}
|
@ -17,7 +17,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Chill\Mainbundle\Export;
|
||||
namespace Chill\MainBundle\Export;
|
||||
|
||||
/**
|
||||
*
|
||||
|
86
Form/Type/DataTransformer/AliasToFormatterTransformer.php
Normal file
86
Form/Type/DataTransformer/AliasToFormatterTransformer.php
Normal file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 Champs-Libres <info@champs-libres.coop>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Form\Type\DataTransformer;
|
||||
|
||||
use Symfony\Component\Form\DataTransformerInterface;
|
||||
use Chill\MainBundle\Export\ExportManager;
|
||||
use Symfony\Component\Form\Exception\TransformationFailedException;
|
||||
|
||||
/**
|
||||
* Transform a formatter alias to an FormatterInterface class
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
class AliasToFormatterTransformer implements DataTransformerInterface
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @var ExportManager
|
||||
*/
|
||||
protected $exportManager;
|
||||
|
||||
public function __construct(ExportManager $exportManager)
|
||||
{
|
||||
$this->exportManager = $exportManager;
|
||||
}
|
||||
|
||||
public function reverseTransform($value)
|
||||
{
|
||||
if ($value === NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!value instanceof \Chill\MainBundle\Export\FormatterInterface) {
|
||||
throw new TransformationFailedException("The given value is not a "
|
||||
. "Chill\MainBundle\Export\FormatterInterface");
|
||||
}
|
||||
|
||||
// we do not have the alias, which is only known by the container.
|
||||
// we try to check the formatter by the php internal object id.
|
||||
$formatters = $this->exportManager
|
||||
->getFormattersByTypes(array($value->getType()));
|
||||
foreach($formatters as $alias => $formatter) {
|
||||
if (spl_object_hash($formatter) === spl_object_hash($value)) {
|
||||
return $alias;
|
||||
}
|
||||
}
|
||||
|
||||
throw new TransformationFailedException("The formatter could not be found "
|
||||
. "by his object_hash. Maybe you created a formatter manually ? "
|
||||
. "Use the export manager to get your formatter.");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param type $value
|
||||
* @return \Chill\MainBundle\Export\FormatterInterface
|
||||
* @throws TransformationFailedException
|
||||
*/
|
||||
public function transform($value)
|
||||
{
|
||||
if (empty($value)) {
|
||||
throw new TransformationFailedException("The formatter with empty "
|
||||
. "alias is not allowed. Given value is ".$value);
|
||||
}
|
||||
|
||||
return $this->exportManager->getFormatter($value);
|
||||
}
|
||||
|
||||
}
|
@ -23,8 +23,7 @@ use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Chill\MainBundle\Export\ExportManager;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -49,15 +48,14 @@ class AggregatorType extends AbstractType
|
||||
$aggregator = $this->exportManager->getAggregator($options['aggregator_alias']);
|
||||
|
||||
$builder
|
||||
->add('order', IntegerType::class, array(
|
||||
'constraints' => array(
|
||||
new Assert\GreaterThanOrEqual(array(
|
||||
'value' => -1
|
||||
)),
|
||||
new Assert\LessThanOrEqual(array(
|
||||
'value' => $options['aggregators_length']
|
||||
))
|
||||
)
|
||||
->add('enabled', ChoiceType::class, array(
|
||||
'choices' => array(
|
||||
'enabled' => true,
|
||||
'disabled' => false
|
||||
),
|
||||
'multiple' => false,
|
||||
'expanded' => true,
|
||||
'choices_as_values' => true
|
||||
));
|
||||
|
||||
$filterFormBuilder = $builder->create('form', 'form', array(
|
||||
|
@ -88,6 +88,10 @@ class ExportType extends AbstractType
|
||||
|
||||
$builder->add($aggregatorBuilder);
|
||||
|
||||
$builder->add('formatter', PickFormatterType::class, array(
|
||||
'export_alias' => $options['export_alias']
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
59
Form/Type/Export/FormatterType.php
Normal file
59
Form/Type/Export/FormatterType.php
Normal file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 Champs-Libres <info@champs-libres.coop>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Form\Type\Export;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Chill\MainBundle\Export\ExportManager;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
class FormatterType extends AbstractType
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @var ExportManager
|
||||
*/
|
||||
protected $exportManager;
|
||||
|
||||
public function __construct(ExportManager $manager)
|
||||
{
|
||||
$this->exportManager = $manager;
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver->setRequired(array('formatter_alias', 'export_alias',
|
||||
'aggregator_aliases'));
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$formatter = $this->exportManager->getFormatter($options['formatter_alias']);
|
||||
|
||||
$formatter->buildForm($builder, $options['export_alias'],
|
||||
$options['aggregator_aliases']);
|
||||
}
|
||||
|
||||
}
|
69
Form/Type/Export/PickFormatterType.php
Normal file
69
Form/Type/Export/PickFormatterType.php
Normal file
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 Champs-Libres <info@champs-libres.coop>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace Chill\MainBundle\Form\Type\Export;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use Chill\MainBundle\Export\ExportManager;
|
||||
use Chill\MainBundle\Form\Type\DataTransformer\AliasToFormatterTransformer;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
class PickFormatterType extends AbstractType
|
||||
{
|
||||
protected $exportManager;
|
||||
|
||||
public function __construct(ExportManager $exportManager)
|
||||
{
|
||||
$this->exportManager = $exportManager;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$export = $this->exportManager->getExport($options['export_alias']);
|
||||
$allowedFormatters = $this->exportManager
|
||||
->getFormattersByTypes($export->getAllowedFormattersTypes());
|
||||
//$transformer = new AliasToFormatterTransformer($this->exportManager);
|
||||
|
||||
//build choices
|
||||
$choices = array();
|
||||
foreach($allowedFormatters as $alias => $formatter) {
|
||||
$choices[$formatter->getName()] = $alias;
|
||||
}
|
||||
|
||||
$builder->add('alias', 'choice', array(
|
||||
'choices' => $choices,
|
||||
'choices_as_values' => true,
|
||||
'multiple' => false
|
||||
));
|
||||
|
||||
//$builder->get('type')->addModelTransformer($transformer);
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver->setRequired(array('export_alias'));
|
||||
}
|
||||
|
||||
}
|
@ -161,3 +161,30 @@ services:
|
||||
- "@chill.main.export_manager"
|
||||
tags:
|
||||
- { name: form.type }
|
||||
|
||||
chill.main.form.pick_formatter_type:
|
||||
class: Chill\MainBundle\Form\Type\Export\PickFormatterType
|
||||
arguments:
|
||||
- "@chill.main.export_manager"
|
||||
tags:
|
||||
- { name: form.type }
|
||||
|
||||
chill.main.form.formatter_type:
|
||||
class: Chill\MainBundle\Form\Type\Export\FormatterType
|
||||
arguments:
|
||||
- "@chill.main.export_manager"
|
||||
tags:
|
||||
- { name: form.type }
|
||||
|
||||
chill.main.countries_repository:
|
||||
class: Doctrine\ORM\EntityRepository
|
||||
factory: ["@doctrine.orm.entity_manager", getRepository]
|
||||
arguments:
|
||||
- "Chill\\MainBundle\\Entity\\Country"
|
||||
|
||||
chill.main.export.csv_formatter:
|
||||
class: Chill\MainBundle\Export\Formatter\CSVFormatter
|
||||
arguments:
|
||||
- "@translator"
|
||||
tags:
|
||||
- { name: chill.export_formatter, alias: 'csv' }
|
||||
|
@ -29,7 +29,7 @@
|
||||
{{ form_start(form) }}
|
||||
<div>
|
||||
<h2>{{ 'Filters'| trans }}</h2>
|
||||
{% for filter_form in form.children.filters %}
|
||||
{% for filter_form in form.children.export.children.filters %}
|
||||
{{ form_label(filter_form) }}
|
||||
{{ form_row(filter_form.enabled) }}
|
||||
{{ form_widget(filter_form.form) }}
|
||||
@ -38,13 +38,18 @@
|
||||
|
||||
<div>
|
||||
<h2>{{ 'Aggregators'| trans }}</h2>
|
||||
{% for aggregator_form in form.children.aggregators %}
|
||||
{% for aggregator_form in form.children.export.children.aggregators %}
|
||||
{{ form_label(aggregator_form) }}
|
||||
{{ form_row(aggregator_form.order) }}
|
||||
{{ form_row(aggregator_form.enabled) }}
|
||||
{{ form_widget(aggregator_form.form) }}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2>{{ 'Formatter'| trans }}</h2>
|
||||
{{ form_row(form.children.export.children.formatter.children.alias) }}
|
||||
</div>
|
||||
|
||||
<p>{{ form_widget(form.submit, { 'attr' : { 'class' : 'sc-button btn-action' } } ) }}</p>
|
||||
{{ form_end(form) }}
|
||||
|
||||
|
38
Resources/views/Export/new_formatter_step.html.twig
Normal file
38
Resources/views/Export/new_formatter_step.html.twig
Normal file
@ -0,0 +1,38 @@
|
||||
{#
|
||||
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
|
||||
<info@champs-libres.coop> / <http://www.champs-libres.coop>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program 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 Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#}
|
||||
|
||||
{% extends "ChillMainBundle::layoutWithVerticalMenu.html.twig" %}
|
||||
|
||||
{% block title %}{{ export.title|trans }}{% endblock %}
|
||||
|
||||
{% block layout_wvm_content %}
|
||||
|
||||
<h1>{{ export.title|trans }}</h1>
|
||||
|
||||
<p>{{ export.description|trans }}</p>
|
||||
|
||||
{{ form_start(form) }}
|
||||
<div>
|
||||
<h2>{{ 'Formatter'| trans }}</h2>
|
||||
{{ form_row(form.children.formatter) }}
|
||||
</div>
|
||||
|
||||
<p>{{ form_widget(form.submit, { 'attr' : { 'class' : 'sc-button btn-action' } } ) }}</p>
|
||||
{{ form_end(form) }}
|
||||
|
||||
{% endblock layout_wvm_content %}
|
Loading…
x
Reference in New Issue
Block a user