Project

General

Profile

0001-changed-opPDODatabaseSessionStorage-write-to-replace.patch

Shinichi Urabe, 2015-06-19 19:38

Download (3.98 KB)

View differences:

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
-