eddy8 /
LightCMS
| 1 | <?php |
||
| 2 | |||
| 3 | use Illuminate\Database\Eloquent\Model; |
||
| 4 | use App\Foundation\Tire; |
||
| 5 | use Illuminate\Support\Facades\Cache; |
||
| 6 | use App\Model\Admin\SensitiveWord; |
||
| 7 | use App\Model\Admin\Config as SiteConfig; |
||
| 8 | |||
| 9 | /** |
||
| 10 | * 直接从数据库获取系统后台配置 |
||
| 11 | * |
||
| 12 | * @param string $key key |
||
| 13 | * @param mixed $default key不存在时的默认值 |
||
| 14 | * @return mixed key对应的value |
||
| 15 | */ |
||
| 16 | function getConfig($key, $default = null) |
||
| 17 | { |
||
| 18 | $v = SiteConfig::where('key', $key)->value('value'); |
||
| 19 | return !is_null($v) ? $v : $default; |
||
| 20 | } |
||
| 21 | |||
| 22 | /** |
||
| 23 | * 后台配置嵌套解析。支持配置值中包含其它配置:{{CONFIG_KEY}} |
||
| 24 | * |
||
| 25 | * @param string $value |
||
| 26 | * @return string |
||
| 27 | */ |
||
| 28 | function parseConfig($value) |
||
| 29 | { |
||
| 30 | if (preg_match_all('/\{\{(\w+)\}\}/', $value, $matches)) { |
||
| 31 | foreach ($matches[1] as $key => $match) { |
||
| 32 | $value = str_replace($matches[0][$key], strval(config('light_config.' . $match)), $value); |
||
| 33 | } |
||
| 34 | } else { |
||
| 35 | return $value; |
||
| 36 | } |
||
| 37 | |||
| 38 | return parseConfig($value); |
||
| 39 | } |
||
| 40 | |||
| 41 | function parseEntityFieldParams($params) |
||
| 42 | { |
||
| 43 | if (strpos($params, 'getFormItemsFrom') === 0 && function_exists($params)) { |
||
| 44 | $params = call_user_func($params); |
||
| 45 | } |
||
| 46 | |||
| 47 | $items = explode("\n", $params); |
||
| 48 | return array_map(function ($item) { |
||
| 49 | return explode("=", $item); |
||
| 50 | }, $items); |
||
| 51 | } |
||
| 52 | |||
| 53 | function isChecked($value, $options) |
||
| 54 | { |
||
| 55 | return in_array($value, explode(',', $options), true); |
||
| 56 | } |
||
| 57 | |||
| 58 | function isCheckedByAnd($value, $options) |
||
| 59 | { |
||
| 60 | return ($options & $value) == $value; |
||
| 61 | } |
||
| 62 | |||
| 63 | function xssFilter($data) |
||
| 64 | { |
||
| 65 | if (is_string($data)) { |
||
| 66 | return htmlspecialchars($data, ENT_QUOTES | ENT_SUBSTITUTE, 'utf-8'); |
||
| 67 | } |
||
| 68 | |||
| 69 | $attributes = $data->getAttributes(); |
||
| 70 | foreach ($attributes as &$v) { |
||
| 71 | if (is_string($v)) { |
||
| 72 | $v = htmlspecialchars($v, ENT_QUOTES | ENT_SUBSTITUTE, 'utf-8'); |
||
| 73 | } |
||
| 74 | } |
||
| 75 | $data->setRawAttributes($attributes); |
||
| 76 | } |
||
| 77 | |||
| 78 | function initTire() |
||
| 79 | { |
||
| 80 | return Cache::rememberForever('sensitive_words_tire', function () { |
||
| 81 | $tires = []; |
||
| 82 | |||
| 83 | foreach (['noun', 'verb', 'exclusive'] as $v) { |
||
| 84 | $words = SensitiveWord::query()->select($v)->where($v, '<>', '')->get(); |
||
| 85 | |||
| 86 | $tire = new Tire(); |
||
| 87 | foreach ($words as $k) { |
||
| 88 | $tire->add($k->$v); |
||
| 89 | } |
||
| 90 | $tires[$v] = $tire; |
||
| 91 | } |
||
| 92 | |||
| 93 | return $tires; |
||
| 94 | }); |
||
| 95 | } |
||
| 96 | |||
| 97 | function initTireSingle() |
||
| 98 | { |
||
| 99 | return Cache::rememberForever('sensitive_words_tire_single', function () { |
||
| 100 | $types = SensitiveWord::query()->select('type')->groupBy('type')->get(); |
||
| 101 | $tire = new Tire(); |
||
| 102 | foreach ($types as $type) { |
||
| 103 | $words = SensitiveWord::query()->where('type', $type->type)->get(); |
||
| 104 | $nouns = []; |
||
| 105 | $verbs = []; |
||
| 106 | $exclusives = []; |
||
| 107 | foreach ($words as $word) { |
||
| 108 | if ($word->noun !== '') { |
||
|
0 ignored issues
–
show
Bug
Best Practice
introduced
by
Loading history...
|
|||
| 109 | $nouns[] = $word->noun; |
||
| 110 | } elseif ($word->verb !== '') { |
||
|
0 ignored issues
–
show
The property
verb does not exist on App\Model\Admin\SensitiveWord. Since you implemented __get, consider adding a @property annotation.
Loading history...
|
|||
| 111 | $verbs[] = $word->verb; |
||
| 112 | } elseif ($word->exclusive !== '') { |
||
|
0 ignored issues
–
show
The property
exclusive does not exist on App\Model\Admin\SensitiveWord. Since you implemented __get, consider adding a @property annotation.
Loading history...
|
|||
| 113 | $exclusives[] = $word->exclusive; |
||
| 114 | } |
||
| 115 | } |
||
| 116 | |||
| 117 | foreach ($exclusives as $k) { |
||
| 118 | $tire->add($k); |
||
| 119 | } |
||
| 120 | foreach ($verbs as $vk) { |
||
| 121 | foreach ($nouns as $nk) { |
||
| 122 | $tire->add($vk . $nk); |
||
| 123 | } |
||
| 124 | } |
||
| 125 | } |
||
| 126 | |||
| 127 | return $tire; |
||
| 128 | }); |
||
| 129 | } |
||
| 130 | |||
| 131 | function mapTypeToVerbOfSensitiveWords() |
||
| 132 | { |
||
| 133 | return Cache::rememberForever('sensitive_verb_words', function () { |
||
| 134 | $words = SensitiveWord::query()->select('verb', 'type')->where('verb', '<>', '')->get(); |
||
| 135 | |||
| 136 | $data = []; |
||
| 137 | foreach ($words as $word) { |
||
| 138 | $data[$word->type <> '' ? $word->type : 'others'][] = $word->verb; |
||
| 139 | } |
||
| 140 | |||
| 141 | return $data; |
||
| 142 | }); |
||
| 143 | } |
||
| 144 | |||
| 145 | /** |
||
| 146 | * 敏感词检查 |
||
| 147 | * |
||
| 148 | * @param string $text 待检查文本 |
||
| 149 | * @param string $type 名词、动词的检测方法。默认为 join 。join:名词和动词相连组合在一起视为违规 all:名词和动词只要同时出现即为违规 |
||
| 150 | * @param mixed $mode 检查模式。仅 $type 为 all 时有效。默认名词、动词、专用词都检查,显示可指定为 noun verb exclusive |
||
| 151 | * @return array |
||
| 152 | */ |
||
| 153 | function checkSensitiveWords(string $text, $type = 'join', $mode = null) |
||
| 154 | { |
||
| 155 | if (!is_null($mode) && !in_array($mode, ['noun', 'verb', 'exclusive'])) { |
||
| 156 | throw new \InvalidArgumentException('mode参数无效,只能为null值、noun、exclusive'); |
||
| 157 | } |
||
| 158 | |||
| 159 | if ($type === 'join') { |
||
| 160 | $tire = initTireSingle(); |
||
| 161 | $result = $tire->seek($text); |
||
| 162 | return $result; |
||
| 163 | } |
||
| 164 | |||
| 165 | $tires = initTire(); |
||
| 166 | if (!is_null($mode)) { |
||
| 167 | return $tires[$mode]->seek($text); |
||
| 168 | } |
||
| 169 | |||
| 170 | $result = []; |
||
| 171 | $return = []; |
||
| 172 | foreach ($tires as $k => $tire) { |
||
| 173 | $result[$k] = $tire->seek($text); |
||
| 174 | } |
||
| 175 | if (!empty($result['noun']) && !empty($result['verb'])) { |
||
| 176 | $data = mapTypeToVerbOfSensitiveWords(); |
||
| 177 | foreach ($result['noun'] as $noun) { |
||
| 178 | $type = Cache::rememberForever('sensitive_words_noun_type:' . $noun, function () use ($noun) { |
||
| 179 | return SensitiveWord::query()->where('noun', $noun)->value('type'); |
||
| 180 | }); |
||
| 181 | $type = $type ? $type : 'others'; |
||
| 182 | $verbs = array_intersect($data[$type], $result['verb']); |
||
| 183 | if (!empty($verbs)) { |
||
| 184 | array_push($verbs, $noun); |
||
| 185 | $return[] = implode(' ', $verbs); |
||
| 186 | } |
||
| 187 | } |
||
| 188 | } |
||
| 189 | return array_merge($return, $result['exclusive']); |
||
| 190 | } |
||
| 191 | |||
| 192 | function isWebp($data) |
||
| 193 | { |
||
| 194 | if (strncmp(substr($data, 8, 7), "WEBPVP8", 7) === 0) { |
||
| 195 | return true; |
||
| 196 | } |
||
| 197 | |||
| 198 | return false; |
||
| 199 | } |
||
| 200 |