Completed
Push — master ( 58f9ca...1ff41e )
by Stefan
02:58
created

DefaultCellBuilder::isWordCharacter()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
/**
3
 * @author neun
4
 * @since  2016-07-11
5
 */
6
7
namespace OneSheet;
8
9
/**
10
 * Class DefaultCellBuilder to build xml cell strings.
11
 * Wheter a numeric value is written as a number or string type cell
12
 * is simply determined by type, to allow for some control by typecasting.
13
 * (Premature) performance considerations (50.000 rows x 15 columns):
14
 * - sprintf 8.3s
15
 * - '<c>' . $value . '</c>' 8.1s
16
 * - "<c>{$value}</c>" 7.9s
17
 * @package OneSheet
18
 */
19
class DefaultCellBuilder implements CellBuilderInterface
20
{
21
    /**
22
     * A-Z character array to build cell ids.
23
     *
24
     * @var array
25
     */
26
    private $characters = array();
27
28
    /**
29
     * Array of control characters that should be escaped.
30
     *
31
     * @var array
32
     */
33
    private $controlCharacters = array();
34
35
    /**
36
     * Array of escape characters to replace control characters.
37
     *
38
     * @var array
39
     */
40
    private $escapeCharacters = array();
41
42
    /**
43
     * CellBuilder constructor to instantiate character properties.
44
     */
45 4
    public function __construct()
46
    {
47 4
        $this->characters = range('A', 'Z');
48
49 4
        foreach(range(chr(0), chr(31)) as $key => $char) {
50 4
            if (!in_array($char, array("\n", "\r", "\t"))) {
51 4
                $this->controlCharacters[] = $char;
52 4
                $this->escapeCharacters[] = sprintf('_x%04s_', strtoupper(dechex($key)));
53 4
            }
54 4
        }
55 4
    }
56
57
    /**
58
     * Build and return the string for a single cell.
59
     *
60
     * @param int    $rowNumber
61
     * @param int    $cellNumber
62
     * @param string $value
63
     * @param int    $styleId
64
     * @return string
65
     */
66 2
    public function build($rowNumber, $cellNumber, $value, $styleId = 0)
67
    {
68 2
        $cellId = $this->getCellId($cellNumber, $rowNumber);
69
70 2
        if (is_int($value) || is_double($value)) {
71 2
            return sprintf(CellXml::NUMBER_XML, $cellId, $styleId, $value);
72 2
        } elseif (is_bool($value)) {
73 1
            return sprintf(CellXml::BOOLEAN_XML, $cellId, $styleId, (int)$value);
74 2
        } elseif (is_numeric($value) || $this->isWordCharacter($value)) {
75 2
            return sprintf(CellXml::STRING_XML, $cellId, $styleId, htmlspecialchars($value));
76
        } else {
77 1
            return sprintf(CellXml::STRING_XML, $cellId, $styleId, $this->escapeControlCharacters($value));
78
        }
79
    }
80
81
    /**
82
     * Turn a integer cell number + row number into a valid cell identifier
83
     * like e.g. A1, Z1, AA1 etc and return it.
84
     *
85
     * @param int      $cellNumber
86
     * @param int|null $rowNumber
87
     * @return string
88
     */
89 2
    private function getCellId($cellNumber, $rowNumber = null)
90
    {
91 2
        if ($cellNumber / 26 < 1) {
92 2
            return $this->characters[$cellNumber] . $rowNumber;
93
        }
94
95 1
        return $this->getCellId(floor($cellNumber / 26) - 1) . $this->characters[$cellNumber % 26] . $rowNumber;
96
    }
97
98
    /**
99
     * Determine if the string requires additional escaping.
100
     *
101
     * @param string $value
102
     * @return bool
103
     */
104 2
    private function isWordCharacter($value)
105
    {
106 2
        return 1 != preg_match('~[^\w]~', $value);
107
    }
108
109
    /**
110
     * Replace control characters with escape characters.
111
     *
112
     * @param string $value
113
     * @return string
114
     */
115 1
    private function escapeControlCharacters($value)
116
    {
117 1
        return str_replace($this->controlCharacters, $this->escapeCharacters, htmlspecialchars($value, ENT_QUOTES));
118
    }
119
}
120