Skip to content

Commit 3f620ee

Browse files
committed
add encodor/decodor pattren and implement utf8 string protocol
1 parent 499ba86 commit 3f620ee

8 files changed

+201
-24
lines changed

composer.json

+8-1
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,12 @@
1313
}
1414
],
1515
"minimum-stability": "stable",
16-
"require": {}
16+
"require": {},
17+
"autoload": {
18+
"psr-4": {
19+
"\\Hidehalo\\": "src/",
20+
"\\Hidehalo\\Features\\": "src/Features/",
21+
"\\Hidehalo\\Unicode\\": "src/Unicode/"
22+
}
23+
}
1724
}

src/Features/EmojiParser.php

+55-18
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,15 @@
11
<?php
2-
/**
3-
* Created by PhpStorm.
4-
* User: TianChen
5-
* Date: 17/1/7
6-
* Time: 15:59
7-
*/
82

93
namespace Hidehalo\Emoji\Features;
104

11-
125
use Hidehalo\Emoji\Unicode\Emoji;
6+
use Hidehalo\Emoji\Features\Protocol\Utf8String;
7+
use Hidehalo\Emoji\Features\Protocol\ProtocolInterface;
138

149
class EmojiParser extends UnicodeParser
1510
{
1611
//http://apps.timwhitlock.info/emoji/tables/unicode
17-
protected $maps = [
12+
private $maps = [
1813
[0x0080,0x02AF],
1914
[0x0300,0x03FF],
2015
[0x0600,0x06FF],
@@ -42,13 +37,19 @@ class EmojiParser extends UnicodeParser
4237
[0x1F910,0x1F918],
4338
[0x1F980,0x1F9C0],
4439
];
40+
/**
41+
* @var string $pattern;
42+
*/
4543
protected $pattern;
44+
/**
45+
* @var ProtocolInterface $protocol
46+
*/
47+
protected $protocol;
4648

47-
public function __construct($config = [])
49+
public function __construct(array $config = [])
4850
{
49-
if (isset($config['maps'])) {
50-
$this->maps = $config['maps'];
51-
}
51+
$protocolName = (isset($config['protocol_name'])) ? $config['protocol_name'] : Utf8String::class;
52+
$this->protocol = ProtocolFactory::generate($protocolName);
5253
$this->pattern = $this->buildRegex($this->maps);
5354
}
5455

@@ -92,18 +93,54 @@ public function clean($string)
9293
return $count>0?$result:$string;
9394
}
9495

95-
public function replace($string,callable $callback)
96+
public function utf8stringEncode($string)
9697
{
97-
if (!$this->pattern) {
98-
return $string;
98+
$protocol = $this->protocol;
99+
$encodeString = $this->replace($string, function ($matches) use ($protocol) {
100+
if (is_array($matches) && !empty($matches)) {
101+
foreach ($matches as &$matched) {
102+
$matched = $protocol->encode($matched);
103+
104+
return $matched;
105+
}
106+
}
107+
108+
return '';
109+
});
110+
111+
return $encodeString;
112+
}
113+
114+
public function utf8StringDecode($string)
115+
{
116+
$protocol = $this->protocol;
117+
$decodeString = $this->replace($string, function ($matches) use ($protocol) {
118+
if (is_array($matches) && !empty($matches)) {
119+
foreach ($matches as &$matched) {
120+
$matched = $protocol->decode($matched);
121+
122+
return $matched;
123+
}
124+
}
125+
126+
return '';
127+
}, $protocol->getPattern());
128+
129+
return $decodeString;
130+
}
131+
132+
private function replace($string,callable $callback, $pattern = '')
133+
{
134+
if (!$pattern) {
135+
$pattern = $this->pattern;
99136
}
100137
$count = 0;
101-
$result = preg_replace_callback($this->pattern,$callback,$string,-1,$count);
138+
$result = preg_replace_callback($pattern,$callback,$string,-1,$count);
102139

103-
return $count>0?$result:$string;
140+
return $count>0 ? $result : $string;
104141
}
105142

106-
protected function buildRegex($maps)
143+
private function buildRegex($maps)
107144
{
108145
$pattern = '';
109146
if ($maps) {

src/Features/Protocol/HtmlNcr.php

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
/**
3+
* Created by PhpStorm.
4+
* User: tian
5+
* Date: 2017/3/30
6+
* Time: 11:22
7+
*/
8+
9+
namespace Hidehalo\Emoji\Features\Protocol;
10+
11+
12+
class HtmlNcr implements ProtocolInterface
13+
{
14+
public function encode($contents, array $options = [])
15+
{
16+
// TODO: Implement encode() method.
17+
}
18+
19+
public function decode($contents, array $options = [])
20+
{
21+
// TODO: Implement decode() method.
22+
}
23+
24+
public function getPattern()
25+
{
26+
// TODO: Implement getPattern() method.
27+
}
28+
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace Hidehalo\Emoji\Features\Protocol;
4+
5+
interface ProtocolInterface
6+
{
7+
public function encode($contents, array $options = []);
8+
public function decode($contents, array $options = []);
9+
public function getPattern();
10+
}

src/Features/Protocol/Utf8String.php

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
/**
3+
* Created by PhpStorm.
4+
* User: tian
5+
* Date: 2017/3/30
6+
* Time: 11:23
7+
*/
8+
9+
namespace Hidehalo\Emoji\Features\Protocol;
10+
11+
use Hidehalo\Emoji\Features\UnicodeParser;
12+
13+
class Utf8String implements ProtocolInterface
14+
{
15+
private $format = "[:%d]";
16+
private $pattern = '/\[\:\d+\]/';
17+
18+
public function encode($contents, array $options = [])
19+
{
20+
$bytesNumber = UnicodeParser::getBytesNumber($contents);
21+
$unicode = UnicodeParser::getUnicode($contents, $bytesNumber);
22+
$format = $this->getFormat();
23+
$encoded = sprintf($format, $unicode);
24+
25+
return $encoded;
26+
}
27+
28+
public function decode($contents, array $options = [])
29+
{
30+
$unicode = (int) substr($contents,2,-1);
31+
$decoded = UnicodeParser::getSymbol($unicode);
32+
33+
return $decoded;
34+
}
35+
36+
public function getPattern()
37+
{
38+
return $this->pattern;
39+
}
40+
41+
private function getFormat()
42+
{
43+
return $this->format;
44+
}
45+
46+
}

src/Features/ProtocolFactory.php

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace Hidehalo\Emoji\Features;
4+
5+
use Hidehalo\Emoji\Features\Protocol\ProtocolInterface;
6+
7+
class ProtocolFactory
8+
{
9+
private static $protocolInstancesMap = [];
10+
11+
public static final function generate($protocolName, array $options = [])
12+
{
13+
$reflector = new \ReflectionClass($protocolName);
14+
$interfaces = $reflector->getInterfaceNames();
15+
$interfacesCount = array_count_values($interfaces);
16+
$isImplementsOf = isset($interfacesCount[ProtocolInterface::class]) ? true : false;
17+
18+
if (class_exists($protocolName) && $isImplementsOf) {
19+
20+
if (isset(self::$protocolInstancesMap[$protocolName])
21+
&& self::$protocolInstancesMap[$protocolName] instanceof ProtocolInterface) {
22+
23+
return self::$protocolInstancesMap[$protocolName];
24+
} elseif (!isset(self::$protocolInstancesMap[$protocolName])) {
25+
self::$protocolInstancesMap[$protocolName] = new $protocolName($options);
26+
27+
return self::$protocolInstancesMap[$protocolName];
28+
} else {
29+
unset(self::$protocolInstancesMap[$protocolName]);
30+
self::$protocolInstancesMap[$protocolName] = new $protocolName($options);
31+
32+
return self::$protocolInstancesMap[$protocolName];
33+
}
34+
}
35+
36+
throw new \Exception('Can not found protocol '.$protocolName);
37+
}
38+
}

src/Features/UnicodeParser.php

+5-5
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ abstract class UnicodeParser implements ParserInterface
99
* @param $unicode
1010
* @return string $symbol
1111
*/
12-
protected function getSymbol($unicode)
12+
public static function getSymbol($unicode)
1313
{
1414
$symbol = iconv('UCS-4LE', 'UTF-8', pack('V', $unicode));
1515

@@ -22,7 +22,7 @@ protected function getSymbol($unicode)
2222
* @param integer $bytes
2323
* @return integer $ascii
2424
*/
25-
protected function getUnicode($symbol,$bytes = 1)
25+
public static function getUnicode($symbol,$bytes = 1)
2626
{
2727
$offset = 0;
2828
$highChar = substr($symbol, $offset ,1);
@@ -44,7 +44,7 @@ protected function getUnicode($symbol,$bytes = 1)
4444
* @param string $symbol
4545
* @return integer $bytesNumber
4646
*/
47-
protected function getBytesNumber($symbol)
47+
public static function getBytesNumber($symbol)
4848
{
4949
$ascii = ord($symbol);
5050
$bytesNumber = 1;
@@ -75,9 +75,9 @@ protected function getBytesNumber($symbol)
7575
/**
7676
* @param $symbol
7777
*/
78-
protected function getBytes($symbol)
78+
public static function getBytes($symbol)
7979
{
80-
$bytesNumber = $this->getBytesNumber($symbol);
80+
$bytesNumber = self::getBytesNumber($symbol);
8181
$bytes = [];
8282
for ($i=0; $i<$bytesNumber; $i++) {
8383
$bytes[] = ord(substr($symbol,$i,1));

test/Unit/EmojiParserTest.php

+10
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,14 @@ public function testClean()
1212
$result = $parser->clean($string);
1313
$this->assertEquals($result, 'Hello ');
1414
}
15+
16+
public function testUtf8StringEncodeAndDecode()
17+
{
18+
$parser = new EmojiParser();
19+
$string = 'Hello ☻';
20+
$result = $parser->utf8stringEncode($string);
21+
$this->assertEquals($result, 'Hello [:9787]');
22+
$result = $parser->utf8StringDecode($result);
23+
$this->assertEquals($string, $result);
24+
}
1525
}

0 commit comments

Comments
 (0)