Completed
Push — master ( d02a95...6a4ba0 )
by Stefan
02:31
created

Finalizer::copyToOutputAndCleanup()   B

Complexity

Conditions 5
Paths 2

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 5.0342

Importance

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