Failed Conditions
Push — develop_3.0 ( 80553c...f9d8ad )
by Adrien
31:09
created

AbstractWorkbook::setCurrentSheet()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2.0185

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 5
cts 6
cp 0.8333
rs 9.6666
c 0
b 0
f 0
cc 2
eloc 6
nc 2
nop 1
crap 2.0185
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
     * @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
     */
33 89
    public function __construct($shouldCreateNewSheetsAutomatically, $defaultRowStyle)
34
    {
35 89
        $this->shouldCreateNewSheetsAutomatically = $shouldCreateNewSheetsAutomatically;
36 89
        $this->internalId = uniqid();
37 89
    }
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
     *
61
     * @return WorksheetInterface The created sheet
62
     * @throws \Box\Spout\Common\Exception\IOException If unable to open the sheet for writing
63
     */
64 89
    public function addNewSheetAndMakeItCurrent()
65
    {
66 89
        $worksheet = $this->addNewSheet();
67 89
        $this->setCurrentWorksheet($worksheet);
68
69 89
        return $worksheet;
70
    }
71
72
    /**
73
     * @return WorksheetInterface[] All the workbook's sheets
74
     */
75 14
    public function getWorksheets()
76
    {
77 14
        return $this->worksheets;
78
    }
79
80
    /**
81
     * Returns the current sheet
82
     *
83
     * @return WorksheetInterface The current sheet
84
     */
85 70
    public function getCurrentWorksheet()
86
    {
87 70
        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
     * @param \Box\Spout\Writer\Common\Sheet $sheet The "external" sheet to set as current
95
     * @return void
96
     * @throws \Box\Spout\Writer\Exception\SheetNotFoundException If the given sheet does not exist in the workbook
97
     */
98 4
    public function setCurrentSheet($sheet)
99
    {
100 4
        $worksheet = $this->getWorksheetFromExternalSheet($sheet);
101 4
        if ($worksheet !== null) {
102 4
            $this->currentWorksheet = $worksheet;
103
        } else {
104
            throw new SheetNotFoundException('The given sheet does not exist in the workbook.');
105
        }
106 4
    }
107
108
    /**
109
     * @param WorksheetInterface $worksheet
110
     * @return void
111
     */
112 89
    protected function setCurrentWorksheet($worksheet)
113
    {
114 89
        $this->currentWorksheet = $worksheet;
115 89
    }
116
117
    /**
118
     * Returns the worksheet associated to the given external sheet.
119
     *
120
     * @param \Box\Spout\Writer\Common\Sheet $sheet
121
     * @return WorksheetInterface|null The worksheet associated to the given external sheet or null if not found.
122
     */
123 4
    protected function getWorksheetFromExternalSheet($sheet)
124
    {
125 4
        $worksheetFound = null;
126
127 4
        foreach ($this->worksheets as $worksheet) {
128 4
            if ($worksheet->getExternalSheet() === $sheet) {
129 4
                $worksheetFound = $worksheet;
130 4
                break;
131
            }
132
        }
133
134 4
        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
     * @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
     * @throws \Box\Spout\Writer\Exception\WriterException If unable to write data
148
     */
149 64
    public function addRowToCurrentWorksheet($dataRow, $style)
150
    {
151 64
        $currentWorksheet = $this->getCurrentWorksheet();
152 64
        $hasReachedMaxRows = $this->hasCurrentWorkseetReachedMaxRows();
153 64
        $styleHelper = $this->getStyleHelper();
154
155
        // if we reached the maximum number of rows for the current sheet...
156 64
        if ($hasReachedMaxRows) {
157
            // ... continue writing in a new sheet if option set
158 4
            if ($this->shouldCreateNewSheetsAutomatically) {
159 2
                $currentWorksheet = $this->addNewSheetAndMakeItCurrent();
160
161 2
                $updatedStyle = $styleHelper->applyExtraStylesIfNeeded($style, $dataRow);
162 2
                $registeredStyle = $styleHelper->registerStyle($updatedStyle);
163 2
                $currentWorksheet->addRow($dataRow, $registeredStyle);
164 2
            } else {
165
                // otherwise, do nothing as the data won't be read anyways
166
            }
167
        } else {
168 64
            $updatedStyle = $styleHelper->applyExtraStylesIfNeeded($style, $dataRow);
169 64
            $registeredStyle = $styleHelper->registerStyle($updatedStyle);
170 64
            $currentWorksheet->addRow($dataRow, $registeredStyle);
171
        }
172 61
    }
173
174
    /**
175
     * @return bool Whether the current worksheet has reached the maximum number of rows per sheet.
176
     */
177 64
    protected function hasCurrentWorkseetReachedMaxRows()
178
    {
179 64
        $currentWorksheet = $this->getCurrentWorksheet();
180 64
        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