Completed
Pull Request — develop_3.0 (#434)
by Hura
04:17
created

WorkbookManagerAbstract::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 15
ccs 8
cts 8
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 13
nc 1
nop 6
crap 1
1
<?php
2
3
namespace Box\Spout\Writer\Common\Manager;
4
5
use Box\Spout\Common\Exception\IOException;
6
use Box\Spout\Writer\Common\Creator\EntityFactory;
7
use Box\Spout\Writer\Common\Entity\Options;
8
use Box\Spout\Writer\Common\Entity\Row;
9
use Box\Spout\Writer\Common\Entity\Style\Style;
10
use Box\Spout\Writer\Common\Entity\Workbook;
11
use Box\Spout\Writer\Common\Entity\Worksheet;
12
use Box\Spout\Writer\Common\Helper\FileSystemWithRootFolderHelperInterface;
13
use Box\Spout\Writer\Common\Helper\StyleHelperInterface;
14
use Box\Spout\Writer\Common\Sheet;
15
use Box\Spout\Writer\Exception\SheetNotFoundException;
16
use Box\Spout\Writer\Exception\WriterException;
17
18
/**
19
 * Class WorkbookManagerAbstract
20
 * Abstract workbook manager, providing the generic interfaces to work with workbook.
21
 *
22
 * @package Box\Spout\Writer\Common\Manager
23
 */
24
abstract class WorkbookManagerAbstract implements WorkbookManagerInterface
25
{
26
    /** @var Workbook The workbook to manage */
27
    protected $workbook;
28
29
    /** @var OptionsManagerInterface */
30
    protected $optionManager;
31
32
    /** @var WorksheetManagerInterface */
33
    protected $worksheetManager;
34
35
    /** @var StyleHelperInterface */
36
    protected $styleHelper;
37
38
    /** @var FileSystemWithRootFolderHelperInterface Helper to perform file system operations */
39
    protected $fileSystemHelper;
40
41
    /** @var EntityFactory Factory to create entities */
42
    private $entityFactory;
43
44
    /** @var Worksheet The worksheet where data will be written to */
45
    protected $currentWorksheet;
46
47
48
    /**
49
     * @param Workbook $workbook
50
     * @param OptionsManagerInterface $optionsManager
51
     * @param WorksheetManagerInterface $worksheetManager
52
     * @param StyleHelperInterface $styleHelper
53
     * @param FileSystemWithRootFolderHelperInterface $fileSystemHelper
54
     * @param EntityFactory $entityFactory
55
     */
56 89
    public function __construct(
57
        Workbook $workbook,
58
        OptionsManagerInterface $optionsManager,
59
        WorksheetManagerInterface $worksheetManager,
60
        StyleHelperInterface $styleHelper,
61
        FileSystemWithRootFolderHelperInterface $fileSystemHelper,
62
        EntityFactory $entityFactory
63
    ) {
64 89
        $this->workbook = $workbook;
65 89
        $this->optionManager = $optionsManager;
66 89
        $this->worksheetManager = $worksheetManager;
67 89
        $this->styleHelper = $styleHelper;
68 89
        $this->fileSystemHelper = $fileSystemHelper;
69 89
        $this->entityFactory = $entityFactory;
70 89
    }
71
72
    /**
73
     * @return int Maximum number of rows/columns a sheet can contain
74
     */
75
    abstract protected function getMaxRowsPerWorksheet();
76
77
    /**
78
     * @param Sheet $sheet
79
     * @return string The file path where the data for the given sheet will be stored
80
     */
81
    abstract protected function getWorksheetFilePath(Sheet $sheet);
82
83
    /**
84
     * @return Workbook
85
     */
86 70
    public function getWorkbook()
87
    {
88 70
        return $this->workbook;
89
    }
90
91
    /**
92
     * Creates a new sheet in the workbook and make it the current sheet.
93
     * The writing will resume where it stopped (i.e. data won't be truncated).
94
     *
95
     * @return Worksheet The created sheet
96
     * @throws IOException If unable to open the sheet for writing
97
     */
98 89
    public function addNewSheetAndMakeItCurrent()
99
    {
100 89
        $worksheet = $this->addNewSheet();
101 89
        $this->setCurrentWorksheet($worksheet);
102
103 89
        return $worksheet;
104
    }
105
106
    /**
107
     * Creates a new sheet in the workbook. The current sheet remains unchanged.
108
     *
109
     * @return Worksheet The created sheet
110
     * @throws \Box\Spout\Common\Exception\IOException If unable to open the sheet for writing
111
     */
112 89
    private function addNewSheet()
113
    {
114 89
        $worksheets = $this->getWorksheets();
115
116 89
        $newSheetIndex = count($worksheets);
117 89
        $sheet = new Sheet($newSheetIndex, $this->workbook->getInternalId());
118
119 89
        $worksheetFilePath = $this->getWorksheetFilePath($sheet);
120 89
        $worksheet = $this->entityFactory->createWorksheet($worksheetFilePath, $sheet);
121
122 89
        $this->worksheetManager->startSheet($worksheet);
123
124 89
        $worksheets[] = $worksheet;
125 89
        $this->workbook->setWorksheets($worksheets);
126
127 89
        return $worksheet;
128
    }
129
130
    /**
131
     * @return Worksheet[] All the workbook's sheets
132
     */
133 89
    public function getWorksheets()
134
    {
135 89
        return $this->workbook->getWorksheets();
136
    }
137
138
    /**
139
     * Returns the current sheet
140
     *
141
     * @return Worksheet The current sheet
142
     */
143 70
    public function getCurrentWorksheet()
144
    {
145 70
        return $this->currentWorksheet;
146
    }
147
148
    /**
149
     * Sets the given sheet as the current one. New data will be written to this sheet.
150
     * The writing will resume where it stopped (i.e. data won't be truncated).
151
     *
152
     * @param Sheet $sheet The "external" sheet to set as current
153
     * @return void
154
     * @throws SheetNotFoundException If the given sheet does not exist in the workbook
155
     */
156 4
    public function setCurrentSheet(Sheet $sheet)
157
    {
158 4
        $worksheet = $this->getWorksheetFromExternalSheet($sheet);
159 4
        if ($worksheet !== null) {
160 4
            $this->currentWorksheet = $worksheet;
161
        } else {
162
            throw new SheetNotFoundException('The given sheet does not exist in the workbook.');
163
        }
164 4
    }
165
166
    /**
167
     * @param Worksheet $worksheet
168
     * @return void
169
     */
170 89
    private function setCurrentWorksheet($worksheet)
171
    {
172 89
        $this->currentWorksheet = $worksheet;
173 89
    }
174
175
    /**
176
     * Returns the worksheet associated to the given external sheet.
177
     *
178
     * @param Sheet $sheet
179
     * @return Worksheet|null The worksheet associated to the given external sheet or null if not found.
180
     */
181 4
    private function getWorksheetFromExternalSheet($sheet)
182
    {
183 4
        $worksheetFound = null;
184
185 4
        foreach ($this->getWorksheets() as $worksheet) {
186 4
            if ($worksheet->getExternalSheet() === $sheet) {
187 4
                $worksheetFound = $worksheet;
188 4
                break;
189
            }
190
        }
191
192 4
        return $worksheetFound;
193
    }
194
195
    /**
196
     * Adds a row to the current sheet.
197
     * If shouldCreateNewSheetsAutomatically option is set to true, it will handle pagination
198
     * with the creation of new worksheets if one worksheet has reached its maximum capicity.
199
     *
200
     * @param Row $row The row to added
201
     * @return void
202
     * @throws IOException If trying to create a new sheet and unable to open the sheet for writing
203
     * @throws WriterException If unable to write data
204
     */
205 64
    public function addRowToCurrentWorksheet(Row $row)
206
    {
207 64
        $currentWorksheet = $this->getCurrentWorksheet();
208 64
        $hasReachedMaxRows = $this->hasCurrentWorkseetReachedMaxRows();
209
210
        // if we reached the maximum number of rows for the current sheet...
211 64
        if ($hasReachedMaxRows) {
212
            // ... continue writing in a new sheet if option set
213 4
            if ($this->optionManager->getOption(Options::SHOULD_CREATE_NEW_SHEETS_AUTOMATICALLY)) {
214 2
                $currentWorksheet = $this->addNewSheetAndMakeItCurrent();
215
216 2
                $this->addRowWithStyleToWorksheet($currentWorksheet, $row);
217 2
            } else {
218
                // otherwise, do nothing as the data won't be written anyways
219
            }
220
        } else {
221 64
            $this->addRowWithStyleToWorksheet($currentWorksheet, $row);
222
        }
223 61
    }
224
225
    /**
226
     * @return bool Whether the current worksheet has reached the maximum number of rows per sheet.
227
     */
228 64
    private function hasCurrentWorkseetReachedMaxRows()
229
    {
230 64
        $currentWorksheet = $this->getCurrentWorksheet();
231 64
        return ($currentWorksheet->getLastWrittenRowIndex() >= $this->getMaxRowsPerWorksheet());
232
    }
233
234
    /**
235
     * Adds data with the given style to the given sheet.
236
     *
237
     * @param Worksheet $worksheet Worksheet to write the row to
238
     * @param array $dataRow Array containing data to be written. Cannot be empty.
0 ignored issues
show
Bug introduced by
There is no parameter named $dataRow. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
239
     *          Example $dataRow = ['data1', 1234, null, '', 'data5'];
240
     * @return void
241
     * @throws WriterException If unable to write data
242
     */
243 64
    private function addRowWithStyleToWorksheet(Worksheet $worksheet, Row $row)
244
    {
245 64
        $this->worksheetManager->addRow($worksheet, $row);
246
247
        // update max num columns for the worksheet
248 61
        $currentMaxNumColumns = $worksheet->getMaxNumColumns();
249 61
        $cellsCount = count($row->getCells());
250 61
        $worksheet->setMaxNumColumns(max($currentMaxNumColumns, $cellsCount));
251 61
    }
252
253
    /**
254
     * Closes the workbook and all its associated sheets.
255
     * All the necessary files are written to disk and zipped together to create the final file.
256
     * All the temporary files are then deleted.
257
     *
258
     * @param resource $finalFilePointer Pointer to the spreadsheet that will be created
259
     * @return void
260
     */
261 70
    public function close($finalFilePointer)
262
    {
263 70
        $this->closeAllWorksheets();
264 70
        $this->closeRemainingObjects();
265 70
        $this->writeAllFilesToDiskAndZipThem($finalFilePointer);
266 70
        $this->cleanupTempFolder();
267 70
    }
268
269
    /**
270
     * Closes custom objects that are still opened
271
     *
272
     * @return void
273
     */
274 34
    protected function closeRemainingObjects()
275
    {
276
        // do nothing by default
277 34
    }
278
279
    /**
280
     * Writes all the necessary files to disk and zip them together to create the final file.
281
     *
282
     * @param resource $finalFilePointer Pointer to the spreadsheet that will be created
283
     * @return void
284
     */
285
    abstract protected function writeAllFilesToDiskAndZipThem($finalFilePointer);
286
287
    /**
288
     * Closes all workbook's associated sheets.
289
     *
290
     * @return void
291
     */
292 70
    private function closeAllWorksheets()
293
    {
294 70
        $worksheets = $this->getWorksheets();
295
296 70
        foreach ($worksheets as $worksheet) {
297 70
            $this->worksheetManager->close($worksheet);
298
        }
299 70
    }
300
301
    /**
302
     * Deletes the root folder created in the temp folder and all its contents.
303
     *
304
     * @return void
305
     */
306 70
    protected function cleanupTempFolder()
307
    {
308 70
        $rootFolder = $this->fileSystemHelper->getRootFolder();
309 70
        $this->fileSystemHelper->deleteFolderRecursively($rootFolder);
310 70
    }
311
}
312