CakePHP 3 plugin CsvView

W artykule przedstawię ciekawy plugin do CakePHP, a mianowicie CsvView. Służy on do łatwego generowania danych wyjściowych w postaci csv. Instalacja za pomocą composera jest bardzo prosta.

composer require friendsofcake/cakephp-csvview
Następnie ładujemy plugin w konsoli.
bin/cake plugin load CsvView
Można też dopisać po prostu linijkę w pliku Application.php w metodzie bootstrap.
$this->addPlugin('CsvView');
Sposób w jaki używamy plugina jest bardzo prosty. Spójrzmy na poniższy przykład metody w kontrolerze.
public function export()
{
    $data = [
        ['a', 'b', 'c'],
        [1, 2, 3],
        ['bla', 'bla2', 'bla3'],
    ];
    $_serialize = 'data';

    $this->viewBuilder()->setClassName('CsvView.Csv');
    $this->set(compact('data', '_serialize'));
}
Wszystkie zmienne, które mają być zawarte w pliku csv, muszą być określone w zmiennej widoku $ _serialize, dokładnie tak, jak działa JsonView lub XmlView. Jest możliwe przekazywanie kilku zmiennych tak jak w przykładzie poniżej.
public function export()
{
    $data = [['a', 'b', 'c']];
    $data2 = [[1, 2, 3]];

    $_serialize = ['data', 'data2'];

    $this->viewBuilder()->setClassName('CsvView.Csv');
    $this->set(compact('data', 'data2', '_serialize'));
}
Jeśli chcesz, aby nagłówek lub stopka były wyświetlane w danych wyjściowych CSV, możesz określić zmienną widoku $ _header lub $ _footer.
$_header = ['ID', 'Name', 'Email'];
$_footer = ['Totals', '400', '$3000'];
$this->set(compact('data', '_serialize', '_header', '_footer'));
Można także określić separator, znak końca linii, znak nowej linii, znak zmiany znaczenia i sekwencję znacznika kolejności bajtów (BOM), używając odpowiednio $ _delimiter, $ _eol, $ _newline, $ _enclosure i $ _bom:
$_serialize = 'data';
$_delimiter = chr(9); //tab
$_enclosure = '"';
$_newline = '\r\n';
$_eol = '~';
$_bom = true;

$this->viewBuilder()->setClassName('CsvView.Csv');
$this->set(compact('data', '_serialize', '_delimiter', '_enclosure', '_newline', '_eol', '_bom'));
Jeśli chcesz uzyskać bardziej skomplikowane dane z modelu, możesz użyć zmiennej widoku $ _extract do określenia poszczególnych ścieżek kompatybilnych z Hash::extract() lub za pomocą funkcji dla każdego rekordu:
public function export()
{
    $posts = $this->Posts->find();
    $_serialize = 'posts';
    $_header = ['Post ID', 'Title', 'Created'];
    $_extract = [
        'id',
        function (array $row) {
            return $row['title'];
        },
        'created'
    ];

    $this->viewBuilder()->setClassName('CsvView.Csv');
    $this->set(compact('posts', '_serialize', '_header', '_extract'));
}
Na obecnym etapie URL naszego eksportu CSV to nazwa_kontrolera/export. Fajnie byłoby dołączyć do rozszerzenia CSV. W tym celu powiemy Cakowi, aby poprawnie przeanalizował żądania pliku CSV. W naszym pliku config/routes.php dodamy:
Router::extensions(['csv']);
Poniższy kod pokazuje jak poprawnie utworzyć link do naszego pliku csv.
<?= $this->Html->link('export', [
	'controller' => 'nazwa_kontrolera', 
	'action' => 'export',
	'_ext' => 'csv'
]) ?>