You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

emoticons_engine.php 6.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. <?php
  2. /**
  3. * @license GNU GPLv3+
  4. * @author Thomas Bruederli
  5. * @author Aleksander Machniak
  6. */
  7. class emoticons_engine
  8. {
  9. const IMG_PATH = 'program/js/tinymce/plugins/emoticons/img/';
  10. /**
  11. * Replaces TinyMCE's emoticon images with plain-text representation
  12. *
  13. * @param string $html HTML content
  14. *
  15. * @return string HTML content
  16. */
  17. public static function icons2text($html)
  18. {
  19. $emoticons = array(
  20. '8-)' => 'smiley-cool',
  21. ':-#' => 'smiley-foot-in-mouth',
  22. ':-*' => 'smiley-kiss',
  23. ':-X' => 'smiley-sealed',
  24. ':-P' => 'smiley-tongue-out',
  25. ':-@' => 'smiley-yell',
  26. ":'(" => 'smiley-cry',
  27. ':-(' => 'smiley-frown',
  28. ':-D' => 'smiley-laughing',
  29. ':-)' => 'smiley-smile',
  30. ':-S' => 'smiley-undecided',
  31. ':-$' => 'smiley-embarassed',
  32. 'O:-)' => 'smiley-innocent',
  33. ':-|' => 'smiley-money-mouth',
  34. ':-O' => 'smiley-surprised',
  35. ';-)' => 'smiley-wink',
  36. );
  37. foreach ($emoticons as $idx => $file) {
  38. // <img title="Cry" src="http://.../program/js/tinymce/plugins/emoticons/img/smiley-cry.gif" border="0" alt="Cry" />
  39. $file = preg_quote(self::IMG_PATH . $file . '.gif', '/');
  40. $search[] = '/<img (title="[a-z ]+" )?src="[^"]+' . $file . '"[^>]+\/>/i';
  41. $replace[] = $idx;
  42. }
  43. return preg_replace($search, $replace, $html);
  44. }
  45. /**
  46. * Replace common plain text emoticons with empticon <img> tags
  47. *
  48. * @param string $text Text
  49. *
  50. * @return string Converted text
  51. */
  52. public static function text2icons($text)
  53. {
  54. // This is a lookbehind assertion which will exclude html entities
  55. // E.g. situation when ";)" in "&quot;)" shouldn't be replaced by the icon
  56. // It's so long because of assertion format restrictions
  57. $entity = '(?<!&'
  58. . '[a-zA-Z0-9]{2}' . '|' . '#[0-9]{2}' . '|'
  59. . '[a-zA-Z0-9]{3}' . '|' . '#[0-9]{3}' . '|'
  60. . '[a-zA-Z0-9]{4}' . '|' . '#[0-9]{4}' . '|'
  61. . '[a-zA-Z0-9]{5}' . '|'
  62. . '[a-zA-Z0-9]{6}' . '|'
  63. . '[a-zA-Z0-9]{7}'
  64. . ')';
  65. // map of emoticon replacements
  66. $map = array(
  67. '/(?<!mailto):D/' => self::img_tag('smiley-laughing.gif', ':D' ),
  68. '/:-D/' => self::img_tag('smiley-laughing.gif', ':-D' ),
  69. '/:\(/' => self::img_tag('smiley-frown.gif', ':(' ),
  70. '/:-\(/' => self::img_tag('smiley-frown.gif', ':-(' ),
  71. '/'.$entity.';\)/' => self::img_tag('smiley-wink.gif', ';)' ),
  72. '/'.$entity.';-\)/' => self::img_tag('smiley-wink.gif', ';-)' ),
  73. '/8\)/' => self::img_tag('smiley-cool.gif', '8)' ),
  74. '/8-\)/' => self::img_tag('smiley-cool.gif', '8-)' ),
  75. '/(?<!mailto):O/i' => self::img_tag('smiley-surprised.gif', ':O' ),
  76. '/(?<!mailto):-O/i' => self::img_tag('smiley-surprised.gif', ':-O' ),
  77. '/(?<!mailto):P/i' => self::img_tag('smiley-tongue-out.gif', ':P' ),
  78. '/(?<!mailto):-P/i' => self::img_tag('smiley-tongue-out.gif', ':-P' ),
  79. '/(?<!mailto):@/i' => self::img_tag('smiley-yell.gif', ':@' ),
  80. '/(?<!mailto):-@/i' => self::img_tag('smiley-yell.gif', ':-@' ),
  81. '/O:\)/i' => self::img_tag('smiley-innocent.gif', 'O:)' ),
  82. '/O:-\)/i' => self::img_tag('smiley-innocent.gif', 'O:-)' ),
  83. '/(?<!O):\)/' => self::img_tag('smiley-smile.gif', ':)' ),
  84. '/(?<!O):-\)/' => self::img_tag('smiley-smile.gif', ':-)' ),
  85. '/(?<!mailto):\$/' => self::img_tag('smiley-embarassed.gif', ':$' ),
  86. '/(?<!mailto):-\$/' => self::img_tag('smiley-embarassed.gif', ':-$' ),
  87. '/(?<!mailto):\*/i' => self::img_tag('smiley-kiss.gif', ':*' ),
  88. '/(?<!mailto):-\*/i' => self::img_tag('smiley-kiss.gif', ':-*' ),
  89. '/(?<!mailto):S/i' => self::img_tag('smiley-undecided.gif', ':S' ),
  90. '/(?<!mailto):-S/i' => self::img_tag('smiley-undecided.gif', ':-S' ),
  91. );
  92. return preg_replace(array_keys($map), array_values($map), $text);
  93. }
  94. protected static function img_tag($ico, $title)
  95. {
  96. return html::img(array('src' => './' . self::IMG_PATH . $ico, 'title' => $title));
  97. }
  98. /**
  99. * Replace emoticon icons <img> 'src' attribute, so it can
  100. * be replaced with real file by Mail_Mime.
  101. *
  102. * @param string &$html HTML content
  103. *
  104. * @return array List of image files
  105. */
  106. public static function replace(&$html)
  107. {
  108. // Replace this:
  109. // <img src="http[s]://.../tinymce/plugins/emoticons/img/smiley-cool.gif" ... />
  110. // with this:
  111. // <img src="/path/on/server/.../tinymce/plugins/emoticons/img/smiley-cool.gif" ... />
  112. $rcube = rcube::get_instance();
  113. $assets_dir = $rcube->config->get('assets_dir');
  114. $path = unslashify($assets_dir ?: INSTALL_PATH) . '/' . self::IMG_PATH;
  115. $offset = 0;
  116. $images = array();
  117. // remove any null-byte characters before parsing
  118. $html = preg_replace('/\x00/', '', $html);
  119. if (preg_match_all('# src=[\'"]([^\'"]+)#', $html, $matches, PREG_OFFSET_CAPTURE)) {
  120. foreach ($matches[1] as $m) {
  121. // find emoticon image tags
  122. if (preg_match('#'. self::IMG_PATH . '(.*)$#', $m[0], $imatches)) {
  123. $image_name = $imatches[1];
  124. // sanitize image name so resulting attachment doesn't leave images dir
  125. $image_name = preg_replace('/[^a-zA-Z0-9_\.\-]/i', '', $image_name);
  126. $image_file = $path . $image_name;
  127. // Add the same image only once
  128. $images[$image_name] = $image_file;
  129. $html = substr_replace($html, $image_file, $m[1] + $offset, strlen($m[0]));
  130. $offset += strlen($image_file) - strlen($m[0]);
  131. }
  132. }
  133. }
  134. return $images;
  135. }
  136. }