Completed
Pull Request — master (#398)
by Adrien
05:26 queued 02:58
created

AbstractWorkbook::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 1
cts 1
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 2
crap 1
1
<?php
2
3
namespace Box\Spout\Writer\Common\Internal;
4
5
use Box\Spout\Writer\Exception\SheetNotFoundException;
6
7
/**
8
 * Class Workbook
9
 * Represents a workbook within a spreadsheet file.
10
 * It provides the functions to work with worksheets.
11
 *
12
 * @package Box\Spout\Writer\Common
13
 */
14
abstract class AbstractWorkbook implements WorkbookInterface
15
{
16
    /** @var bool Whether new sheets should be automatically created when the max rows limit per sheet is reached */
17
    protected $shouldCreateNewSheetsAutomatically;
18
19
    /** @var string Timestamp based unique ID identifying the workbook */
20
    protected $internalId;
21
22
    /** @var WorksheetInterface[] Array containing the workbook's sheets */
23
    protected $worksheets = [];
24
25
    /** @var WorksheetInterface The worksheet where data will be written to */
26
    protected $currentWorksheet;
27
28
    /**
29
     * @param bool $shouldCreateNewSheetsAutomatically
30 246
     * @param \Box\Spout\Writer\Style\Style $defaultRowStyle
31
     * @throws \Box\Spout\Common\Exception\IOException If unable to create at least one of the base folders
32 246
     */
33 246
    public function __construct($shouldCreateNewSheetsAutomatically, $defaultRowStyle)
34
    {
35
        $this->shouldCreateNewSheetsAutomatically = $shouldCreateNewSheetsAutomatically;
36
        $this->internalId = uniqid();
37
    }
38
39
    /**
40
     * @return \Box\Spout\Writer\Common\Helper\AbstractStyleHelper The specific style helper
41
     */
42
    abstract protected function getStyleHelper();
43
44
    /**
45
     * @return int Maximum number of rows/columns a sheet can contain
46
     */
47
    abstract protected function getMaxRowsPerWorksheet();
48
49
    /**
50
     * Creates a new sheet in the workbook. The current sheet remains unchanged.
51
     *
52
     * @return WorksheetInterface The created sheet
53
     * @throws \Box\Spout\Common\Exception\IOException If unable to open the sheet for writing
54
     */
55
    abstract public function addNewSheet();
56
57
    /**
58
     * Creates a new sheet in the workbook and make it the current sheet.
59
     * The writing will resume where it stopped (i.e. data won't be truncated).
60 246
     *
61
     * @return WorksheetInterface The created sheet
62 246
     * @throws \Box\Spout\Common\Exception\IOException If unable to open the sheet for writing
63 246
     */
64
    public function addNewSheetAndMakeItCurrent()
65 246
    {
66
        $worksheet = $this->addNewSheet();
67
        $this->setCurrentWorksheet($worksheet);
68
69
        return $worksheet;
70
    }
71 42
72
    /**
73 42
     * @return WorksheetInterface[] All the workbook's sheets
74
     */
75
    public function getWorksheets()
76
    {
77
        return $this->worksheets;
78
    }
79
80
    /**
81 195
     * Returns the current sheet
82
     *
83 195
     * @return WorksheetInterface The current sheet
84
     */
85
    public function getCurrentWorksheet()
86
    {
87
        return $this->currentWorksheet;
88
    }
89
90
    /**
91
     * Sets the given sheet as the current one. New data will be written to this sheet.
92
     * The writing will resume where it stopped (i.e. data won't be truncated).
93
     *
94 12
     * @param \Box\Spout\Writer\Common\Sheet $sheet The "external" sheet to set as current
95
     * @return void
96 12
     * @throws \Box\Spout\Writer\Exception\SheetNotFoundException If the given sheet does not exist in the workbook
97 12
     */
98 12
    public function setCurrentSheet($sheet)
99 12
    {
100
        $worksheet = $this->getWorksheetFromExternalSheet($sheet);
101
        if ($worksheet !== null) {
102 12
            $this->currentWorksheet = $worksheet;
103
        } else {
104
            throw new SheetNotFoundException('The given sheet does not exist in the workbook.');
105
        }
106
    }
107
108 246
    /**
109
     * @param WorksheetInterface $worksheet
110 246
     * @return void
111 246
     */
112
    protected function setCurrentWorksheet($worksheet)
113
    {
114
        $this->currentWorksheet = $worksheet;
115
    }
116
117
    /**
118
     * Returns the worksheet associated to the given external sheet.
119 12
     *
120
     * @param \Box\Spout\Writer\Common\Sheet $sheet
121 12
     * @return WorksheetInterface|null The worksheet associated to the given external sheet or null if not found.
122
     */
123 12
    protected function getWorksheetFromExternalSheet($sheet)
124 12
    {
125 12
        $worksheetFound = null;
126 12
127
        foreach ($this->worksheets as $worksheet) {
128 12
            if ($worksheet->getExternalSheet() === $sheet) {
129
                $worksheetFound = $worksheet;
130 12
                break;
131
            }
132
        }
133
134
        return $worksheetFound;
135
    }
136
137
    /**
138
     * Adds data to the current sheet.
139
     * If shouldCreateNewSheetsAutomatically option is set to true, it will handle pagination
140
     * with the creation of new worksheets if one worksheet has reached its maximum capicity.
141
     *
142
     * @param array $dataRow Array containing data to be written. Cannot be empty.
143
     *          Example $dataRow = ['data1', 1234, null, '', 'data5'];
144
     * @param \Box\Spout\Writer\Style\Style $style Style to be applied to the row.
145 177
     * @return void
146
     * @throws \Box\Spout\Common\Exception\IOException If trying to create a new sheet and unable to open the sheet for writing
147 177
     * @throws \Box\Spout\Writer\Exception\WriterException If unable to write data
148 177
     */
149 177
    public function addRowToCurrentWorksheet($dataRow, $style)
150
    {
151
        $currentWorksheet = $this->getCurrentWorksheet();
152 177
        $hasReachedMaxRows = $this->hasCurrentWorkseetReachedMaxRows();
153
        $styleHelper = $this->getStyleHelper();
154 12
155 6
        // if we reached the maximum number of rows for the current sheet...
156
        if ($hasReachedMaxRows) {
157 6
            // ... continue writing in a new sheet if option set
158 6
            if ($this->shouldCreateNewSheetsAutomatically) {
159 6
                $currentWorksheet = $this->addNewSheetAndMakeItCurrent();
160 6
161
                $updatedStyle = $styleHelper->applyExtraStylesIfNeeded($style, $dataRow);
162
                $registeredStyle = $styleHelper->registerStyle($updatedStyle);
163 12
                $currentWorksheet->addRow($dataRow, $registeredStyle);
164 177
            } else {
165 177
                // otherwise, do nothing as the data won't be read anyways
166 177
            }
167
        } else {
168 168
            $updatedStyle = $styleHelper->applyExtraStylesIfNeeded($style, $dataRow);
169
            $registeredStyle = $styleHelper->registerStyle($updatedStyle);
170
            $currentWorksheet->addRow($dataRow, $registeredStyle);
171
        }
172
    }
173 177
174
    /**
175 177
     * @return bool Whether the current worksheet has reached the maximum number of rows per sheet.
176 177
     */
177
    protected function hasCurrentWorkseetReachedMaxRows()
178
    {
179
        $currentWorksheet = $this->getCurrentWorksheet();
180
        return ($currentWorksheet->getLastWrittenRowIndex() >= $this->getMaxRowsPerWorksheet());
181
    }
182
183
    /**
184
     * Closes the workbook and all its associated sheets.
185
     * All the necessary files are written to disk and zipped together to create the ODS file.
186
     * All the temporary files are then deleted.
187
     *
188
     * @param resource $finalFilePointer Pointer to the ODS that will be created
189
     * @return void
190
     */
191
    abstract public function close($finalFilePointer);
192
}
193