Completed
Pull Request — master (#715)
by
unknown
14:17
created

WorkbookManagerAbstract::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 19
ccs 9
cts 9
cp 1
rs 9.6333
c 0
b 0
f 0
cc 1
nc 1
nop 8
crap 1

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
namespace Box\Spout\Writer\Common\Manager;
4
5
use Box\Spout\Common\Entity\Row;
6
use Box\Spout\Common\Exception\IOException;
7
use Box\Spout\Common\Manager\OptionsManagerInterface;
8
use Box\Spout\Writer\Common\Creator\InternalEntityFactory;
9
use Box\Spout\Writer\Common\Creator\ManagerFactoryInterface;
10
use Box\Spout\Writer\Common\Entity\Options;
11
use Box\Spout\Writer\Common\Entity\Sheet;
12
use Box\Spout\Writer\Common\Entity\Workbook;
13
use Box\Spout\Writer\Common\Entity\Worksheet;
14
use Box\Spout\Writer\Common\Helper\FileSystemWithRootFolderHelperInterface;
15
use Box\Spout\Writer\Common\Manager\Style\StyleManagerInterface;
16
use Box\Spout\Writer\Common\Manager\Style\StyleMerger;
17
use Box\Spout\Writer\Exception\SheetNotFoundException;
18
19
/**
20
 * Class WorkbookManagerAbstract
21
 * Abstract workbook manager, providing the generic interfaces to work with workbook.
22
 */
23
abstract class WorkbookManagerAbstract implements WorkbookManagerInterface
24
{
25
    /** @var Workbook The workbook to manage */
26
    protected $workbook;
27
28
    /** @var OptionsManagerInterface */
29
    protected $optionsManager;
30
31
    /** @var WorksheetManagerInterface */
32
    protected $worksheetManager;
33
34
    /** @var StyleManagerInterface Manages styles */
35
    protected $styleManager;
36
37
    /** @var StyleMerger Helper to merge styles */
38
    protected $styleMerger;
39
40
    /** @var FileSystemWithRootFolderHelperInterface Helper to perform file system operations */
41
    protected $fileSystemHelper;
42
43
    /** @var InternalEntityFactory Factory to create entities */
44
    protected $entityFactory;
45
46
    /** @var ManagerFactoryInterface $managerFactory Factory to create managers */
47
    protected $managerFactory;
48
49
    /** @var Worksheet The worksheet where data will be written to */
50
    protected $currentWorksheet;
51
52
    /**
53
     * @param Workbook $workbook
54
     * @param OptionsManagerInterface $optionsManager
55
     * @param WorksheetManagerInterface $worksheetManager
56
     * @param StyleManagerInterface $styleManager
57
     * @param StyleMerger $styleMerger
58
     * @param FileSystemWithRootFolderHelperInterface $fileSystemHelper
59
     * @param InternalEntityFactory $entityFactory
60
     * @param ManagerFactoryInterface $managerFactory
61
     */
62
    public function __construct(
63 80
        Workbook $workbook,
64
        OptionsManagerInterface $optionsManager,
65
        WorksheetManagerInterface $worksheetManager,
66
        StyleManagerInterface $styleManager,
67
        StyleMerger $styleMerger,
68
        FileSystemWithRootFolderHelperInterface $fileSystemHelper,
69
        InternalEntityFactory $entityFactory,
70
        ManagerFactoryInterface $managerFactory
71
    ) {
72
        $this->workbook = $workbook;
73 80
        $this->optionsManager = $optionsManager;
74 80
        $this->worksheetManager = $worksheetManager;
75 80
        $this->styleManager = $styleManager;
76 80
        $this->styleMerger = $styleMerger;
77 80
        $this->fileSystemHelper = $fileSystemHelper;
78 80
        $this->entityFactory = $entityFactory;
79 80
        $this->managerFactory = $managerFactory;
80 80
    }
81 80
82
    /**
83
     * @return int Maximum number of rows/columns a sheet can contain
84
     */
85
    abstract protected function getMaxRowsPerWorksheet();
86
87
    /**
88
     * @param Sheet $sheet
89
     * @return string The file path where the data for the given sheet will be stored
90
     */
91
    abstract protected function getWorksheetFilePath(Sheet $sheet);
92
93
    /**
94
     * @return Workbook
95
     */
96
    public function getWorkbook()
97 74
    {
98
        return $this->workbook;
99 74
    }
100
101
    /**
102
     * Creates a new sheet in the workbook and make it the current sheet.
103
     * The writing will resume where it stopped (i.e. data won't be truncated).
104
     *
105
     * @return Worksheet The created sheet
106
     */
107
    public function addNewSheetAndMakeItCurrent()
108
    {
109 80
        $worksheet = $this->addNewSheet();
110
        $this->setCurrentWorksheet($worksheet);
111 80
112 80
        return $worksheet;
113
    }
114 80
115
    /**
116
     * Creates a new sheet in the workbook. The current sheet remains unchanged.
117
     *
118
     * @throws IOException
119
     * @return Worksheet The created sheet
120
     */
121
    private function addNewSheet()
122
    {
123 80
        $worksheets = $this->getWorksheets();
124
125 80
        $newSheetIndex = \count($worksheets);
126
        $sheetManager = $this->managerFactory->createSheetManager();
127 80
        $sheet = $this->entityFactory->createSheet($newSheetIndex, $this->workbook->getInternalId(), $sheetManager);
128 80
129 80
        $worksheetFilePath = $this->getWorksheetFilePath($sheet);
130
        $worksheet = $this->entityFactory->createWorksheet($worksheetFilePath, $sheet);
131 80
132 80
        $this->worksheetManager->startSheet($worksheet);
133
134 80
        $worksheets[] = $worksheet;
135
        $this->workbook->setWorksheets($worksheets);
136 80
137 80
        return $worksheet;
138
    }
139 80
140
    /**
141
     * @return Worksheet[] All the workbook's sheets
142
     */
143
    public function getWorksheets()
144
    {
145 80
        return $this->workbook->getWorksheets();
146
    }
147 80
148
    /**
149
     * Returns the current sheet
150
     *
151
     * @return Worksheet The current sheet
152
     */
153
    public function getCurrentWorksheet()
154
    {
155 74
        return $this->currentWorksheet;
156
    }
157 74
158
    /**
159
     * Starts the current sheet and opens the file pointer
160
     *
161
     * @throws IOException
162
     */
163
    public function startCurrentSheet()
164
    {
165
        $this->worksheetManager->startSheet($this->getCurrentWorksheet());
166
    }
167
168 4
    /**
169
     * Sets the given sheet as the current one. New data will be written to this sheet.
170 4
     * The writing will resume where it stopped (i.e. data won't be truncated).
171 4
     *
172 4
     * @param Sheet $sheet The "external" sheet to set as current
173
     * @throws SheetNotFoundException If the given sheet does not exist in the workbook
174
     * @return void
175
     */
176 4
    public function setCurrentSheet(Sheet $sheet)
177
    {
178
        $worksheet = $this->getWorksheetFromExternalSheet($sheet);
179
        if ($worksheet !== null) {
180
            $this->currentWorksheet = $worksheet;
181
        } else {
182 80
            throw new SheetNotFoundException('The given sheet does not exist in the workbook.');
183
        }
184 80
    }
185 80
186
    /**
187
     * @param Worksheet $worksheet
188
     * @return void
189
     */
190
    private function setCurrentWorksheet($worksheet)
191
    {
192
        $this->currentWorksheet = $worksheet;
193 4
    }
194
195 4
    /**
196
     * Returns the worksheet associated to the given external sheet.
197 4
     *
198 4
     * @param Sheet $sheet
199 4
     * @return Worksheet|null The worksheet associated to the given external sheet or null if not found.
200 4
     */
201
    private function getWorksheetFromExternalSheet($sheet)
202
    {
203
        $worksheetFound = null;
204 4
205
        foreach ($this->getWorksheets() as $worksheet) {
206
            if ($worksheet->getExternalSheet() === $sheet) {
207
                $worksheetFound = $worksheet;
208
                break;
209
            }
210
        }
211
212
        return $worksheetFound;
213
    }
214
215
    /**
216
     * Adds a row to the current sheet.
217 68
     * If shouldCreateNewSheetsAutomatically option is set to true, it will handle pagination
218
     * with the creation of new worksheets if one worksheet has reached its maximum capicity.
219 68
     *
220 68
     * @param Row $row The row to be added
221
     *
222
     * @throws IOException If trying to create a new sheet and unable to open the sheet for writing
223 68
     * @throws \Box\Spout\Common\Exception\InvalidArgumentException
224
     * @return void
225 4
     */
226 2
    public function addRowToCurrentWorksheet(Row $row)
227
    {
228 2
        $currentWorksheet = $this->getCurrentWorksheet();
229 4
        $hasReachedMaxRows = $this->hasCurrentWorksheetReachedMaxRows();
230
231
        // if we reached the maximum number of rows for the current sheet...
232
        if ($hasReachedMaxRows) {
233 68
            // ... continue writing in a new sheet if option set
234
            if ($this->optionsManager->getOption(Options::SHOULD_CREATE_NEW_SHEETS_AUTOMATICALLY)) {
235 66
                $currentWorksheet = $this->addNewSheetAndMakeItCurrent();
236
237
                $this->addRowToWorksheet($currentWorksheet, $row);
238
            } else {
239
                // otherwise, do nothing as the data won't be written anyways
240 68
            }
241
        } else {
242 68
            $this->addRowToWorksheet($currentWorksheet, $row);
243
        }
244 68
    }
245
246
    /**
247
     * @return bool Whether the current worksheet has reached the maximum number of rows per sheet.
248
     */
249
    private function hasCurrentWorksheetReachedMaxRows()
250
    {
251
        $currentWorksheet = $this->getCurrentWorksheet();
252
253
        return ($currentWorksheet->getLastWrittenRowIndex() >= $this->getMaxRowsPerWorksheet());
254
    }
255 68
256
    /**
257 68
     * Adds a row to the given sheet.
258 68
     *
259
     * @param Worksheet $worksheet Worksheet to write the row to
260
     * @param Row $row The row to be added
261 66
     *
262 66
     * @throws IOException
263 66
     * @throws \Box\Spout\Common\Exception\InvalidArgumentException
264 66
     * @return void
265
     */
266
    private function addRowToWorksheet(Worksheet $worksheet, Row $row)
267
    {
268
        $this->applyDefaultRowStyle($row);
269 68
        $this->worksheetManager->addRow($worksheet, $row);
270
271 68
        // update max num columns for the worksheet
272
        $currentMaxNumColumns = $worksheet->getMaxNumColumns();
273 68
        $cellsCount = $row->getNumCells();
274 68
        $worksheet->setMaxNumColumns(\max($currentMaxNumColumns, $cellsCount));
275 68
    }
276
277 68
    /**
278
     * @param Row $row
279
     */
280
    private function applyDefaultRowStyle(Row $row)
281
    {
282
        $defaultRowStyle = $this->optionsManager->getOption(Options::DEFAULT_ROW_STYLE);
283
284
        if ($defaultRowStyle !== null) {
285
            $mergedStyle = $this->styleMerger->merge($row->getStyle(), $defaultRowStyle);
286
            $row->setStyle($mergedStyle);
287 73
        }
288
    }
289 73
290 73
    /**
291 73
     * @param float $width
292 73
     */
293 73
    public function setDefaultColumnWidth(float $width)
294
    {
295
        $this->worksheetManager->setDefaultColumnWidth($width);
296
    }
297
298
    /**
299
     * @param float $height
300 35
     */
301
    public function setDefaultRowHeight(float $height)
302
    {
303 35
        $this->worksheetManager->setDefaultRowHeight($height);
304
    }
305
306
    /**
307
     * @param float $width
308
     * @param array $columns One or more columns with this width
309
     */
310
    public function setColumnWidth(float $width, ...$columns)
311
    {
312
        $this->worksheetManager->setColumnWidth($width, ...$columns);
313
    }
314
315
    /**
316
     * @param float $width The width to set
317
     * @param int $start First column index of the range
318 73
     * @param int $end Last column index of the range
319
     */
320 73
    public function setColumnWidthForRange(float $width, int $start, int $end)
321
    {
322 73
        $this->worksheetManager->setColumnWidthForRange($width, $start, $end);
323 73
    }
324
325 73
    /**
326
     * Closes the workbook and all its associated sheets.
327
     * All the necessary files are written to disk and zipped together to create the final file.
328
     * All the temporary files are then deleted.
329
     *
330
     * @param resource $finalFilePointer Pointer to the spreadsheet that will be created
331
     * @return void
332 73
     */
333
    public function close($finalFilePointer)
334 73
    {
335 73
        $this->closeAllWorksheets();
336 73
        $this->closeRemainingObjects();
337
        $this->writeAllFilesToDiskAndZipThem($finalFilePointer);
338
        $this->cleanupTempFolder();
339
    }
340
341
    /**
342
     * Closes custom objects that are still opened
343
     *
344
     * @return void
345
     */
346
    protected function closeRemainingObjects()
347
    {
348
        // do nothing by default
349
    }
350
351
    /**
352
     * Writes all the necessary files to disk and zip them together to create the final file.
353
     *
354
     * @param resource $finalFilePointer Pointer to the spreadsheet that will be created
355
     * @return void
356
     */
357
    abstract protected function writeAllFilesToDiskAndZipThem($finalFilePointer);
358
359
    /**
360
     * Closes all workbook's associated sheets.
361
     *
362
     * @return void
363
     */
364
    private function closeAllWorksheets()
365
    {
366
        $worksheets = $this->getWorksheets();
367
368
        foreach ($worksheets as $worksheet) {
369
            $this->worksheetManager->close($worksheet);
370
        }
371
    }
372
373
    /**
374
     * Deletes the root folder created in the temp folder and all its contents.
375
     *
376
     * @return void
377
     */
378
    protected function cleanupTempFolder()
379
    {
380
        $rootFolder = $this->fileSystemHelper->getRootFolder();
381
        $this->fileSystemHelper->deleteFolderRecursively($rootFolder);
382
    }
383
}
384