1
+ <?php
2
+ /**
3
+ * Gravatar 头像缓存插件
4
+ *
5
+ * @package GravatarCache
6
+ * @author Byends
7
+ * @version 2.0.2
8
+ * @link http://www.byends.com
9
+ */
10
+ class GravatarCache implements Typecho_Plugin_Interface
11
+ {
12
+ /**
13
+ * 激活插件方法,如果激活失败,直接抛出异常
14
+ *
15
+ * @access public
16
+ * @return void
17
+ * @throws Typecho_Plugin_Exception
18
+ */
19
+ public static function activate ()
20
+ {
21
+ Typecho_Plugin::factory ('Widget_Abstract_Comments ' )->gravatar = array ('GravatarCache ' , 'getGravatar ' );
22
+ }
23
+
24
+ /**
25
+ * 禁用插件方法,如果禁用失败,直接抛出异常
26
+ *
27
+ * @static
28
+ * @access public
29
+ * @return void
30
+ * @throws Typecho_Plugin_Exception
31
+ */
32
+ public static function deactivate ()
33
+ {
34
+ self ::deleteFile ();
35
+ }
36
+
37
+ /**
38
+ * 获取插件配置面板
39
+ *
40
+ * @access public
41
+ * @param Typecho_Widget_Helper_Form $form 配置面板
42
+ * @return void
43
+ */
44
+ public static function config (Typecho_Widget_Helper_Form $ form )
45
+ {
46
+ $ timeCache = new Typecho_Widget_Helper_Form_Element_Text ('timeCache ' , NULL , '1209600 ' , _t ('缓存时间 ' ),_t ('缓存时间,默认 14天 = 1209600 秒 ' ));
47
+ $ timeCache ->input ->setAttribute ('class ' , 'mini ' );
48
+ $ form ->addInput ($ timeCache ->addRule ('required ' , _t ('必须填写缓存时间 ' ))->addRule ('isInteger ' , _t ('缓存时间必须是整数 ' )));
49
+
50
+ $ dir = new Typecho_Widget_Helper_Form_Element_Text ('dir ' , null , '/usr/uploads/avatarCache/ ' , _t ('存放路径 ' ), _t ('缓存头像存放的路径,请确保第一个目录可写! ' ));
51
+ $ form ->addInput ($ dir ->addRule ('required ' , _t ('必须填写缓存目录 ' )));
52
+
53
+ $ delCache = new Typecho_Widget_Helper_Form_Element_Radio ( 'delCache ' , array ( 'delY ' => '是 ' , 'delN ' => '否 ' ), 'delY ' , '删除缓存 ' ,_t ('禁用插件时是否删除缓存头像和目录 ' ) );
54
+ $ form ->addInput ($ delCache );
55
+
56
+ return _t ('请到插件配置里设置相应选项 ' );
57
+ }
58
+
59
+ /**
60
+ * 个人用户的配置面板
61
+ *
62
+ * @access public
63
+ * @param Typecho_Widget_Helper_Form $form
64
+ * @return void
65
+ */
66
+ public static function personalConfig (Typecho_Widget_Helper_Form $ form ){}
67
+
68
+ /**
69
+ * 插件实现方法
70
+ *
71
+ * @param $size
72
+ * @param $rating
73
+ * @param $default
74
+ * @param $comments
75
+ */
76
+ public static function getGravatar ($ size , $ rating , $ default , $ comments )
77
+ {
78
+ $ imgUrl = self ::getGravatarCache ($ comments ->mail , $ comments ->request ->isSecure (), $ size , $ rating , $ default );
79
+ echo '<img class="avatar" src=" ' .$ imgUrl .' "alt=" ' .$ comments ->author .'" width=" ' .$ size .'" height=" ' .$ size .'" /> ' ;
80
+ }
81
+
82
+ /**
83
+ * 外部调用方法
84
+ *
85
+ * @param $mail
86
+ * @param bool $isSecure
87
+ * @param int $size
88
+ * @param string $rating
89
+ * @param string $default
90
+ * @return string
91
+ * @throws exception
92
+ */
93
+ public static function getGravatarCache ($ mail , $ isSecure = false , $ size = 32 , $ rating = 'G ' , $ default = 'mm ' )
94
+ {
95
+ $ option = Typecho_Widget::widget ('Widget_Options ' )->plugin ('GravatarCache ' );
96
+ $ siteUrl = Helper::options ()->siteUrl ;
97
+ $ dir = __TYPECHO_ROOT_DIR__ . DIRECTORY_SEPARATOR ;
98
+ $ referer = "http://www.gravatar.com " ;
99
+ $ path = $ option ->dir ;
100
+ $ path = substr ($ path , 0 , 1 ) == '/ ' ? substr ($ path , 1 ) : $ path ;
101
+ $ path = substr ($ path , -1 , 1 ) != '/ ' ? $ path .'/ ' : $ path ;
102
+ $ file = $ dir .$ path .'default.jpg ' ;
103
+ $ default = empty ($ default ) ? 'mm ' : $ default ;
104
+ $ default = $ default == 'mm ' ? $ default : urlencode ($ default );
105
+
106
+ if (!self ::mkdirs (dirname ($ file ))){
107
+ throw new exception ('GravatarCache 目录创建失败,请检查指定的根目录是否可写 ' );
108
+ }
109
+
110
+ /** 如果默认的 default.jpg不存在,则下载 gravatar 默认的头像到本地*/
111
+ if (!file_exists ($ file )){
112
+ $ avatar = 'http://www.gravatar.com/avatar/00000000000000000000000000000000?d= ' .$ default .'&s= ' .$ size .'&r= ' .$ rating ;
113
+ if (!self ::download ($ avatar , $ referer , $ file )) copy ($ avatar , $ file );
114
+ }
115
+
116
+ $ timeCache = $ option ->timeCache ;
117
+ $ defaultMail = empty ($ mail ) ? 'default ' : md5 ( strtolower ( $ mail ) );
118
+ $ imgUrl = $ siteUrl .$ path .$ defaultMail .'.jpg ' ;
119
+ $ baseFile = $ dir .$ path .$ defaultMail .'.jpg ' ;
120
+
121
+ if (!file_exists ($ baseFile ) || (time () - filemtime ($ baseFile )) > $ timeCache ){
122
+ $ host = $ isSecure ? 'https://secure.gravatar.com ' : 'http://www.gravatar.com ' ;
123
+ $ avatar = $ host .'/avatar/ ' .$ defaultMail .'?d= ' .$ default .'&s= ' .$ size .'&r= ' .$ rating ;
124
+ if (!self ::download ($ avatar , $ referer , $ baseFile )) copy ($ avatar , $ baseFile );
125
+ if (filesize ($ baseFile ) == 911 && filesize ($ file ) != 911 ) copy ($ file , $ baseFile );
126
+ }
127
+ return $ imgUrl ;
128
+ }
129
+
130
+ /**
131
+ * 生成多级目录
132
+ *
133
+ * @param $dir
134
+ * @return bool
135
+ */
136
+ public static function mkdirs ($ dir )
137
+ {
138
+ return is_dir ($ dir ) or (self ::mkdirs (dirname ($ dir )) and mkdir ($ dir , 0777 ));
139
+ }
140
+
141
+ /**
142
+ * 禁用插件时同时删除缓存头像
143
+ *
144
+ * @access public
145
+ * @return void
146
+ */
147
+ public static function deleteFile ()
148
+ {
149
+
150
+ $ option = Typecho_Widget::widget ('Widget_Options ' )->plugin ('GravatarCache ' );
151
+ $ path = __TYPECHO_ROOT_DIR__ . DIRECTORY_SEPARATOR . $ option ->dir ;
152
+ if (substr ($ path ,-1 )!='/ ' ) {$ path .='/ ' ;}
153
+ if ( $ option ->delCache == 'delY ' ){
154
+ foreach (glob ( $ path . '*.jpg ' ) as $ filename ) {
155
+ unlink ($ filename );
156
+ }
157
+ $ sysDir = array ( 'usr ' , 'uploads ' , 'themes ' , 'plugins ' );
158
+ $ dirArray = explode ("/ " , $ path );
159
+ array_pop ($ dirArray );
160
+ $ currentDir = array_pop ($ dirArray );
161
+
162
+ if (!in_array ( $ currentDir , $ sysDir )) { rmdir ($ path ); }
163
+ }
164
+ }
165
+
166
+ /**
167
+ * 下载头像到本地
168
+ *
169
+ * @param $url
170
+ * @param $referer
171
+ * @param $imagePath
172
+ * @return bool
173
+ */
174
+ public static function download ( $ url , $ referer , $ imagePath )
175
+ {
176
+ $ fpLocal = @fopen ( $ imagePath , 'w ' );
177
+ if ( !$ fpLocal ) {
178
+ return false ;
179
+ }
180
+
181
+ if ( is_callable ('curl_init ' ) ) {
182
+ $ ch = curl_init ();
183
+ curl_setopt ( $ ch , CURLOPT_URL , $ url );
184
+ curl_setopt ( $ ch , CURLOPT_REFERER , $ referer );
185
+ curl_setopt ( $ ch , CURLOPT_CONNECTTIMEOUT , 10 );
186
+ curl_setopt ( $ ch , CURLOPT_FOLLOWLOCATION , 1 );
187
+ curl_setopt ( $ ch , CURLOPT_HEADER , 0 );
188
+ curl_setopt ( $ ch , CURLOPT_FILE , $ fpLocal );
189
+ if ( !curl_exec ($ ch ) ) {
190
+ fclose ( $ fpLocal );
191
+ curl_close ( $ ch );
192
+ return false ;
193
+ }
194
+ curl_close ( $ ch );
195
+ }else {
196
+ $ opts = array (
197
+ 'http ' => array (
198
+ 'method ' => "GET " ,
199
+ 'header ' => "Referer: $ referer \r\n"
200
+ )
201
+ );
202
+
203
+ $ context = stream_context_create ( $ opts );
204
+ $ fpRemote = @fopen ( $ url , 'r ' , false , $ context );
205
+ if ( !$ fpRemote ) {
206
+ fclose ( $ fpLocal );
207
+ return false ;
208
+ }
209
+
210
+ while ( !feof ( $ fpRemote ) ) {
211
+ fwrite ( $ fpLocal , fread ($ fpRemote , 8192 ) );
212
+ }
213
+ fclose ( $ fpRemote );
214
+ }
215
+
216
+ fclose ( $ fpLocal );
217
+ return true ;
218
+ }
219
+ }
0 commit comments