Completed
Pull Request — master (#649)
by Adrien
03:03 queued 33s
created

WorkbookManagerAbstract::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 1

Importance

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