Differences Between: [Versions 402 and 403]
1 <?php 2 3 declare(strict_types=1); 4 5 namespace OpenSpout\Writer; 6 7 use OpenSpout\Common\Entity\Row; 8 use OpenSpout\Common\Exception\IOException; 9 use OpenSpout\Writer\Exception\WriterNotOpenedException; 10 11 abstract class AbstractWriter implements WriterInterface 12 { 13 /** @var resource Pointer to the file/stream we will write to */ 14 protected $filePointer; 15 16 /** @var string Content-Type value for the header - to be defined by child class */ 17 protected static string $headerContentType; 18 19 /** @var string Path to the output file */ 20 private string $outputFilePath; 21 22 /** @var bool Indicates whether the writer has been opened or not */ 23 private bool $isWriterOpened = false; 24 25 /** @var 0|positive-int */ 26 private int $writtenRowCount = 0; 27 28 /** 29 * {@inheritdoc} 30 */ 31 final public function openToFile($outputFilePath): void 32 { 33 $this->outputFilePath = $outputFilePath; 34 35 $errorMessage = null; 36 set_error_handler(static function ($nr, $message) use (&$errorMessage): bool { 37 $errorMessage = $message; 38 39 return true; 40 }); 41 42 $resource = fopen($this->outputFilePath, 'w'); 43 restore_error_handler(); 44 if (null !== $errorMessage) { 45 throw new IOException("Unable to open file {$this->outputFilePath}: {$errorMessage}"); 46 } 47 \assert(false !== $resource); 48 $this->filePointer = $resource; 49 50 $this->openWriter(); 51 $this->isWriterOpened = true; 52 } 53 54 /** 55 * @codeCoverageIgnore 56 * {@inheritdoc} 57 */ 58 final public function openToBrowser($outputFileName): void 59 { 60 $this->outputFilePath = basename($outputFileName); 61 62 $resource = fopen('php://output', 'w'); 63 \assert(false !== $resource); 64 $this->filePointer = $resource; 65 66 // Clear any previous output (otherwise the generated file will be corrupted) 67 // @see https://github.com/box/spout/issues/241 68 if (ob_get_length() > 0) { 69 ob_end_clean(); 70 } 71 72 /* 73 * Set headers 74 * 75 * For newer browsers such as Firefox, Chrome, Opera, Safari, etc., they all support and use `filename*` 76 * specified by the new standard, even if they do not automatically decode filename; it does not matter; 77 * and for older versions of Internet Explorer, they are not recognized `filename*`, will automatically 78 * ignore it and use the old `filename` (the only minor flaw is that there must be an English suffix name). 79 * In this way, the multi-browser multi-language compatibility problem is perfectly solved, which does not 80 * require UA judgment and is more in line with the standard. 81 * 82 * @see https://github.com/box/spout/issues/745 83 * @see https://tools.ietf.org/html/rfc6266 84 * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition 85 */ 86 header('Content-Type: '.static::$headerContentType); 87 header( 88 'Content-Disposition: attachment; '. 89 'filename="'.rawurlencode($this->outputFilePath).'"; '. 90 'filename*=UTF-8\'\''.rawurlencode($this->outputFilePath) 91 ); 92 93 /* 94 * When forcing the download of a file over SSL,IE8 and lower browsers fail 95 * if the Cache-Control and Pragma headers are not set. 96 * 97 * @see http://support.microsoft.com/KB/323308 98 * @see https://github.com/liuggio/ExcelBundle/issues/45 99 */ 100 header('Cache-Control: max-age=0'); 101 header('Pragma: public'); 102 103 $this->openWriter(); 104 $this->isWriterOpened = true; 105 } 106 107 /** 108 * {@inheritdoc} 109 */ 110 final public function addRow(Row $row): void 111 { 112 if (!$this->isWriterOpened) { 113 throw new WriterNotOpenedException('The writer needs to be opened before adding row.'); 114 } 115 116 $this->addRowToWriter($row); 117 ++$this->writtenRowCount; 118 } 119 120 /** 121 * {@inheritdoc} 122 */ 123 final public function addRows(array $rows): void 124 { 125 foreach ($rows as $row) { 126 $this->addRow($row); 127 } 128 } 129 130 /** 131 * {@inheritdoc} 132 */ 133 final public function getWrittenRowCount(): int 134 { 135 return $this->writtenRowCount; 136 } 137 138 /** 139 * {@inheritdoc} 140 */ 141 final public function close(): void 142 { 143 if (!$this->isWriterOpened) { 144 return; 145 } 146 147 $this->closeWriter(); 148 149 fclose($this->filePointer); 150 151 $this->isWriterOpened = false; 152 } 153 154 /** 155 * Opens the streamer and makes it ready to accept data. 156 * 157 * @throws IOException If the writer cannot be opened 158 */ 159 abstract protected function openWriter(): void; 160 161 /** 162 * Adds a row to the currently opened writer. 163 * 164 * @param Row $row The row containing cells and styles 165 * 166 * @throws WriterNotOpenedException If the workbook is not created yet 167 * @throws IOException If unable to write data 168 */ 169 abstract protected function addRowToWriter(Row $row): void; 170 171 /** 172 * Closes the streamer, preventing any additional writing. 173 */ 174 abstract protected function closeWriter(): void; 175 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body