<?php
namespace App\Controller;
use App\Entity\Event;
use Doctrine\ORM\Internal\Hydration\ArrayHydrator;
use Doctrine\ORM\Internal\Hydration\ObjectHydrator;
use Doctrine\ORM\Query\ResultSetMappingBuilder;
use Exporter\Handler;
use App\Entity\Result;
use App\Entity\Survey;
use Exporter\Writer\CsvWriter;
use Doctrine\ORM\Query\ResultSetMapping;
use Exporter\Source\ArraySourceIterator;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Serializer\Encoder\CsvEncoder;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class DefaultController extends AbstractController
{
/**
* @Route("/", name="homepage")
*/
public function indexAction()
{
return $this->render('default/index.html.twig');
}
/**
* @Route("/keolis", name="keolis")
*/
public function keolisAction(Request $request)
{
if ($request->get('start')) {
$start = $request->get('start') . " 00:00:00";
} else {
$start = date('Y-m-01', time());
}
if ($request->get('end')) {
$end = $request->get('end') . " 23:59:59";
} else {
$end = date('Y-m-t', time());
}
$datas = $this->queries('DIVIA', $start, $end, null);
return $this->render('dashboard/keolis.html.twig', [
'codes' => $datas['codes'],
'ages' => $datas['ages'],
'genders' => $datas['genders'],
'actions' => $datas['actions'],
'durations' => $datas['durations'],
'travels' => $datas['travels'],
'start' => $start,
'end' => $end
]);
}
/**
* @Route("/sncf", name="sncf")
*/
public function sncfAction(Request $request)
{
if ($request->get('start')) {
$start = $request->get('start') . " 00:00:00";
} else {
$start = date('Y-m-01', time());
}
if ($request->get('end')) {
$end = $request->get('end') . " 23:59:59";
} else {
$end = date('Y-m-t', time());
}
$datas = $this->queries('TER', $start, $end);
return $this->render('dashboard/sncf.html.twig', [
'codes' => $datas['codes'],
'ages' => $datas['ages'],
'genders' => $datas['genders'],
'actions' => $datas['actions'],
'durations' => $datas['durations'],
'moods' => $datas['moods'],
'categories' => $datas['categories'],
'start' => $start,
'end' => $end
]);
}
/**
* @Route("/download/{network}/{start}/{end}/{raw}", name="download")
*/
public function downloadAction($network, $start, $end, $raw = false)
{
$start = new \DateTime($start);
$start->setTime(00, 00);
$end = new \DateTime($end);
$end->setTime(23, 59);
// create a new spreadsheet object
$spreadsheet = new Spreadsheet();
$spreadsheet->getProperties()
->setCreator("PIMMS")
->setLastModifiedBy("PIMMS")
->setTitle("Export données " . $network);
$spreadsheet = ($raw) ?
$this->getRawDatas($spreadsheet, $network, $start, $end)
: $this->getNiceDatas($spreadsheet, $network, $start, $end);
$spreadsheet->getActiveSheet()->setTitle(($raw) ? 'Données' : 'Stats');
// Set active sheet index to the first sheet, so Excel opens this as the first sheet
$spreadsheet->setActiveSheetIndex(0);
// create the writer
$writer = new Xlsx($spreadsheet);
// create the response
$response = new StreamedResponse(
function () use ($writer) {
$writer->save('php://output');
}
);
// adding headers
$response->headers->set('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=utf-8');
$response->headers->set('Content-Disposition', 'attachment; filename="pimms_' . (($raw) ? 'donnees_' : 'stats_') . $network . '_' . $start->format('d-m-Y') . '-' . $end->format('d-m-Y') . '.xlsx"');
return $response;
}
private function getNiceDatas($spreadsheet, $network, $start, $end)
{
$datas = $this->queries($network, $start, $end);
if ($datas['genders']) {
$spreadsheet->getActiveSheet()
->setCellValue('A1', 'Sexe')
->setCellValue('B1', 'Effectifs');
foreach ($datas['genders'] as $k => $g) {
$spreadsheet->getActiveSheet()
->setCellValue('A' . ($k + 2), $g['gender'])
->setCellValue('B' . ($k + 2), $g['genderCount']);
}
}
if ($datas['ages']) {
$spreadsheet->getActiveSheet()
->setCellValue('D1', 'Age')
->setCellValue('E1', 'Effectifs');
foreach ($datas['ages'] as $k => $g) {
$spreadsheet->getActiveSheet()
->setCellValue('D' . ($k + 2), $g['age'])
->setCellValue('E' . ($k + 2), $g['ageCount']);
}
}
if ($datas['durations']) {
$spreadsheet->getActiveSheet()
->setCellValue('G1', 'Durée')
->setCellValue('H1', 'Effectifs');
foreach ($datas['durations'] as $k => $g) {
$spreadsheet->getActiveSheet()
->setCellValue('G' . ($k + 2), $g['duration'])
->setCellValue('H' . ($k + 2), $g['durationCount']);
}
}
if ($datas['actions']) {
$spreadsheet->getActiveSheet()
->setCellValue('A10', 'Type d\'action')
->setCellValue('B10', 'Effectifs');
foreach ($datas['actions'] as $k => $g) {
$spreadsheet->getActiveSheet()
->setCellValue('A' . ($k + 11), $g['action'])
->setCellValue('B' . ($k + 11), $g['actionCount']);
}
}
if ($datas['moods']) {
$spreadsheet->getActiveSheet()
->setCellValue('D10', 'Ambiance')
->setCellValue('E10', 'Effectifs');
foreach ($datas['moods'] as $k => $g) {
$spreadsheet->getActiveSheet()
->setCellValue('D' . ($k + 11), $g['mood'])
->setCellValue('E' . ($k + 11), $g['moodCount']);
}
}
if ($datas['categories']) {
$spreadsheet->getActiveSheet()
->setCellValue('G10', 'Catégorie d\'action')
->setCellValue('H10', 'Effectifs');
foreach ($datas['categories'] as $k => $g) {
if (isset($g['category'][0])) {
$spreadsheet->getActiveSheet()
->setCellValue('G' . ($k + 11), implode(' > ', $g['category']))
->setCellValue('H' . ($k + 11), $g['categoryCount']);
}
}
}
if ($datas['travels']) {
$spreadsheet->getActiveSheet()
->setCellValue('J10', 'Ligne')
->setCellValue('K10', 'Trajets');
$index = 0;
foreach ($datas['travels'] as $k => $g) {
$spreadsheet->getActiveSheet()
->setCellValue('J' . ($index + 11), $k)
->setCellValue('K' . ($index + 11), $g);
$index++;
}
}
return $spreadsheet;
}
public function getRawDatas($spreadsheet, $network, $start, $end)
{
$em = $this->getDoctrine()->getManager();
$events = $this->getDoctrine()
->getManager()
->createQueryBuilder()
->select('MAX(e.id) AS id', 'e.user', 'e.network', 'e.age', 'e.gender', 'e.mood', 'e.duration', 'e.comment', 'e.action', 'e.creation', 'e.altercation', 'e.line', 'e.code', 'e.codename', 'e.vehicule', 'e.stop', 'e.category')
->from('App\Entity\Event', 'e')
->where('e.network = :network')
->andWhere('e.codename != :null')
->andWhere('e.creation <= :end')
->andWhere('e.creation >= :start')
->groupBy('e.user', 'e.network', 'e.age', 'e.gender', 'e.mood', 'e.duration', 'e.comment', 'e.action', 'e.creation', 'e.altercation', 'e.line', 'e.code', 'e.codename', 'e.vehicule', 'e.stop', 'e.category')
->setParameters([
'network' => $network,
'null' => '',
'start' => $start,
'end' => $end,
])
->getQuery()
->execute();
$datas = array();
foreach ($events as $e) {
$datas[] = [
'Ligne' => $e['line'],
'Arrêt' => $e['stop'],
'Véhicule' => $e['vehicule'],
'Code' => $e['code'],
'Nom du code' => $e['codename'],
'Catégorie' => implode(' / ', (array)$e['category']),
'Agent' => $e['user'],
'Age' => $e['age'],
'Genre' => $e['gender'],
'Humeur' => $e['mood'],
'Durée' => $e['duration'],
'Commentaire' => $e['comment'],
'Action' => $e['action'],
'Date' => $e['creation']->format('Y-m-d'),
'Heure' => $e['creation']->format('H:i'),
'Altercation' => $e['altercation']
];
}
$letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'H', 'K', 'L', 'M', 'N', 'O'];
$col = 1;
// Set headers
foreach ($datas[0] as $key => $value) {
$spreadsheet->getActiveSheet()->setCellValueByColumnAndRow($col, 1, $key);
$col++;
}
// Set datas
$row = 2;
foreach ($datas as $data) {
$col = 1;
foreach ($data as $value) {
$spreadsheet->getActiveSheet()->setCellValueByColumnAndRow($col, $row, $value);
$col++;
}
$row++;
}
return $spreadsheet;
}
private function queries($network, $start, $end, $raw = false)
{
$rp = $this->getDoctrine()->getRepository(Event::class);
$parameters = array(
'network' => $network,
'null' => '',
'start' => $start,
'end' => $end,
'descente' => 'descente'
);
$codes = $rp->createQueryBuilder('e')
->select('COUNT(e.codename) AS codeCount, e.codename')
->where('e.network = :network')
->andWhere('e.codename != :null')
->andWhere('e.codename != :descente')
->andWhere('e.creation <= :end')
->andWhere('e.creation >= :start')
->setParameters($parameters)
->groupBy('e.codename')
->getQuery()
->getResult();
$ages = $rp->createQueryBuilder('e')
->select('COUNT(e.age) AS ageCount, e.age')
->where('e.network = :network')
->andWhere('e.age != :null')
->andWhere('e.creation <= :end')
->andWhere('e.creation >= :start')
->andWhere('e.codename != :descente')
->setParameters($parameters)
->groupBy('e.age')
->getQuery()
->getResult();
$genders = $rp->createQueryBuilder('e')
->select('COUNT(e.gender) AS genderCount, e.gender')
->where('e.network = :network')
->andWhere('e.gender != :null')
->andWhere('e.creation <= :end')
->andWhere('e.creation >= :start')
->andWhere('e.codename != :descente')
->setParameters($parameters)
->groupBy('e.gender')
->getQuery()
->getResult();
$actions = $rp->createQueryBuilder('e')
->select('COUNT(e.action) AS actionCount, e.action')
->where('e.network = :network')
->andWhere('e.action != :null')
->andWhere('e.creation <= :end')
->andWhere('e.creation >= :start')
->andWhere('e.codename != :descente')
->setParameters($parameters)
->groupBy('e.action')
->getQuery()
->getResult();
$durations = $rp->createQueryBuilder('e')
->select('COUNT(e.duration) AS durationCount, e.duration')
->where('e.network = :network')
->andWhere('e.duration != :null')
->andWhere('e.creation <= :end')
->andWhere('e.creation >= :start')
->andWhere('e.codename != :descente')
->setParameters($parameters)
->groupBy('e.duration')
->getQuery()
->getResult();
$moods = $rp->createQueryBuilder('e')
->select('COUNT(e.mood) AS moodCount, e.mood')
->where('e.network = :network')
->andWhere('e.mood != :null')
->andWhere('e.creation <= :end')
->andWhere('e.creation >= :start')
->andWhere('e.codename != :descente')
->setParameters($parameters)
->groupBy('e.mood')
->getQuery()
->getResult();
$categories = $rp->createQueryBuilder('e')
->select('COUNT(e.category) AS categoryCount, e.category')
->where('e.network = :network')
->andWhere('e.category != :null')
->andWhere('e.creation <= :end')
->andWhere('e.creation >= :start')
->andWhere('e.codename != :descente')
->setParameters($parameters)
->groupBy('e.category')
->getQuery()
->getResult();
$tResults = $rp->createQueryBuilder('e')
->where('e.network = :network')
->andWhere('e.creation <= :end')
->andWhere('e.creation >= :start')
->setParameters([
'network' => $network,
'start' => $start,
'end' => $end,
])
->orderBy('e.line', 'ASC')
->addOrderBy('e.creation', 'ASC')
->getQuery()
->getResult();
$travels = [];
$lastDate = 0;
foreach ($tResults as $r) {
if (isset($travels[$r->getLine()])) {
if ($r->getCreation()->getTimestamp() - $lastDate > 900) {
$travels[$r->getLine()]++;
$lastDate = $r->getCreation()->getTimestamp();
}
} else {
$travels[$r->getLine()] = 1;
$lastDate = $r->getCreation()->getTimestamp();
}
}
return [
'codes' => $codes,
'ages' => $ages,
'genders' => $genders,
'actions' => $actions,
'durations' => $durations,
'moods' => $moods,
'categories' => $categories,
'travels' => $travels
];
}
/**
* @Route("/export/{network}/{start}/{end}", name="export")
*/
public function exportAction($network, $start, $end)
{
$q = $this->getDoctrine()
->getRepository(Event::class)
->createQueryBuilder('e')
->where('e.codename != :null')
->andWhere('e.creation <= :end')
->andWhere('e.creation >= :start')
->setParameters(['null' => null, 'end' => $end, 'start' => $start]);
if ($network) {
$q = $q->andWhere('e.network = :network')
->setParameter('network', $network);
}
$events = $q->getQuery()
->getResult();
$datas = array();
foreach ($events as $e) {
$datas[] = [
'id' => $e->getId(),
'user' => ($e->getUser() ?: '-'),
'network' => ($e->getNetwork() ?: '-'),
'line' => ($e->getLine() ?: '-'),
'stop' => ($e->getStop() ?: '-'),
'code' => ($e->getCode() ?: '-'),
'codename' => ($e->getCodename() ?: '-'),
'vehicule' => ($e->getVehicule() ?: '-'),
'age' => ($e->getAge() ?: '-'),
'gender' => ($e->getGender() ?: '-'),
'mood' => ($e->getMood() ?: '-'),
'duration' => ($e->getDuration() ?: '-'),
'comment' => ($e->getComment() ?: '-'),
'action' => ($e->getAction() ?: '-'),
'creation' => ($e->getCreation()->format('d/m/Y h:i:s') ?: '-'),
'altercation' => ($e->getAltercation() ?: '-'),
'category' => (($e->getCategory() ? implode(', ', $e->getCategory()) : '-'))
];
}
$encoders = array(new CsvEncoder());
$normalizers = array(new ObjectNormalizer());
$serializer = new Serializer($normalizers, $encoders);
$content = $serializer->serialize($datas, 'csv');
$this->showExportAction($content);
}
/**
* @Route("/export_ccas/{ids}", name="export_ccas")
*/
public function exportCCASAction($ids)
{
$ids = explode(', ', $ids);
$q = $this->getDoctrine()
->getRepository('App:SurveyCCAS')
->createQueryBuilder('s')
->where('s.id IN (:ids)')
->setParameter('ids', array_values($ids))
->getQuery()
->getResult();
$header = [];
foreach ($q as $result) {
foreach ($result->getAnswers() as $answer) {
foreach ($answer as $question) {
if (!in_array($question['e'], $header)) {
$header[] = $question['e'];
}
}
}
}
foreach ($header as $questionHeader) {
$headerFormat[$questionHeader] = "";
}
$datas = [];
foreach ($q as $i => $result) {
$tmp = [
'Médiateur' => ((string)$result->getUser() ?: '-'),
'Foyer' => ((string)$result->getHouse() ?: '-'),
'Date' => ($result->getDate()->format('d/m/Y h:i:s') ?: '-'),
'Nombre de visite' => ($result->getNumber() ?: '-')
];
$datas[$i] = $headerFormat;
foreach ($result->getAnswers() as $answer) {
foreach ($answer as $question) {
if (is_array($question['a'])) {
$datas[$i][$question['e']] = join('; ', $question['a']) . '.';
} else {
$datas[$i][$question['e']] = $question['a'];
}
}
}
$datas[$i] = array_merge($tmp, $datas[$i]);
}
$phpExcelObject = $this->get('phpexcel')->createPHPExcelObject();
$phpExcelObject->getProperties()
->setCreator("PIMMS")
->setLastModifiedBy("PIMMS")
->setTitle("Export données " . time());
$letters = [];
$letter = 'A';
$col = 0;
while ($letter !== 'AAA') {
$letters[] = $letter++;
}
foreach ($datas[0] as $key => $value) {
$phpExcelObject->setActiveSheetIndex(0)->setCellValue($letters[$col] . '1', $key);
$col++;
}
foreach ($datas as $r => $row) {
$col = 0;
foreach ($row as $key => $value) {
$phpExcelObject->setActiveSheetIndex(0)->setCellValue($letters[$col] . ($r + 2), $value);
$col++;
}
}
$writer = $this->get('phpexcel')->createWriter($phpExcelObject, 'Excel5');
$response = $this->get('phpexcel')->createStreamedResponse($writer);
$dispositionHeader = $response->headers->makeDisposition(
ResponseHeaderBag::DISPOSITION_ATTACHMENT,
time() . '.xls'
);
$response->headers->set('Content-Type', 'text/vnd.ms-excel; charset=utf-8');
$response->headers->set('Pragma', 'public');
$response->headers->set('Cache-Control', 'maxage=1');
$response->headers->set('Content-Disposition', $dispositionHeader);
return $response;
}
/**
* @Route("/export_result/{id}", name="export_result")
*/
public function exportResultAction($id)
{
$survey = $this->getDoctrine()->getRepository(Survey::class)->find($id);
$questionList = $survey->getQuestions()->getValues();
foreach ($questionList as $question) {
$exportSample[$question->getExportName()] = '';
}
$results = $survey->getResults();
$datas = array();
foreach ($results as $result) {
$tmp = [
'Médiateur' => ((string)$result->getUser() ?: '-'),
'Date' => ($result->getDate()->format('Y-m-d H:i:s') ?: '-'),
'Nombre de visite' => ($result->getVisits() ?: '-'),
'Statut' => (Result::STATUS[$result->getStatus()] ?: '-'),
];
foreach ($result->getAnswers() as $answer) {
if (in_array($answer->getQuestion(), $questionList)) {
$exportSample[$answer->getQuestion()->getExportName()] = $answer->getValue();
}
}
foreach ($exportSample as $header => $line) {
$tmp[$header] = $line;
}
$datas[] = $tmp;
}
$today = new \DateTime('now', new \DateTimeZone('Europe/Paris'));
$fileName = $survey->getName() . ' ' . $today->format('d/m/Y h:i:s');
$encoders = array(new CsvEncoder(';'));
$normalizers = array(new ObjectNormalizer());
$serializer = new Serializer($normalizers, $encoders);
$content = $serializer->serialize($datas, 'csv');
$response = new Response($content);
$response->headers->set('Content-Type', 'text/csv');
$response->headers->set('Content-Disposition', 'attachment; filename="' . $fileName . '.csv";');
return $response;
}
public function showExportAction($content)
{
$response = new Response();
$response->setContent($content);
$response->headers->set('Content-Type', 'text/plain');
return $response;
}
}