Skip to content

Instantly share code, notes, and snippets.

@slywalker
Created December 5, 2010 13:13
Show Gist options
  • Save slywalker/729064 to your computer and use it in GitHub Desktop.
Save slywalker/729064 to your computer and use it in GitHub Desktop.
<?php
class Emoji4Unicode {
protected $_config = array();
private $__carrierMap = array(
'docomo' => 'docomo',
'kddi' => 'kddi',
'softbank' => 'softbank',
'google' => 'google',
'img' => 'img',
);
private $__xmlObject = null;
public function __construct(array $config = array()) {
$defaults = array(
'basePath' => dirname(__FILE__) . DIRECTORY_SEPARATOR,
'dataSource' => 'emoji4unicode.xml',
'imageDir' => 'img',
);
$config += $defaults;
$dataSource = $config['basePath'] . $config['dataSource'];
if (!file_exists($dataSource)) {
throw new ErrorException('DataSource is not exists. "' . $dataSource . '"');
}
$this->__xmlObject = simplexml_load_file($dataSource);
$this->_config = $config;
}
/**
* Set Carrier Map
*
* @param array $carrierMap array('kddi' => 'au)
* @return array set CarrierMap
*/
public function setCarrierMap(array $carrierMap) {
$carrierMap += $this->__carrierMap;
return $this->__carrierMap = $carrierMap;
}
private function __convertCarrierMap($carrier) {
$result = array_search($carrier, $this->__carrierMap);
if ($result === false) {
throw new ErrorException('Undefined carrier name. "' . $carrier . '"');
}
return $result;
}
/**
* Convert Emoji Code
*
* @param string $string
* @param string $to Carrier 'docomo', 'kddi', 'softbank', 'google' or 'img'
* @param string $from Carrier 'docomo', 'kddi', 'softbank', 'google'
* @param array $options Options
* 'class' img tag class name
* 'width' img tag width
* 'height' img tag height
* 'textFallback' if it is true, return text
* 'defaultText' default value return text
* 'binary' if it is true, return binary
* 'encoding' it is used when binary encode
* @return string
*/
public function convert($string, $to, $from, array $options = array()) {
$to = $this->__convertCarrierMap($to);
$from = $this->__convertCarrierMap($from);
$default = array(
'class' => 'emoji',
'width' => '20',
'height' => '20',
'textFallback' => true,
'defaultText' => '[emoji]',
'binary' => false,
'encoding' => 'UTF-8',
);
$options += $default;
preg_match_all('/&#x([0-9A-F]+);/', $string, $matches);
$matches[0] = array_unique($matches[0]);
$matches[1] = array_unique($matches[1]);
$map = $this->__xmlObject;
foreach ($matches[1] as $key => $match) {
$results = $map->xpath('//e[@' . $from . '="' . $match . '"]');
$result = current($results);
try {
if ($to === 'img') {
$replace = $this->__toImg($result, $match, $from, $options);
} else {
$replace = $this->__toEmoji($result, $to, $options);
}
} catch (Exception $e) {
$replace = $this->__toText($result, $options);
}
$search = $matches[0][$key];
$string = str_replace($search, $replace, $string);
}
return $string;
}
private function __toImg($result, $match, $from, $options) {
$folder = $from;
$emoji = $match;
if (isset($result['img_from']) && $result['img_from'] !== 'google') {
$folder = $result['img_from'];
$emoji = $result[$result['img_from']];
}
elseif ($from === 'google') {
$carrier = array_keys($this->__carrierMap);
foreach ($carrier as $_carrier) {
if (isset($result[$_carrier])) {
$folder = $_carrier;
$emoji = $result[$_carrier];
}
break;
}
}
$src = $this->_config['basePath'] . $this->_config['imageDir'] . DIRECTORY_SEPARATOR;
$src .= $folder . DIRECTORY_SEPARATOR . $emoji . '.gif';
if (!file_exists($src)) {
throw new Exception('Emoji not found');
}
$base64 = base64_encode(file_get_contents($src));
$replace = sprintf('<img class="%s" src="data:image/gif;base64,%s" width="%s" height="%s" />', $options['class'], $base64, $options['width'], $options['height']);
return $replace;
}
private function __toEmoji($result, $to, $options) {
if (!isset($result[$to])) {
throw new Exception('Emoji not found');
}
$result[$to] = str_replace('>', '', $result[$to]);
if ($options['binary'] === true) {
$replace = mb_convert_encoding(pack('H*', $result[$to]), $options['encoding'], 'UCS-2');
} else {
$replace = '&#x' . $result[$to] . ';';
}
return $replace;
}
private function __toText($result, $options) {
if ($options['textFallback'] === false) {
return '';
}
$replace = $options['defaultText'];
if (isset($result['text_fallback'])) {
$replace = $result['text_fallback'];
}
return $replace;
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment