1 <?php
2
3 /*
4 * This file is part of the Icybee package.
5 *
6 * (c) Olivier Laviale <olivier.laviale@gmail.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12 namespace Icybee\Modules\Comments;
13
14 use ICanBoogie\DateTime;
15
16 /**
17 * A comment.
18 *
19 * @property DateTime $created_at The date and time at which the node was created.
20 * @property DateTime $updated_at The date and time at which the node was updated.
21 * @property-read string $absolute_url URL of the comment.
22 * @property-read string $author_icon URL of the author's Gravatar.
23 * @property-read string $css_class A suitable string for the HTML `class` attribute.
24 * @property-read array $css_class_names CSS class names.
25 * @property-read string $excerpt HTML excerpt of the comment, made of the first 55 words.
26 * @property-read bool $is_author `true` if the author of the comment is the author of the attached node.
27 * @property-read \Icybee\Modules\Nodes\Node $node The node the comment is attached to.
28 * @property-read string $url URL of the comment relative to the website.
29 */
30 class Comment extends \ICanBoogie\ActiveRecord implements \Brickrouge\CSSClassNames
31 {
32 use \Brickrouge\CSSClassNamesProperty;
33
34 const COMMENTID = 'commentid';
35 const NID = 'nid';
36 const PARENTID = 'parentid';
37 const UID = 'uid';
38 const AUTHOR = 'author';
39 const AUTHOR_EMAIL = 'author_email';
40 const AUTHOR_URL = 'author_url';
41 const AUTHOR_IP = 'author_ip';
42 const CONTENTS = 'contents';
43 const STATUS = 'status';
44 const STATUS_APPROVED = 'approved';
45 const STATUS_PENDING = 'pending';
46 const STATUS_SPAM = 'spam';
47 const NOTIFY = 'notify';
48 const CREATED_AT = 'created_at';
49 const UPDATED_AT = 'updated_at';
50
51 /**
52 * Comment identifier.
53 *
54 * @var int
55 */
56 public $commentid;
57
58 /**
59 * Node identifier.
60 *
61 * @var int
62 */
63 public $nid;
64
65 /**
66 * Parent comment identifier.
67 *
68 * @var int
69 */
70 public $parentid;
71
72 /**
73 * User identifier.
74 *
75 * The user identifier is zero (0) if the user is a guest.
76 *
77 * @var int
78 */
79 public $uid;
80
81 /**
82 * Author name.
83 *
84 * @var string
85 */
86 public $author;
87
88 /**
89 * Author email.
90 *
91 * @var string
92 */
93 public $author_email;
94
95 /**
96 * Author's website URL.
97 *
98 * @var string
99 */
100 public $author_url;
101
102 /**
103 * Author IP.
104 *
105 * @var string
106 */
107 public $author_ip;
108
109 /**
110 * Body of the comment.
111 *
112 * @var string
113 */
114 public $contents;
115
116 /**
117 * Status. One of `pending`, `approved` and `spam`.
118 *
119 * @var string
120 */
121 public $status;
122
123 /**
124 * Notify status. One of `no`, `yes`, `author` and `done`.
125 *
126 * @var string
127 */
128 public $notify;
129
130 /**
131 * The date and time the comment was created.
132 *
133 * @var \ICanBoogie\DateTime
134 */
135 private $created_at;
136
137 /**
138 * Returns the date and time the comment was created.
139 *
140 * @return \ICanBoogie\DateTime
141 */
142 protected function get_created_at()
143 {
144 $datetime = $this->created_at;
145
146 if ($datetime instanceof DateTime)
147 {
148 return $datetime;
149 }
150
151 return $this->created_at = ($datetime === null) ? DateTime::none() : new DateTime($datetime, 'utc');
152 }
153
154 /**
155 * Sets the date and time the comment was created.
156 *
157 * @param \DateTime|string $datetime
158 */
159 protected function set_created_at($datetime)
160 {
161 $this->created_at = $datetime;
162 }
163
164 /**
165 * The date and time the comment was updated.
166 *
167 * @var \ICanBoogie\DateTime
168 */
169 private $updated_at;
170
171 /**
172 * Returns the date and time the comment was updated.
173 *
174 * @return \ICanBoogie\DateTime
175 */
176 protected function get_updated_at()
177 {
178 $datetime = $this->updated_at;
179
180 if ($datetime instanceof DateTime)
181 {
182 return $datetime;
183 }
184
185 return $this->updated_at = ($datetime === null) ? DateTime::none() : new DateTime($datetime, 'utc');
186 }
187
188 /**
189 * Sets the date and time the comment was updated.
190 *
191 * @param \DateTime|string $datetime
192 */
193 protected function set_updated_at($datetime)
194 {
195 $this->updated_at = $datetime;
196 }
197
198 /**
199 * Defaults model to "comments".
200 */
201 public function __construct($model='comments')
202 {
203 parent::__construct($model);
204 }
205
206 /**
207 * Returns the URL of the comment.
208 *
209 * The URL of the comment is created from the URL of the node and to identifier of the comment
210 * using the following pattern: `{node.url}#comment{commentid}`.
211 *
212 * @return string
213 */
214 protected function get_url()
215 {
216 $node = $this->node;
217
218 return ($node ? $this->node->url : '#unknown-node-' . $this->nid) . '#comment-' . $this->commentid;
219 }
220
221 /**
222 * Returns the absolute URL of the comment.
223 *
224 * @return string
225 */
226 protected function get_absolute_url()
227 {
228 $node = $this->node;
229
230 return ($node ? $this->node->absolute_url : '#unknown-node-' . $this->nid) . '#comment-' . $this->commentid;
231 }
232
233 /**
234 * Returns the URL of the author's Gravatar.
235 *
236 * @return string
237 */
238 protected function get_author_icon()
239 {
240 $hash = md5(strtolower(trim($this->author_email)));
241
242 return 'http://www.gravatar.com/avatar/' . $hash . '.jpg?' . http_build_query
243 (
244 array
245 (
246 'd' => 'identicon'
247 )
248 );
249 }
250
251 /**
252 * Returns an HTML excerpt of the comment.
253 *
254 * @param int $limit The maximum number of words to use to create the excerpt. Defaults to 55.
255 *
256 * @return string
257 */
258 public function excerpt($limit=55)
259 {
260 return \ICanBoogie\excerpt((string) $this, $limit);
261 }
262
263 /**
264 * Returns an HTML excerpt of the comment.
265 *
266 * @return string
267 */
268 protected function lazy_get_excerpt()
269 {
270 return $this->excerpt();
271 }
272
273 /**
274 * Whether the author of the node is the author of the comment.
275 *
276 * @return boolean `true` if the author is the same, `false` otherwise.
277 */
278 protected function get_is_author()
279 {
280 return $this->node->uid == $this->uid;
281 }
282
283 /**
284 * Returns the CSS class names of the comment.
285 *
286 * @return array[string]mixed
287 */
288 protected function get_css_class_names()
289 {
290 return array
291 (
292 'type' => 'comment',
293 'id' => 'comment-' . $this->commentid,
294 'author-reply' => $this->is_author
295 );
296 }
297
298 /**
299 * Renders the comment into a HTML string.
300 *
301 * @return string
302 */
303 public function __toString()
304 {
305 $str = \Textmark_Parser::parse($this->contents);
306
307 return \Icybee\Kses::sanitizeComment($str);
308 }
309 }