Passed
Pull Request — master (#52)
by Stefan
03:58 queued 02:07
created

Finalizer::finalize()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2.0116

Importance

Changes 0
Metric Value
dl 0
loc 11
ccs 6
cts 7
cp 0.8571
rs 9.9
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 2.0116
1
<?php
2
3
namespace OneSheet;
4
5
use OneSheet\Style\Styler;
6
use OneSheet\Xml\DefaultXml;
7
use OneSheet\Xml\SheetXml;
8
9
class Finalizer
10
{
11
    /**
12
     * @var Sheet
13
     */
14
    private $sheet;
15
16
    /**
17
     * @var SheetFile
18
     */
19
    private $sheetFile;
20
21
    /**
22
     * @var \ZipArchive
23
     */
24
    private $zip;
25
26
    /**
27
     * @var Styler
28
     */
29
    private $styler;
30
31
    /**
32
     * @var Workbook
33
     */
34
    private $workbook;
35
36
    /**
37
     * Finalizer constructor.
38
     *
39
     * @param Workbook $workbook
40
     * @param Sheet              $sheet
41
     * @param Styler             $styler
42
     * @param SheetFile          $sheetFile
43
     */
44 4
    public function __construct(Sheet $sheet, Styler $styler, SheetFile $sheetFile, Workbook $workbook)
45
    {
46 4
        $this->sheet = $sheet;
47 4
        $this->styler = $styler;
48 4
        $this->sheetFile = $sheetFile;
49 4
        $this->workbook = $workbook;
50 4
        $this->zip = new \ZipArchive();
51 4
    }
52
53
    /**
54
     * Finalize the xlsx file.
55
     *
56
     * @param resource $output
57
     */
58 4
    public function finalize($output)
59
    {
60 4
        $zipFileUrl = sys_get_temp_dir() . '/' . uniqid();
61
62 4
        $this->fillZipWithFileContents($zipFileUrl);
63 4
        if (!$this->zip->close()) {
64
            throw new \RuntimeException('Failed to close zip file!');
65
        }
66
67 4
        $this->copyToOutputAndCleanup($output, $zipFileUrl);
68 4
    }
69
70
    /**
71
     * Add all file and string contents to zip file.
72
     *
73
     * @param string $zipFileUrl
74
     */
75 4
    private function fillZipWithFileContents($zipFileUrl)
76
    {
77 4
        $this->zip->open($zipFileUrl, \ZipArchive::CREATE);
78 4
        $this->finalizeSheet();
79 4
        $this->finalizeStyles();
80 4
        $this->finalizeWorkbook();
81 4
        $this->finalizeDefaultXmls();
82 4
    }
83
84
    /**
85
     * Wrap up the sheet (write header, column xmls).
86
     */
87 4
    private function finalizeSheet()
88
    {
89 4
        $this->sheetFile->fwrite('</sheetData></worksheet>');
90 4
        $this->sheetFile->rewind();
91 4
        $this->sheetFile->fwrite(SheetXml::HEADER_XML);
92 4
        $this->sheetFile->fwrite($this->sheet->getDimensionXml());
93 4
        $this->sheetFile->fwrite($this->sheet->getSheetViewsXml());
94 4
        $this->sheetFile->fwrite($this->sheet->getColsXml());
95 4
        $this->zip->addFile($this->sheetFile->getFilePath(), 'xl/worksheets/sheet1.xml');
96 4
    }
97
98
    /**
99
     * Write style xml file.
100
     */
101 4
    private function finalizeStyles()
102
    {
103 4
        $this->zip->addFromString('xl/styles.xml', $this->styler->getStyleSheetXml());
104 4
    }
105
106
    /**
107
     * Write workbook file.
108
     */
109 4
    private function finalizeWorkbook()
110
    {
111 4
        $this->zip->addFromString('xl/workbook.xml', $this->workbook->getWorkbookXml());
112 4
    }
113
114
    /**
115
     * Add default xmls to zip archive.
116
     */
117 4
    private function finalizeDefaultXmls()
118
    {
119 4
        $this->zip->addFromString('[Content_Types].xml', DefaultXml::CONTENT_TYPES);
120 4
        $this->zip->addFromString('docProps/core.xml',
121 4
            sprintf(DefaultXml::DOCPROPS_CORE, date(DATE_W3C), date(DATE_W3C)));
122 4
        $this->zip->addFromString('docProps/app.xml', DefaultXml::DOCPROPS_APP);
123 4
        $this->zip->addFromString('_rels/.rels', DefaultXml::RELS_RELS);
124 4
        $this->zip->addFromString('xl/_rels/workbook.xml.rels', DefaultXml::XL_RELS_WORKBOOK);
125 4
    }
126
127
    /**
128
     * Write zip/xlsx contents to specified output
129
     * and unlink/delete files.
130
     *
131
     * @param resource $output
132
     * @param string   $zipFileUrl
133
     */
134 4
    private function copyToOutputAndCleanup($output, $zipFileUrl)
135
    {
136 4
        $zipFilePointer = fopen($zipFileUrl, 'r');
137 4
        if (!stream_copy_to_stream($zipFilePointer, $output)
138 4
            || !fclose($zipFilePointer)
139 4
            || !fclose($output)
140 4
            || !unlink($zipFileUrl)
141
        ) {
142
            throw new \RuntimeException("Failed to copy stream and clean up!");
143
        }
144 4
    }
145
}
146