Proyectos de Subversion LeadersLinked - Backend

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
5866 eleazar 1
<?php
2
 
3
declare(strict_types=1);
4
 
5
namespace LeadersLinked\Controller;
6
 
7
use Laminas\Db\Adapter\AdapterInterface;
8
use Laminas\Cache\Storage\Adapter\AbstractAdapter;
9
use Laminas\Mvc\Controller\AbstractActionController;
10
use Laminas\Log\LoggerInterface;
11
use Laminas\View\Model\ViewModel;
12
use Laminas\View\Model\JsonModel;
13
use LeadersLinked\Mapper\QueryMapper;
14
use Laminas\Db\Sql\Select;
15
use LeadersLinked\Library\Functions;
16
use LeadersLinked\Mapper\SurveyTestMapper;
17
use LeadersLinked\Mapper\SurveyMapper;
18
use LeadersLinked\Mapper\SurveyFormMapper;
19
use LeadersLinked\Form\SurveyTestForm;
20
use LeadersLinked\Model\SurveyTest;
21
use LeadersLinked\Mapper\UserMapper;
22
use LeadersLinked\Hydrator\ObjectPropertyHydrator;
23
use LeadersLinked\Library\SurveyReport;
24
 
25
class SurveyReportController extends AbstractActionController {
26
 
27
    /**
28
     *
29
     * @var AdapterInterface
30
     */
31
    private $adapter;
32
 
33
    /**
34
     *
35
     * @var AbstractAdapter
36
     */
37
    private $cache;
38
 
39
    /**
40
     *
41
     * @var  LoggerInterface
42
     */
43
    private $logger;
44
 
45
    /**
46
     *
47
     * @var array
48
     */
49
    private $config;
50
 
51
    /**
52
     *
53
     * @param AdapterInterface $adapter
54
     * @param AbstractAdapter $cache
55
     * @param LoggerInterface $logger
56
     * @param array $config
57
     */
58
    public function __construct($adapter, $cache, $logger, $config) {
59
        $this->adapter = $adapter;
60
        $this->cache = $cache;
61
        $this->logger = $logger;
62
        $this->config = $config;
63
    }
64
 
65
    public function indexAction() {
5911 eleazar 66
 
5866 eleazar 67
        $request = $this->getRequest();
68
        $currentUserPlugin = $this->plugin('currentUserPlugin');
69
        $currentCompany = $currentUserPlugin->getCompany();
70
        $currentUser = $currentUserPlugin->getUser();
71
 
6424 eleazar 72
        try{
5866 eleazar 73
        $request = $this->getRequest();
74
        if ($request->isGet()) {
75
 
76
            $headers = $request->getHeaders();
77
 
78
            $isJson = false;
79
            if ($headers->has('Accept')) {
80
                $accept = $headers->get('Accept');
81
 
82
                $prioritized = $accept->getPrioritized();
83
 
84
                foreach ($prioritized as $key => $value) {
85
                    $raw = trim($value->getRaw());
86
 
87
                    if (!$isJson) {
88
                        $isJson = strpos($raw, 'json');
89
                    }
90
                }
91
            }
92
 
93
            if ($isJson) {
5911 eleazar 94
 
5866 eleazar 95
                $search = $this->params()->fromQuery('search', []);
96
                $search = empty($search['value']) ? '' : filter_var($search['value'], FILTER_SANITIZE_STRING);
97
 
98
                $page = intval($this->params()->fromQuery('start', 1), 10);
99
                $records_x_page = intval($this->params()->fromQuery('length', 10), 10);
100
                $order = $this->params()->fromQuery('order', []);
101
                $order_field = empty($order[0]['column']) ? 99 : intval($order[0]['column'], 10);
102
                $order_direction = empty($order[0]['dir']) ? 'ASC' : strtoupper(filter_var($order[0]['dir'], FILTER_SANITIZE_STRING));
103
 
6411 eleazar 104
                $fields = ['name'];
6416 eleazar 105
                $order_field = isset($fields[$order_field]) ? $fields[$order_field] : 'name';
5866 eleazar 106
 
107
                if (!in_array($order_direction, ['ASC', 'DESC'])) {
108
                    $order_direction = 'ASC';
109
                }
110
 
6411 eleazar 111
                $surveyMapper = SurveyMapper::getInstance($this->adapter);
6412 eleazar 112
                $paginator = $surveyMapper->fetchAllDataTableByCompanyId($currentCompany->id, $search, $page, $records_x_page, $order_field, $order_direction);
6423 eleazar 113
 
114
                $surveyFormMapper = SurveyFormMapper::getInstance($this->adapter);
115
 
5866 eleazar 116
                $items = [];
117
                $records = $paginator->getCurrentItems();
6866 eleazar 118
 
5866 eleazar 119
                foreach ($records as $record) {
6423 eleazar 120
                    $surveyForm = $surveyFormMapper->fetchOne($record->form_id);
6451 eleazar 121
                    $params = [
122
 
123
                        'id' => $record->uuid,
124
                    ];
5866 eleazar 125
                    $item = [
126
                        'id' => $record->id,
6426 eleazar 127
                        'name' => $record->name,
6211 eleazar 128
                        'form' => $surveyForm->name,
6427 eleazar 129
                        'status' => $record->status,
5866 eleazar 130
                        'actions' => [
6496 eleazar 131
                            'link_report_all' => $this->url()->fromRoute('survey/report/all', ['survey_id' => $record->uuid]),
7021 eleazar 132
                            'link_report_csv' => $this->url()->fromRoute('survey/report/csv', ['survey_id' => $record->uuid]),
6496 eleazar 133
                            'link_overview' => $this->url()->fromRoute('survey/report/overview', ['survey_id' => $record->uuid])
5866 eleazar 134
                        ]
135
                    ];
136
 
137
                    array_push($items, $item);
138
                }
139
 
140
                return new JsonModel([
141
                    'success' => true,
142
                    'data' => [
143
                        'items' => $items,
144
                        'total' => $paginator->getTotalItemCount(),
145
                    ]
146
                ]);
5911 eleazar 147
            } else {
148
                $surveyMapper = SurveyMapper::getInstance($this->adapter);
149
                $survies = $surveyMapper->fetchAllByCompanyId($currentCompany->id);
150
 
5866 eleazar 151
                $form = new SurveyTestForm($this->adapter, $currentCompany->id);
152
 
153
                $this->layout()->setTemplate('layout/layout-backend');
154
                $viewModel = new ViewModel();
5933 eleazar 155
                $viewModel->setTemplate('leaders-linked/survey-report/index.phtml');
5866 eleazar 156
                $viewModel->setVariables([
5911 eleazar 157
                    'form'      => $form,
158
                    'survies' => $survies
5866 eleazar 159
                ]);
160
                return $viewModel;
161
            }
162
        } else {
163
            return new JsonModel([
164
                'success' => false,
165
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
166
            ]);
167
 
6424 eleazar 168
        }
169
        } catch (\Throwable $e) {
170
            $e->getMessage();
171
            return new JsonModel([
172
                'success' => false,
173
                'data' => $e
174
            ]);
5866 eleazar 175
        }
6212 eleazar 176
 
5866 eleazar 177
    }
5911 eleazar 178
 
6496 eleazar 179
    public function overviewAction(){
180
        $request = $this->getRequest();
181
        $currentUserPlugin = $this->plugin('currentUserPlugin');
182
        $currentCompany = $currentUserPlugin->getCompany();
183
        $currentUser = $currentUserPlugin->getUser();
184
 
185
        $request = $this->getRequest();
186
        $uuid = $this->params()->fromRoute('survey_id');
187
 
188
        if (!$uuid) {
189
            $data = [
190
                'success' => false,
191
                'data' => 'ERROR_INVALID_PARAMETER'
192
            ];
193
 
194
            return new JsonModel($data);
195
        }
196
 
197
        $surveyMapper = SurveyMapper::getInstance($this->adapter);
198
        $survey = $surveyMapper->fetchOneByUuid($uuid);
199
 
200
        $surveyMapper = SurveyMapper::getInstance($this->adapter);
201
        $survey = $surveyMapper->fetchOneByUuid($uuid);
202
 
203
        $surveyTestMapper = SurveyTestMapper::getInstance($this->adapter);
204
        $surveyTests = $surveyTestMapper->fetchAllBySurveyId($survey->id);
205
 
206
        $surveyFormMapper = SurveyFormMapper::getInstance($this->adapter);
207
        $surveyForm = $surveyFormMapper->fetchOne($survey->form_id);
208
 
209
        $sections = json_decode($surveyForm->content, true);
210
 
211
        $allTests = array_map(
212
            function($response) {
213
                return json_decode($response->content, true);
214
            },
215
            $surveyTests,
216
        );
217
 
218
        $averages = [];
219
 
220
        foreach($sections as $section) {
221
            foreach($section['questions'] as $question) {
222
                switch ($question['type']) {
223
                    case 'multiple':
224
                        $totals = [];
225
 
226
                        foreach($question['options'] as $option) {
227
                            $totals[$option['slug_option']] = 0;
228
                        }
229
 
230
                        foreach($question['options'] as $option) {
231
                            $totals[$option['slug_option']] = count(array_filter(
232
                                $allTests,
233
                                function ($test) use($option, $question) {
234
                                    return in_array($option['slug_option'], $test[$question['slug_question']]);
235
                                }
236
                            ));
237
                        }
238
 
239
                        $averages[$question['slug_question']] = $totals;
240
 
241
                        break;
242
 
243
                    case 'simple':
244
                        $totals = [];
245
 
246
                        foreach($question['options'] as $option) {
247
                            $totals[$option['slug_option']] = 0;
248
                        }
249
 
250
                        foreach ($allTests as $test) {
251
                            $totals[$test[$question['slug_question']]]++;
252
                        }
253
 
254
                        foreach($totals as $slug => $amount) {
255
                            $totals[$slug] = ($amount / count($allTests)) * 100;
256
                        }
257
 
258
                        $averages[$question['slug_question']] = $totals;
259
                    break;
260
 
261
                }
262
            }
263
        }
264
 
265
        $this->layout()->setTemplate('layout/layout-backend.phtml');
266
        $viewModel = new ViewModel();
267
        $viewModel->setTemplate('leaders-linked/survey-report/overview.phtml');
268
        $viewModel->setVariables([
6506 eleazar 269
            'sections' => $sections,
6524 eleazar 270
            'averages' => $averages,
6496 eleazar 271
        ]);
272
        return $viewModel ;
273
 
274
    }
275
 
6447 eleazar 276
    public function allAction() {
5930 eleazar 277
        $request = $this->getRequest();
278
        $currentUserPlugin = $this->plugin('currentUserPlugin');
279
        $currentCompany = $currentUserPlugin->getCompany();
280
        $currentUser = $currentUserPlugin->getUser();
281
 
282
        $request = $this->getRequest();
6043 eleazar 283
        $uuid = $this->params()->fromRoute('survey_id');
5961 eleazar 284
 
5930 eleazar 285
 
286
 
287
        if (!$uuid) {
288
            $data = [
289
                'success' => false,
290
                'data' => 'ERROR_INVALID_PARAMETER'
291
            ];
292
 
293
            return new JsonModel($data);
294
        }
295
 
6039 eleazar 296
        $surveyMapper = SurveyMapper::getInstance($this->adapter);
297
        $survey = $surveyMapper->fetchOneByUuid($uuid);
6044 eleazar 298
 
5965 eleazar 299
        $surveyTestMapper = SurveyTestMapper::getInstance($this->adapter);
6052 eleazar 300
        $surveyTests = $surveyTestMapper->fetchAllBySurveyId($survey->id);
5966 eleazar 301
 
6052 eleazar 302
        if (!$surveyTests) {
5930 eleazar 303
            $data = [
304
                'success' => false,
5961 eleazar 305
                'data' => 'ERROR_RECORD_NOT_FOUND'
5930 eleazar 306
            ];
307
 
308
            return new JsonModel($data);
309
        }
310
 
5965 eleazar 311
 
5930 eleazar 312
        if ($request->isGet()) {
313
            $hydrator = new ObjectPropertyHydrator();
314
 
315
            //get form data
316
            $surveyFormMapper = SurveyFormMapper::getInstance($this->adapter);
5965 eleazar 317
            $surveyForm = $surveyFormMapper->fetchOne($survey->form_id);
5930 eleazar 318
 
319
            if ($surveyForm) {
320
 
6052 eleazar 321
                return $this->renderPDF($surveyForm, $surveyTests, $survey);
5930 eleazar 322
            } else {
323
 
324
                $data = [
325
                    'success' => false,
326
                    'data' => 'ERROR_METHOD_NOT_ALLOWED'
327
                ];
328
 
329
                return new JsonModel($data);
330
            }
331
        } else {
332
            $data = [
333
                'success' => false,
334
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
335
            ];
336
 
337
            return new JsonModel($data);
338
        }
339
 
340
        return new JsonModel($data);
341
    }
342
 
343
 
6052 eleazar 344
    public function renderPDF($surveyForm, $surveyTests, $survey) {
5930 eleazar 345
 
6052 eleazar 346
        $target_path = $this->config['leaderslinked.fullpath.company'] . DIRECTORY_SEPARATOR . $survey->uuid;
5930 eleazar 347
 
348
 
349
        if(file_exists($target_path)) {
350
            Functions::deleteFiles($target_path);
351
        } else {
352
            @mkdir($target_path, 0755, true);
353
        }
354
 
355
        // Set Data
356
        $headerFormName = utf8_decode($surveyForm->name);
6071 eleazar 357
        $headerSurveyName = utf8_decode('Informe de Encuesta: ' . trim($survey->name) . ' al ' . date("m-d-Y H:i:s", strtotime($survey->added_on)));
6052 eleazar 358
        $sections = json_decode($surveyForm->content, true);
359
 
6053 eleazar 360
        $allTests = array_map(
6052 eleazar 361
            function($response) {
362
                return json_decode($response->content, true);
363
            },
364
            $surveyTests,
365
        );
366
 
367
        $averages = [];
368
 
369
        foreach($sections as $section) {
370
            foreach($section['questions'] as $question) {
371
                switch ($question['type']) {
6054 eleazar 372
                    case 'multiple':
6056 eleazar 373
                        $totals = [];
374
 
375
                        foreach($question['options'] as $option) {
376
                            $totals[$option['slug_option']] = 0;
377
                        }
378
 
379
                        foreach($question['options'] as $option) {
6057 eleazar 380
                            $totals[$option['slug_option']] = count(array_filter(
6056 eleazar 381
                                $allTests,
6452 eleazar 382
                                function ($test) use($option, $question) {
6450 eleazar 383
                                    return in_array($option['slug_option'], $test[$question['slug_question']]);
6056 eleazar 384
                                }
385
                            ));
386
                        }
6084 eleazar 387
 
6056 eleazar 388
                        $averages[$question['slug_question']] = $totals;
389
 
390
                        break;
6449 eleazar 391
 
6052 eleazar 392
                    case 'simple':
6053 eleazar 393
                        $totals = [];
6052 eleazar 394
 
395
                        foreach($question['options'] as $option) {
6053 eleazar 396
                            $totals[$option['slug_option']] = 0;
6052 eleazar 397
                        }
398
 
6053 eleazar 399
                        foreach ($allTests as $test) {
400
                            $totals[$test[$question['slug_question']]]++;
6052 eleazar 401
                        }
402
 
6053 eleazar 403
                        foreach($totals as $slug => $amount) {
404
                            $totals[$slug] = ($amount / count($allTests)) * 100;
6052 eleazar 405
                        }
406
 
6084 eleazar 407
                        $averages[$question['slug_question']] = $totals;
6052 eleazar 408
                    break;
6071 eleazar 409
 
6052 eleazar 410
                }
411
            }
412
        }
413
 
5930 eleazar 414
        //Generate New PDF
5971 eleazar 415
        $pdf = new SurveyReport();
5930 eleazar 416
 
417
        $pdf->AliasNbPages();
418
        $pdf->AddPage();
419
 
420
        // Set header secundary
6071 eleazar 421
        $pdf->customHeader($headerFormName, $headerSurveyName);
5930 eleazar 422
 
6609 eleazar 423
        $countSection = 0;
424
 
6615 eleazar 425
        for ($i = 0; $i < count($sections); $i++) {
426
            if ($countSection > 1) {
427
                $countSection = 0;
428
                $pdf->AddPage();
429
                $pdf->customHeader($headerFormName, $headerUserName);
430
            }
431
            $section = $sections[$i];
6084 eleazar 432
 
433
            foreach ($section['questions'] as $question) {
6615 eleazar 434
 
6614 eleazar 435
                    switch ($question['type']) {
436
                        case 'simple':
437
                            $labels = [];
438
                            $values = [];
6039 eleazar 439
 
6614 eleazar 440
                            foreach($question['options'] as $option) {
441
                                $labels []= strip_tags($option['text']) . "\n(%.1f%%)";
6133 eleazar 442
 
6614 eleazar 443
                                $values []= $averages[$question['slug_question']][$option['slug_option']];
444
                            }
445
 
446
                            $filename = $target_path . DIRECTORY_SEPARATOR .  $question['slug_question'] . '.png';
6635 eleazar 447
                            $pdf->Cell(0,10,strip_tags(trim(str_replace(' ', ' ', html_entity_decode($question['text'])))),0,1);
6914 eleazar 448
                            $pdf->pieChart($labels, $values, '', $filename);
6614 eleazar 449
                            $pdf->SetFont('Arial', '', 12);
450
                            $pdf->Image($filename, 45, $pdf->getY(), 120);
451
                            $pdf->setY($pdf->getY() + 90);
6912 eleazar 452
 
6614 eleazar 453
 
454
                            break;
455
 
456
                        case 'multiple':
457
                            $labels = [];
458
                            $values = [];
459
 
460
                            foreach($question['options'] as $option) {
461
                                $labels []= strip_tags($option['text']);
462
 
463
                                $values []= $averages[$question['slug_question']][$option['slug_option']];
464
                            }
465
 
466
                            $filename = $target_path . DIRECTORY_SEPARATOR .  $question['slug_question'] . '.png';
467
                            $pdf->Cell(0,10,strip_tags($question['text']),0,1);
468
                            $pdf->barChart($labels, $values, '', $filename);
469
                            $pdf->SetFont('Arial', '', 12);
470
                            $pdf->Image($filename, 12, $pdf->getY());
471
                            $pdf->setY($pdf->getY() + (count($values) * 13) + 10);
472
 
473
                            break;
474
                    }
6615 eleazar 475
                $countSection++;
6084 eleazar 476
            }
6608 eleazar 477
 
6615 eleazar 478
 
5930 eleazar 479
        }
480
 
7021 eleazar 481
        return $pdf->Output();
482
    }
483
 
484
    public function csvAction() {
485
        $request = $this->getRequest();
486
        $currentUserPlugin = $this->plugin('currentUserPlugin');
487
        $currentCompany = $currentUserPlugin->getCompany();
488
        $currentUser = $currentUserPlugin->getUser();
489
 
490
        $request = $this->getRequest();
491
        $uuid = $this->params()->fromRoute('survey_id');
492
 
493
 
494
 
495
        if (!$uuid) {
496
            $data = [
497
                'success' => false,
498
                'data' => 'ERROR_INVALID_PARAMETER'
499
            ];
500
 
501
            return new JsonModel($data);
502
        }
503
 
504
        $surveyMapper = SurveyMapper::getInstance($this->adapter);
505
        $survey = $surveyMapper->fetchOneByUuid($uuid);
506
 
507
        $surveyTestMapper = SurveyTestMapper::getInstance($this->adapter);
508
        $surveyTests = $surveyTestMapper->fetchAllBySurveyId($survey->id);
509
 
510
        if (!$surveyTests) {
511
            $data = [
512
                'success' => false,
513
                'data' => 'ERROR_RECORD_NOT_FOUND'
514
            ];
515
 
516
            return new JsonModel($data);
517
        }
518
 
519
 
520
        if ($request->isGet()) {
521
            $hydrator = new ObjectPropertyHydrator();
522
 
523
            //get form data
524
            $surveyFormMapper = SurveyFormMapper::getInstance($this->adapter);
525
            $surveyForm = $surveyFormMapper->fetchOne($survey->form_id);
526
 
527
            if ($surveyForm) {
528
 
529
                return $this->csvRender($surveyForm, $surveyTests, $survey);
530
            } else {
531
 
532
                $data = [
533
                    'success' => false,
534
                    'data' => 'ERROR_METHOD_NOT_ALLOWED'
535
                ];
536
 
537
                return new JsonModel($data);
538
            }
539
        } else {
540
            $data = [
541
                'success' => false,
542
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
543
            ];
544
 
545
            return new JsonModel($data);
546
        }
547
 
548
        return new JsonModel($data);
549
    }
550
 
551
 
552
    public function csvRender($surveyForm, $surveyTests, $survey)
553
    {
7020 eleazar 554
        $tmpName = tempnam(sys_get_temp_dir(), 'data');
555
        $tmp = fopen($tmpName, 'w');
7026 eleazar 556
        $sections = json_decode($surveyForm->content, true);
7020 eleazar 557
 
7025 eleazar 558
        $allTests = array_map(
559
            function($response) {
560
                return json_decode($response->content, true);
561
            },
562
            $surveyTests,
563
        );
564
 
565
        $averages = [];
566
 
567
        foreach($sections as $section) {
568
            foreach($section['questions'] as $question) {
569
                switch ($question['type']) {
570
                    case 'multiple':
571
                        $totals = [];
572
 
573
                        foreach($question['options'] as $option) {
574
                            $totals[$option['slug_option']] = 0;
575
                        }
576
 
577
                        foreach($question['options'] as $option) {
578
                            $totals[$option['slug_option']] = count(array_filter(
579
                                $allTests,
580
                                function ($test) use($option, $question) {
581
                                    return in_array($option['slug_option'], $test[$question['slug_question']]);
582
                                }
583
                            ));
584
                        }
585
 
586
                        $averages[$question['slug_question']] = $totals;
587
 
588
                        break;
589
 
590
                    case 'simple':
591
                        $totals = [];
592
 
593
                        foreach($question['options'] as $option) {
594
                            $totals[$option['slug_option']] = 0;
595
                        }
596
 
597
                        foreach ($allTests as $test) {
598
                            $totals[$test[$question['slug_question']]]++;
599
                        }
600
 
601
                        foreach($totals as $slug => $amount) {
602
                            $totals[$slug] = ($amount / count($allTests)) * 100;
603
                        }
604
 
605
                        $averages[$question['slug_question']] = $totals;
606
                    break;
607
 
608
                }
609
            }
610
        }
611
 
612
        for ($i = 0; $i < count($sections); $i++) {
613
            $section = $sections[$i];
614
 
615
            foreach ($section['questions'] as $question) {
7028 eleazar 616
                switch ($question['type']) {
7032 eleazar 617
                    case 'simple':
618
                        fputcsv($tmp, [strip_tags($question['text']), '']);
619
                        foreach($question['options'] as $option) {
620
                            fputcsv($tmp, [strip_tags($option['text']), round($averages[$question['slug_question']][$option['slug_option']], 2) . '%']);
621
                        }
7025 eleazar 622
 
7032 eleazar 623
                        break;
7025 eleazar 624
 
7032 eleazar 625
                    case 'multiple':
626
                        fputcsv($tmp, [strip_tags($question['text']), '']);
627
                        foreach($question['options'] as $option) {
628
                            fputcsv($tmp, [strip_tags($option['text']), $averages[$question['slug_question']][$option['slug_option']]]);
629
                        }
7025 eleazar 630
 
7032 eleazar 631
                        break;
632
                }
7025 eleazar 633
            }
634
 
635
 
636
        }
637
 
638
 
7020 eleazar 639
        fclose($tmp);
640
 
641
        header('Content-Description: File Transfer');
642
        header('Content-Type: text/csv');
643
        header('Content-Disposition: attachment; filename=report.csv');
644
        header('Content-Transfer-Encoding: binary');
645
        header('Expires: 0');
646
        header('Cache-Control: must-revalidate');
647
        header('Pragma: public');
648
        header('Content-Length: ' . filesize($tmpName));
649
 
650
        ob_clean();
651
        flush();
652
 
653
        readfile($tmpName);
654
        unlink($tmpName);
655
        return;
5930 eleazar 656
    }
5866 eleazar 657
}