OSDN Git Service

Merge branch 'skinnable-master'
[nucleus-jp/nucleus-next.git] / nucleus / libs / COMMENT.php
1 <<<<<<< HEAD
2 <?php\r
3 \r
4 /*\r
5  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)\r
6  * Copyright (C) 2002-2007 The Nucleus Group\r
7  *\r
8  * This program is free software; you can redistribute it and/or\r
9  * modify it under the terms of the GNU General Public License\r
10  * as published by the Free Software Foundation; either version 2\r
11  * of the License, or (at your option) any later version.\r
12  * (see nucleus/documentation/index.html#license for more info)\r
13  */\r
14 /**\r
15  * A class representing a single comment\r
16  *\r
17  * @license http://nucleuscms.org/license.txt GNU General Public License\r
18  * @copyright Copyright (C) 2002-2007 The Nucleus Group\r
19  * @version $Id: COMMENT.php 1844 2012-05-13 11:14:38Z sakamocchi $\r
20  */\r
21 class Comment\r
22 {\r
23         /**\r
24          * Comment::getComment()\r
25          * Returns the requested comment\r
26          *\r
27          * @static\r
28          * @param       integer $commentid      id for comment\r
29          * @return      array   comment information\r
30          * \r
31          */\r
32         static function getComment($commentid)\r
33         {\r
34                 $query = 'SELECT cnumber AS commentid,'\r
35                               . ' cbody AS body,'\r
36                               . ' cuser AS user,'\r
37                               . ' cmail AS userid,'\r
38                               . ' cemail AS email,'\r
39                               . ' cmember AS memberid,'\r
40                               . ' ctime,'\r
41                               . ' chost AS host,'\r
42                               . ' mname AS member,'\r
43                               . ' cip AS ip,'\r
44                               . ' cblog AS blogid'\r
45                        . ' FROM %s LEFT OUTER JOIN %s ON cmember = mnumber'\r
46                        . ' WHERE cnumber = %d;';\r
47                 \r
48                 $query = sprintf($query, sql_table('comment'), sql_table('member'), (integer) $commentid);\r
49                 $aCommentInfo = DB::getRow($query);\r
50                 \r
51                 if ( $aCommentInfo )\r
52                 {\r
53                         $aCommentInfo['timestamp'] = strtotime($aCommentInfo['ctime']);\r
54                 }\r
55                 \r
56                 return $aCommentInfo;\r
57         }\r
58         \r
59         /**\r
60          * Comment::prepare()\r
61          * Prepares a comment to be saved\r
62          *\r
63          * @static\r
64          * @param       array   $comment        comment data\r
65          * @return      array   comment date\r
66          * \r
67          */\r
68         static function prepare($comment)\r
69         {\r
70                 $comment['user']        = strip_tags($comment['user']);\r
71                 $comment['userid']      = strip_tags($comment['userid']);\r
72                 $comment['email']       = strip_tags($comment['email']);\r
73                 \r
74                 // remove newlines from user; remove quotes and newlines from userid and email; trim whitespace from beginning and end\r
75                 $comment['user']        = trim(strtr($comment['user'], "\n", ' ') );\r
76                 $comment['userid']      = trim(strtr($comment['userid'], "\'\"\n", '-- ') );\r
77                 $comment['email']       = trim(strtr($comment['email'], "\'\"\n", '-- ') );\r
78                 \r
79                 // begin if: a comment userid is supplied, but does not have an "http://" or "https://" at the beginning - prepend an "http://"\r
80                 if ( array_key_exists('userid', $comment)\r
81                   && !empty($comment['userid'])\r
82                   && (i18n::strpos($comment['userid'], 'http://') !== 0)\r
83                   && (i18n::strpos($comment['userid'], 'https://') !== 0) )\r
84                 {\r
85                         $comment['userid'] = 'http://' . $comment['userid'];\r
86                 }\r
87                 \r
88                 $comment['body'] = Comment::prepareBody($comment['body']);\r
89                 \r
90                 return $comment;\r
91         }\r
92         \r
93         /**\r
94          * Comment::prepareBody()\r
95          * Prepares the body of a comment\r
96          *\r
97          * @static\r
98          * @param       string  $body   string for comment body\r
99          * @return      string  validate string for comment body\r
100          */\r
101         static public function prepareBody($body)\r
102         {\r
103                 // convert Windows and Mac style 'returns' to *nix newlines\r
104                 $body = preg_replace("/\r\n/", "\n", $body);\r
105                 $body = preg_replace("/\r/", "\n", $body);\r
106                 \r
107                 // then remove newlines when too many in a row (3 or more newlines get converted to 1 newline)\r
108                 $body = preg_replace("/\n{3,}/", "\n\n", $body);\r
109                 \r
110                 // encode special characters as entities\r
111                 $body = Entity::hsc($body);\r
112                 \r
113                 // trim away whitespace and newlines at beginning and end\r
114                 $body = trim($body);\r
115                 \r
116                 // add <br /> tags\r
117                 $body = addBreaks($body);\r
118                 \r
119                 // create hyperlinks for http:// addresses\r
120                 // there's a testcase for this in /build/testcases/urllinking.txt\r
121                 $replace_from = array(\r
122                         '/([^:\/\/\w]|^)((https:\/\/)([\w\.-]+)([\/\w+\.~%&?@=_:;#,-]+))/i',\r
123                         '/([^:\/\/\w]|^)((http:\/\/|www\.)([\w\.-]+)([\/\w+\.~%&?@=_:;#,-]+))/i',\r
124                         '/([^:\/\/\w]|^)((ftp:\/\/|ftp\.)([\w\.-]+)([\/\w+\.~%&?@=_:;#,-]+))/i',\r
125                         '/([^:\/\/\w]|^)(mailto:(([a-zA-Z\@\%\.\-\+_])+))/i'\r
126                 );\r
127                 \r
128                 return preg_replace_callback($replace_from, array(__CLASS__, 'prepareBody_cb'), $body);\r
129         }\r
130         \r
131         /**\r
132          * Comment::createLinkCode()\r
133          * Creates a link code for unlinked URLs with different protocols\r
134          *\r
135          * @static\r
136          * @param       string  $pre    Prefix of comment\r
137          * @param       string  $url    URL\r
138          * @param       string  $protocol       http, mailto and so on\r
139          * @return      string  string  including anchor element and child text\r
140          */\r
141         static private function createLinkCode($pre, $url, $protocol = 'http')\r
142         {\r
143                 $post = '';\r
144                 \r
145                 // it's possible that $url ends contains entities we don't want,\r
146                 // since htmlspecialchars is applied _before_ URL linking\r
147                 // move the part of URL, starting from the disallowed entity to the 'post' link part\r
148                 $aBadEntities = array('&quot;', '&gt;', '&lt;');\r
149                 foreach ( $aBadEntities as $entity )\r
150                 {\r
151                         $pos = i18n::strpos($url, $entity);\r
152                         \r
153                         if ( $pos )\r
154                         {\r
155                                 $post = i18n::substr($url, $pos) . $post;\r
156                                 $url = i18n::substr($url, 0, $pos);\r
157                         }\r
158                 }\r
159                 \r
160                 // remove entities at end (&&&&)\r
161                 if ( preg_match('/(&\w+;)+$/i', $url, $matches) )\r
162                 {\r
163                         $post = $matches[0] . $post;    // found entities (1 or more)\r
164                         $url = i18n::substr($url, 0, i18n::strlen($url) - i18n::strlen($post) );\r
165                 }\r
166                 \r
167                 // move ending comma from url to 'post' part\r
168                 if ( i18n::substr($url, i18n::strlen($url) - 1) == ',' )\r
169                 {\r
170                         $url = i18n::substr($url, 0, i18n::strlen($url) - 1);\r
171                         $post = ',' . $post;\r
172                 }\r
173                 \r
174                 if ( !preg_match('#^' . $protocol . '://#', $url) )\r
175                 {\r
176                         $linkedUrl = $protocol . ( ($protocol == 'mailto') ? ':' : '://') . $url;\r
177                 }\r
178                 else\r
179                 {\r
180                         $linkedUrl = $url;\r
181                 }\r
182                 \r
183                 if ( $protocol != 'mailto' )\r
184                 {\r
185                         $displayedUrl = $linkedUrl;\r
186                 }\r
187                 else\r
188                 {\r
189                         $displayedUrl = $url;\r
190                 }\r
191                 \r
192                 return $pre . '<a href="' . $linkedUrl . '" rel="nofollow">' . Entity::hsc(Entity::shorten($displayedUrl,30,'...')) . '</a>' . $post;\r
193         }\r
194         \r
195         /**\r
196          * Comment::prepareBody_cb()\r
197          * This method is a callback for creating link codes\r
198          * \r
199          * @param       array   $match  elements for achor\r
200          * @return      string  including anchor element and child text\r
201          * \r
202          */\r
203         static public function prepareBody_cb($match)\r
204         {\r
205                 if ( !preg_match('/^[a-z]+/i', $match[2], $protocol) )\r
206                 {\r
207                         return $match[0];\r
208                 }\r
209                 \r
210                 switch( strtolower($protocol[0]) )\r
211                 {\r
212                         case 'https':\r
213                                 return self::createLinkCode($match[1], $match[2], 'https');\r
214                         break;\r
215                         \r
216                         case 'ftp':\r
217                                 return self::createLinkCode($match[1], $match[2], 'ftp');\r
218                         break;\r
219                         \r
220                         case 'mailto':\r
221                                 return self::createLinkCode($match[1], $match[3], 'mailto');\r
222                         break;\r
223                         \r
224                         default:\r
225                                 return self::createLinkCode($match[1], $match[2], 'http');\r
226                         break;\r
227                 }\r
228                 return;\r
229         }\r
230 }\r
231 =======
232 <?php
233
234 /*
235  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
236  * Copyright (C) 2002-2007 The Nucleus Group
237  *
238  * This program is free software; you can redistribute it and/or
239  * modify it under the terms of the GNU General Public License
240  * as published by the Free Software Foundation; either version 2
241  * of the License, or (at your option) any later version.
242  * (see nucleus/documentation/index.html#license for more info)
243  */
244 /**
245  * A class representing a single comment
246  *
247  * @license http://nucleuscms.org/license.txt GNU General Public License
248  * @copyright Copyright (C) 2002-2007 The Nucleus Group
249  * @version $Id: COMMENT.php 1844 2012-05-13 11:14:38Z sakamocchi $
250  */
251 class Comment 
252 {
253         /**
254          * Comment::getComment()
255          * Returns the requested comment
256          *
257          * @static
258          * @param       integer $commentid      id for comment
259          * @return      array   comment information
260          * 
261          */
262         static function getComment($commentid)
263         {
264                 $query = 'SELECT cnumber AS commentid,'
265                               . ' cbody AS body,'
266                               . ' cuser AS user,'
267                               . ' cmail AS userid,'
268                               . ' cemail AS email,'
269                               . ' cmember AS memberid,'
270                               . ' ctime,'
271                               . ' chost AS host,'
272                               . ' mname AS member,'
273                               . ' cip AS ip,'
274                               . ' cblog AS blogid'
275                        . ' FROM %s LEFT OUTER JOIN %s ON cmember = mnumber'
276                        . ' WHERE cnumber = %d;';
277                 
278                 $query = sprintf($query, sql_table('comment'), sql_table('member'), (integer) $commentid);
279                 $aCommentInfo = DB::getRow($query);
280                 
281                 if ( $aCommentInfo )
282                 {
283                         $aCommentInfo['timestamp'] = strtotime($aCommentInfo['ctime']);
284                 }
285                 
286                 return $aCommentInfo;
287         }
288         
289         /**
290          * Comment::prepare()
291          * Prepares a comment to be saved
292          *
293          * @static
294          * @param       array   $comment        comment data
295          * @return      array   comment date
296          * 
297          */
298         static function prepare($comment)
299         {
300                 $comment['user']        = strip_tags($comment['user']);
301                 $comment['userid']      = strip_tags($comment['userid']);
302                 $comment['email']       = strip_tags($comment['email']);
303                 
304                 // remove newlines from user; remove quotes and newlines from userid and email; trim whitespace from beginning and end
305                 $comment['user']        = trim(strtr($comment['user'], "\n", ' ') );
306                 $comment['userid']      = trim(strtr($comment['userid'], "\'\"\n", '-- ') );
307                 $comment['email']       = trim(strtr($comment['email'], "\'\"\n", '-- ') );
308                 
309                 // begin if: a comment userid is supplied, but does not have an "http://" or "https://" at the beginning - prepend an "http://"
310                 if ( array_key_exists('userid', $comment)
311                   && !empty($comment['userid'])
312                   && (i18n::strpos($comment['userid'], 'http://') !== 0)
313                   && (i18n::strpos($comment['userid'], 'https://') !== 0) )
314                 {
315                         $comment['userid'] = 'http://' . $comment['userid'];
316                 }
317                 
318                 $comment['body'] = Comment::prepareBody($comment['body']);
319                 
320                 return $comment;
321         }
322         
323         /**
324          * Comment::prepareBody()
325          * Prepares the body of a comment
326          *
327          * @static
328          * @param       string  $body   string for comment body
329          * @return      string  validate string for comment body
330          */
331         static public function prepareBody($body)
332         {
333                 // convert Windows and Mac style 'returns' to *nix newlines
334                 $body = preg_replace("/\r\n/", "\n", $body);
335                 $body = preg_replace("/\r/", "\n", $body);
336                 
337                 // then remove newlines when too many in a row (3 or more newlines get converted to 1 newline)
338                 $body = preg_replace("/\n{3,}/", "\n\n", $body);
339                 
340                 // encode special characters as entities
341                 $body = Entity::hsc($body);
342                 
343                 // trim away whitespace and newlines at beginning and end
344                 $body = trim($body);
345                 
346                 // add <br /> tags
347                 $body = addBreaks($body);
348                 
349                 // create hyperlinks for http:// addresses
350                 // there's a testcase for this in /build/testcases/urllinking.txt
351                 $replace_from = array(
352                         '/([^:\/\/\w]|^)((https:\/\/)([\w\.-]+)([\/\w+\.~%&?@=_:;#,-]+))/i',
353                         '/([^:\/\/\w]|^)((http:\/\/|www\.)([\w\.-]+)([\/\w+\.~%&?@=_:;#,-]+))/i',
354                         '/([^:\/\/\w]|^)((ftp:\/\/|ftp\.)([\w\.-]+)([\/\w+\.~%&?@=_:;#,-]+))/i',
355                         '/([^:\/\/\w]|^)(mailto:(([a-zA-Z\@\%\.\-\+_])+))/i'
356                 );
357                 
358                 return preg_replace_callback($replace_from, array(__CLASS__, 'prepareBody_cb'), $body);
359         }
360         
361         /**
362          * Comment::createLinkCode()
363          * Creates a link code for unlinked URLs with different protocols
364          *
365          * @static
366          * @param       string  $pre    Prefix of comment
367          * @param       string  $url    URL
368          * @param       string  $protocol       http, mailto and so on
369          * @return      string  string  including anchor element and child text
370          */
371         static private function createLinkCode($pre, $url, $protocol = 'http')
372         {
373                 $post = '';
374                 
375                 // it's possible that $url ends contains entities we don't want,
376                 // since htmlspecialchars is applied _before_ URL linking
377                 // move the part of URL, starting from the disallowed entity to the 'post' link part
378                 $aBadEntities = array('&quot;', '&gt;', '&lt;');
379                 foreach ( $aBadEntities as $entity )
380                 {
381                         $pos = i18n::strpos($url, $entity);
382                         
383                         if ( $pos )
384                         {
385                                 $post = i18n::substr($url, $pos) . $post;
386                                 $url = i18n::substr($url, 0, $pos);
387                         }
388                 }
389                 
390                 // remove entities at end (&&&&)
391                 if ( preg_match('/(&\w+;)+$/i', $url, $matches) )
392                 {
393                         $post = $matches[0] . $post;    // found entities (1 or more)
394                         $url = i18n::substr($url, 0, i18n::strlen($url) - i18n::strlen($post) );
395                 }
396                 
397                 // move ending comma from url to 'post' part
398                 if ( i18n::substr($url, i18n::strlen($url) - 1) == ',' )
399                 {
400                         $url = i18n::substr($url, 0, i18n::strlen($url) - 1);
401                         $post = ',' . $post;
402                 }
403                 
404                 if ( !preg_match('#^' . $protocol . '://#', $url) )
405                 {
406                         $linkedUrl = $protocol . ( ($protocol == 'mailto') ? ':' : '://') . $url;
407                 }
408                 else
409                 {
410                         $linkedUrl = $url;
411                 }
412                 
413                 if ( $protocol != 'mailto' )
414                 {
415                         $displayedUrl = $linkedUrl;
416                 }
417                 else
418                 {
419                         $displayedUrl = $url;
420                 }
421                 
422                 return $pre . '<a href="' . $linkedUrl . '" rel="nofollow">' . Entity::hsc(Entity::shorten($displayedUrl,30,'...')) . '</a>' . $post;
423         }
424         
425         /**
426          * Comment::prepareBody_cb()
427          * This method is a callback for creating link codes
428          * 
429          * @param       array   $match  elements for achor
430          * @return      string  including anchor element and child text
431          * 
432          */
433         static public function prepareBody_cb($match)
434         {
435                 if ( !preg_match('/^[a-z]+/i', $match[2], $protocol) )
436                 {
437                         return $match[0];
438                 }
439                 
440                 switch( strtolower($protocol[0]) )
441                 {
442                         case 'https':
443                                 return self::createLinkCode($match[1], $match[2], 'https');
444                         break;
445                         
446                         case 'ftp':
447                                 return self::createLinkCode($match[1], $match[2], 'ftp');
448                         break;
449                         
450                         case 'mailto':
451                                 return self::createLinkCode($match[1], $match[3], 'mailto');
452                         break;
453                         
454                         default:
455                                 return self::createLinkCode($match[1], $match[2], 'http');
456                         break;
457                 }
458                 return;
459         }
460 }
461 >>>>>>> skinnable-master