mirror of
				https://gitlab.com/Chill-Projet/chill-bundles.git
				synced 2025-10-31 01:08:26 +00:00 
			
		
		
		
	[wip] add different steps to handle request
This commit is contained in:
		| @@ -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  %} | ||||
		Reference in New Issue
	
	Block a user