Completed
Push — develop ( 2b41bd...39b55d )
by Adrien
22:48
created

Workbook   B

Complexity

Total Complexity 44

Size/Duplication

Total Lines 420
Duplicated Lines 7.14 %

Coupling/Cohesion

Components 1
Dependencies 8

Test Coverage

Coverage 87.06%

Importance

Changes 0
Metric Value
dl 30
loc 420
ccs 148
cts 170
cp 0.8706
rs 8.3396
c 0
b 0
f 0
wmc 44
lcom 1
cbo 8

14 Methods

Rating   Name   Duplication   Size   Complexity  
B writeWorkbook() 5 46 3
A writeFileVersion() 0 9 1
A writeWorkbookPr() 0 12 2
A writeBookViews() 0 22 1
B writeWorkbookProtection() 0 19 7
A writeCalcPr() 0 15 3
A writeSheets() 0 18 2
A writeSheet() 16 16 4
B writeDefinedNames() 0 26 3
A writeNamedRanges() 0 8 2
B writeDefinedNameForNamedRange() 6 23 4
B writeDefinedNameForAutofilter() 3 27 3
B writeDefinedNameForPrintTitles() 0 34 6
B writeDefinedNameForPrintArea() 0 26 3

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Workbook often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Workbook, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Writer\Xlsx;
4
5
/**
6
 * Copyright (c) 2006 - 2016 PhpSpreadsheet
7
 *
8
 * This library is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2.1 of the License, or (at your option) any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with this library; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21
 *
22
 * @category   PhpSpreadsheet
23
 * @copyright  Copyright (c) 2006 - 2016 PhpSpreadsheet (https://github.com/PHPOffice/PhpSpreadsheet)
24
 * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
25
 * @version    ##VERSION##, ##DATE##
26
 */
27
class Workbook extends WriterPart
28
{
29
    /**
30
     * Write workbook to XML format
31
     *
32
     * @param \PhpOffice\PhpSpreadsheet\SpreadSheet $spreadsheet
33
     * @param    bool        $recalcRequired    Indicate whether formulas should be recalculated before writing
34
     * @throws     \PhpOffice\PhpSpreadsheet\Writer\Exception
35
     * @return string  XML Output
36
     */
37 56
    public function writeWorkbook(\PhpOffice\PhpSpreadsheet\SpreadSheet $spreadsheet = null, $recalcRequired = false)
38
    {
39
        // Create XML writer
40 56 View Code Duplication
        if ($this->getParentWriter()->getUseDiskCaching()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
Bug introduced by
It seems like you code against a concrete implementation and not the interface PhpOffice\PhpSpreadsheet\Writer\IWriter as the method getUseDiskCaching() does only exist in the following implementations of said interface: PhpOffice\PhpSpreadsheet\Writer\BaseWriter, PhpOffice\PhpSpreadsheet\Writer\CSV, PhpOffice\PhpSpreadsheet\Writer\Excel5, PhpOffice\PhpSpreadsheet\Writer\HTML, PhpOffice\PhpSpreadsheet\Writer\OpenDocument, PhpOffice\PhpSpreadsheet\Writer\PDF\Core, PhpOffice\PhpSpreadsheet\Writer\PDF\DomPDF, PhpOffice\PhpSpreadsheet\Writer\PDF\MPDF, PhpOffice\PhpSpreadsheet\Writer\PDF\TcPDF, PhpOffice\PhpSpreadsheet\Writer\Xlsx.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
41
            $objWriter = new \PhpOffice\PhpSpreadsheet\Shared\XMLWriter(\PhpOffice\PhpSpreadsheet\Shared\XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface PhpOffice\PhpSpreadsheet\Writer\IWriter as the method getDiskCachingDirectory() does only exist in the following implementations of said interface: PhpOffice\PhpSpreadsheet\Writer\BaseWriter, PhpOffice\PhpSpreadsheet\Writer\CSV, PhpOffice\PhpSpreadsheet\Writer\Excel5, PhpOffice\PhpSpreadsheet\Writer\HTML, PhpOffice\PhpSpreadsheet\Writer\OpenDocument, PhpOffice\PhpSpreadsheet\Writer\PDF\Core, PhpOffice\PhpSpreadsheet\Writer\PDF\DomPDF, PhpOffice\PhpSpreadsheet\Writer\PDF\MPDF, PhpOffice\PhpSpreadsheet\Writer\PDF\TcPDF, PhpOffice\PhpSpreadsheet\Writer\Xlsx.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
42
        } else {
43 56
            $objWriter = new \PhpOffice\PhpSpreadsheet\Shared\XMLWriter(\PhpOffice\PhpSpreadsheet\Shared\XMLWriter::STORAGE_MEMORY);
44
        }
45
46
        // XML header
47 56
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
48
49
        // workbook
50 56
        $objWriter->startElement('workbook');
51 56
        $objWriter->writeAttribute('xml:space', 'preserve');
52 56
        $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main');
53 56
        $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');
54
55
        // fileVersion
56 56
        $this->writeFileVersion($objWriter);
57
58
        // workbookPr
59 56
        $this->writeWorkbookPr($objWriter);
60
61
        // workbookProtection
62 56
        $this->writeWorkbookProtection($objWriter, $spreadsheet);
63
64
        // bookViews
65 56
        if ($this->getParentWriter()->getOffice2003Compatibility() === false) {
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface PhpOffice\PhpSpreadsheet\Writer\IWriter as the method getOffice2003Compatibility() does only exist in the following implementations of said interface: PhpOffice\PhpSpreadsheet\Writer\Xlsx.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
66 56
            $this->writeBookViews($objWriter, $spreadsheet);
67
        }
68
69
        // sheets
70 56
        $this->writeSheets($objWriter, $spreadsheet);
71
72
        // definedNames
73 56
        $this->writeDefinedNames($objWriter, $spreadsheet);
74
75
        // calcPr
76 56
        $this->writeCalcPr($objWriter, $recalcRequired);
77
78 56
        $objWriter->endElement();
79
80
        // Return
81 56
        return $objWriter->getData();
82
    }
83
84
    /**
85
     * Write file version
86
     *
87
     * @param     \PhpOffice\PhpSpreadsheet\Shared\XMLWriter $objWriter         XML Writer
88
     * @throws     \PhpOffice\PhpSpreadsheet\Writer\Exception
89
     */
90 56
    private function writeFileVersion(\PhpOffice\PhpSpreadsheet\Shared\XMLWriter $objWriter)
91
    {
92 56
        $objWriter->startElement('fileVersion');
93 56
        $objWriter->writeAttribute('appName', 'xl');
94 56
        $objWriter->writeAttribute('lastEdited', '4');
95 56
        $objWriter->writeAttribute('lowestEdited', '4');
96 56
        $objWriter->writeAttribute('rupBuild', '4505');
97 56
        $objWriter->endElement();
98 56
    }
99
100
    /**
101
     * Write WorkbookPr
102
     *
103
     * @param     \PhpOffice\PhpSpreadsheet\Shared\XMLWriter $objWriter         XML Writer
104
     * @throws     \PhpOffice\PhpSpreadsheet\Writer\Exception
105
     */
106 56
    private function writeWorkbookPr(\PhpOffice\PhpSpreadsheet\Shared\XMLWriter $objWriter)
107
    {
108 56
        $objWriter->startElement('workbookPr');
109
110 56
        if (\PhpOffice\PhpSpreadsheet\Shared\Date::getExcelCalendar() == \PhpOffice\PhpSpreadsheet\Shared\Date::CALENDAR_MAC_1904) {
111
            $objWriter->writeAttribute('date1904', '1');
112
        }
113
114 56
        $objWriter->writeAttribute('codeName', 'ThisWorkbook');
115
116 56
        $objWriter->endElement();
117 56
    }
118
119
    /**
120
     * Write BookViews
121
     *
122
     * @param     \PhpOffice\PhpSpreadsheet\Shared\XMLWriter     $objWriter         XML Writer
123
     * @param     \PhpOffice\PhpSpreadsheet\Spreadsheet                    $spreadsheet
124
     * @throws     \PhpOffice\PhpSpreadsheet\Writer\Exception
125
     */
126 56
    private function writeBookViews(\PhpOffice\PhpSpreadsheet\Shared\XMLWriter $objWriter, \PhpOffice\PhpSpreadsheet\SpreadSheet $spreadsheet = null)
127
    {
128
        // bookViews
129 56
        $objWriter->startElement('bookViews');
130
131
        // workbookView
132 56
        $objWriter->startElement('workbookView');
133
134 56
        $objWriter->writeAttribute('activeTab', $spreadsheet->getActiveSheetIndex());
0 ignored issues
show
Bug introduced by
It seems like $spreadsheet is not always an object, but can also be of type null. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
135 56
        $objWriter->writeAttribute('autoFilterDateGrouping', '1');
136 56
        $objWriter->writeAttribute('firstSheet', '0');
137 56
        $objWriter->writeAttribute('minimized', '0');
138 56
        $objWriter->writeAttribute('showHorizontalScroll', '1');
139 56
        $objWriter->writeAttribute('showSheetTabs', '1');
140 56
        $objWriter->writeAttribute('showVerticalScroll', '1');
141 56
        $objWriter->writeAttribute('tabRatio', '600');
142 56
        $objWriter->writeAttribute('visibility', 'visible');
143
144 56
        $objWriter->endElement();
145
146 56
        $objWriter->endElement();
147 56
    }
148
149
    /**
150
     * Write WorkbookProtection
151
     *
152
     * @param     \PhpOffice\PhpSpreadsheet\Shared\XMLWriter     $objWriter         XML Writer
153
     * @param     \PhpOffice\PhpSpreadsheet\Spreadsheet                    $spreadsheet
154
     * @throws     \PhpOffice\PhpSpreadsheet\Writer\Exception
155
     */
156 56
    private function writeWorkbookProtection(\PhpOffice\PhpSpreadsheet\Shared\XMLWriter $objWriter, \PhpOffice\PhpSpreadsheet\SpreadSheet $spreadsheet = null)
157
    {
158 56
        if ($spreadsheet->getSecurity()->isSecurityEnabled()) {
159 2
            $objWriter->startElement('workbookProtection');
160 2
            $objWriter->writeAttribute('lockRevision', ($spreadsheet->getSecurity()->getLockRevision() ? 'true' : 'false'));
0 ignored issues
show
Bug introduced by
It seems like $spreadsheet is not always an object, but can also be of type null. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
161 2
            $objWriter->writeAttribute('lockStructure', ($spreadsheet->getSecurity()->getLockStructure() ? 'true' : 'false'));
162 2
            $objWriter->writeAttribute('lockWindows', ($spreadsheet->getSecurity()->getLockWindows() ? 'true' : 'false'));
163
164 2
            if ($spreadsheet->getSecurity()->getRevisionsPassword() != '') {
165
                $objWriter->writeAttribute('revisionsPassword', $spreadsheet->getSecurity()->getRevisionsPassword());
166
            }
167
168 2
            if ($spreadsheet->getSecurity()->getWorkbookPassword() != '') {
169 2
                $objWriter->writeAttribute('workbookPassword', $spreadsheet->getSecurity()->getWorkbookPassword());
170
            }
171
172 2
            $objWriter->endElement();
173
        }
174 56
    }
175
176
    /**
177
     * Write calcPr
178
     *
179
     * @param     \PhpOffice\PhpSpreadsheet\Shared\XMLWriter    $objWriter        XML Writer
180
     * @param    bool                        $recalcRequired    Indicate whether formulas should be recalculated before writing
181
     * @throws     \PhpOffice\PhpSpreadsheet\Writer\Exception
182
     */
183 56
    private function writeCalcPr(\PhpOffice\PhpSpreadsheet\Shared\XMLWriter $objWriter, $recalcRequired = true)
184
    {
185 56
        $objWriter->startElement('calcPr');
186
187
        //    Set the calcid to a higher value than Excel itself will use, otherwise Excel will always recalc
188
        //  If MS Excel does do a recalc, then users opening a file in MS Excel will be prompted to save on exit
189
        //     because the file has changed
190 56
        $objWriter->writeAttribute('calcId', '999999');
191 56
        $objWriter->writeAttribute('calcMode', 'auto');
192
        //    fullCalcOnLoad isn't needed if we've recalculating for the save
193 56
        $objWriter->writeAttribute('calcCompleted', ($recalcRequired) ? 1 : 0);
194 56
        $objWriter->writeAttribute('fullCalcOnLoad', ($recalcRequired) ? 0 : 1);
195
196 56
        $objWriter->endElement();
197 56
    }
198
199
    /**
200
     * Write sheets
201
     *
202
     * @param     \PhpOffice\PhpSpreadsheet\Shared\XMLWriter     $objWriter         XML Writer
203
     * @param     \PhpOffice\PhpSpreadsheet\Spreadsheet                    $spreadsheet
204
     * @throws     \PhpOffice\PhpSpreadsheet\Writer\Exception
205
     */
206 56
    private function writeSheets(\PhpOffice\PhpSpreadsheet\Shared\XMLWriter $objWriter, \PhpOffice\PhpSpreadsheet\SpreadSheet $spreadsheet = null)
207
    {
208
        // Write sheets
209 56
        $objWriter->startElement('sheets');
210 56
        $sheetCount = $spreadsheet->getSheetCount();
0 ignored issues
show
Bug introduced by
It seems like $spreadsheet is not always an object, but can also be of type null. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
211 56
        for ($i = 0; $i < $sheetCount; ++$i) {
212
            // sheet
213 56
            $this->writeSheet(
214
                $objWriter,
215 56
                $spreadsheet->getSheet($i)->getTitle(),
216 56
                ($i + 1),
217 56
                ($i + 1 + 3),
218 56
                $spreadsheet->getSheet($i)->getSheetState()
219
            );
220
        }
221
222 56
        $objWriter->endElement();
223 56
    }
224
225
    /**
226
     * Write sheet
227
     *
228
     * @param     \PhpOffice\PhpSpreadsheet\Shared\XMLWriter     $objWriter         XML Writer
229
     * @param     string                         $pSheetname         Sheet name
230
     * @param     int                            $pSheetId             Sheet id
231
     * @param     int                            $pRelId                Relationship ID
232
     * @param   string                      $sheetState         Sheet state (visible, hidden, veryHidden)
233
     * @throws     \PhpOffice\PhpSpreadsheet\Writer\Exception
234
     */
235 56 View Code Duplication
    private function writeSheet(\PhpOffice\PhpSpreadsheet\Shared\XMLWriter $objWriter, $pSheetname = '', $pSheetId = 1, $pRelId = 1, $sheetState = 'visible')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
236
    {
237 56
        if ($pSheetname != '') {
238
            // Write sheet
239 56
            $objWriter->startElement('sheet');
240 56
            $objWriter->writeAttribute('name', $pSheetname);
241 56
            $objWriter->writeAttribute('sheetId', $pSheetId);
242 56
            if ($sheetState != 'visible' && $sheetState != '') {
243
                $objWriter->writeAttribute('state', $sheetState);
244
            }
245 56
            $objWriter->writeAttribute('r:id', 'rId' . $pRelId);
246 56
            $objWriter->endElement();
247
        } else {
248
            throw new \PhpOffice\PhpSpreadsheet\Writer\Exception('Invalid parameters passed.');
249
        }
250 56
    }
251
252
    /**
253
     * Write Defined Names
254
     *
255
     * @param     \PhpOffice\PhpSpreadsheet\Shared\XMLWriter    $objWriter         XML Writer
256
     * @param     \PhpOffice\PhpSpreadsheet\Spreadsheet                    $spreadsheet
257
     * @throws     \PhpOffice\PhpSpreadsheet\Writer\Exception
258
     */
259 56
    private function writeDefinedNames(\PhpOffice\PhpSpreadsheet\Shared\XMLWriter $objWriter, \PhpOffice\PhpSpreadsheet\SpreadSheet $spreadsheet = null)
260
    {
261
        // Write defined names
262 56
        $objWriter->startElement('definedNames');
263
264
        // Named ranges
265 56
        if (count($spreadsheet->getNamedRanges()) > 0) {
0 ignored issues
show
Bug introduced by
It seems like $spreadsheet is not always an object, but can also be of type null. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
266
            // Named ranges
267 4
            $this->writeNamedRanges($objWriter, $spreadsheet);
0 ignored issues
show
Bug introduced by
It seems like $spreadsheet defined by parameter $spreadsheet on line 259 can be null; however, PhpOffice\PhpSpreadsheet...ook::writeNamedRanges() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
268
        }
269
270
        // Other defined names
271 56
        $sheetCount = $spreadsheet->getSheetCount();
272 56
        for ($i = 0; $i < $sheetCount; ++$i) {
273
            // definedName for autoFilter
274 56
            $this->writeDefinedNameForAutofilter($objWriter, $spreadsheet->getSheet($i), $i);
275
276
            // definedName for Print_Titles
277 56
            $this->writeDefinedNameForPrintTitles($objWriter, $spreadsheet->getSheet($i), $i);
278
279
            // definedName for Print_Area
280 56
            $this->writeDefinedNameForPrintArea($objWriter, $spreadsheet->getSheet($i), $i);
281
        }
282
283 56
        $objWriter->endElement();
284 56
    }
285
286
    /**
287
     * Write named ranges
288
     *
289
     * @param     \PhpOffice\PhpSpreadsheet\Shared\XMLWriter    $objWriter         XML Writer
290
     * @param \PhpOffice\PhpSpreadsheet\SpreadSheet $spreadsheet
291
     * @throws     \PhpOffice\PhpSpreadsheet\Writer\Exception
292
     */
293 4
    private function writeNamedRanges(\PhpOffice\PhpSpreadsheet\Shared\XMLWriter $objWriter, \PhpOffice\PhpSpreadsheet\SpreadSheet $spreadsheet)
294
    {
295
        // Loop named ranges
296 4
        $namedRanges = $spreadsheet->getNamedRanges();
297 4
        foreach ($namedRanges as $namedRange) {
298 4
            $this->writeDefinedNameForNamedRange($objWriter, $namedRange);
299
        }
300 4
    }
301
302
    /**
303
     * Write Defined Name for named range
304
     *
305
     * @param     \PhpOffice\PhpSpreadsheet\Shared\XMLWriter    $objWriter         XML Writer
306
     * @param     \PhpOffice\PhpSpreadsheet\NamedRange            $pNamedRange
307
     * @throws     \PhpOffice\PhpSpreadsheet\Writer\Exception
308
     */
309 4
    private function writeDefinedNameForNamedRange(\PhpOffice\PhpSpreadsheet\Shared\XMLWriter $objWriter, \PhpOffice\PhpSpreadsheet\NamedRange $pNamedRange)
310
    {
311
        // definedName for named range
312 4
        $objWriter->startElement('definedName');
313 4
        $objWriter->writeAttribute('name', $pNamedRange->getName());
314 4
        if ($pNamedRange->getLocalOnly()) {
315
            $objWriter->writeAttribute('localSheetId', $pNamedRange->getScope()->getParent()->getIndex($pNamedRange->getScope()));
316
        }
317
318
        // Create absolute coordinate and write as raw text
319 4
        $range = \PhpOffice\PhpSpreadsheet\Cell::splitRange($pNamedRange->getRange());
320 4 View Code Duplication
        for ($i = 0; $i < count($range); ++$i) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
321 4
            $range[$i][0] = '\'' . str_replace("'", "''", $pNamedRange->getWorksheet()->getTitle()) . '\'!' . \PhpOffice\PhpSpreadsheet\Cell::absoluteReference($range[$i][0]);
322 4
            if (isset($range[$i][1])) {
323 3
                $range[$i][1] = \PhpOffice\PhpSpreadsheet\Cell::absoluteReference($range[$i][1]);
324
            }
325
        }
326 4
        $range = \PhpOffice\PhpSpreadsheet\Cell::buildRange($range);
327
328 4
        $objWriter->writeRawData($range);
329
330 4
        $objWriter->endElement();
331 4
    }
332
333
    /**
334
     * Write Defined Name for autoFilter
335
     *
336
     * @param     \PhpOffice\PhpSpreadsheet\Shared\XMLWriter    $objWriter         XML Writer
337
     * @param     \PhpOffice\PhpSpreadsheet\Worksheet            $pSheet
338
     * @param     int                            $pSheetId
339
     * @throws     \PhpOffice\PhpSpreadsheet\Writer\Exception
340
     */
341 56
    private function writeDefinedNameForAutofilter(\PhpOffice\PhpSpreadsheet\Shared\XMLWriter $objWriter, \PhpOffice\PhpSpreadsheet\Worksheet $pSheet = null, $pSheetId = 0)
342
    {
343
        // definedName for autoFilter
344 56
        $autoFilterRange = $pSheet->getAutoFilter()->getRange();
0 ignored issues
show
Bug introduced by
It seems like $pSheet is not always an object, but can also be of type null. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
345 56
        if (!empty($autoFilterRange)) {
346 3
            $objWriter->startElement('definedName');
347 3
            $objWriter->writeAttribute('name', '_xlnm._FilterDatabase');
348 3
            $objWriter->writeAttribute('localSheetId', $pSheetId);
349 3
            $objWriter->writeAttribute('hidden', '1');
350
351
            // Create absolute coordinate and write as raw text
352 3
            $range = \PhpOffice\PhpSpreadsheet\Cell::splitRange($autoFilterRange);
353 3
            $range = $range[0];
354
            //    Strip any worksheet ref so we can make the cell ref absolute
355 3 View Code Duplication
            if (strpos($range[0], '!') !== false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
356
                list($ws, $range[0]) = explode('!', $range[0]);
0 ignored issues
show
Unused Code introduced by
The assignment to $ws is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
357
            }
358
359 3
            $range[0] = \PhpOffice\PhpSpreadsheet\Cell::absoluteCoordinate($range[0]);
360 3
            $range[1] = \PhpOffice\PhpSpreadsheet\Cell::absoluteCoordinate($range[1]);
361 3
            $range = implode(':', $range);
362
363 3
            $objWriter->writeRawData('\'' . str_replace("'", "''", $pSheet->getTitle()) . '\'!' . $range);
364
365 3
            $objWriter->endElement();
366
        }
367 56
    }
368
369
    /**
370
     * Write Defined Name for PrintTitles
371
     *
372
     * @param     \PhpOffice\PhpSpreadsheet\Shared\XMLWriter    $objWriter         XML Writer
373
     * @param     \PhpOffice\PhpSpreadsheet\Worksheet            $pSheet
374
     * @param     int                            $pSheetId
375
     * @throws     \PhpOffice\PhpSpreadsheet\Writer\Exception
376
     */
377 56
    private function writeDefinedNameForPrintTitles(\PhpOffice\PhpSpreadsheet\Shared\XMLWriter $objWriter, \PhpOffice\PhpSpreadsheet\Worksheet $pSheet = null, $pSheetId = 0)
378
    {
379
        // definedName for PrintTitles
380 56
        if ($pSheet->getPageSetup()->isColumnsToRepeatAtLeftSet() || $pSheet->getPageSetup()->isRowsToRepeatAtTopSet()) {
381 1
            $objWriter->startElement('definedName');
382 1
            $objWriter->writeAttribute('name', '_xlnm.Print_Titles');
383 1
            $objWriter->writeAttribute('localSheetId', $pSheetId);
384
385
            // Setting string
386 1
            $settingString = '';
387
388
            // Columns to repeat
389 1
            if ($pSheet->getPageSetup()->isColumnsToRepeatAtLeftSet()) {
390
                $repeat = $pSheet->getPageSetup()->getColumnsToRepeatAtLeft();
0 ignored issues
show
Bug introduced by
It seems like $pSheet is not always an object, but can also be of type null. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
391
392
                $settingString .= '\'' . str_replace("'", "''", $pSheet->getTitle()) . '\'!$' . $repeat[0] . ':$' . $repeat[1];
393
            }
394
395
            // Rows to repeat
396 1
            if ($pSheet->getPageSetup()->isRowsToRepeatAtTopSet()) {
397 1
                if ($pSheet->getPageSetup()->isColumnsToRepeatAtLeftSet()) {
398
                    $settingString .= ',';
399
                }
400
401 1
                $repeat = $pSheet->getPageSetup()->getRowsToRepeatAtTop();
402
403 1
                $settingString .= '\'' . str_replace("'", "''", $pSheet->getTitle()) . '\'!$' . $repeat[0] . ':$' . $repeat[1];
404
            }
405
406 1
            $objWriter->writeRawData($settingString);
407
408 1
            $objWriter->endElement();
409
        }
410 56
    }
411
412
    /**
413
     * Write Defined Name for PrintTitles
414
     *
415
     * @param     \PhpOffice\PhpSpreadsheet\Shared\XMLWriter    $objWriter         XML Writer
416
     * @param     \PhpOffice\PhpSpreadsheet\Worksheet            $pSheet
417
     * @param     int                            $pSheetId
418
     * @throws     \PhpOffice\PhpSpreadsheet\Writer\Exception
419
     */
420 56
    private function writeDefinedNameForPrintArea(\PhpOffice\PhpSpreadsheet\Shared\XMLWriter $objWriter, \PhpOffice\PhpSpreadsheet\Worksheet $pSheet = null, $pSheetId = 0)
421
    {
422
        // definedName for PrintArea
423 56
        if ($pSheet->getPageSetup()->isPrintAreaSet()) {
424
            $objWriter->startElement('definedName');
425
            $objWriter->writeAttribute('name', '_xlnm.Print_Area');
426
            $objWriter->writeAttribute('localSheetId', $pSheetId);
427
428
            // Setting string
429
            $settingString = '';
0 ignored issues
show
Unused Code introduced by
$settingString is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
430
431
            // Print area
432
            $printArea = \PhpOffice\PhpSpreadsheet\Cell::splitRange($pSheet->getPageSetup()->getPrintArea());
0 ignored issues
show
Bug introduced by
It seems like $pSheet is not always an object, but can also be of type null. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
433
434
            $chunks = [];
435
            foreach ($printArea as $printAreaRect) {
436
                $printAreaRect[0] = \PhpOffice\PhpSpreadsheet\Cell::absoluteReference($printAreaRect[0]);
437
                $printAreaRect[1] = \PhpOffice\PhpSpreadsheet\Cell::absoluteReference($printAreaRect[1]);
438
                $chunks[] = '\'' . str_replace("'", "''", $pSheet->getTitle()) . '\'!' . implode(':', $printAreaRect);
439
            }
440
441
            $objWriter->writeRawData(implode(',', $chunks));
442
443
            $objWriter->endElement();
444
        }
445 56
    }
446
}
447