Completed
Push — master ( 2d139c...e71e30 )
by Stefan
02:44
created

CellBuilder::build()   B

Complexity

Conditions 6
Paths 4

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 6.0493

Importance

Changes 6
Bugs 2 Features 1
Metric Value
c 6
b 2
f 1
dl 0
loc 14
ccs 8
cts 9
cp 0.8889
rs 8.8571
cc 6
eloc 9
nc 4
nop 4
crap 6.0493
1
<?php
2
3
namespace OneSheet;
4
5
use OneSheet\Xml\CellXml;
6
7
/**
8
 * Class CellBuilder to build xml cell strings.
9
 * Wheter a numeric value is written as a number or string type cell
10
 * is simply determined by type, to allow for some control by typecasting.
11
 *
12
 * @package OneSheet
13
 */
14
class CellBuilder
15
{
16
    /**
17
     * Array of control characters that should be escaped.
18
     *
19
     * @var array
20
     */
21
    private $controlCharacters = array();
22
23
    /**
24
     * Array of escape characters to replace control characters.
25
     *
26
     * @var array
27
     */
28
    private $escapeCharacters = array();
29
30
    /**
31
     * Regex pattern containing control characters.
32
     *
33
     * @var string
34
     */
35
    private $escapeCharacterPattern;
36
37
    /**
38
     * CellBuilder constructor to create escaping arrays.
39
     */
40 17
    public function __construct()
41
    {
42 17
        foreach (range(chr(0), chr(31)) as $key => $character) {
43 17
            if (!in_array($character, array("\n", "\r", "\t"))) {
44 17
                $this->controlCharacters[] = $character;
45 17
                $this->escapeCharacters[] = sprintf('_x%04s_', strtoupper(dechex($key)));
46 17
            }
47 17
        }
48
49 17
        $this->escapeCharacterPattern = '~[' . preg_quote(implode($this->controlCharacters)) . ']~';
50 17
    }
51
52
    /**
53
     * Build and return the string for a single cell.
54
     *
55
     * @param int   $rowNumber
56
     * @param int   $cellNumber
57
     * @param mixed $cellValue
58
     * @param int   $styleId
59
     *
60
     * @return string
61
     */
62 6
    public function build($rowNumber, $cellNumber, $cellValue, $styleId = 0)
63
    {
64 6
        $cellId = $this->getCellId($cellNumber, $rowNumber);
65
66 6
        if (is_int($cellValue) || is_float($cellValue)) {
67 3
            return sprintf(CellXml::NUMBER_XML, $cellId, $styleId, $cellValue);
68 4
        } elseif (is_bool($cellValue)) {
69 1
            return sprintf(CellXml::BOOLEAN_XML, $cellId, $styleId, (int)$cellValue);
70 4
        } elseif (0 === strlen($cellValue) && $styleId > 0) {
71
            return sprintf(CellXml::EMPTY_XML, $cellId, $styleId);
72
        }
73
74 4
        return sprintf(CellXml::STRING_XML, $cellId, $styleId, $this->escape($cellValue));
0 ignored issues
show
Bug introduced by
It seems like $cellValue defined by parameter $cellValue on line 62 can also be of type array or null or object; however, OneSheet\CellBuilder::escape() does only seem to accept string, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
75
    }
76
77
    /**
78
     * Turn a integer cell number + row number into a valid cell identifier
79
     * like e.g. A1, Z1, AA1 etc and return it.
80
     *
81
     * @param int      $cellNumber
82
     * @param int|null $rowNumber
83
     *
84
     * @return string
85
     */
86 7
    public function getCellId($cellNumber, $rowNumber = null)
87
    {
88 7
        if ($cellNumber / 26 < 1) {
89 7
            return chr(65 + $cellNumber) . $rowNumber;
90
        }
91
92 1
        return $this->getCellId(floor($cellNumber / 26) - 1) . chr(65 + $cellNumber % 26) . $rowNumber;
93
    }
94
95
    /**
96
     * Escape/replace control characters.
97
     *
98
     * @param string $value
99
     *
100
     * @return string
101
     */
102 4
    private function escape($value)
103
    {
104 4
        if (1 !== preg_match($this->escapeCharacterPattern, $value)) {
105 4
            return htmlspecialchars($value, ENT_QUOTES);
106
        }
107
108 1
        return str_replace(
109 1
            $this->controlCharacters, $this->escapeCharacters, htmlspecialchars($value, ENT_QUOTES)
110 1
        );
111
    }
112
}
113
114