mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-12 21:34:25 +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\Bundle\FrameworkBundle\Controller\Controller;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Chill\MainBundle\Form\Type\Export\ExportType;
|
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');
|
$exportManager = $this->get('chill.main.export_manager');
|
||||||
|
|
||||||
$export = $exportManager->getExport($alias);
|
$export = $exportManager->getExport($alias);
|
||||||
|
|
||||||
$form = $this->createCreateForm($alias);
|
$form = $this->createCreateFormExport($alias);
|
||||||
|
|
||||||
return $this->render('ChillMainBundle:Export:new.html.twig', array(
|
return $this->render('ChillMainBundle:Export:new.html.twig', array(
|
||||||
'form' => $form->createView(),
|
'form' => $form->createView(),
|
||||||
'export_alias' => $alias,
|
'export_alias' => $alias,
|
||||||
'export' => $export
|
'export' => $export
|
||||||
));
|
));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -65,30 +103,150 @@ class ExportController extends Controller
|
|||||||
* @param string $alias
|
* @param string $alias
|
||||||
* @return \Symfony\Component\Form\Form
|
* @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,
|
'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'
|
'label' => 'Generate'
|
||||||
));
|
));
|
||||||
|
|
||||||
return $form;
|
return $builder->getForm();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function generateAction(Request $request, $alias)
|
public function generateAction(Request $request, $alias)
|
||||||
{
|
{
|
||||||
$exportManager = $this->get('chill.main.export_manager');
|
$exportManager = $this->get('chill.main.export_manager');
|
||||||
|
|
||||||
$form = $this->createCreateForm($alias);
|
$form = $this->createCreateFormGenerate($request, $alias);
|
||||||
$form->handleRequest($request);
|
$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->compileExports($chillManagerDefinition, $container);
|
||||||
$this->compileFilters($chillManagerDefinition, $container);
|
$this->compileFilters($chillManagerDefinition, $container);
|
||||||
$this->compileAggregators($chillManagerDefinition, $container);
|
$this->compileAggregators($chillManagerDefinition, $container);
|
||||||
|
$this->compileFormatters($chillManagerDefinition, $container);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function compileExports(Definition $chillManagerDefinition,
|
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;
|
$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];
|
return $this->filters[$alias];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getFilters(array $aliases)
|
||||||
|
{
|
||||||
|
foreach($aliases as $alias) {
|
||||||
|
yield $alias => $this->getFilter($alias);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param string $alias
|
* @param string $alias
|
||||||
@ -172,6 +179,31 @@ class ExportManager
|
|||||||
return $this->aggregators[$alias];
|
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
|
* Return a \Generator containing filter which support type
|
||||||
@ -242,11 +274,18 @@ class ExportManager
|
|||||||
'class' => self::class, 'function' => __FUNCTION__
|
'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)
|
private function retrieveUsedModifiers($data)
|
||||||
{
|
{
|
||||||
$usedTypes = array();
|
$usedTypes = array_merge(
|
||||||
|
$this->retrieveUsedFiltersType($data['filters']),
|
||||||
// used filters
|
$this->retrieveUsedAggregatorsType($data['aggregators'])
|
||||||
$this->retrieveUsedFilters($data, $usedTypes);
|
);
|
||||||
// used aggregators
|
|
||||||
$this->retrieveUsedAggregators($data, $usedTypes);
|
|
||||||
|
|
||||||
$this->logger->debug('Required types are '.implode(', ', $usedTypes),
|
$this->logger->debug('Required types are '.implode(', ', $usedTypes),
|
||||||
array('class' => self::class, 'function' => __FUNCTION__));
|
array('class' => self::class, 'function' => __FUNCTION__));
|
||||||
@ -270,9 +307,10 @@ class ExportManager
|
|||||||
return $usedTypes;
|
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){
|
if ($filterData['enabled'] == true){
|
||||||
$filter = $this->getFilter($alias);
|
$filter = $this->getFilter($alias);
|
||||||
if (!in_array($filter->applyOn(), $usedTypes)) {
|
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){
|
if ($aggregatorData['order']> 0){
|
||||||
$aggregator = $this->getAggregator($alias);
|
yield $alias => $this->getAggregator($alias);
|
||||||
if (!in_array($aggregator->applyOn(), $usedTypes)) {
|
|
||||||
array_push($usedTypes, $aggregator->applyOn());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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/>.
|
* 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\OptionsResolver\OptionsResolver;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Chill\MainBundle\Export\ExportManager;
|
use Chill\MainBundle\Export\ExportManager;
|
||||||
use Symfony\Component\Validator\Constraints as Assert;
|
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -49,15 +48,14 @@ class AggregatorType extends AbstractType
|
|||||||
$aggregator = $this->exportManager->getAggregator($options['aggregator_alias']);
|
$aggregator = $this->exportManager->getAggregator($options['aggregator_alias']);
|
||||||
|
|
||||||
$builder
|
$builder
|
||||||
->add('order', IntegerType::class, array(
|
->add('enabled', ChoiceType::class, array(
|
||||||
'constraints' => array(
|
'choices' => array(
|
||||||
new Assert\GreaterThanOrEqual(array(
|
'enabled' => true,
|
||||||
'value' => -1
|
'disabled' => false
|
||||||
)),
|
),
|
||||||
new Assert\LessThanOrEqual(array(
|
'multiple' => false,
|
||||||
'value' => $options['aggregators_length']
|
'expanded' => true,
|
||||||
))
|
'choices_as_values' => true
|
||||||
)
|
|
||||||
));
|
));
|
||||||
|
|
||||||
$filterFormBuilder = $builder->create('form', 'form', array(
|
$filterFormBuilder = $builder->create('form', 'form', array(
|
||||||
|
@ -88,6 +88,10 @@ class ExportType extends AbstractType
|
|||||||
|
|
||||||
$builder->add($aggregatorBuilder);
|
$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"
|
- "@chill.main.export_manager"
|
||||||
tags:
|
tags:
|
||||||
- { name: form.type }
|
- { 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) }}
|
{{ form_start(form) }}
|
||||||
<div>
|
<div>
|
||||||
<h2>{{ 'Filters'| trans }}</h2>
|
<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_label(filter_form) }}
|
||||||
{{ form_row(filter_form.enabled) }}
|
{{ form_row(filter_form.enabled) }}
|
||||||
{{ form_widget(filter_form.form) }}
|
{{ form_widget(filter_form.form) }}
|
||||||
@ -38,13 +38,18 @@
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<h2>{{ 'Aggregators'| trans }}</h2>
|
<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_label(aggregator_form) }}
|
||||||
{{ form_row(aggregator_form.order) }}
|
{{ form_row(aggregator_form.enabled) }}
|
||||||
{{ form_widget(aggregator_form.form) }}
|
{{ form_widget(aggregator_form.form) }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</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>
|
<p>{{ form_widget(form.submit, { 'attr' : { 'class' : 'sc-button btn-action' } } ) }}</p>
|
||||||
{{ form_end(form) }}
|
{{ 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