PageRenderTime 46ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/forum/lib/badwords/dictionary.php

https://gitlab.com/alexprowars/bitrix
PHP | 206 lines | 156 code | 21 blank | 29 comment | 26 complexity | 974c0304882fd7159e4575606dc0db00 MD5 | raw file
  1. <?php
  2. namespace Bitrix\Forum\BadWords;
  3. use Bitrix\Main;
  4. use \Bitrix\Main\Localization\Loc;
  5. use Bitrix\Main\ORM\Fields\EnumField;
  6. use Bitrix\Main\ORM\Fields\IntegerField;
  7. use Bitrix\Main\ORM\Fields\StringField;
  8. Loc::loadMessages(__FILE__);
  9. /**
  10. * Class DictionaryTable
  11. *
  12. * DO NOT WRITE ANYTHING BELOW THIS
  13. *
  14. * <<< ORMENTITYANNOTATION
  15. * @method static EO_Dictionary_Query query()
  16. * @method static EO_Dictionary_Result getByPrimary($primary, array $parameters = array())
  17. * @method static EO_Dictionary_Result getById($id)
  18. * @method static EO_Dictionary_Result getList(array $parameters = array())
  19. * @method static EO_Dictionary_Entity getEntity()
  20. * @method static \Bitrix\Forum\BadWords\EO_Dictionary createObject($setDefaultValues = true)
  21. * @method static \Bitrix\Forum\BadWords\EO_Dictionary_Collection createCollection()
  22. * @method static \Bitrix\Forum\BadWords\EO_Dictionary wakeUpObject($row)
  23. * @method static \Bitrix\Forum\BadWords\EO_Dictionary_Collection wakeUpCollection($rows)
  24. */
  25. class DictionaryTable extends Main\Entity\DataManager
  26. {
  27. private static $dataById = [];
  28. /**
  29. * Returns DB table name for entity
  30. *
  31. * @return string
  32. */
  33. public static function getTableName()
  34. {
  35. return 'b_forum_dictionary';
  36. }
  37. public static function getMap()
  38. {
  39. return [
  40. (new IntegerField("ID", ["primary" => true, "autocomplete" => true])),
  41. (new StringField("TITLE", ["required" => true, "size" => 50])),
  42. (new EnumField("TYPE", ["values" => ["T", "W"], "required" => true])),
  43. ];
  44. }
  45. public static function getDataById($id, $ttl = 84600)
  46. {
  47. if (!array_key_exists($id, self::$dataById))
  48. {
  49. self::$dataById[$id] = self::getList([
  50. "select" => ["*"],
  51. "filter" => ["ID" => $id],
  52. "cache" => [
  53. "ttl" => $ttl
  54. ]
  55. ])->fetch();
  56. }
  57. return self::$dataById[$id];
  58. }
  59. }
  60. class Dictionary {
  61. use \Bitrix\Forum\Internals\EntityFabric;
  62. use \Bitrix\Forum\Internals\EntityBaseMethods;
  63. /** @var int */
  64. protected $id; // means nothing now
  65. /** @var array */
  66. protected $data;
  67. /** @var int */
  68. protected $translitId;
  69. /** @var string */
  70. private const NOT_WORD = "\s.,;:!?\#\-\*\|\[\]\(\)";
  71. public function __construct($id, $languageId = null)
  72. {
  73. $this->id = $id;
  74. $this->data = DictionaryTable::getById($this->id)->fetch();
  75. //Todo make a link with translit dictionary
  76. if ($languageId === null)
  77. {
  78. $languageId = LANGUAGE_ID;
  79. }
  80. $this->translitId = Main\Config\Option::get("forum", "FILTER_DICT_T", "", $languageId);
  81. }
  82. public function delete()
  83. {
  84. DictionaryTable::delete($this->id);
  85. if ($this->data["TYPE"] == "T")
  86. $DB->Query("DELETE FROM b_forum_letter WHERE DICTIONARY_ID=".$ID);
  87. else
  88. $DB->Query("DELETE FROM b_forum_filter WHERE DICTIONARY_ID=".$ID);
  89. }
  90. private function getTranslitDictionary($multiLetter = true) : array
  91. {
  92. static $letters = null;
  93. if (is_null($letters))
  94. {
  95. $letters = [
  96. "singleLetter" => [],
  97. "multiLetter" => []
  98. ];
  99. $dbRes = LetterTable::getList([
  100. "select" => ["*"],
  101. "filter" => ["DICTIONARY_ID" => $this->translitId],
  102. "cache" => [
  103. "ttl" => 84600
  104. ]
  105. ]);
  106. while ($lett = $dbRes->fetch())
  107. {
  108. $space = false;
  109. $arrRes = array();
  110. $arrRepl = explode(",", $lett["REPLACEMENT"]);
  111. // create letters.
  112. for ($ii = 0; $ii < count($arrRepl); $ii++)
  113. {
  114. $arrRepl[$ii] = trim($arrRepl[$ii]);
  115. if (strlen($lett["LETTER"]) == 1)
  116. {
  117. if (strlen($arrRepl[$ii]) == 1)
  118. {
  119. $arrRes[$ii] = $arrRepl[$ii]."+";
  120. }
  121. else if (strpos($arrRepl[$ii], "(") === 0 && substr($arrRepl[$ii], -1, 1) == ")")
  122. {
  123. $arrRes[$ii] = $arrRepl[$ii]."+";
  124. }
  125. else if (strpos($arrRepl[$ii], "(") === 0 && substr($arrRepl[$ii], -2, 1) == ")")
  126. {
  127. $arrRes[$ii] = $arrRepl[$ii];
  128. }
  129. else if (strlen($arrRepl[$ii]) > 1)
  130. {
  131. $arrRes[$ii] = "[".$arrRepl[$ii]."]+";
  132. }
  133. else
  134. {
  135. $space = true;
  136. }
  137. }
  138. else if ($arrRepl[$ii] <> '')
  139. {
  140. $arrRes[$ii] = $arrRepl[$ii];
  141. }
  142. }
  143. if (strlen($lett["LETTER"]) == 1)
  144. {
  145. if ($space)
  146. {
  147. $arrRes[] = "";
  148. }
  149. $letters["singleLetter"][$lett["LETTER"]] = "(".implode("|", $arrRes).")";
  150. }
  151. else
  152. {
  153. $letters["multiLetter"]["/".preg_quote($lett["LETTER"])."/is".BX_UTF_PCRE_MODIFIER] = "(".implode("|", $arrRes).")";
  154. }
  155. }
  156. $letters["singleLetter"]["*"] = "[^".self::NOT_WORD."]*";
  157. $letters["singleLetter"]["+"] = "[^".self::NOT_WORD."]+";
  158. $letters["singleLetter"]["?"] = ".?";
  159. }
  160. return ($multiLetter === true ? $letters["multiLetter"] : $letters["singleLetter"]);
  161. }
  162. public function translitAndCreatePattern(string $word) : string
  163. {
  164. //replace big constrction
  165. $letters = $this->getTranslitDictionary(true);
  166. $word = preg_replace(array_keys($letters), array_values($letters), strtolower(trim($word)));
  167. //replace single letter construction
  168. $letters = $this->getTranslitDictionary(false);
  169. $replace = array_flip(array_keys($letters));
  170. $length = strlen(count($replace));
  171. $replace1 = array_map(function ($number) use ($length) {
  172. $number = str_pad($number, $length, "0", STR_PAD_LEFT);
  173. return "\017x$number";}, $replace);
  174. $word = str_replace(array_keys($replace), array_values($replace1), $word);
  175. $word = preg_quote($word);
  176. $word = str_replace(array_values($replace1), array_values($letters), $word);
  177. $word = "/(?<=[".self::NOT_WORD."])(".$word.")(?=[".self::NOT_WORD."])/is".BX_UTF_PCRE_MODIFIER;
  178. return $word;
  179. }
  180. public function createPattern(string $word) : string
  181. {
  182. $res = "/(?<=[".self::NOT_WORD."])(".preg_quote($word).")(?=[".self::NOT_WORD."])/is".BX_UTF_PCRE_MODIFIER;
  183. return $res;
  184. }
  185. }