Failed Conditions
Pull Request — develop_3.0 (#434)
by Hura
03:29
created

getWorksheetFromExternalSheet()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

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