1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* This file is part of PHPOffice Common |
4
|
|
|
* |
5
|
|
|
* PHPOffice Common is free software distributed under the terms of the GNU Lesser |
6
|
|
|
* General Public License version 3 as published by the Free Software Foundation. |
7
|
|
|
* |
8
|
|
|
* For the full copyright and license information, please read the LICENSE |
9
|
|
|
* file that was distributed with this source code. For the full list of |
10
|
|
|
* contributors, visit https://github.com/PHPOffice/Common/contributors. |
11
|
|
|
* |
12
|
|
|
* @link https://github.com/PHPOffice/Common |
13
|
|
|
* @copyright 2009-2016 PHPOffice Common contributors |
14
|
|
|
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 |
15
|
|
|
*/ |
16
|
|
|
|
17
|
|
|
namespace PhpOffice\Common; |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* Text |
21
|
|
|
*/ |
22
|
|
|
class Text |
23
|
|
|
{ |
24
|
|
|
/** |
25
|
|
|
* Control characters array |
26
|
|
|
* |
27
|
|
|
* @var string[] |
28
|
|
|
*/ |
29
|
|
|
private static $controlCharacters = array(); |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* Build control characters array |
33
|
|
|
*/ |
34
|
1 |
|
private static function buildControlCharacters() |
35
|
|
|
{ |
36
|
1 |
|
for ($i = 0; $i <= 19; ++$i) { |
37
|
1 |
|
if ($i != 9 && $i != 10 && $i != 13) { |
38
|
1 |
|
$find = '_x' . sprintf('%04s', strtoupper(dechex($i))) . '_'; |
39
|
1 |
|
$replace = chr($i); |
40
|
1 |
|
self::$controlCharacters[$find] = $replace; |
41
|
1 |
|
} |
42
|
1 |
|
} |
43
|
1 |
|
} |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* Convert from PHP control character to OpenXML escaped control character |
47
|
|
|
* |
48
|
|
|
* Excel 2007 team: |
49
|
|
|
* ---------------- |
50
|
|
|
* That's correct, control characters are stored directly in the shared-strings table. |
51
|
|
|
* We do encode characters that cannot be represented in XML using the following escape sequence: |
52
|
|
|
* _xHHHH_ where H represents a hexadecimal character in the character's value... |
53
|
|
|
* So you could end up with something like _x0008_ in a string (either in a cell value (<v>) |
54
|
|
|
* element or in the shared string <t> element. |
55
|
|
|
* |
56
|
|
|
* @param string $value Value to escape |
57
|
|
|
* @return string |
58
|
|
|
*/ |
59
|
1 |
|
public static function controlCharacterPHP2OOXML($value = '') |
60
|
|
|
{ |
61
|
1 |
|
if (empty(self::$controlCharacters)) { |
62
|
1 |
|
self::buildControlCharacters(); |
63
|
1 |
|
} |
64
|
|
|
|
65
|
1 |
|
return str_replace(array_values(self::$controlCharacters), array_keys(self::$controlCharacters), $value); |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
/** |
69
|
|
|
* Return a number formatted for being integrated in xml files |
70
|
|
|
* @param float $number |
71
|
|
|
* @param integer $decimals |
72
|
|
|
*/ |
73
|
1 |
|
public static function numberFormat($number, $decimals) |
74
|
|
|
{ |
75
|
1 |
|
return number_format($number, $decimals, '.', ''); |
76
|
|
|
} |
77
|
|
|
|
78
|
|
|
/** |
79
|
|
|
* @param int $dec |
80
|
|
|
* @link http://stackoverflow.com/a/7153133/2235790 |
81
|
|
|
* @author velcrow |
82
|
|
|
*/ |
83
|
1 |
|
public static function chr($dec) |
84
|
|
|
{ |
85
|
1 |
|
if ($dec<=0x7F) { |
86
|
1 |
|
return chr($dec); |
87
|
|
|
} |
88
|
1 |
|
if ($dec<=0x7FF) { |
89
|
1 |
|
return chr(($dec>>6)+192).chr(($dec&63)+128); |
90
|
|
|
} |
91
|
1 |
|
if ($dec<=0xFFFF) { |
92
|
1 |
|
return chr(($dec>>12)+224).chr((($dec>>6)&63)+128).chr(($dec&63)+128); |
93
|
|
|
} |
94
|
1 |
|
if ($dec<=0x1FFFFF) { |
95
|
1 |
|
return chr(($dec>>18)+240).chr((($dec>>12)&63)+128).chr((($dec>>6)&63)+128).chr(($dec&63)+128); |
96
|
|
|
} |
97
|
1 |
|
return ''; |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
/** |
101
|
|
|
* Convert from OpenXML escaped control character to PHP control character |
102
|
|
|
* |
103
|
|
|
* @param string $value Value to unescape |
104
|
|
|
* @return string |
105
|
|
|
*/ |
106
|
1 |
|
public static function controlCharacterOOXML2PHP($value = '') |
107
|
|
|
{ |
108
|
1 |
|
if (empty(self::$controlCharacters)) { |
109
|
|
|
self::buildControlCharacters(); |
110
|
|
|
} |
111
|
|
|
|
112
|
1 |
|
return str_replace(array_keys(self::$controlCharacters), array_values(self::$controlCharacters), $value); |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
/** |
116
|
|
|
* Check if a string contains UTF-8 data |
117
|
|
|
* |
118
|
|
|
* @deprecated 0.2.4 Use `Zend\Stdlib\StringUtils::isValidUtf8` instead. |
119
|
|
|
* |
120
|
|
|
* @param string $value |
121
|
|
|
* @return boolean |
122
|
|
|
*/ |
123
|
1 |
|
public static function isUTF8($value = '') |
124
|
|
|
{ |
125
|
1 |
|
return $value === '' || preg_match('/^./su', $value) === 1; |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
/** |
129
|
|
|
* Return UTF8 encoded value |
130
|
|
|
* |
131
|
|
|
* @param string $value |
132
|
|
|
* @return string |
133
|
|
|
*/ |
134
|
|
|
public static function toUTF8($value = '') |
135
|
|
|
{ |
136
|
|
|
if (!is_null($value) && !self::isUTF8($value)) { |
|
|
|
|
137
|
|
|
$value = utf8_encode($value); |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
return $value; |
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
/** |
144
|
|
|
* Returns unicode from UTF8 text |
145
|
|
|
* |
146
|
|
|
* The function is splitted to reduce cyclomatic complexity |
147
|
|
|
* |
148
|
|
|
* @param string $text UTF8 text |
149
|
|
|
* @return string Unicode text |
150
|
|
|
* @since 0.11.0 |
151
|
|
|
*/ |
152
|
1 |
|
public static function toUnicode($text) |
153
|
|
|
{ |
154
|
1 |
|
return self::unicodeToEntities(self::utf8ToUnicode($text)); |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
/** |
158
|
|
|
* Returns unicode array from UTF8 text |
159
|
|
|
* |
160
|
|
|
* @param string $text UTF8 text |
161
|
|
|
* @return array |
162
|
|
|
* @since 0.11.0 |
163
|
|
|
* @link http://www.randomchaos.com/documents/?source=php_and_unicode |
164
|
|
|
*/ |
165
|
1 |
|
public static function utf8ToUnicode($text) |
166
|
|
|
{ |
167
|
1 |
|
$unicode = array(); |
168
|
1 |
|
$values = array(); |
169
|
1 |
|
$lookingFor = 1; |
170
|
|
|
|
171
|
|
|
// Gets unicode for each character |
172
|
1 |
|
for ($i = 0; $i < strlen($text); $i++) { |
173
|
1 |
|
$thisValue = ord($text[$i]); |
174
|
1 |
|
if ($thisValue < 128) { |
175
|
1 |
|
$unicode[] = $thisValue; |
176
|
1 |
|
} else { |
177
|
1 |
|
if (count($values) == 0) { |
178
|
1 |
|
$lookingFor = $thisValue < 224 ? 2 : 3; |
179
|
1 |
|
} |
180
|
1 |
|
$values[] = $thisValue; |
181
|
1 |
|
if (count($values) == $lookingFor) { |
182
|
1 |
|
if ($lookingFor == 3) { |
183
|
1 |
|
$number = (($values[0] % 16) * 4096) + (($values[1] % 64) * 64) + ($values[2] % 64); |
184
|
1 |
|
} else { |
185
|
1 |
|
$number = (($values[0] % 32) * 64) + ($values[1] % 64); |
186
|
|
|
} |
187
|
1 |
|
$unicode[] = $number; |
188
|
1 |
|
$values = array(); |
189
|
1 |
|
$lookingFor = 1; |
190
|
1 |
|
} |
191
|
|
|
} |
192
|
1 |
|
} |
193
|
|
|
|
194
|
1 |
|
return $unicode; |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
/** |
198
|
|
|
* Returns entites from unicode array |
199
|
|
|
* |
200
|
|
|
* @param array $unicode |
201
|
|
|
* @return string |
202
|
|
|
* @since 0.11.0 |
203
|
|
|
* @link http://www.randomchaos.com/documents/?source=php_and_unicode |
204
|
|
|
*/ |
205
|
1 |
|
private static function unicodeToEntities($unicode) |
206
|
|
|
{ |
207
|
1 |
|
$entities = ''; |
208
|
|
|
|
209
|
1 |
|
foreach ($unicode as $value) { |
210
|
1 |
|
if ($value != 65279) { |
211
|
1 |
|
$entities .= $value > 127 ? '\uc0{\u' . $value . '}' : chr($value); |
212
|
1 |
|
} |
213
|
1 |
|
} |
214
|
|
|
|
215
|
1 |
|
return $entities; |
216
|
|
|
} |
217
|
|
|
|
218
|
|
|
/** |
219
|
|
|
* Return name without underscore for < 0.10.0 variable name compatibility |
220
|
|
|
* |
221
|
|
|
* @param string $value |
222
|
|
|
* @return string |
223
|
|
|
*/ |
224
|
1 |
|
public static function removeUnderscorePrefix($value) |
225
|
|
|
{ |
226
|
1 |
|
if (!is_null($value)) { |
227
|
1 |
|
if (substr($value, 0, 1) == '_') { |
228
|
1 |
|
$value = substr($value, 1); |
229
|
1 |
|
} |
230
|
1 |
|
} |
231
|
|
|
|
232
|
1 |
|
return $value; |
233
|
|
|
} |
234
|
|
|
} |
235
|
|
|
|
This method has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.