0001-changed-opPDODatabaseSessionStorage-write-to-replace.patch
lib/user/opPDODatabaseSessionStorage.class.php | ||
---|---|---|
26 | 26 | |
27 | 27 |
return parent::sessionOpen($path, $name); |
28 | 28 |
} |
29 | ||
30 |
/** |
|
31 |
* Writes data to this storage replacing 4 byte utf8 characters. |
|
32 |
* |
|
33 |
* @param string $key A unique key identifying your data |
|
34 |
* @param mixed $data Data associated with your key |
|
35 |
* |
|
36 |
* @see sfSessionStorage |
|
37 |
*/ |
|
38 |
public function write($key, $data) |
|
39 |
{ |
|
40 |
// "utf8", a type of character set in MySQL, can't handle 4 bytes utf8 characters |
|
41 |
// so we replace such a character to "U+FFFD" (A unicode "REPLACEMENT CHARACTER"). |
|
42 |
if (!$this->isReadyFor4BytesUtf8()) |
|
43 |
{ |
|
44 |
$data = $this->replace4BytesUtf8Characters($data); |
|
45 |
} |
|
46 | ||
47 |
parent::write($key, $data); |
|
48 |
} |
|
49 | ||
50 |
protected function replace4BytesUtf8Characters($value) |
|
51 |
{ |
|
52 |
if (is_array($value)) |
|
53 |
{ |
|
54 |
$result = array(); |
|
55 |
foreach ($value as $k => $v) |
|
56 |
{ |
|
57 |
$result[$this->replace4BytesUtf8Characters($k)] = $this->replace4BytesUtf8Characters($v); |
|
58 |
} |
|
59 | ||
60 |
return $result; |
|
61 |
} |
|
62 |
elseif (!is_string($value)) |
|
63 |
{ |
|
64 |
return $value; |
|
65 |
} |
|
66 | ||
67 |
// See: RFC 3629 (section 4, Syntax of UTF-8 Byte Sequences) |
|
68 |
// http://tools.ietf.org/html/rfc3629#section-4 |
|
69 |
return preg_replace('/( |
|
70 |
\xF0[\x90-\xBF][\x80-\xBF]{2}| # %xF0 %x90-BF 2( UTF8-tail ) |
|
71 |
[\xF1-\xF3][\x80-\xBF]{3}| # %xF1-F3 3( UTF8-tail ) |
|
72 |
\xF4[\x80-\x8F][\x80-\xBF]{2} # %xF4 %x80-8F 2( UTF8-tail ) |
|
73 |
)/x', "\xEF\xBF\xBD", $value); |
|
74 |
} |
|
75 | ||
76 |
protected function isReadyFor4BytesUtf8() |
|
77 |
{ |
|
78 |
return 'mysql' !== $this->db->getAttribute(PDO::ATTR_DRIVER_NAME); |
|
79 |
} |
|
29 | 80 |
} |
test/unit/user/opPDODatabaseSessionStrageTest.class.php | ||
---|---|---|
1 |
<?php |
|
2 | ||
3 |
require_once(dirname(__FILE__).'/../../bootstrap/unit.php'); |
|
4 | ||
5 |
$_app = 'pc_frontend'; |
|
6 |
$_end = 'test'; |
|
7 |
$configuration = ProjectConfiguration::getApplicationConfiguration($_app, $_env, true); |
|
8 |
sfContext::createInstance($configuration); |
|
9 |
new sfDatabaseManager($configuration); |
|
10 | ||
11 |
$t = new lime_test(2 + 2, new lime_output_color()); |
|
12 | ||
13 |
$storage = new opPDODatabaseSessionStorage(array( |
|
14 |
'db_table' => 'session', |
|
15 |
'database' => 'doctrine', |
|
16 |
'db_id_col' => 'id', |
|
17 |
'db_data_col' => 'session_data', |
|
18 |
'db_time_col' => 'time', |
|
19 |
)); |
|
20 | ||
21 |
$t->ok($storage instanceof sfStorage, 'sfPDOSessionStorage is an instance of sfStorage'); |
|
22 |
$t->ok($storage instanceof sfDatabaseSessionStorage, 'sfPDOSessionStorage is an instance of sfDatabaseSessionStorage'); |
|
23 | ||
24 |
$storage->sessionOpen(); |
|
25 | ||
26 |
// main test |
|
27 | ||
28 |
$sessionId = '1'; |
|
29 |
$newSessionData = 'foo:bar:baz'; |
|
30 |
$storage->write($sessionId, $newSessionData); |
|
31 |
$t->is($storage->read($sessionId), $newSessionData, 'session data can get data correctly'); |
|
32 | ||
33 |
$sessionId = '1'; |
|
34 |
$newSessionData = 'testⓉⒺⓈⓉテスト🅃🄴🅂🅃てすと'; |
|
35 |
$strConverted = 'testⓉⒺⓈⓉテスト����てすと'; |
|
36 |
$storage->write($sessionId, $newSessionData); |
|
37 |
$t->is($storage->read($sessionId), $strConverted, 'session data using 4 byte utf characters can get data correctly'); |
|
0 |
- |