mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
create a first set of export framework
- create interfaces - create an export manager - add a compiler pass to gather services tagged for export
This commit is contained in:
parent
876a656bd2
commit
b40b85527a
@ -8,6 +8,7 @@ use Chill\MainBundle\DependencyInjection\SearchableServicesCompilerPass;
|
||||
use Chill\MainBundle\DependencyInjection\ConfigConsistencyCompilerPass;
|
||||
use Chill\MainBundle\DependencyInjection\TimelineCompilerClass;
|
||||
use Chill\MainBundle\DependencyInjection\RoleProvidersCompilerPass;
|
||||
use Chill\MainBundle\DependencyInjection\CompilerPass\ExportsCompilerPass;
|
||||
|
||||
class ChillMainBundle extends Bundle
|
||||
{
|
||||
@ -17,6 +18,7 @@ class ChillMainBundle extends Bundle
|
||||
$container->addCompilerPass(new SearchableServicesCompilerPass());
|
||||
$container->addCompilerPass(new ConfigConsistencyCompilerPass());
|
||||
$container->addCompilerPass(new TimelineCompilerClass());
|
||||
$container->addCompilerPass(new RoleProvidersCompilerPass);
|
||||
$container->addCompilerPass(new RoleProvidersCompilerPass());
|
||||
$container->addCompilerPass(new ExportsCompilerPass());
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,9 @@
|
||||
namespace Chill\MainBundle\Controller;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Chill\MainBundle\Form\Type\Export\ExportType;
|
||||
|
||||
|
||||
/**
|
||||
* ExportController is the controller use for exporting data.
|
||||
@ -30,10 +33,62 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
*/
|
||||
class ExportController extends Controller
|
||||
{
|
||||
public function indexAction($menu = 'admin',
|
||||
$header_title = 'views.Main.admin.index.header_title',
|
||||
$page_title = 'views.Main.admin.index.page_title')
|
||||
public function indexAction(Request $request)
|
||||
{
|
||||
return $this->render('ChillMainBundle:Export:layout.html.twig');
|
||||
$exportManager = $this->get('chill.main.export_manager');
|
||||
|
||||
$exports = $exportManager->getExports();
|
||||
|
||||
return $this->render('ChillMainBundle:Export:layout.html.twig', array(
|
||||
'exports' => $exports
|
||||
));
|
||||
}
|
||||
|
||||
public function newAction($alias)
|
||||
{
|
||||
$exportManager = $this->get('chill.main.export_manager');
|
||||
|
||||
$export = $exportManager->getExport($alias);
|
||||
|
||||
$form = $this->createCreateForm($alias);
|
||||
|
||||
return $this->render('ChillMainBundle:Export:new.html.twig', array(
|
||||
'form' => $form->createView(),
|
||||
'export_alias' => $alias,
|
||||
'export' => $export
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $alias
|
||||
* @return \Symfony\Component\Form\Form
|
||||
*/
|
||||
protected function createCreateForm($alias)
|
||||
{
|
||||
$form = $this->createForm(ExportType::class, array(), array(
|
||||
'export_alias' => $alias,
|
||||
'method' => 'GET',
|
||||
'action' => $this->generateUrl('chill_main_export_generate', array(
|
||||
'alias' => $alias
|
||||
))
|
||||
));
|
||||
|
||||
$form->add('submit', 'submit', array(
|
||||
'label' => 'Generate'
|
||||
));
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
public function generateAction(Request $request, $alias)
|
||||
{
|
||||
$exportManager = $this->get('chill.main.export_manager');
|
||||
|
||||
$form = $this->createCreateForm($alias);
|
||||
$form->handleRequest($request);
|
||||
|
||||
return $exportManager->generate($alias, $form->getData());
|
||||
}
|
||||
}
|
||||
|
147
DependencyInjection/CompilerPass/ExportsCompilerPass.php
Normal file
147
DependencyInjection/CompilerPass/ExportsCompilerPass.php
Normal file
@ -0,0 +1,147 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 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\DependencyInjection\CompilerPass;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
|
||||
/**
|
||||
* Compiles the services tagged with :
|
||||
*
|
||||
* - chill.export
|
||||
* - chill.export_formatter
|
||||
* - chill.export_aggregator
|
||||
* - chill.export_filter
|
||||
*
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
class ExportsCompilerPass implements CompilerPassInterface
|
||||
{
|
||||
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
if (!$container->hasDefinition('chill.main.export_manager')) {
|
||||
throw new \LogicException('service chill.main.export_manager '
|
||||
. 'is not defined. It is required by ExportsCompilerPass');
|
||||
}
|
||||
|
||||
$chillManagerDefinition = $container->getDefinition(
|
||||
'chill.main.export_manager'
|
||||
);
|
||||
|
||||
$this->compileExports($chillManagerDefinition, $container);
|
||||
$this->compileFilters($chillManagerDefinition, $container);
|
||||
$this->compileAggregators($chillManagerDefinition, $container);
|
||||
}
|
||||
|
||||
private function compileExports(Definition $chillManagerDefinition,
|
||||
ContainerBuilder $container)
|
||||
{
|
||||
$taggedServices = $container->findTaggedServiceIds(
|
||||
'chill.export'
|
||||
);
|
||||
|
||||
$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 service with alias "
|
||||
.$attributes["alias"].". Choose another alias.");
|
||||
}
|
||||
$knownAliases[] = $attributes["alias"];
|
||||
|
||||
$chillManagerDefinition->addMethodCall(
|
||||
'addExport',
|
||||
array(new Reference($id), $attributes["alias"])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function compileFilters(Definition $chillManagerDefinition,
|
||||
ContainerBuilder $container)
|
||||
{
|
||||
$taggedServices = $container->findTaggedServiceIds(
|
||||
'chill.export_filter'
|
||||
);
|
||||
|
||||
$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_filter service with alias "
|
||||
.$attributes["alias"].". Choose another alias.");
|
||||
}
|
||||
$knownAliases[] = $attributes["alias"];
|
||||
|
||||
$chillManagerDefinition->addMethodCall(
|
||||
'addFilter',
|
||||
array(new Reference($id), $attributes["alias"])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function compileAggregators(Definition $chillManagerDefinition,
|
||||
ContainerBuilder $container)
|
||||
{
|
||||
$taggedServices = $container->findTaggedServiceIds(
|
||||
'chill.export_aggregator'
|
||||
);
|
||||
|
||||
$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_aggregator service with alias "
|
||||
.$attributes["alias"].". Choose another alias.");
|
||||
}
|
||||
$knownAliases[] = $attributes["alias"];
|
||||
|
||||
$chillManagerDefinition->addMethodCall(
|
||||
'addAggregator',
|
||||
array(new Reference($id), $attributes["alias"])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
38
Export/AggregatorInterface.php
Normal file
38
Export/AggregatorInterface.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 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;
|
||||
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
interface AggregatorInterface
|
||||
{
|
||||
public function applyOn();
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder);
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data);
|
||||
|
||||
public function getTitle();
|
||||
}
|
55
Export/ExportInterface.php
Normal file
55
Export/ExportInterface.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 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;
|
||||
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
interface ExportInterface
|
||||
{
|
||||
|
||||
public function getType();
|
||||
|
||||
public function getDescription();
|
||||
|
||||
public function getTitle();
|
||||
|
||||
/**
|
||||
*
|
||||
* @param QueryBuilder $qb
|
||||
* @param array $requiredModifiers
|
||||
* TODO : we should add ability to receive data from a form
|
||||
*/
|
||||
public function initiateQuery(QueryBuilder $qb, array $requiredModifiers);
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder);
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function hasForm();
|
||||
|
||||
public function supportsModifiers();
|
||||
|
||||
}
|
338
Export/ExportManager.php
Normal file
338
Export/ExportManager.php
Normal file
@ -0,0 +1,338 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 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;
|
||||
|
||||
use Chill\MainBundle\Export\FilterInterface;
|
||||
use Chill\MainBundle\Export\AggregatorInterface;
|
||||
use Chill\MainBundle\Export\ExportInterface;
|
||||
use Chill\MainBundle\Export\FormatterInterface;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
|
||||
/**
|
||||
* Collects all agregators, filters and export from
|
||||
* the installed bundle.
|
||||
*
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
class ExportManager
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @var FilterInterface[]
|
||||
*/
|
||||
private $filters = array();
|
||||
|
||||
/**
|
||||
*
|
||||
* @var AggregatorInterface[]
|
||||
*/
|
||||
private $aggregators = array();
|
||||
|
||||
/**
|
||||
*
|
||||
* @var ExportInterface[]
|
||||
*/
|
||||
private $exports = array();
|
||||
|
||||
/**
|
||||
*
|
||||
* @var FormatterInterface[]
|
||||
*/
|
||||
private $formatters = array();
|
||||
|
||||
/**
|
||||
*
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var EntityManagerInterface
|
||||
*/
|
||||
private $em;
|
||||
|
||||
public function __construct(LoggerInterface $logger, EntityManagerInterface $em)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
$this->em = $em;
|
||||
}
|
||||
|
||||
public function addFilter(FilterInterface $filter, $alias)
|
||||
{
|
||||
$this->filters[$alias] = $filter;
|
||||
}
|
||||
|
||||
public function addAggregator(AggregatorInterface $aggregator, $alias)
|
||||
{
|
||||
$this->aggregators[$alias] = $aggregator;
|
||||
}
|
||||
|
||||
public function addExport(ExportInterface $export, $alias)
|
||||
{
|
||||
$this->exports[$alias] = $export;
|
||||
}
|
||||
|
||||
public function addFormatter(FormatterInterface $formatter)
|
||||
{
|
||||
array_push($this->formatters, $formatter);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string[] the existing type for known exports
|
||||
*/
|
||||
public function getExistingExportsTypes()
|
||||
{
|
||||
$existingTypes = array();
|
||||
|
||||
foreach($this->exports as $export) {
|
||||
if (!in_array($export->getType(), $existingTypes)) {
|
||||
array_push($existingTypes, $export->getType());
|
||||
}
|
||||
}
|
||||
|
||||
return $existingTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all exports. The exports's alias are the array's keys.
|
||||
*
|
||||
* @return ExportInterface[] an array where export's alias are keys
|
||||
*/
|
||||
public function getExports()
|
||||
{
|
||||
return $this->exports;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an export by his alias
|
||||
*
|
||||
* @param string $alias
|
||||
* @return ExportInterface
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function getExport($alias)
|
||||
{
|
||||
if (!array_key_exists($alias, $this->exports)) {
|
||||
throw new \RuntimeException("The export with alias $alias is not known.");
|
||||
}
|
||||
|
||||
return $this->exports[$alias];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $alias
|
||||
* @return FilterInterface
|
||||
* @throws \RuntimeException if the filter is not known
|
||||
*/
|
||||
public function getFilter($alias)
|
||||
{
|
||||
if (!array_key_exists($alias, $this->filters)) {
|
||||
throw new \RuntimeException("The filter with alias $alias is not known.");
|
||||
}
|
||||
|
||||
return $this->filters[$alias];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $alias
|
||||
* @return AggregatorInterface
|
||||
* @throws \RuntimeException if the aggregator is not known
|
||||
*/
|
||||
public function getAggregator($alias)
|
||||
{
|
||||
if (!array_key_exists($alias, $this->aggregators)) {
|
||||
throw new \RuntimeException("The aggregator with alias $alias is not known.");
|
||||
}
|
||||
|
||||
return $this->aggregators[$alias];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a \Generator containing filter which support type
|
||||
*
|
||||
* @param string[] $types
|
||||
* @return FilterInterface[] a \Generator that contains filters. The key is the filter's alias
|
||||
*/
|
||||
public function &getFiltersApplyingOn(array $types)
|
||||
{
|
||||
foreach ($this->filters as $alias => $filter) {
|
||||
if (in_array($filter->applyOn(), $types)) {
|
||||
yield $alias => $filter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a \Generator containing filter which support type
|
||||
*
|
||||
* @param string $types
|
||||
* @return FilterInterface[] a \Generator that contains filters. The key is the filter's alias
|
||||
*/
|
||||
public function &getFiltersSupportingType($type)
|
||||
{
|
||||
foreach ($this->filters as $alias => $filter) {
|
||||
if ($filter->supportsType($type)) {
|
||||
yield $alias => $filter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a \Generator containing aggregators which support type
|
||||
*
|
||||
* @param string[] $types
|
||||
* @return AggregatorInterface[] a \Generator that contains aggretagors. The key is the filter's alias
|
||||
*/
|
||||
public function &getAggregatorsApplyingOn(array $types)
|
||||
{
|
||||
foreach ($this->aggregators as $alias => $aggregator) {
|
||||
if (in_array($aggregator->applyOn(), $types)) {
|
||||
yield $alias => $aggregator;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a response which contains the requested data.
|
||||
*
|
||||
* @param string $exportAlias
|
||||
* @param mixed[] $data
|
||||
* @return Response
|
||||
*/
|
||||
public function generate($exportAlias, array $data)
|
||||
{
|
||||
$export = $this->getExport($exportAlias);
|
||||
$qb = $this->em->createQueryBuilder();
|
||||
|
||||
$qb = $export->initiateQuery($qb, $this->retrieveUsedModifiers($data));
|
||||
|
||||
//handle filters
|
||||
$this->handleFilters($export, $qb, $data['filters']);
|
||||
|
||||
//handle aggregators
|
||||
$this->handleAggregators($export, $qb, $data['aggregators']);
|
||||
|
||||
$this->logger->debug('current query is '.$qb->getDQL(), array(
|
||||
'class' => self::class, 'function' => __FUNCTION__
|
||||
));
|
||||
|
||||
$results = $qb->getQuery()->getResult(\Doctrine\ORM\Query::HYDRATE_SCALAR);
|
||||
|
||||
var_dump($results);
|
||||
|
||||
return new Response('everything is fine !');
|
||||
}
|
||||
|
||||
/**
|
||||
* parse the data to retrieve the used filters and aggregators
|
||||
*
|
||||
* @param mixed $data
|
||||
* @return string[]
|
||||
*/
|
||||
private function retrieveUsedModifiers($data)
|
||||
{
|
||||
$usedTypes = array();
|
||||
|
||||
// used filters
|
||||
$this->retrieveUsedFilters($data, $usedTypes);
|
||||
// used aggregators
|
||||
$this->retrieveUsedAggregators($data, $usedTypes);
|
||||
|
||||
$this->logger->debug('Required types are '.implode(', ', $usedTypes),
|
||||
array('class' => self::class, 'function' => __FUNCTION__));
|
||||
|
||||
return $usedTypes;
|
||||
}
|
||||
|
||||
private function retrieveUsedFilters($data, &$usedTypes)
|
||||
{
|
||||
foreach($data['filters'] as $alias => $filterData) {
|
||||
if ($filterData['enabled'] == true){
|
||||
$filter = $this->getFilter($alias);
|
||||
if (!in_array($filter->applyOn(), $usedTypes)) {
|
||||
array_push($usedTypes, $filter->applyOn());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function retrieveUsedAggregators($data, &$usedTypes)
|
||||
{
|
||||
foreach($data['aggregators'] as $alias => $aggregatorData) {
|
||||
if ($aggregatorData['order']> 0){
|
||||
$aggregator = $this->getAggregator($alias);
|
||||
if (!in_array($aggregator->applyOn(), $usedTypes)) {
|
||||
array_push($usedTypes, $aggregator->applyOn());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param ExportInterface $export
|
||||
* @param QueryBuilder $qb
|
||||
* @param mixed $data the data under the initial 'filters' data
|
||||
*/
|
||||
private function handleFilters(ExportInterface $export, QueryBuilder $qb, $data)
|
||||
{
|
||||
$filters = $this->getFiltersApplyingOn($export->supportsModifiers());
|
||||
|
||||
foreach($filters as $alias => $filter) {
|
||||
$this->logger->debug('handling filter '.$alias, array(
|
||||
'class' => self::class, 'function' => __FUNCTION__
|
||||
));
|
||||
|
||||
$formData = $data[$alias];
|
||||
|
||||
if ($formData['enabled'] == true) {
|
||||
$this->logger->debug('alter query by filter '.$alias, array(
|
||||
'class' => self::class, 'function' => __FUNCTION__
|
||||
));
|
||||
$filter->alterQuery($qb, $formData['form']);
|
||||
} else {
|
||||
$this->logger->debug('skipping filter '.$alias.' because not enabled',
|
||||
array('class' => self::class, 'function' => __FUNCTION__));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function handleAggregators(ExportInterface $export, QueryBuilder $qb, $data)
|
||||
{
|
||||
$aggregators = $this->getAggregatorsApplyingOn($export->supportsModifiers());
|
||||
|
||||
foreach ($aggregators as $alias => $aggregator) {
|
||||
$formData = $data[$alias];
|
||||
if ($formData['order'] >= 0) {
|
||||
$aggregator->alterQuery($qb, $formData['form']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
39
Export/FilterInterface.php
Normal file
39
Export/FilterInterface.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 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;
|
||||
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
interface FilterInterface
|
||||
{
|
||||
public function applyOn();
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder);
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data);
|
||||
|
||||
public function getTitle();
|
||||
}
|
29
Export/FormatterInterface.php
Normal file
29
Export/FormatterInterface.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 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;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
interface FormatterInterface
|
||||
{
|
||||
//put your code here
|
||||
}
|
82
Form/Type/Export/AggregatorType.php
Normal file
82
Form/Type/Export/AggregatorType.php
Normal file
@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 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;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
class AggregatorType extends AbstractType
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @var \ExportManager
|
||||
*/
|
||||
private $exportManager;
|
||||
|
||||
public function __construct(ExportManager $exportManager)
|
||||
{
|
||||
$this->exportManager = $exportManager;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$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']
|
||||
))
|
||||
)
|
||||
));
|
||||
|
||||
$filterFormBuilder = $builder->create('form', 'form', array(
|
||||
'compound' => true, 'required' => false));
|
||||
$aggregator->buildForm($filterFormBuilder);
|
||||
|
||||
$builder->add($filterFormBuilder);
|
||||
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver->setRequired('aggregator_alias')
|
||||
->setRequired('aggregators_length')
|
||||
->setAllowedTypes(array(
|
||||
'aggregators_length' => 'int'
|
||||
))
|
||||
->setDefault('compound', true)
|
||||
;
|
||||
}
|
||||
|
||||
}
|
102
Form/Type/Export/ExportType.php
Normal file
102
Form/Type/Export/ExportType.php
Normal file
@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* Copyright (C) 2014-2015, Champs Libres Cooperative SCRLFS,
|
||||
* <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/>.
|
||||
*/
|
||||
|
||||
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;
|
||||
use Chill\MainBundle\Form\Type\Export\FilterType;
|
||||
use Chill\MainBundle\Form\Type\Export\AggregatorType;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
class ExportType extends AbstractType
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @var ExportManager
|
||||
*/
|
||||
protected $exportManager;
|
||||
|
||||
public function __construct(ExportManager $exportManager)
|
||||
{
|
||||
$this->exportManager = $exportManager;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$export = $this->exportManager->getExport($options['export_alias']);
|
||||
|
||||
/* this part has not been experimented
|
||||
if ($export->hasForm()) {
|
||||
$exportBuilder = $builder->create('export', null, array('compound' => true));
|
||||
$export->buildForm($exportBuilder);
|
||||
$builder->add($exportBuilder);
|
||||
} */
|
||||
|
||||
//add filters
|
||||
$filters = $this->exportManager->getFiltersApplyingOn($export->supportsModifiers());
|
||||
$filterBuilder = $builder->create('filters', 'form', array('compound' => true));
|
||||
|
||||
foreach($filters as $alias => $filter) {
|
||||
$filterBuilder->add($alias, new FilterType($this->exportManager), array(
|
||||
'filter_alias' => $alias,
|
||||
'label' => $filter->getTitle()
|
||||
));
|
||||
}
|
||||
|
||||
$builder->add($filterBuilder);
|
||||
|
||||
//add aggregators
|
||||
$aggregators = iterator_to_array($this->exportManager
|
||||
->getAggregatorsApplyingOn($export->supportsModifiers()));
|
||||
$aggregatorBuilder = $builder->create('aggregators', 'form',
|
||||
array('compound' => true));
|
||||
$nb = count($aggregators);
|
||||
|
||||
foreach($aggregators as $alias => $aggregator) {
|
||||
$aggregatorBuilder->add($alias, new AggregatorType($this->exportManager), array(
|
||||
'aggregator_alias' => $alias,
|
||||
'aggregators_length' => $nb,
|
||||
'label' => $aggregator->getTitle()
|
||||
));
|
||||
}
|
||||
|
||||
$builder->add($aggregatorBuilder);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver->setRequired(array('export_alias'))
|
||||
->setAllowedTypes('export_alias', array('string'))
|
||||
->setDefault('compound', true)
|
||||
;
|
||||
|
||||
}
|
||||
}
|
75
Form/Type/Export/FilterType.php
Normal file
75
Form/Type/Export/FilterType.php
Normal file
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 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 FilterType extends AbstractType
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @var \ExportManager
|
||||
*/
|
||||
private $exportManager;
|
||||
|
||||
public function __construct(ExportManager $exportManager)
|
||||
{
|
||||
$this->exportManager = $exportManager;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$filter = $this->exportManager->getFilter($options['filter_alias']);
|
||||
|
||||
$builder
|
||||
->add('enabled', 'choice', array(
|
||||
'choices' => array(
|
||||
'enabled' => true,
|
||||
'disabled' => false
|
||||
),
|
||||
'multiple' => false,
|
||||
'expanded' => true,
|
||||
'choices_as_values' => true
|
||||
));
|
||||
|
||||
$filterFormBuilder = $builder->create('form', null, array(
|
||||
'compound' => true, 'required' => false));
|
||||
$filter->buildForm($filterFormBuilder);
|
||||
|
||||
$builder->add($filterFormBuilder);
|
||||
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver->setRequired('filter_alias')
|
||||
->setDefault('compound', true)
|
||||
;
|
||||
}
|
||||
|
||||
}
|
@ -13,6 +13,10 @@ chill_main_admin_scope:
|
||||
chill_main_admin:
|
||||
resource: "@ChillMainBundle/Resources/config/routing/center.yml"
|
||||
prefix: "{_locale}/admin/center"
|
||||
|
||||
chill_main_exports:
|
||||
resource: "@ChillMainBundle/Resources/config/routing/exports.yml"
|
||||
prefix: "{_locale}/exports"
|
||||
|
||||
root:
|
||||
path: /
|
||||
@ -35,15 +39,6 @@ chill_main_homepage:
|
||||
label: Homepage
|
||||
icons: [home]
|
||||
|
||||
chill_main_export_index:
|
||||
path: /{_locale}/export
|
||||
defaults: { _controller: ChillMainBundle:Export:index }
|
||||
options:
|
||||
menus:
|
||||
section:
|
||||
order: 20
|
||||
label: Export Menu
|
||||
icons: [upload]
|
||||
|
||||
chill_main_admin_central:
|
||||
path: /{_locale}/admin
|
||||
|
18
Resources/config/routing/exports.yml
Normal file
18
Resources/config/routing/exports.yml
Normal file
@ -0,0 +1,18 @@
|
||||
chill_main_export_index:
|
||||
path: /
|
||||
defaults: { _controller: ChillMainBundle:Export:index }
|
||||
options:
|
||||
menus:
|
||||
section:
|
||||
order: 20
|
||||
label: Export Menu
|
||||
icons: [upload]
|
||||
|
||||
chill_main_export_new:
|
||||
path: /new/{alias}
|
||||
defaults: { _controller: ChillMainBundle:Export:new }
|
||||
|
||||
chill_main_export_generate:
|
||||
path: /generate/{alias}
|
||||
defaults: { _controller: ChillMainBundle:Export:generate }
|
||||
methods: [GET]
|
@ -148,3 +148,16 @@ services:
|
||||
- "@chill.main.helper.translatable_string"
|
||||
tags:
|
||||
- { name: form.type }
|
||||
|
||||
chill.main.export_manager:
|
||||
class: Chill\MainBundle\Export\ExportManager
|
||||
arguments:
|
||||
- "@logger"
|
||||
- "@doctrine.orm.entity_manager"
|
||||
|
||||
chill.main.form.type.export:
|
||||
class: Chill\MainBundle\Form\Type\Export\ExportType
|
||||
arguments:
|
||||
- "@chill.main.export_manager"
|
||||
tags:
|
||||
- { name: form.type }
|
||||
|
@ -18,6 +18,8 @@
|
||||
|
||||
{% extends "ChillMainBundle::layoutWithVerticalMenu.html.twig" %}
|
||||
|
||||
{% block title %}{{ 'Exports list'|trans }}{% endblock %}
|
||||
|
||||
{% block vertical_menu_content %}
|
||||
{{ chill_menu('export', {
|
||||
'layout': 'ChillMainBundle::Menu/export.html.twig',
|
||||
@ -25,7 +27,20 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block layout_wvm_content %}
|
||||
{% block export_content %}<!-- block personcontent empty -->
|
||||
Welcome to the Export section !
|
||||
{% block export_content %}
|
||||
<h1>{{ 'Exports list'|trans }}</h1>
|
||||
|
||||
{% for export_alias,export in exports %}
|
||||
<div class="export">
|
||||
<h2>{{ export.title|trans }}</h2>
|
||||
<p>{{ export.description|trans }}</p>
|
||||
|
||||
<p>
|
||||
<a class="sc-button bt-action" href="{{ path('chill_main_export_new', { 'alias': export_alias } ) }}">
|
||||
{{ 'Create an export'|trans }}
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
{% endblock %}
|
51
Resources/views/Export/new.html.twig
Normal file
51
Resources/views/Export/new.html.twig
Normal file
@ -0,0 +1,51 @@
|
||||
{#
|
||||
* 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>{{ 'Filters'| trans }}</h2>
|
||||
{% for filter_form in form.children.filters %}
|
||||
{{ form_label(filter_form) }}
|
||||
{{ form_row(filter_form.enabled) }}
|
||||
{{ form_widget(filter_form.form) }}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2>{{ 'Aggregators'| trans }}</h2>
|
||||
{% for aggregator_form in form.children.aggregators %}
|
||||
{{ form_label(aggregator_form) }}
|
||||
{{ form_row(aggregator_form.order) }}
|
||||
{{ form_widget(aggregator_form.form) }}
|
||||
{% endfor %}
|
||||
</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