OSDN Git Service

FIX: リファレンスにまつわるコードを修正
[nucleus-jp/nucleus-next.git] / nucleus / libs / COMMENT.php
1 <?php
2
3 /*
4  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
5  * Copyright (C) 2002-2007 The Nucleus Group
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  * (see nucleus/documentation/index.html#license for more info)
12  */
13 /**
14  * A class representing a single comment
15  *
16  * @license http://nucleuscms.org/license.txt GNU General Public License
17  * @copyright Copyright (C) 2002-2007 The Nucleus Group
18  * @version $Id: COMMENT.php 1844 2012-05-13 11:14:38Z sakamocchi $
19  */
20 class Comment 
21 {
22         /**
23          * Comment::getComment()
24          * Returns the requested comment
25          *
26          * @static
27          * @param       integer $commentid      id for comment
28          * @return      array   comment information
29          * 
30          */
31         static function getComment($commentid)
32         {
33                 $query = 'SELECT cnumber AS commentid,'
34                               . ' cbody AS body,'
35                               . ' cuser AS user,'
36                               . ' cmail AS userid,'
37                               . ' cemail AS email,'
38                               . ' cmember AS memberid,'
39                               . ' ctime,'
40                               . ' chost AS host,'
41                               . ' mname AS member,'
42                               . ' cip AS ip,'
43                               . ' cblog AS blogid'
44                        . ' FROM %s LEFT OUTER JOIN %s ON cmember = mnumber'
45                        . ' WHERE cnumber = %d;';
46                 
47                 $query = sprintf($query, sql_table('comment'), sql_table('member'), (integer) $commentid);
48                 $aCommentInfo = DB::getRow($query);
49                 
50                 if ( $aCommentInfo )
51                 {
52                         $aCommentInfo['timestamp'] = strtotime($aCommentInfo['ctime']);
53                 }
54                 
55                 return $aCommentInfo;
56         }
57         
58         /**
59          * Comment::prepare()
60          * Prepares a comment to be saved
61          *
62          * @static
63          * @param       array   $comment        comment data
64          * @return      array   comment date
65          * 
66          */
67         static function prepare($comment)
68         {
69                 $comment['user']        = strip_tags($comment['user']);
70                 $comment['userid']      = strip_tags($comment['userid']);
71                 $comment['email']       = strip_tags($comment['email']);
72                 
73                 // remove newlines from user; remove quotes and newlines from userid and email; trim whitespace from beginning and end
74                 $comment['user']        = trim(strtr($comment['user'], "\n", ' ') );
75                 $comment['userid']      = trim(strtr($comment['userid'], "\'\"\n", '-- ') );
76                 $comment['email']       = trim(strtr($comment['email'], "\'\"\n", '-- ') );
77                 
78                 // begin if: a comment userid is supplied, but does not have an "http://" or "https://" at the beginning - prepend an "http://"
79                 if ( array_key_exists('userid', $comment)
80                   && !empty($comment['userid'])
81                   && (i18n::strpos($comment['userid'], 'http://') !== 0)
82                   && (i18n::strpos($comment['userid'], 'https://') !== 0) )
83                 {
84                         $comment['userid'] = 'http://' . $comment['userid'];
85                 }
86                 
87                 $comment['body'] = Comment::prepareBody($comment['body']);
88                 
89                 return $comment;
90         }
91         
92         /**
93          * Comment::prepareBody()
94          * Prepares the body of a comment
95          *
96          * @static
97          * @param       string  $body   string for comment body
98          * @return      string  validate string for comment body
99          */
100         static public function prepareBody($body)
101         {
102                 // convert Windows and Mac style 'returns' to *nix newlines
103                 $body = preg_replace("/\r\n/", "\n", $body);
104                 $body = preg_replace("/\r/", "\n", $body);
105                 
106                 // then remove newlines when too many in a row (3 or more newlines get converted to 1 newline)
107                 $body = preg_replace("/\n{3,}/", "\n\n", $body);
108                 
109                 // encode special characters as entities
110                 $body = Entity::hsc($body);
111                 
112                 // trim away whitespace and newlines at beginning and end
113                 $body = trim($body);
114                 
115                 // add <br /> tags
116                 $body = addBreaks($body);
117                 
118                 // create hyperlinks for http:// addresses
119                 // there's a testcase for this in /build/testcases/urllinking.txt
120                 $replace_from = array(
121                         '/([^:\/\/\w]|^)((https:\/\/)([\w\.-]+)([\/\w+\.~%&?@=_:;#,-]+))/i',
122                         '/([^:\/\/\w]|^)((http:\/\/|www\.)([\w\.-]+)([\/\w+\.~%&?@=_:;#,-]+))/i',
123                         '/([^:\/\/\w]|^)((ftp:\/\/|ftp\.)([\w\.-]+)([\/\w+\.~%&?@=_:;#,-]+))/i',
124                         '/([^:\/\/\w]|^)(mailto:(([a-zA-Z\@\%\.\-\+_])+))/i'
125                 );
126                 
127                 return preg_replace_callback($replace_from, array(__CLASS__, 'prepareBody_cb'), $body);
128         }
129         
130         /**
131          * Comment::createLinkCode()
132          * Creates a link code for unlinked URLs with different protocols
133          *
134          * @static
135          * @param       string  $pre    Prefix of comment
136          * @param       string  $url    URL
137          * @param       string  $protocol       http, mailto and so on
138          * @return      string  string  including anchor element and child text
139          */
140         static private function createLinkCode($pre, $url, $protocol = 'http')
141         {
142                 $post = '';
143                 
144                 // it's possible that $url ends contains entities we don't want,
145                 // since htmlspecialchars is applied _before_ URL linking
146                 // move the part of URL, starting from the disallowed entity to the 'post' link part
147                 $aBadEntities = array('&quot;', '&gt;', '&lt;');
148                 foreach ( $aBadEntities as $entity )
149                 {
150                         $pos = i18n::strpos($url, $entity);
151                         
152                         if ( $pos )
153                         {
154                                 $post = i18n::substr($url, $pos) . $post;
155                                 $url = i18n::substr($url, 0, $pos);
156                         }
157                 }
158                 
159                 // remove entities at end (&&&&)
160                 if ( preg_match('/(&\w+;)+$/i', $url, $matches) )
161                 {
162                         $post = $matches[0] . $post;    // found entities (1 or more)
163                         $url = i18n::substr($url, 0, i18n::strlen($url) - i18n::strlen($post) );
164                 }
165                 
166                 // move ending comma from url to 'post' part
167                 if ( i18n::substr($url, i18n::strlen($url) - 1) == ',' )
168                 {
169                         $url = i18n::substr($url, 0, i18n::strlen($url) - 1);
170                         $post = ',' . $post;
171                 }
172                 
173                 if ( !preg_match('#^' . $protocol . '://#', $url) )
174                 {
175                         $linkedUrl = $protocol . ( ($protocol == 'mailto') ? ':' : '://') . $url;
176                 }
177                 else
178                 {
179                         $linkedUrl = $url;
180                 }
181                 
182                 if ( $protocol != 'mailto' )
183                 {
184                         $displayedUrl = $linkedUrl;
185                 }
186                 else
187                 {
188                         $displayedUrl = $url;
189                 }
190                 
191                 return $pre . '<a href="' . $linkedUrl . '" rel="nofollow">' . Entity::hsc(Entity::shorten($displayedUrl,30,'...')) . '</a>' . $post;
192         }
193         
194         /**
195          * Comment::prepareBody_cb()
196          * This method is a callback for creating link codes
197          * 
198          * @param       array   $match  elements for achor
199          * @return      string  including anchor element and child text
200          * 
201          */
202         static public function prepareBody_cb($match)
203         {
204                 if ( !preg_match('/^[a-z]+/i', $match[2], $protocol) )
205                 {
206                         return $match[0];
207                 }
208                 
209                 switch( strtolower($protocol[0]) )
210                 {
211                         case 'https':
212                                 return self::createLinkCode($match[1], $match[2], 'https');
213                         break;
214                         
215                         case 'ftp':
216                                 return self::createLinkCode($match[1], $match[2], 'ftp');
217                         break;
218                         
219                         case 'mailto':
220                                 return self::createLinkCode($match[1], $match[3], 'mailto');
221                         break;
222                         
223                         default:
224                                 return self::createLinkCode($match[1], $match[2], 'http');
225                         break;
226                 }
227                 return;
228         }
229 }