Failed Conditions
Push — master ( 27d83b...a2771e )
by Adrien
35:04
created

Ods::save()   C

Complexity

Conditions 8
Paths 13

Size

Total Lines 39
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 10.6925

Importance

Changes 0
Metric Value
cc 8
eloc 22
c 0
b 0
f 0
nc 13
nop 1
dl 0
loc 39
ccs 15
cts 23
cp 0.6522
crap 10.6925
rs 5.3846
1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Writer;
4
5
use PhpOffice\PhpSpreadsheet\Shared\File;
6
use PhpOffice\PhpSpreadsheet\Spreadsheet;
7
use PhpOffice\PhpSpreadsheet\Writer\Exception as WriterException;
8
use PhpOffice\PhpSpreadsheet\Writer\Ods\Content;
9
use PhpOffice\PhpSpreadsheet\Writer\Ods\Meta;
10
use PhpOffice\PhpSpreadsheet\Writer\Ods\MetaInf;
11
use PhpOffice\PhpSpreadsheet\Writer\Ods\Mimetype;
12
use PhpOffice\PhpSpreadsheet\Writer\Ods\Settings;
13
use PhpOffice\PhpSpreadsheet\Writer\Ods\Styles;
14
use PhpOffice\PhpSpreadsheet\Writer\Ods\Thumbnails;
15
use ZipArchive;
16
17
class Ods extends BaseWriter
18
{
19
    /**
20
     * Private writer parts.
21
     *
22
     * @var Ods\WriterPart[]
23
     */
24
    private $writerParts = [];
25
26
    /**
27
     * Private PhpSpreadsheet.
28
     *
29
     * @var Spreadsheet
30
     */
31
    private $spreadSheet;
32
33
    /**
34
     * Create a new Ods.
35
     *
36
     * @param Spreadsheet $spreadsheet
37
     */
38 5
    public function __construct(Spreadsheet $spreadsheet)
39
    {
40 5
        $this->setSpreadsheet($spreadsheet);
41
42
        $writerPartsArray = [
43 5
            'content' => Content::class,
44
            'meta' => Meta::class,
45
            'meta_inf' => MetaInf::class,
46
            'mimetype' => Mimetype::class,
47
            'settings' => Settings::class,
48
            'styles' => Styles::class,
49
            'thumbnails' => Thumbnails::class,
50
        ];
51
52 5
        foreach ($writerPartsArray as $writer => $class) {
53 5
            $this->writerParts[$writer] = new $class($this);
54
        }
55 5
    }
56
57
    /**
58
     * Get writer part.
59
     *
60
     * @param string $pPartName Writer part name
61
     *
62
     * @return null|Ods\WriterPart
63
     */
64 2
    public function getWriterPart($pPartName)
65
    {
66 2
        if ($pPartName != '' && isset($this->writerParts[strtolower($pPartName)])) {
67 2
            return $this->writerParts[strtolower($pPartName)];
68
        }
69
70
        return null;
71
    }
72
73
    /**
74
     * Save PhpSpreadsheet to file.
75
     *
76
     * @param string $pFilename
77
     *
78
     * @throws WriterException
79
     */
80 2
    public function save($pFilename)
81
    {
82 2
        if (!$this->spreadSheet) {
83
            throw new WriterException('PhpSpreadsheet object unassigned.');
84
        }
85
86
        // garbage collect
87 2
        $this->spreadSheet->garbageCollect();
88
89
        // If $pFilename is php://output or php://stdout, make it a temporary file...
90 2
        $originalFilename = $pFilename;
91 2
        if (strtolower($pFilename) == 'php://output' || strtolower($pFilename) == 'php://stdout') {
92
            $pFilename = @tempnam(File::sysGetTempDir(), 'phpxltmp');
93
            if ($pFilename == '') {
94
                $pFilename = $originalFilename;
95
            }
96
        }
97
98 2
        $zip = $this->createZip($pFilename);
99
100 2
        $zip->addFromString('META-INF/manifest.xml', $this->getWriterPart('meta_inf')->writeManifest());
101 2
        $zip->addFromString('Thumbnails/thumbnail.png', $this->getWriterPart('thumbnails')->writeThumbnail());
102 2
        $zip->addFromString('content.xml', $this->getWriterPart('content')->write());
103 2
        $zip->addFromString('meta.xml', $this->getWriterPart('meta')->write());
104 2
        $zip->addFromString('mimetype', $this->getWriterPart('mimetype')->write());
105 2
        $zip->addFromString('settings.xml', $this->getWriterPart('settings')->write());
106 2
        $zip->addFromString('styles.xml', $this->getWriterPart('styles')->write());
107
108
        // Close file
109 2
        if ($zip->close() === false) {
110
            throw new WriterException("Could not close zip file $pFilename.");
111
        }
112
113
        // If a temporary file was used, copy it to the correct file stream
114 2
        if ($originalFilename != $pFilename) {
115
            if (copy($pFilename, $originalFilename) === false) {
116
                throw new WriterException("Could not copy temporary zip file $pFilename to $originalFilename.");
117
            }
118
            @unlink($pFilename);
119
        }
120 2
    }
121
122
    /**
123
     * Create zip object.
124
     *
125
     * @param string $pFilename
126
     *
127
     * @throws WriterException
128
     *
129
     * @return ZipArchive
130
     */
131 2
    private function createZip($pFilename)
132
    {
133
        // Create new ZIP file and open it for writing
134 2
        $zip = new ZipArchive();
135
136 2
        if (file_exists($pFilename)) {
137 2
            unlink($pFilename);
138
        }
139
        // Try opening the ZIP file
140 2
        if ($zip->open($pFilename, ZipArchive::OVERWRITE) !== true) {
141 2
            if ($zip->open($pFilename, ZipArchive::CREATE) !== true) {
142
                throw new WriterException("Could not open $pFilename for writing.");
143
            }
144
        }
145
146 2
        return $zip;
147
    }
148
149
    /**
150
     * Get Spreadsheet object.
151
     *
152
     * @throws WriterException
153
     *
154
     * @return Spreadsheet
155
     */
156 4
    public function getSpreadsheet()
157
    {
158 4
        if ($this->spreadSheet !== null) {
159 4
            return $this->spreadSheet;
160
        }
161
162
        throw new WriterException('No PhpSpreadsheet assigned.');
163
    }
164
165
    /**
166
     * Set Spreadsheet object.
167
     *
168
     * @param Spreadsheet $spreadsheet PhpSpreadsheet object
169
     *
170
     * @return self
171
     */
172 5
    public function setSpreadsheet(Spreadsheet $spreadsheet)
173
    {
174 5
        $this->spreadSheet = $spreadsheet;
175
176 5
        return $this;
177
    }
178
}
179