-
Notifications
You must be signed in to change notification settings - Fork 3
/
JixinParser.php
235 lines (212 loc) · 9.38 KB
/
JixinParser.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
<?php
class JixinParser{
/**
* superLink
* 主实现函数
*
* @param $content HTML格式文本
* @return $content 解析完毕后返回
*/
public function superLink($content){
if(preg_match_all('/<a(.*?)href="(.*?)"(.*?)>(.*?)<\/a>/is',$content,$matches)){
/*
if ($matches[2] != $matches[4]){
//如果href的值不等于a标签包裹的值,直接把内容丢回去,下面的解析就不执行了
return $content;
}
*/
//DEBUG
//echo '<pre>';
//print_r($matches);
//echo '</pre>';
//让包裹着a标签的url的array进行foreach的操作
foreach ($matches[0] as $child){
//$strip_child 为去HTML标签之后的url,方便下面进行匹配
$strip_child = strip_tags($child);
if($this->media_bilibili($strip_child)){
$content = preg_replace('/'.preg_quote($child,'/').'/i',$this->pregBilibili($strip_child,$this->media_bilibili($strip_child)),$content);
}
if($this->card_github($strip_child)){
$content = preg_replace('/'.preg_quote($child,'/').'/i',$this->pregGithub($strip_child),$content);
}
if($this->media_neteasemusic($strip_child)){
$content = preg_replace('/'.preg_quote($child,'/').'/i',$this->pregNeteasemusic($strip_child,$this->media_neteasemusic($strip_child)),$content);
}
if($this->card_gitee($strip_child)){
$content = preg_replace('/'.preg_quote($child,'/').'/i',$this->pregGitee($strip_child),$content);
}
}
}
//解析完毕,丢回去
return $content;
}
/**
* media_bilibili
* 对B站视频进行相关的解析
* https://gitee.com/ComsenzDiscuz/DiscuzX/blob/master/upload/source/function/media/media_bilibili.php
*
* @param $url 视频网站链接,丢进去进行判断,用于转换成iframe的url
* @param $type 0:返回iframe 1|other:返回AV|BV号
* @return $iframe 若解析成功返回iframe的内容,失败的话返回布朗值0
*/
private function media_bilibili($url,$type = 0) {
$quality_request = "&as_wide=1&high_quality=1";
if(preg_match("/https?:\/\/(m.|www.|)bilibili.(com|tv)\/video\/(a|b)v([A-Za-z0-9]+)(\/?.*?&p=|\/?\?p=)?(\d+)?/i", $url, $matches)) {
$vid = (is_numeric($matches[4]) ? 'aid='.$matches[4] : 'bvid='.$matches[4]) . (empty($matches[6]) ? '' : '&page='.intval($matches[6]));
$iframe = 'https://player.bilibili.com/player.html?'.$vid.$quality_request;
if ($type == 0) {
return $iframe;
} else {
$vid = str_replace("bvid=","BV",$vid);
$vid = str_replace("aid=","AV",$vid);
return $vid;
}
} else if(preg_match("/https?:\/\/(www.|)(acg|b23).tv\/(a|b)v([A-Za-z0-9]+)(\/?.*?&p=|\/?\?p=)?(\d+)?/i", $url, $matches)) {
$vid = (is_numeric($matches[4]) ? 'aid='.$matches[4] : 'bvid='.$matches[4]) . (empty($matches[6]) ? '' : '&page='.intval($matches[6]));
$iframe = 'https://player.bilibili.com/player.html?'.$vid.$quality_request;
if ($type == 0) {
return $iframe;
} else {
$vid = str_replace("bvid=","BV",$vid);
$vid = str_replace("aid=","AV",$vid);
return $vid;
}
} else {
return 0;
}
}
/**
* pregBilibili
* 解析形如Bilibili的iframe的内容
*
* @param $url 视频网站的跳转地址
* @param $iframe 传入解析完毕的iframe地址
* @return 解析好待替换的HTML内容
*/
private function pregBilibili($url,$iframe){
return '<div class="JixinParser-card bilibili" data-src="'.$iframe.'"><div class="JixinParser-card-meta"><a href="'.$url.'" target="_blank" rel="external nofollow">'.$this->media_bilibili($url,"1").'</a><span class="fold">展开/收起</span></div><div class="iframe-container"></div></div>';
}
/**
* card_github
* 判断 是否符合github repo卡片的解析条件
*
* @param $url 需要进行判断的url
* @return boolean
*/
private function card_github($url){
if (preg_match("/https?:\/\/github.com\/(.*?)\/(.*?)/is",$url,$matches)){
if (preg_match("/https?:\/\/github.com\/blog\/(.*?)/is",$url,$matches)){
return 0;
}
if (preg_match("/https?:\/\/github.com\/(.*?)\/(.*?)\/(.*?)\//is",$url,$matches)){
return 0;
}
return 1;
} else {
return 0;
}
}
/**
* pregGithub
* 处理Github卡片的HTML
*
* @param $url 经判断为仓库首页的URL
* @param $iframe 此形参不起作用
* @return 解析好待替换的HTML内容
*/
private function pregGithub($url,$iframe = NULL){
$iframe = preg_replace('/https?:\/\/github.com\//is','https://api.github.com/repos/',$url);
$repo = preg_replace('/https?:\/\/github.com\//is','',$url);
return '<div class="JixinParser-card github" data-src="'.$iframe.'"><div class="JixinParser-card-meta"><a href="'.$url.'" target="_blank" rel="external nofollow">'.$repo.'</a><span>Github</span></div><div class="iframe-container">Loading...</div></div>';
}
/**
* media_neteasemusic
*
* @param $url 网站链接,丢进去进行判断,用于转换成iframe的url
* @param $type 0:返回iframe 1|other:返回id
* @return $iframe 若解析成功返回iframe的内容,失败的话返回布朗值0
*/
private function media_neteasemusic($url,$type = 0) {
$outchain = $this->isMobileDevice() ? 'https://music.163.com/m/outchain/' : 'https://music.163.com/outchain/';
if(preg_match("/^https:\/\/music\.163\.com\/#\/song\?id=(\d+)$/is", $url, $matches)) {
$sid = $matches[1];
$iframe = $outchain . 'player?type=2&id='.$sid.'&height=66';
if ($type == 0) {
return $iframe;
} else {
return $sid;
}
} else if(preg_match("/^https:\/\/music\.163\.com\/#\/playlist\?id=(\d+)$/is", $url, $matches)) {
$sid = $matches[1];
$iframe = $outchain . 'player?type=0&id='.$sid;
if ($type == 0) {
return $iframe;
} else {
return $sid;
}
} else {
return 0;
}
}
/**
* pregNeteasemusic
* 解析形如网易云音乐的iframe的内容
*
* @param $url 网站的跳转地址
* @param $iframe 传入解析完毕的iframe地址
* @return 解析好待替换的HTML内容
*/
private function pregNeteasemusic($url,$iframe){
if(preg_match("/^https:\/\/music\.163\.com\/#\/song\?id=(\d+)$/is", $url, $matches)) {
$class = 'JixinParser-card neteasemusic single';
} else {
$class = 'JixinParser-card neteasemusic';
}
return '<div class="'.$class.'" data-src="'.$iframe.'"><div class="JixinParser-card-meta"><a href="'.$url.'" target="_blank" rel="external nofollow">网易云音乐 · '.$this->media_neteasemusic($url,"1").'</a><span class="fold">展开/收起</span></div><div class="iframe-container"></div></div>';
}
/**
* isMobileDevice
* 粗判是否为移动端设备,解决大聪明网易的外链地址区分设备,不会自动跳转的问题
*
* @return boolean
*/
private function isMobileDevice() {
return preg_match("/(android|avantgo|blackberry|bolt|boost|cricket|docomo|fone|hiptop|mini|mobi|palm|phone|pie|tablet|up\.browser|up\.link|webos|wos)/i", $_SERVER["HTTP_USER_AGENT"]);
}
/**
* card_gitee
* 判断 是否符合gitee repo卡片的解析条件
*
* @param $url 需要进行判断的url
* @return boolean
*/
private function card_gitee($url){
if (preg_match("/https?:\/\/gitee.com\/(.*?)\/(.*?)/is",$url,$matches)){
if (preg_match("/https?:\/\/gitee.com\/explore\/(.*?)/is",$url,$matches)){
return 0;
}
if (preg_match("/https?:\/\/gitee.com\/api\/(.*?)/is",$url,$matches)){
return 0;
}
if (preg_match("/https?:\/\/gitee.com\/(.*?)\/(.*?)\/(.*?)\//is",$url,$matches)){
return 0;
}
return 1;
} else {
return 0;
}
}
/**
* pregGitee
* 处理Gitee卡片的HTML
*
* @param $url 经判断为仓库首页的URL
* @param $iframe 此形参不起作用
* @return 解析好待替换的HTML内容
*/
private function pregGitee($url,$iframe = NULL){
$iframe = preg_replace('/https?:\/\/gitee.com\//is','https://gitee.com/api/v5/repos/',$url);
$repo = preg_replace('/https?:\/\/gitee.com\//is','',$url);
return '<div class="JixinParser-card github" data-src="'.$iframe.'"><div class="JixinParser-card-meta"><a href="'.$url.'" target="_blank" rel="external nofollow">'.$repo.'</a><span>Gitee</span></div><div class="iframe-container">Loading...</div></div>';
}
}