Completed
Push — master ( af7b98...388b72 )
by Vitaliy
02:45
created

src/Components/CsvExport.php (3 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Nayjest\Grids\Components;
4
5
use Event;
6
use Illuminate\Http\Response;
7
use Nayjest\Grids\Components\Base\RenderableComponent;
8
use Nayjest\Grids\Components\Base\RenderableRegistry;
9
use Nayjest\Grids\DataProvider;
10
use Nayjest\Grids\DataRow;
11
use Nayjest\Grids\Grid;
12
13
/**
14
 * Class CsvExport
15
 *
16
 * The component provides control for exporting data to CSV.
17
 *
18
 * @author: Vitaliy Ofat <[email protected]>
19
 * @package Nayjest\Grids\Components
20
 */
21
class CsvExport extends RenderableComponent
22
{
23
    const NAME = 'csv_export';
24
    const INPUT_PARAM = 'csv';
25
    const CSV_DELIMITER = ';';
26
    const CSV_EXT = '.csv';
27
    const DEFAULT_ROWS_LIMIT = 5000;
28
29
    protected $template = '*.components.csv_export';
30
    protected $name = CsvExport::NAME;
31
    protected $render_section = RenderableRegistry::SECTION_END;
32
    protected $rows_limit = self::DEFAULT_ROWS_LIMIT;
33
34
    /**
35
     * @var string
36
     */
37
    protected $output;
38
39
    /**
40
     * @var string
41
     */
42
    protected $fileName;
43
44
    /**
45
     * @param Grid $grid
46
     * @return null|void
47
     */
48 View Code Duplication
    public function initialize(Grid $grid)
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
49
    {
50
        parent::initialize($grid);
51
        Event::listen(Grid::EVENT_PREPARE, function (Grid $grid) {
52
            if ($this->grid !== $grid) {
53
                return;
54
            }
55
            if ($grid->getInputProcessor()->getValue(static::INPUT_PARAM, false)) {
56
                $this->renderCsv();
57
            }
58
        });
59
    }
60
61
    /**
62
     * @param string $name
63
     * @return $this
64
     */
65
    public function setFileName($name)
66
    {
67
        $this->fileName = $name;
68
        return $this;
69
    }
70
71
    /**
72
     * @return string
73
     */
74
    public function getFileName()
75
    {
76
        return $this->fileName . static::CSV_EXT;
77
    }
78
79
    /**
80
     * @return int
81
     */
82
    public function getRowsLimit()
83
    {
84
        return $this->rows_limit;
85
    }
86
87
    /**
88
     * @param int $limit
89
     *
90
     * @return $this
91
     */
92
    public function setRowsLimit($limit)
93
    {
94
        $this->rows_limit = $limit;
95
        return $this;
96
    }
97
98
    protected function setCsvHeaders(Response $response)
99
    {
100
        $response->header('Content-Type', 'application/csv');
101
        $response->header('Content-Disposition', 'attachment; filename=' . $this->getFileName());
102
        $response->header('Pragma', 'no-cache');
103
    }
104
105
    protected function resetPagination(DataProvider $provider)
106
    {
107
        $provider->setPageSize($this->getRowsLimit());
108
        $provider->setCurrentPage(1);
109
    }
110
111
    protected function renderCsv()
112
    {
113
        $file = fopen('php://output', 'w');
114
115
        header('Content-Type: text/csv');
116
        header('Content-Disposition: attachment; filename="'. $this->getFileName() .'"');
117
        header('Pragma: no-cache');
118
119
        set_time_limit(0);
120
121
        /** @var $provider DataProvider */
122
        $provider = $this->grid->getConfig()->getDataProvider();
123
124
        $this->renderHeader($file);
125
126
        $this->resetPagination($provider);
127
        $provider->reset();
128
        /** @var DataRow $row */
129
        while ($row = $provider->getRow()) {
130
            $output = [];
131
            foreach ($this->grid->getConfig()->getColumns() as $column) {
132
                if (!$column->isHidden()) {
133
                    $output[] = $this->escapeString( $column->getValue($row) );
134
                }
135
            }
136
            fputcsv($file, $output, static::CSV_DELIMITER);
137
138
        }
139
140
        fclose($file);
141
        exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method renderCsv() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
142
    }
143
144
    /**
145
     * @param string $str
146
     * @return string
147
     */
148
    protected function escapeString($str)
149
    {
150
        return str_replace('"', '\'', strip_tags(html_entity_decode($str)));
151
    }
152
153
    /**
154
     * @param resource $file
155
     */
156
    protected function renderHeader($file)
157
    {
158
        $output = [];
159 View Code Duplication
        foreach ($this->grid->getConfig()->getColumns() as $column) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
160
            if (!$column->isHidden()) {
161
                $output[] = $this->escapeString($column->getLabel());
162
            }
163
        }
164
        fputcsv($file, $output, static::CSV_DELIMITER);
165
    }
166
}
167