Completed
Push — develop ( 3560f1...5fce89 )
by Adrien
21:58 queued 15:06
created

Content::writeCellSpan()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 8

Duplication

Lines 7
Ratio 63.64 %

Code Coverage

Tests 5
CRAP Score 3.7898

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 3
nop 3
dl 7
loc 11
ccs 5
cts 9
cp 0.5556
crap 3.7898
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Writer\Ods;
4
5
/*
6
 * PhpSpreadsheet.
7
 *
8
 * Copyright (c) 2006 - 2015 PhpSpreadsheet
9
 *
10
 * This library is free software; you can redistribute it and/or
11
 * modify it under the terms of the GNU Lesser General Public
12
 * License as published by the Free Software Foundation; either
13
 * version 2.1 of the License, or (at your option) any later version.
14
 *
15
 * This library is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18
 * Lesser General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Lesser General Public
21
 * License along with this library; if not, write to the Free Software
22
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23
 *
24
 * @category   PhpSpreadsheet
25
 *
26
 * @copyright  Copyright (c) 2006 - 2015 PhpSpreadsheet (https://github.com/PHPOffice/PhpSpreadsheet)
27
 * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
28
 */
29
30
use PhpOffice\PhpSpreadsheet\Cell;
31
use PhpOffice\PhpSpreadsheet\Cell\DataType;
32
use PhpOffice\PhpSpreadsheet\Shared\XMLWriter;
33
use PhpOffice\PhpSpreadsheet\Spreadsheet;
34
use PhpOffice\PhpSpreadsheet\Style\Fill;
35
use PhpOffice\PhpSpreadsheet\Style\Font;
36
use PhpOffice\PhpSpreadsheet\Worksheet;
37
use PhpOffice\PhpSpreadsheet\Writer\Exception;
38
use PhpOffice\PhpSpreadsheet\Writer\Ods;
39
use PhpOffice\PhpSpreadsheet\Writer\Ods\Cell\Comment;
40
41
/**
42
 * @category   PhpSpreadsheet
43
 *
44
 * @method Ods getParentWriter
45
 *
46
 * @copyright  Copyright (c) 2006 - 2015 PhpSpreadsheet (https://github.com/PHPOffice/PhpSpreadsheet)
47
 * @author     Alexander Pervakov <[email protected]>
48
 */
49
class Content extends WriterPart
50
{
51
    const NUMBER_COLS_REPEATED_MAX = 1024;
52
    const NUMBER_ROWS_REPEATED_MAX = 1048576;
53
    const CELL_STYLE_PREFIX = 'ce';
54
55
    /**
56
     * Write content.xml to XML format.
57
     *
58
     * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
59
     *
60
     * @return string XML Output
61
     */
62 2
    public function write()
63
    {
64 2
        $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...
65 2 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 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\Html, PhpOffice\PhpSpreadsheet\Writer\Ods, PhpOffice\PhpSpreadsheet\Writer\Pdf\Core, PhpOffice\PhpSpreadsheet\Writer\Pdf\DomPDF, PhpOffice\PhpSpreadsheet\Writer\Pdf\MPDF, PhpOffice\PhpSpreadsheet\Writer\Pdf\TcPDF, PhpOffice\PhpSpreadsheet\Writer\Xls, 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...
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...
66
            $objWriter = new XMLWriter(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\Html, PhpOffice\PhpSpreadsheet\Writer\Ods, PhpOffice\PhpSpreadsheet\Writer\Pdf\Core, PhpOffice\PhpSpreadsheet\Writer\Pdf\DomPDF, PhpOffice\PhpSpreadsheet\Writer\Pdf\MPDF, PhpOffice\PhpSpreadsheet\Writer\Pdf\TcPDF, PhpOffice\PhpSpreadsheet\Writer\Xls, 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...
67
        } else {
68 2
            $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
69
        }
70
71
        // XML header
72 2
        $objWriter->startDocument('1.0', 'UTF-8');
73
74
        // Content
75 2
        $objWriter->startElement('office:document-content');
76 2
        $objWriter->writeAttribute('xmlns:office', 'urn:oasis:names:tc:opendocument:xmlns:office:1.0');
77 2
        $objWriter->writeAttribute('xmlns:style', 'urn:oasis:names:tc:opendocument:xmlns:style:1.0');
78 2
        $objWriter->writeAttribute('xmlns:text', 'urn:oasis:names:tc:opendocument:xmlns:text:1.0');
79 2
        $objWriter->writeAttribute('xmlns:table', 'urn:oasis:names:tc:opendocument:xmlns:table:1.0');
80 2
        $objWriter->writeAttribute('xmlns:draw', 'urn:oasis:names:tc:opendocument:xmlns:drawing:1.0');
81 2
        $objWriter->writeAttribute('xmlns:fo', 'urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0');
82 2
        $objWriter->writeAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
83 2
        $objWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/');
84 2
        $objWriter->writeAttribute('xmlns:meta', 'urn:oasis:names:tc:opendocument:xmlns:meta:1.0');
85 2
        $objWriter->writeAttribute('xmlns:number', 'urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0');
86 2
        $objWriter->writeAttribute('xmlns:presentation', 'urn:oasis:names:tc:opendocument:xmlns:presentation:1.0');
87 2
        $objWriter->writeAttribute('xmlns:svg', 'urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0');
88 2
        $objWriter->writeAttribute('xmlns:chart', 'urn:oasis:names:tc:opendocument:xmlns:chart:1.0');
89 2
        $objWriter->writeAttribute('xmlns:dr3d', 'urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0');
90 2
        $objWriter->writeAttribute('xmlns:math', 'http://www.w3.org/1998/Math/MathML');
91 2
        $objWriter->writeAttribute('xmlns:form', 'urn:oasis:names:tc:opendocument:xmlns:form:1.0');
92 2
        $objWriter->writeAttribute('xmlns:script', 'urn:oasis:names:tc:opendocument:xmlns:script:1.0');
93 2
        $objWriter->writeAttribute('xmlns:ooo', 'http://openoffice.org/2004/office');
94 2
        $objWriter->writeAttribute('xmlns:ooow', 'http://openoffice.org/2004/writer');
95 2
        $objWriter->writeAttribute('xmlns:oooc', 'http://openoffice.org/2004/calc');
96 2
        $objWriter->writeAttribute('xmlns:dom', 'http://www.w3.org/2001/xml-events');
97 2
        $objWriter->writeAttribute('xmlns:xforms', 'http://www.w3.org/2002/xforms');
98 2
        $objWriter->writeAttribute('xmlns:xsd', 'http://www.w3.org/2001/XMLSchema');
99 2
        $objWriter->writeAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
100 2
        $objWriter->writeAttribute('xmlns:rpt', 'http://openoffice.org/2005/report');
101 2
        $objWriter->writeAttribute('xmlns:of', 'urn:oasis:names:tc:opendocument:xmlns:of:1.2');
102 2
        $objWriter->writeAttribute('xmlns:xhtml', 'http://www.w3.org/1999/xhtml');
103 2
        $objWriter->writeAttribute('xmlns:grddl', 'http://www.w3.org/2003/g/data-view#');
104 2
        $objWriter->writeAttribute('xmlns:tableooo', 'http://openoffice.org/2009/table');
105 2
        $objWriter->writeAttribute('xmlns:field', 'urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0');
106 2
        $objWriter->writeAttribute('xmlns:formx', 'urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0');
107 2
        $objWriter->writeAttribute('xmlns:css3t', 'http://www.w3.org/TR/css3-text/');
108 2
        $objWriter->writeAttribute('office:version', '1.2');
109
110 2
        $objWriter->writeElement('office:scripts');
111 2
        $objWriter->writeElement('office:font-face-decls');
112
113
        // Styles XF
114 2
        $objWriter->startElement('office:automatic-styles');
115 2
        $this->writeXfStyles($objWriter, $this->getParentWriter()->getSpreadsheet());
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 getSpreadsheet() does only exist in the following implementations of said interface: PhpOffice\PhpSpreadsheet\Writer\Ods, 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...
116 2
        $objWriter->endElement();
117
118 2
        $objWriter->startElement('office:body');
119 2
        $objWriter->startElement('office:spreadsheet');
120 2
        $objWriter->writeElement('table:calculation-settings');
121
122 2
        $this->writeSheets($objWriter);
123
124 2
        $objWriter->writeElement('table:named-expressions');
125 2
        $objWriter->endElement();
126 2
        $objWriter->endElement();
127 2
        $objWriter->endElement();
128
129 2
        return $objWriter->getData();
130
    }
131
132
    /**
133
     * Write sheets.
134
     *
135
     * @param XMLWriter $objWriter
136
     */
137 2
    private function writeSheets(XMLWriter $objWriter)
138
    {
139 2
        $spreadsheet = $this->getParentWriter()->getSpreadsheet(); /* @var $spreadsheet Spreadsheet */
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 getSpreadsheet() does only exist in the following implementations of said interface: PhpOffice\PhpSpreadsheet\Writer\Ods, 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...
140
141 2
        $sheetCount = $spreadsheet->getSheetCount();
142 2
        for ($i = 0; $i < $sheetCount; ++$i) {
143 2
            $objWriter->startElement('table:table');
144 2
            $objWriter->writeAttribute('table:name', $spreadsheet->getSheet($i)->getTitle());
145 2
            $objWriter->writeElement('office:forms');
146 2
            $objWriter->startElement('table:table-column');
147 2
            $objWriter->writeAttribute('table:number-columns-repeated', self::NUMBER_COLS_REPEATED_MAX);
148 2
            $objWriter->endElement();
149 2
            $this->writeRows($objWriter, $spreadsheet->getSheet($i));
150 2
            $objWriter->endElement();
151
        }
152 2
    }
153
154
    /**
155
     * Write rows of the specified sheet.
156
     *
157
     * @param XMLWriter $objWriter
158
     * @param Worksheet $sheet
159
     */
160 2
    private function writeRows(XMLWriter $objWriter, Worksheet $sheet)
161
    {
162 2
        $numberRowsRepeated = self::NUMBER_ROWS_REPEATED_MAX;
163 2
        $span_row = 0;
164 2
        $rows = $sheet->getRowIterator();
165 2
        while ($rows->valid()) {
166 2
            --$numberRowsRepeated;
167 2
            $row = $rows->current();
168 2
            if ($row->getCellIterator()->valid()) {
169 2
                if ($span_row) {
170
                    $objWriter->startElement('table:table-row');
171
                    if ($span_row > 1) {
172
                        $objWriter->writeAttribute('table:number-rows-repeated', $span_row);
173
                    }
174
                    $objWriter->startElement('table:table-cell');
175
                    $objWriter->writeAttribute('table:number-columns-repeated', self::NUMBER_COLS_REPEATED_MAX);
176
                    $objWriter->endElement();
177
                    $objWriter->endElement();
178
                    $span_row = 0;
179
                }
180 2
                $objWriter->startElement('table:table-row');
181 2
                $this->writeCells($objWriter, $row);
182 2
                $objWriter->endElement();
183
            } else {
184
                ++$span_row;
185
            }
186 2
            $rows->next();
187
        }
188 2
    }
189
190
    /**
191
     * Write cells of the specified row.
192
     *
193
     * @param XMLWriter $objWriter
194
     * @param Worksheet\Row $row
195
     *
196
     * @throws Exception
197
     */
198 2
    private function writeCells(XMLWriter $objWriter, Worksheet\Row $row)
199
    {
200 2
        $numberColsRepeated = self::NUMBER_COLS_REPEATED_MAX;
201 2
        $prevColumn = -1;
202 2
        $cells = $row->getCellIterator();
203 2
        while ($cells->valid()) {
204
            /** @var Cell $cell */
205 2
            $cell = $cells->current();
206 2
            $column = Cell::columnIndexFromString($cell->getColumn()) - 1;
207
208 2
            $this->writeCellSpan($objWriter, $column, $prevColumn);
209 2
            $objWriter->startElement('table:table-cell');
210
211
            // Style XF
212 2
            $style = $cell->getXfIndex();
213 2
            if ($style !== null) {
214 2
                $objWriter->writeAttribute('table:style-name', self::CELL_STYLE_PREFIX . $style);
215
            }
216
217 2
            switch ($cell->getDataType()) {
218 2 View Code Duplication
                case DataType::TYPE_BOOL:
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...
219 1
                    $objWriter->writeAttribute('office:value-type', 'boolean');
220 1
                    $objWriter->writeAttribute('office:value', $cell->getValue());
221 1
                    $objWriter->writeElement('text:p', $cell->getValue());
222 1
                    break;
223 2
                case DataType::TYPE_ERROR:
224
                    throw new Exception('Writing of error not implemented yet.');
225
                    break;
0 ignored issues
show
Unused Code introduced by
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
226 2
                case DataType::TYPE_FORMULA:
227
                    try {
228 1
                        $formulaValue = $cell->getCalculatedValue();
229
                    } catch (\Exception $e) {
230
                        $formulaValue = $cell->getValue();
231
                    }
232 1
                    $objWriter->writeAttribute('table:formula', 'of:' . $cell->getValue());
233 1
                    if (is_numeric($formulaValue)) {
234
                        $objWriter->writeAttribute('office:value-type', 'float');
235
                    } else {
236 1
                        $objWriter->writeAttribute('office:value-type', 'string');
237
                    }
238 1
                    $objWriter->writeAttribute('office:value', $formulaValue);
239 1
                    $objWriter->writeElement('text:p', $formulaValue);
240 1
                    break;
241 2
                case DataType::TYPE_INLINE:
242
                    throw new Exception('Writing of inline not implemented yet.');
243
                    break;
0 ignored issues
show
Unused Code introduced by
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
244 2 View Code Duplication
                case DataType::TYPE_NUMERIC:
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...
245 1
                    $objWriter->writeAttribute('office:value-type', 'float');
246 1
                    $objWriter->writeAttribute('office:value', $cell->getValue());
247 1
                    $objWriter->writeElement('text:p', $cell->getValue());
248 1
                    break;
249 2
                case DataType::TYPE_STRING:
250 1
                    $objWriter->writeAttribute('office:value-type', 'string');
251 1
                    $objWriter->writeElement('text:p', $cell->getValue());
252 1
                    break;
253
            }
254 2
            Comment::write($objWriter, $cell);
255 2
            $objWriter->endElement();
256 2
            $prevColumn = $column;
257 2
            $cells->next();
258
        }
259 2
        $numberColsRepeated = $numberColsRepeated - $prevColumn - 1;
260 2 View Code Duplication
        if ($numberColsRepeated > 0) {
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...
261 2
            if ($numberColsRepeated > 1) {
262 2
                $objWriter->startElement('table:table-cell');
263 2
                $objWriter->writeAttribute('table:number-columns-repeated', $numberColsRepeated);
264 2
                $objWriter->endElement();
265
            } else {
266
                $objWriter->writeElement('table:table-cell');
267
            }
268
        }
269 2
    }
270
271
    /**
272
     * Write span.
273
     *
274
     * @param XMLWriter $objWriter
275
     * @param int $curColumn
276
     * @param int $prevColumn
277
     */
278 2
    private function writeCellSpan(XMLWriter $objWriter, $curColumn, $prevColumn)
279
    {
280 2
        $diff = $curColumn - $prevColumn - 1;
281 2 View Code Duplication
        if (1 === $diff) {
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...
282
            $objWriter->writeElement('table:table-cell');
283 2
        } elseif ($diff > 1) {
284
            $objWriter->startElement('table:table-cell');
285
            $objWriter->writeAttribute('table:number-columns-repeated', $diff);
286
            $objWriter->endElement();
287
        }
288 2
    }
289
290
    /**
291
     * Write XF cell styles.
292
     *
293
     * @param XMLWriter $writer
294
     * @param Spreadsheet $spreadsheet
295
     */
296 2
    private function writeXfStyles(XMLWriter $writer, Spreadsheet $spreadsheet)
297
    {
298 2
        foreach ($spreadsheet->getCellXfCollection() as $style) {
299 2
            $writer->startElement('style:style');
300 2
            $writer->writeAttribute('style:name', self::CELL_STYLE_PREFIX . $style->getIndex());
301 2
            $writer->writeAttribute('style:family', 'table-cell');
302 2
            $writer->writeAttribute('style:parent-style-name', 'Default');
303
304
            /*
305
             * style:text-properties
306
             */
307
308
            // Font
309 2
            $writer->startElement('style:text-properties');
310
311 2
            $font = $style->getFont();
312
313 2
            if ($font->getBold()) {
314 1
                $writer->writeAttribute('fo:font-weight', 'bold');
315 1
                $writer->writeAttribute('style:font-weight-complex', 'bold');
316 1
                $writer->writeAttribute('style:font-weight-asian', 'bold');
317
            }
318
319 2
            if ($font->getItalic()) {
320 1
                $writer->writeAttribute('fo:font-style', 'italic');
321
            }
322
323 2
            if ($color = $font->getColor()) {
324 2
                $writer->writeAttribute('fo:color', sprintf('#%s', $color->getRGB()));
325
            }
326
327 2
            if ($family = $font->getName()) {
328 2
                $writer->writeAttribute('fo:font-family', $family);
329
            }
330
331 2
            if ($size = $font->getSize()) {
332 2
                $writer->writeAttribute('fo:font-size', sprintf('%.1fpt', $size));
333
            }
334
335 2
            if ($font->getUnderline() && $font->getUnderline() != Font::UNDERLINE_NONE) {
336 1
                $writer->writeAttribute('style:text-underline-style', 'solid');
337 1
                $writer->writeAttribute('style:text-underline-width', 'auto');
338 1
                $writer->writeAttribute('style:text-underline-color', 'font-color');
339
340 1
                switch ($font->getUnderline()) {
341 1
                    case Font::UNDERLINE_DOUBLE:
342 1
                        $writer->writeAttribute('style:text-underline-type', 'double');
343 1
                        break;
344 1
                    case Font::UNDERLINE_SINGLE:
345 1
                        $writer->writeAttribute('style:text-underline-type', 'single');
346 1
                        break;
347
                }
348
            }
349
350 2
            $writer->endElement(); // Close style:text-properties
351
352
            /*
353
             * style:table-cell-properties
354
             */
355
356 2
            $writer->startElement('style:table-cell-properties');
357 2
            $writer->writeAttribute('style:rotation-align', 'none');
358
359
            // Fill
360 2
            if ($fill = $style->getFill()) {
361 2
                switch ($fill->getFillType()) {
362 2
                    case Fill::FILL_SOLID:
363 1
                        $writer->writeAttribute('fo:background-color', sprintf(
364 1
                            '#%s',
365 1
                            strtolower($fill->getStartColor()->getRGB())
366
                        ));
367 1
                        break;
368 2
                    case Fill::FILL_GRADIENT_LINEAR:
369 2
                    case Fill::FILL_GRADIENT_PATH:
370
                        /// TODO :: To be implemented
371
                        break;
372 2
                    case Fill::FILL_NONE:
373
                    default:
374
                }
375
            }
376
377 2
            $writer->endElement(); // Close style:table-cell-properties
378
379
            /*
380
             * End
381
             */
382
383 2
            $writer->endElement(); // Close style:style
384
        }
385 2
    }
386
}
387