PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.3.19
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.3.19
1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.4 1.5.5 1.5.3 1.5.2 1.5.1 1.5.0 1.4.2 1.4.1 1.4.0 1.3.28 1.3.27 1.3.26 1.3.25 1.3.23 1.3.22 1.3.21 1.3.20 1.3.19 trunk All 48 releases
fluent-cart / vendor / openspout / openspout / src / Writer / WriterAbstract.php

WriterAbstract.php in FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler 1.3.19, at vendor/openspout/openspout/src/Writer/WriterAbstract.php

208 lines 8.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCart\OpenSpout\Writer;
4
5 use FluentCart\OpenSpout\Common\Creator\HelperFactory;
6 use FluentCart\OpenSpout\Common\Entity\Row;
7 use FluentCart\OpenSpout\Common\Entity\Style\Style;
8 use FluentCart\OpenSpout\Common\Exception\InvalidArgumentException;
9 use FluentCart\OpenSpout\Common\Exception\IOException;
10 use FluentCart\OpenSpout\Common\Exception\SpoutException;
11 use FluentCart\OpenSpout\Common\Helper\GlobalFunctionsHelper;
12 use FluentCart\OpenSpout\Common\Manager\OptionsManagerInterface;
13 use FluentCart\OpenSpout\Writer\Common\Entity\Options;
14 use FluentCart\OpenSpout\Writer\Exception\WriterAlreadyOpenedException;
15 use FluentCart\OpenSpout\Writer\Exception\WriterNotOpenedException;
16 abstract class WriterAbstract implements WriterInterface
17 {
18 /** @var string Path to the output file */
19 protected $outputFilePath;
20 /** @var resource Pointer to the file/stream we will write to */
21 protected $filePointer;
22 /** @var bool Indicates whether the writer has been opened or not */
23 protected $isWriterOpened = \false;
24 /** @var GlobalFunctionsHelper Helper to work with global functions */
25 protected $globalFunctionsHelper;
26 /** @var HelperFactory */
27 protected $helperFactory;
28 /** @var OptionsManagerInterface Writer options manager */
29 protected $optionsManager;
30 /** @var string Content-Type value for the header - to be defined by child class */
31 protected static $headerContentType;
32 public function __construct(OptionsManagerInterface $optionsManager, GlobalFunctionsHelper $globalFunctionsHelper, HelperFactory $helperFactory)
33 {
34 $this->optionsManager = $optionsManager;
35 $this->globalFunctionsHelper = $globalFunctionsHelper;
36 $this->helperFactory = $helperFactory;
37 }
38 /**
39 * {@inheritdoc}
40 */
41 public function setDefaultRowStyle(Style $defaultStyle)
42 {
43 $this->optionsManager->setOption(Options::DEFAULT_ROW_STYLE, $defaultStyle);
44 return $this;
45 }
46 /**
47 * {@inheritdoc}
48 */
49 public function openToFile($outputFilePath)
50 {
51 $this->outputFilePath = $outputFilePath;
52 $this->filePointer = $this->globalFunctionsHelper->fopen($this->outputFilePath, 'w');
53 $this->throwIfFilePointerIsNotAvailable();
54 $this->openWriter();
55 $this->isWriterOpened = \true;
56 return $this;
57 }
58 /**
59 * @codeCoverageIgnore
60 * {@inheritdoc}
61 */
62 public function openToBrowser($outputFileName)
63 {
64 $this->outputFilePath = $this->globalFunctionsHelper->basename($outputFileName);
65 $this->filePointer = $this->globalFunctionsHelper->fopen('php://output', 'w');
66 $this->throwIfFilePointerIsNotAvailable();
67 // Clear any previous output (otherwise the generated file will be corrupted)
68 // @see https://github.com/box/spout/issues/241
69 $this->globalFunctionsHelper->ob_end_clean();
70 /*
71 * Set headers
72 *
73 * For newer browsers such as Firefox, Chrome, Opera, Safari, etc., they all support and use `filename*`
74 * specified by the new standard, even if they do not automatically decode filename; it does not matter;
75 * and for older versions of Internet Explorer, they are not recognized `filename*`, will automatically
76 * ignore it and use the old `filename` (the only minor flaw is that there must be an English suffix name).
77 * In this way, the multi-browser multi-language compatibility problem is perfectly solved, which does not
78 * require UA judgment and is more in line with the standard.
79 *
80 * @see https://github.com/box/spout/issues/745
81 * @see https://tools.ietf.org/html/rfc6266
82 * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
83 */
84 $this->globalFunctionsHelper->header('Content-Type: ' . static::$headerContentType);
85 $this->globalFunctionsHelper->header('Content-Disposition: attachment; ' . 'filename="' . \rawurlencode($this->outputFilePath) . '"; ' . 'filename*=UTF-8\'\'' . \rawurlencode($this->outputFilePath));
86 /*
87 * When forcing the download of a file over SSL,IE8 and lower browsers fail
88 * if the Cache-Control and Pragma headers are not set.
89 *
90 * @see http://support.microsoft.com/KB/323308
91 * @see https://github.com/liuggio/ExcelBundle/issues/45
92 */
93 $this->globalFunctionsHelper->header('Cache-Control: max-age=0');
94 $this->globalFunctionsHelper->header('Pragma: public');
95 $this->openWriter();
96 $this->isWriterOpened = \true;
97 return $this;
98 }
99 /**
100 * {@inheritdoc}
101 */
102 public function addRow(Row $row)
103 {
104 if ($this->isWriterOpened) {
105 try {
106 $this->addRowToWriter($row);
107 } catch (SpoutException $e) {
108 // if an exception occurs while writing data,
109 // close the writer and remove all files created so far.
110 $this->closeAndAttemptToCleanupAllFiles();
111 // re-throw the exception to alert developers of the error
112 throw $e;
113 }
114 } else {
115 throw new WriterNotOpenedException('The writer needs to be opened before adding row.');
116 }
117 return $this;
118 }
119 /**
120 * {@inheritdoc}
121 */
122 public function addRows(array $rows)
123 {
124 foreach ($rows as $row) {
125 if (!$row instanceof Row) {
126 $this->closeAndAttemptToCleanupAllFiles();
127 throw new InvalidArgumentException('The input should be an array of Row');
128 }
129 $this->addRow($row);
130 }
131 return $this;
132 }
133 /**
134 * {@inheritdoc}
135 */
136 public function close()
137 {
138 if (!$this->isWriterOpened) {
139 return;
140 }
141 $this->closeWriter();
142 if (\is_resource($this->filePointer)) {
143 $this->globalFunctionsHelper->fclose($this->filePointer);
144 }
145 $this->isWriterOpened = \false;
146 }
147 /**
148 * Opens the streamer and makes it ready to accept data.
149 *
150 * @throws IOException If the writer cannot be opened
151 */
152 protected abstract function openWriter();
153 /**
154 * Adds a row to the currently opened writer.
155 *
156 * @param Row $row The row containing cells and styles
157 *
158 * @throws WriterNotOpenedException If the workbook is not created yet
159 * @throws IOException If unable to write data
160 */
161 protected abstract function addRowToWriter(Row $row);
162 /**
163 * Closes the streamer, preventing any additional writing.
164 */
165 protected abstract function closeWriter();
166 /**
167 * Checks if the pointer to the file/stream to write to is available.
168 * Will throw an exception if not available.
169 *
170 * @throws IOException If the pointer is not available
171 */
172 protected function throwIfFilePointerIsNotAvailable()
173 {
174 if (!\is_resource($this->filePointer)) {
175 throw new IOException('File pointer has not be opened');
176 }
177 }
178 /**
179 * Checks if the writer has already been opened, since some actions must be done before it gets opened.
180 * Throws an exception if already opened.
181 *
182 * @param string $message Error message
183 *
184 * @throws WriterAlreadyOpenedException if the writer was already opened and must not be
185 */
186 protected function throwIfWriterAlreadyOpened($message)
187 {
188 if ($this->isWriterOpened) {
189 throw new WriterAlreadyOpenedException($message);
190 }
191 }
192 /**
193 * Closes the writer and attempts to cleanup all files that were
194 * created during the writing process (temp files & final file).
195 */
196 private function closeAndAttemptToCleanupAllFiles()
197 {
198 // close the writer, which should remove all temp files
199 $this->close();
200 // remove output file if it was created
201 if ($this->globalFunctionsHelper->file_exists($this->outputFilePath)) {
202 $outputFolderPath = \dirname($this->outputFilePath);
203 $fileSystemHelper = $this->helperFactory->createFileSystemHelper($outputFolderPath);
204 $fileSystemHelper->deleteFile($this->outputFilePath);
205 }
206 }
207 }
208