• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

contributte / datagrid / 13794085766

11 Mar 2025 05:12PM UTC coverage: 33.801% (-0.2%) from 34.009%
13794085766

push

github

f3l1x
Refactor: drop contributte/application (copy CsvResponse to datagrid)

9 of 45 new or added lines in 2 files covered. (20.0%)

1132 of 3349 relevant lines covered (33.8%)

0.34 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

18.18
/src/Response/CsvResponse.php
1
<?php declare(strict_types = 1);
2

3
namespace Contributte\Datagrid\Response;
4

5
use Nette\Application\Response;
6
use Nette\Http\IRequest as HttpRequest;
7
use Nette\Http\IResponse as HttpResponse;
8
use Nette\InvalidStateException;
9
use Tracy\Debugger;
10

11
/**
12
 * CSV file download response
13
 */
14
class CsvResponse implements Response
15
{
16

17
        protected string $contentType = 'application/octet-stream';
18

19
        protected string $delimiter;
20

21
        /** @var array<int|string, array<scalar>> */
22
        protected array $data;
23

24
        protected string $outputEncoding;
25

26
        protected bool $includeBom;
27

28
        protected string $name;
29

30
        /** @var string[] */
31
        protected array $headers = [
32
                'Expires' => '0',
33
                'Cache-Control' => 'no-cache',
34
                'Pragma' => 'Public',
35
        ];
36

37
        /**
38
         * @param array<int|string, array<scalar>> $data Input data
39
         */
40
        public function __construct(
1✔
41
                array $data,
42
                string $name = 'export.csv',
43
                string $outputEncoding = 'utf-8',
44
                string $delimiter = ';',
45
                bool $includeBom = false
46
        )
47
        {
48
                if (strpos($name, '.csv') === false) {
1✔
NEW
49
                        $name = sprintf('%s.csv', $name);
×
50
                }
51

52
                $this->name = $name;
1✔
53
                $this->delimiter = $delimiter;
1✔
54
                $this->data = $data;
1✔
55
                $this->outputEncoding = $outputEncoding;
1✔
56
                $this->includeBom = $includeBom;
1✔
57
        }
1✔
58

59
        public function send(HttpRequest $httpRequest, HttpResponse $httpResponse): void
60
        {
61
                // Disable tracy bar
NEW
62
                if (class_exists(Debugger::class)) {
×
NEW
63
                        Debugger::$productionMode = true;
×
64
                }
65

66
                // Set Content-Type header
NEW
67
                $httpResponse->setContentType($this->contentType, $this->outputEncoding);
×
68

69
                // Set Content-Disposition header
NEW
70
                $httpResponse->setHeader('Content-Disposition', sprintf('attachment; filename="%s"', $this->name));
×
71

72
                // Set other headers
NEW
73
                foreach ($this->headers as $key => $value) {
×
NEW
74
                        $httpResponse->setHeader($key, $value);
×
75
                }
76

NEW
77
                if (function_exists('ob_start')) {
×
NEW
78
                        ob_start();
×
79
                }
80

81
                // Output data
NEW
82
                if ($this->includeBom) {
×
NEW
83
                        echo $this->getBom();
×
84
                }
85

NEW
86
                foreach ($this->data as $row) {
×
NEW
87
                        $csvRow = $this->printCsv((array) $row); // @phpstan-ignore-line
×
88

NEW
89
                        if (strtolower($this->outputEncoding) === 'utf-8') {
×
NEW
90
                                echo $csvRow;
×
NEW
91
                        } elseif (strtolower($this->outputEncoding) === 'windows-1250') {
×
NEW
92
                                echo iconv('utf-8', $this->outputEncoding, $csvRow);
×
93
                        } else {
NEW
94
                                echo mb_convert_encoding($csvRow, $this->outputEncoding);
×
95
                        }
96
                }
97

NEW
98
                if (function_exists('ob_end_flush')) {
×
NEW
99
                        ob_end_flush();
×
100
                }
101
        }
102

103
        private function getBom(): string
104
        {
NEW
105
                switch (strtolower($this->outputEncoding)) {
×
NEW
106
                        case 'utf-8':
×
NEW
107
                                return b"\xEF\xBB\xBF";
×
NEW
108
                        case 'utf-16':
×
NEW
109
                                return b"\xFF\xFE";
×
110
                        default:
NEW
111
                                return '';
×
112
                }
113
        }
114

115
        /**
116
         * @param array<scalar> $row
117
         */
118
        private function printCsv(array $row): string
119
        {
NEW
120
                $out = fopen('php://memory', 'wb+');
×
121

NEW
122
                if ($out === false) {
×
NEW
123
                        throw new InvalidStateException('Unable to open memory stream');
×
124
                }
125

NEW
126
                fputcsv($out, $row, $this->delimiter, escape: '\\');
×
NEW
127
                rewind($out);
×
NEW
128
                $c = stream_get_contents($out);
×
NEW
129
                fclose($out);
×
130

NEW
131
                if ($c === false) {
×
NEW
132
                        throw new InvalidStateException('Unable to read from memory stream');
×
133
                }
134

NEW
135
                return $c;
×
136
        }
137

138
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc