replacing the response of Export::getLabel by a Closure

This commit is contained in:
Julien Fastré 2016-04-21 22:20:37 +02:00
parent 85dfb222ae
commit 4bfe4b361f
4 changed files with 62 additions and 19 deletions

View File

@ -116,9 +116,9 @@ interface ExportInterface extends ExportElementInterface
* have, as value, a string for the header. See example in return declaration
*
* @param string $key The column key, as added in the query
* @param mixed[] $values The values from the result. Each value should be unique. Example: array('FR', 'BE', 'CZ')
* @param mixed $data The data from the form
* @return string[] where keys are the identifier given by result, and the value a string which should be displayed to the user. A special key '_header' should be added for the header. Example: array('FR' => 'France', 'BE' => 'Belgium', 'CZ' => 'Tchécoslovaquie', '_header' => 'Pays')
* @param mixed[] $values The values from the result. if there are duplicates, those might be given twice. Example: array('FR', 'BE', 'CZ', 'FR', 'BE', 'FR')
* @param mixed $data The data from the export's form (as defined in `buildForm`
* @return \Closure where the first argument is the value, and the function should return the label to show in the formatted file. Example : `function($countryCode) use ($countries) { return $countries[$countryCode]->getName(); }`
*/
public function getLabels($key, array $values, $data);

View File

@ -398,9 +398,9 @@ class ExportManager
//handle aggregators
$this->handleAggregators($export, $qb, $data[ExportType::AGGREGATOR_KEY], $centers);
$this->logger->debug('current query is '.$qb->getDQL(), array(
'class' => self::class, 'function' => __FUNCTION__
));
// $this->logger->debug('current query is '.$qb->getDQL(), array(
// 'class' => self::class, 'function' => __FUNCTION__
// ));
$result = $export->getResult($qb, $data[ExportType::EXPORT_KEY]);

View File

@ -19,13 +19,12 @@
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;
use Chill\MainBundle\Export\ExportManager;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
// 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
@ -50,6 +49,8 @@ class CSVListFormatter implements FormatterInterface
protected $exportData = null;
protected $formatterData = null;
/**
*
* @var ExportManager
@ -94,7 +95,17 @@ class CSVListFormatter implements FormatterInterface
$exportAlias,
array $aggregatorAliases
){
// do nothing
$builder->add('numerotation', ChoiceType::class, array(
'choices' => array(
'yes' => true,
'no' => false
),
'expanded' => true,
'multiple' => false,
'label' => "Add a number on first column",
'choices_as_values' => true,
'data' => true
));
}
/**
@ -118,17 +129,27 @@ class CSVListFormatter implements FormatterInterface
$this->result = $result;
$this->exportAlias = $exportAlias;
$this->exportData = $exportData;
$this->formatterData = $formatterData;
$output = fopen('php://output', 'w');
$this->prepareHeaders($output);
$i = 1;
foreach ($result as $row) {
$line = array();
if ($this->formatterData['numerotation'] === true) {
$line[] = $i;
}
foreach ($row as $key => $value) {
$line[] = $this->getLabel($key, $value);
}
fputcsv($output, $line);
$i++;
}
$csvContent = stream_get_contents($output);
@ -144,6 +165,11 @@ class CSVListFormatter implements FormatterInterface
return $response;
}
/**
* add the headers to the csv file
*
* @param resource $output
*/
protected function prepareHeaders($output)
{
$keys = $this->exportManager->getExport($this->exportAlias)->getQueryKeys($this->exportData);
@ -151,6 +177,10 @@ class CSVListFormatter implements FormatterInterface
$first_row = count($this->result) > 0 ? $this->result[0] : array();
$header_line = array();
if ($this->formatterData['numerotation'] === true) {
$header_line[] = $this->translator->trans('Number');
}
foreach ($first_row as $key => $value) {
$header_line[] = $this->getLabel($key, '_header');
}
@ -160,29 +190,36 @@ class CSVListFormatter implements FormatterInterface
}
}
/**
* Give the label corresponding to the given key and value.
*
* @param string $key
* @param string $value
* @return string
* @throws \LogicException if the label is not found
*/
protected function getLabel($key, $value)
{
if ($this->labelsCache === null) {
$this->prepareLabels();
}
if (!isset($this->labelsCache[$key][$value])) {
throw new \LogicException("The label for key $key and value $value was not given "
. "by the export, aggregator or filter responsible for this key.");
$this->prepareCacheLabels();
}
return $this->labelsCache[$key][$value];
return $this->labelsCache[$key]($value);
}
protected function prepareLabels()
/**
* Prepare the label cache which will be used by getLabel. This function
* should be called only once in the generation lifecycle.
*/
protected function prepareCacheLabels()
{
$export = $this->exportManager->getExport($this->exportAlias);
$keys = $export->getQueryKeys($this->exportData);
foreach($keys as $key) {
// get an array with all values for this key
$values = array_unique(array_map(function ($v) use ($key) { return $v[$key]; }, $this->result));
// get an array with all values for this key if possible
$values = \array_map(function ($v) use ($key) { return $v[$key]; }, $this->result);
// store the label in the labelsCache property
$this->labelsCache[$key] = $export->getLabels($key, $values, $this->exportData);
}

View File

@ -105,3 +105,9 @@ Circle: Cercle
Circle edit: Modification du cercle
Circle creation: Création d'un cercle
Create a new circle: Créer un nouveau cercle
#export
#CSV List Formatter
Add a number on first column: La première colonne est un numéro
Number: Numéro