Completed
Push — develop ( 91417a...f02c33 )
by Adrien
18:11
created

Rels::writeHeaderFooterDrawingRelationships()   B

Complexity

Conditions 3
Paths 4

Size

Total Lines 32
Code Lines 17

Duplication

Lines 5
Ratio 15.63 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 17
c 1
b 0
f 0
nc 4
nop 1
dl 5
loc 32
ccs 0
cts 22
cp 0
crap 12
rs 8.8571
1
<?php
2
3
namespace PhpSpreadsheet\Writer\Excel2007;
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 Rels extends WriterPart
28
{
29
    /**
30
     * Write relationships to XML format
31
     *
32
     * @param \PhpSpreadsheet\SpreadSheet $spreadsheet
33
     * @throws     \PhpSpreadsheet\Writer\Exception
34
     * @return string  XML Output
35
     */
36
    public function writeRelationships(\PhpSpreadsheet\SpreadSheet $spreadsheet = null)
37
    {
38
        // Create XML writer
39
        $objWriter = null;
0 ignored issues
show
Unused Code introduced by
$objWriter 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...
40 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 PhpSpreadsheet\Writer\IWriter as the method getUseDiskCaching() does only exist in the following implementations of said interface: PhpSpreadsheet\Writer\BaseWriter, PhpSpreadsheet\Writer\CSV, PhpSpreadsheet\Writer\Excel2007, PhpSpreadsheet\Writer\Excel5, PhpSpreadsheet\Writer\HTML, PhpSpreadsheet\Writer\OpenDocument, PhpSpreadsheet\Writer\PDF\Core, PhpSpreadsheet\Writer\PDF\DomPDF, PhpSpreadsheet\Writer\PDF\MPDF, PhpSpreadsheet\Writer\PDF\TcPDF.

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 \PhpSpreadsheet\Shared\XMLWriter(\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 PhpSpreadsheet\Writer\IWriter as the method getDiskCachingDirectory() does only exist in the following implementations of said interface: PhpSpreadsheet\Writer\BaseWriter, PhpSpreadsheet\Writer\CSV, PhpSpreadsheet\Writer\Excel2007, PhpSpreadsheet\Writer\Excel5, PhpSpreadsheet\Writer\HTML, PhpSpreadsheet\Writer\OpenDocument, PhpSpreadsheet\Writer\PDF\Core, PhpSpreadsheet\Writer\PDF\DomPDF, PhpSpreadsheet\Writer\PDF\MPDF, PhpSpreadsheet\Writer\PDF\TcPDF.

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
            $objWriter = new \PhpSpreadsheet\Shared\XMLWriter(\PhpSpreadsheet\Shared\XMLWriter::STORAGE_MEMORY);
44
        }
45
46
        // XML header
47
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
48
49
        // Relationships
50
        $objWriter->startElement('Relationships');
51
        $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
52
53
        $customPropertyList = $spreadsheet->getProperties()->getCustomProperties();
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...
54
        if (!empty($customPropertyList)) {
55
            // Relationship docProps/app.xml
56
            $this->writeRelationship(
57
                $objWriter,
58
                4,
59
                'http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties',
60
                'docProps/custom.xml'
61
            );
62
        }
63
64
        // Relationship docProps/app.xml
65
        $this->writeRelationship(
66
            $objWriter,
67
            3,
68
            'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties',
69
            'docProps/app.xml'
70
        );
71
72
        // Relationship docProps/core.xml
73
        $this->writeRelationship(
74
            $objWriter,
75
            2,
76
            'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties',
77
            'docProps/core.xml'
78
        );
79
80
        // Relationship xl/workbook.xml
81
        $this->writeRelationship(
82
            $objWriter,
83
            1,
84
            'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument',
85
            'xl/workbook.xml'
86
        );
87
        // a custom UI in workbook ?
88
        if ($spreadsheet->hasRibbon()) {
89
            $this->writeRelationShip(
90
                $objWriter,
91
                5,
92
                'http://schemas.microsoft.com/office/2006/relationships/ui/extensibility',
93
                $spreadsheet->getRibbonXMLData('target')
94
            );
95
        }
96
97
        $objWriter->endElement();
98
99
        return $objWriter->getData();
100
    }
101
102
    /**
103
     * Write workbook relationships to XML format
104
     *
105
     * @param \PhpSpreadsheet\SpreadSheet $spreadsheet
106
     * @throws     \PhpSpreadsheet\Writer\Exception
107
     * @return string  XML Output
108
     */
109
    public function writeWorkbookRelationships(\PhpSpreadsheet\SpreadSheet $spreadsheet = null)
110
    {
111
        // Create XML writer
112
        $objWriter = null;
0 ignored issues
show
Unused Code introduced by
$objWriter 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...
113 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 PhpSpreadsheet\Writer\IWriter as the method getUseDiskCaching() does only exist in the following implementations of said interface: PhpSpreadsheet\Writer\BaseWriter, PhpSpreadsheet\Writer\CSV, PhpSpreadsheet\Writer\Excel2007, PhpSpreadsheet\Writer\Excel5, PhpSpreadsheet\Writer\HTML, PhpSpreadsheet\Writer\OpenDocument, PhpSpreadsheet\Writer\PDF\Core, PhpSpreadsheet\Writer\PDF\DomPDF, PhpSpreadsheet\Writer\PDF\MPDF, PhpSpreadsheet\Writer\PDF\TcPDF.

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...
114
            $objWriter = new \PhpSpreadsheet\Shared\XMLWriter(\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 PhpSpreadsheet\Writer\IWriter as the method getDiskCachingDirectory() does only exist in the following implementations of said interface: PhpSpreadsheet\Writer\BaseWriter, PhpSpreadsheet\Writer\CSV, PhpSpreadsheet\Writer\Excel2007, PhpSpreadsheet\Writer\Excel5, PhpSpreadsheet\Writer\HTML, PhpSpreadsheet\Writer\OpenDocument, PhpSpreadsheet\Writer\PDF\Core, PhpSpreadsheet\Writer\PDF\DomPDF, PhpSpreadsheet\Writer\PDF\MPDF, PhpSpreadsheet\Writer\PDF\TcPDF.

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...
115
        } else {
116
            $objWriter = new \PhpSpreadsheet\Shared\XMLWriter(\PhpSpreadsheet\Shared\XMLWriter::STORAGE_MEMORY);
117
        }
118
119
        // XML header
120
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
121
122
        // Relationships
123
        $objWriter->startElement('Relationships');
124
        $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
125
126
        // Relationship styles.xml
127
        $this->writeRelationship(
128
            $objWriter,
129
            1,
130
            'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles',
131
            'styles.xml'
132
        );
133
134
        // Relationship theme/theme1.xml
135
        $this->writeRelationship(
136
            $objWriter,
137
            2,
138
            'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme',
139
            'theme/theme1.xml'
140
        );
141
142
        // Relationship sharedStrings.xml
143
        $this->writeRelationship(
144
            $objWriter,
145
            3,
146
            'http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings',
147
            'sharedStrings.xml'
148
        );
149
150
        // Relationships with sheets
151
        $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...
152
        for ($i = 0; $i < $sheetCount; ++$i) {
153
            $this->writeRelationship(
154
                $objWriter,
155
                ($i + 1 + 3),
156
                'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet',
157
                'worksheets/sheet' . ($i + 1) . '.xml'
158
            );
159
        }
160
        // Relationships for vbaProject if needed
161
        // id : just after the last sheet
162
        if ($spreadsheet->hasMacros()) {
163
            $this->writeRelationShip(
164
                $objWriter,
165
                ($i + 1 + 3),
166
                'http://schemas.microsoft.com/office/2006/relationships/vbaProject',
167
                'vbaProject.bin'
168
            );
169
            ++$i; //increment i if needed for an another relation
170
        }
171
172
        $objWriter->endElement();
173
174
        return $objWriter->getData();
175
    }
176
177
    /**
178
     * Write worksheet relationships to XML format
179
     *
180
     * Numbering is as follows:
181
     *     rId1                 - Drawings
182
     *  rId_hyperlink_x     - Hyperlinks
183
     *
184
     * @param     \PhpSpreadsheet\Worksheet    $pWorksheet
185
     * @param     int                    $pWorksheetId
186
     * @param    bool                $includeCharts    Flag indicating if we should write charts
187
     * @throws     \PhpSpreadsheet\Writer\Exception
188
     * @return string          XML Output
189
     */
190
    public function writeWorksheetRelationships(\PhpSpreadsheet\Worksheet $pWorksheet = null, $pWorksheetId = 1, $includeCharts = false)
191
    {
192
        // Create XML writer
193
        $objWriter = null;
0 ignored issues
show
Unused Code introduced by
$objWriter 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...
194 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 PhpSpreadsheet\Writer\IWriter as the method getUseDiskCaching() does only exist in the following implementations of said interface: PhpSpreadsheet\Writer\BaseWriter, PhpSpreadsheet\Writer\CSV, PhpSpreadsheet\Writer\Excel2007, PhpSpreadsheet\Writer\Excel5, PhpSpreadsheet\Writer\HTML, PhpSpreadsheet\Writer\OpenDocument, PhpSpreadsheet\Writer\PDF\Core, PhpSpreadsheet\Writer\PDF\DomPDF, PhpSpreadsheet\Writer\PDF\MPDF, PhpSpreadsheet\Writer\PDF\TcPDF.

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...
195
            $objWriter = new \PhpSpreadsheet\Shared\XMLWriter(\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 PhpSpreadsheet\Writer\IWriter as the method getDiskCachingDirectory() does only exist in the following implementations of said interface: PhpSpreadsheet\Writer\BaseWriter, PhpSpreadsheet\Writer\CSV, PhpSpreadsheet\Writer\Excel2007, PhpSpreadsheet\Writer\Excel5, PhpSpreadsheet\Writer\HTML, PhpSpreadsheet\Writer\OpenDocument, PhpSpreadsheet\Writer\PDF\Core, PhpSpreadsheet\Writer\PDF\DomPDF, PhpSpreadsheet\Writer\PDF\MPDF, PhpSpreadsheet\Writer\PDF\TcPDF.

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...
196
        } else {
197
            $objWriter = new \PhpSpreadsheet\Shared\XMLWriter(\PhpSpreadsheet\Shared\XMLWriter::STORAGE_MEMORY);
198
        }
199
200
        // XML header
201
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
202
203
        // Relationships
204
        $objWriter->startElement('Relationships');
205
        $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
206
207
        // Write drawing relationships?
208
        $d = 0;
209
        if ($includeCharts) {
210
            $charts = $pWorksheet->getChartCollection();
0 ignored issues
show
Bug introduced by
It seems like $pWorksheet 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
        } else {
212
            $charts = [];
213
        }
214
        if (($pWorksheet->getDrawingCollection()->count() > 0) ||
215
            (count($charts) > 0)) {
216
            $this->writeRelationship(
217
                $objWriter,
218
                ++$d,
219
                'http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing',
220
                '../drawings/drawing' . $pWorksheetId . '.xml'
221
            );
222
        }
223
224
        // Write hyperlink relationships?
225
        $i = 1;
226
        foreach ($pWorksheet->getHyperlinkCollection() as $hyperlink) {
227
            if (!$hyperlink->isInternal()) {
228
                $this->writeRelationship(
229
                    $objWriter,
230
                    '_hyperlink_' . $i,
231
                    'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink',
232
                    $hyperlink->getUrl(),
233
                    'External'
234
                );
235
236
                ++$i;
237
            }
238
        }
239
240
        // Write comments relationship?
241
        $i = 1;
242
        if (count($pWorksheet->getComments()) > 0) {
243
            $this->writeRelationship(
244
                $objWriter,
245
                '_comments_vml' . $i,
246
                'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing',
247
                '../drawings/vmlDrawing' . $pWorksheetId . '.vml'
248
            );
249
250
            $this->writeRelationship(
251
                $objWriter,
252
                '_comments' . $i,
253
                'http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments',
254
                '../comments' . $pWorksheetId . '.xml'
255
            );
256
        }
257
258
        // Write header/footer relationship?
259
        $i = 1;
260
        if (count($pWorksheet->getHeaderFooter()->getImages()) > 0) {
261
            $this->writeRelationship(
262
                $objWriter,
263
                '_headerfooter_vml' . $i,
264
                'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing',
265
                '../drawings/vmlDrawingHF' . $pWorksheetId . '.vml'
266
            );
267
        }
268
269
        $objWriter->endElement();
270
271
        return $objWriter->getData();
272
    }
273
274
    /**
275
     * Write drawing relationships to XML format
276
     *
277
     * @param     \PhpSpreadsheet\Worksheet    $pWorksheet
278
     * @param    int                    &$chartRef        Chart ID
279
     * @param    bool                $includeCharts    Flag indicating if we should write charts
280
     * @throws     \PhpSpreadsheet\Writer\Exception
281
     * @return string          XML Output
282
     */
283
    public function writeDrawingRelationships(\PhpSpreadsheet\Worksheet $pWorksheet, &$chartRef, $includeCharts = false)
284
    {
285
        // Create XML writer
286
        $objWriter = null;
0 ignored issues
show
Unused Code introduced by
$objWriter 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...
287 View Code Duplication
        if ($this->getParentWriter()->getUseDiskCaching()) {
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface PhpSpreadsheet\Writer\IWriter as the method getUseDiskCaching() does only exist in the following implementations of said interface: PhpSpreadsheet\Writer\BaseWriter, PhpSpreadsheet\Writer\CSV, PhpSpreadsheet\Writer\Excel2007, PhpSpreadsheet\Writer\Excel5, PhpSpreadsheet\Writer\HTML, PhpSpreadsheet\Writer\OpenDocument, PhpSpreadsheet\Writer\PDF\Core, PhpSpreadsheet\Writer\PDF\DomPDF, PhpSpreadsheet\Writer\PDF\MPDF, PhpSpreadsheet\Writer\PDF\TcPDF.

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...
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...
288
            $objWriter = new \PhpSpreadsheet\Shared\XMLWriter(\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 PhpSpreadsheet\Writer\IWriter as the method getDiskCachingDirectory() does only exist in the following implementations of said interface: PhpSpreadsheet\Writer\BaseWriter, PhpSpreadsheet\Writer\CSV, PhpSpreadsheet\Writer\Excel2007, PhpSpreadsheet\Writer\Excel5, PhpSpreadsheet\Writer\HTML, PhpSpreadsheet\Writer\OpenDocument, PhpSpreadsheet\Writer\PDF\Core, PhpSpreadsheet\Writer\PDF\DomPDF, PhpSpreadsheet\Writer\PDF\MPDF, PhpSpreadsheet\Writer\PDF\TcPDF.

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...
289
        } else {
290
            $objWriter = new \PhpSpreadsheet\Shared\XMLWriter(\PhpSpreadsheet\Shared\XMLWriter::STORAGE_MEMORY);
291
        }
292
293
        // XML header
294
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
295
296
        // Relationships
297
        $objWriter->startElement('Relationships');
298
        $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
299
300
        // Loop through images and write relationships
301
        $i = 1;
302
        $iterator = $pWorksheet->getDrawingCollection()->getIterator();
0 ignored issues
show
Bug introduced by
The method getIterator cannot be called on $pWorksheet->getDrawingCollection() (of type array<integer,object<Php...Worksheet\BaseDrawing>>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
303
        while ($iterator->valid()) {
304
            if ($iterator->current() instanceof \PhpSpreadsheet\Worksheet\Drawing
305
                || $iterator->current() instanceof \PhpSpreadsheet\Worksheet\MemoryDrawing) {
306
                // Write relationship for image drawing
307
                $this->writeRelationship(
308
                    $objWriter,
309
                    $i,
310
                    'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image',
311
                    '../media/' . str_replace(' ', '', $iterator->current()->getIndexedFilename())
312
                );
313
            }
314
315
            $iterator->next();
316
            ++$i;
317
        }
318
319
        if ($includeCharts) {
320
            // Loop through charts and write relationships
321
            $chartCount = $pWorksheet->getChartCount();
322
            if ($chartCount > 0) {
323
                for ($c = 0; $c < $chartCount; ++$c) {
324
                    $this->writeRelationship(
325
                        $objWriter,
326
                        $i++,
327
                        'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart',
328
                        '../charts/chart' . ++$chartRef . '.xml'
329
                    );
330
                }
331
            }
332
        }
333
334
        $objWriter->endElement();
335
336
        return $objWriter->getData();
337
    }
338
339
    /**
340
     * Write header/footer drawing relationships to XML format
341
     *
342
     * @param     \PhpSpreadsheet\Worksheet            $pWorksheet
343
     * @throws     \PhpSpreadsheet\Writer\Exception
344
     * @return string                  XML Output
345
     */
346
    public function writeHeaderFooterDrawingRelationships(\PhpSpreadsheet\Worksheet $pWorksheet = null)
347
    {
348
        // Create XML writer
349
        $objWriter = null;
0 ignored issues
show
Unused Code introduced by
$objWriter 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...
350 View Code Duplication
        if ($this->getParentWriter()->getUseDiskCaching()) {
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface PhpSpreadsheet\Writer\IWriter as the method getUseDiskCaching() does only exist in the following implementations of said interface: PhpSpreadsheet\Writer\BaseWriter, PhpSpreadsheet\Writer\CSV, PhpSpreadsheet\Writer\Excel2007, PhpSpreadsheet\Writer\Excel5, PhpSpreadsheet\Writer\HTML, PhpSpreadsheet\Writer\OpenDocument, PhpSpreadsheet\Writer\PDF\Core, PhpSpreadsheet\Writer\PDF\DomPDF, PhpSpreadsheet\Writer\PDF\MPDF, PhpSpreadsheet\Writer\PDF\TcPDF.

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...
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...
351
            $objWriter = new \PhpSpreadsheet\Shared\XMLWriter(\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 PhpSpreadsheet\Writer\IWriter as the method getDiskCachingDirectory() does only exist in the following implementations of said interface: PhpSpreadsheet\Writer\BaseWriter, PhpSpreadsheet\Writer\CSV, PhpSpreadsheet\Writer\Excel2007, PhpSpreadsheet\Writer\Excel5, PhpSpreadsheet\Writer\HTML, PhpSpreadsheet\Writer\OpenDocument, PhpSpreadsheet\Writer\PDF\Core, PhpSpreadsheet\Writer\PDF\DomPDF, PhpSpreadsheet\Writer\PDF\MPDF, PhpSpreadsheet\Writer\PDF\TcPDF.

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...
352
        } else {
353
            $objWriter = new \PhpSpreadsheet\Shared\XMLWriter(\PhpSpreadsheet\Shared\XMLWriter::STORAGE_MEMORY);
354
        }
355
356
        // XML header
357
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
358
359
        // Relationships
360
        $objWriter->startElement('Relationships');
361
        $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');
362
363
        // Loop through images and write relationships
364
        foreach ($pWorksheet->getHeaderFooter()->getImages() as $key => $value) {
0 ignored issues
show
Bug introduced by
It seems like $pWorksheet 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...
365
            // Write relationship for image drawing
366
            $this->writeRelationship(
367
                $objWriter,
368
                $key,
369
                'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image',
370
                '../media/' . $value->getIndexedFilename()
371
            );
372
        }
373
374
        $objWriter->endElement();
375
376
        return $objWriter->getData();
377
    }
378
379
    /**
380
     * Write Override content type
381
     *
382
     * @param     \PhpSpreadsheet\Shared\XMLWriter     $objWriter         XML Writer
383
     * @param     int                            $pId            Relationship ID. rId will be prepended!
384
     * @param     string                        $pType            Relationship type
385
     * @param     string                         $pTarget        Relationship target
386
     * @param     string                         $pTargetMode    Relationship target mode
387
     * @throws     \PhpSpreadsheet\Writer\Exception
388
     */
389 View Code Duplication
    private function writeRelationship(\PhpSpreadsheet\Shared\XMLWriter $objWriter = null, $pId = 1, $pType = '', $pTarget = '', $pTargetMode = '')
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...
390
    {
391
        if ($pType != '' && $pTarget != '') {
392
            // Write relationship
393
            $objWriter->startElement('Relationship');
0 ignored issues
show
Bug introduced by
It seems like $objWriter 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...
394
            $objWriter->writeAttribute('Id', 'rId' . $pId);
395
            $objWriter->writeAttribute('Type', $pType);
396
            $objWriter->writeAttribute('Target', $pTarget);
397
398
            if ($pTargetMode != '') {
399
                $objWriter->writeAttribute('TargetMode', $pTargetMode);
400
            }
401
402
            $objWriter->endElement();
403
        } else {
404
            throw new \PhpSpreadsheet\Writer\Exception('Invalid parameters passed.');
405
        }
406
    }
407
}
408