PluginProbe
wpForo Forum / 1.4.13
wpForo Forum v1.4.13
3.1.5 3.1.4 3.1.2 3.1.1 3.1.0 3.0.9 3.0.8 3.0.7 trunk 1.0.0 1.0.1 1.0.2 1.1.0 1.1.1 1.1.2 1.2.0 1.3.0 1.3.1 1.4.0 1.4.1 1.4.10 1.4.11 1.4.12 1.4.13 1.4.2 All 137 releases
wpforo / wpf-includes / class-posts.php

class-posts.php in wpForo Forum 1.4.13, at wpf-includes/class-posts.php

1,009 lines 37.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // Exit if accessed directly
3 if( !defined( 'ABSPATH' ) ) exit;
4
5 class wpForoPost{
6 public $default;
7 public $options;
8
9 public static $cache = array( 'posts' => array(), 'post' => array(), 'item' => array(), 'topic_slug' => array(), 'forum_slug' => array(), 'post_url' => array() );
10
11 function __construct(){
12 $this->init_defaults();
13 $this->init_options();
14 }
15
16 private function init_defaults(){
17 $this->default = new stdClass;
18
19 $upload_max_filesize = @ini_get('upload_max_filesize');
20 $upload_max_filesize = wpforo_human_size_to_bytes($upload_max_filesize);
21 if( !$upload_max_filesize || $upload_max_filesize > 10485760 ) $upload_max_filesize = 10485760;
22
23 $this->default->options = array(
24 'layout_extended_intro_posts_toggle' => 1,
25 'layout_extended_intro_posts_count' => 4,
26 'layout_extended_intro_posts_length' => 50,
27 'recent_posts_type' => 'topics',
28 'topics_per_page' => 10,
29 'eot_durr' => 300,
30 'dot_durr' => 300,
31 'posts_per_page' => 15,
32 'eor_durr' => 300,
33 'dor_durr' => 300,
34 'max_upload_size' => $upload_max_filesize,
35 'attach_cant_view_msg' => __("You are not permitted to view this attachment", 'wpforo')
36 );
37 }
38
39 private function init_options(){
40 $this->options = get_wpf_option('wpforo_post_options', $this->default->options);
41 }
42
43 public function get_cache( $var ){
44 if( isset(self::$cache[$var]) ) return self::$cache[$var];
45 }
46
47 public function add( $args = array() ){
48
49 //This variable will be based on according CAN of guest usergroup once Guest Posing is ready
50 $guestposting = false;
51
52 if( empty($args) && empty($_REQUEST['post']) ){ WPF()->notice->add('Reply request error', 'error'); return FALSE; }
53 if( empty($args) && !empty($_REQUEST['post']) ){ $args = $_REQUEST['post']; $args['body'] = $_REQUEST['postbody']; }
54 if( !isset($args['body']) || !$args['body'] ){ WPF()->notice->add('Post is empty', 'error'); return FALSE; }
55 $args['name'] = (isset($args['name']) ? strip_tags($args['name']) : '' );
56 $args['email'] = (isset($args['email']) ? sanitize_email($args['email']) : '' );
57 if( isset($args['userid']) && $args['userid'] == 0 && $args['name'] && $args['email'] ) $guestposting = true;
58
59 extract($args);
60
61 if( !isset($topicid) || !$topicid ){ WPF()->notice->add('Error: No topic selected', 'error'); return FALSE; }
62 if( !$topic = WPF()->topic->get_topic(intval($topicid)) ){ WPF()->notice->add('Error: Topic is not found', 'error'); return FALSE; }
63 if( !$forum = WPF()->forum->get_forum(intval($topic['forumid'])) ){ WPF()->notice->add('Error: Forum is not found', 'error'); return FALSE; }
64
65 if( $topic['closed'] ){
66 WPF()->notice->add('Can\'t write a post: This topic is closed', 'error');
67 return FALSE;
68 }
69
70 if( !$guestposting && !WPF()->perm->forum_can('cr', $topic['forumid']) ){
71 WPF()->notice->add('You don\'t have permission to create post in this forum', 'error');
72 return FALSE;
73 }
74
75 if( !is_user_logged_in() ){
76 if( !$args['name'] || !$args['email'] ){
77 WPF()->notice->add('Please insert required fields!', 'error');
78 return FALSE;
79 }
80 else{
81 WPF()->member->set_guest_cookies( $args );
82 }
83 }
84
85 do_action( 'wpforo_start_add_post', $args );
86
87 $post = $args;
88 $post['forumid'] = $forumid = (isset($topic['forumid']) ? intval($topic['forumid']) : 0);
89 $post['parentid'] = $parentid = (isset($parentid) ? intval($parentid) : 0);
90 $post['title'] = $title = (isset($title) ? wpforo_text( trim($title), 250, false ) : '');
91 $post['body'] = $body = ( isset($body) ? preg_replace('#</pre>[\r\n\t\s\0]*<pre>#isu', "\r\n", $body) : '' );
92 $post['created'] = $created = ( isset($created) ? $created : current_time( 'mysql', 1 ) );
93 $post['userid'] = $userid = ( isset($userid) ? intval($userid) : WPF()->current_userid );
94
95 $post = apply_filters('wpforo_add_post_data_filter', $post);
96
97 if(empty($post)) return FALSE;
98
99 extract($post, EXTR_OVERWRITE);
100
101 if(isset($forumid)) $forumid = intval($forumid);
102 if(isset($topicid)) $topicid = intval($topicid);
103 if(isset($parentid)) $parentid = intval($parentid);
104 if(isset($title)) $title = sanitize_text_field(trim($title));
105 if(isset($created)) $created = sanitize_text_field($created);
106 if(isset($userid)) $userid = intval($userid);
107 if(isset($body)) $body = wpforo_kses(trim($body), 'post');
108 $status = ( isset($status) && $status ? 1 : 0 );
109 $private = ( isset($topic['private']) && $topic['private'] ? 1 : 0 );
110 if(isset($name)) $name = strip_tags(trim($name));
111 if(isset($email)) $email = strip_tags(trim($email));
112
113 do_action( 'wpforo_before_add_post', $post );
114
115 if(
116 WPF()->db->insert(
117 WPF()->tables->posts,
118 array(
119 'forumid' => $forumid,
120 'topicid' => $topicid,
121 'parentid' => $parentid,
122 'userid' => $userid,
123 'title' => stripslashes($title),
124 'body' => stripslashes($body),
125 'created' => $created,
126 'modified' => $created,
127 'status' => $status,
128 'private' => $private,
129 'name' => $name,
130 'email' => $email
131 ),
132 array('%d','%d','%d','%d','%s','%s','%s','%s','%d','%d','%s','%s')
133 )
134 ){
135 $postid = WPF()->db->insert_id;
136
137 $answ_incr = '';
138 $comm_incr = '';
139 if( isset($forum['cat_layout']) && $forum['cat_layout'] == 3 ){
140
141 if($parentid){
142 $comm_incr = ', `comments` = `comments` + 1 ';
143 }else{
144 $answ_incr = ', `answers` = `answers` + 1 ';
145 }
146 }
147
148 WPF()->db->query( "UPDATE `".WPF()->tables->profiles."` SET `posts` = `posts` + 1 $answ_incr $comm_incr WHERE `userid` = " . intval($userid) );
149
150 $post['postid'] = $postid;
151 $post['status'] = $status;
152 $post['private'] = $private;
153 $post['posturl'] = $this->get_post_url($postid);
154
155 if( !$status ) {
156 WPF()->topic->rebuild_first_last($topic);
157 WPF()->topic->rebuild_stats($topic);
158 WPF()->forum->rebuild_last_infos($forum['forumid']);
159 WPF()->forum->rebuild_stats($forum['forumid']);
160 }
161
162 do_action( 'wpforo_after_add_post', $post, $topic );
163
164 wpforo_clean_cache('post', $postid, $post);
165 WPF()->member->reset($userid);
166 WPF()->notice->add('You successfully replied', 'success');
167 return $postid;
168 }
169
170 WPF()->notice->add('Reply request error', 'error');
171 return FALSE;
172 }
173
174 public function edit( $args = array() ){
175
176 //This variable will be based on according CAN of guest usergroup once Guest Posing is ready
177 $guestposting = false;
178
179 if( empty($args) && (!isset($_REQUEST['post']) || empty($_REQUEST['post'])) ) return FALSE;
180 if( empty($args) && !empty($_REQUEST['post']) ){ $args = $_REQUEST['post']; $args['body'] = $_REQUEST['postbody']; }
181 if( isset($args['name']) ){ $args['name'] = strip_tags($args['name']); }
182 if( isset($args['email']) ){ $args['email'] = sanitize_email($args['email']); }
183
184 do_action( 'wpforo_start_edit_post', $args );
185
186 if( !isset($args['postid']) || !$args['postid'] || !is_numeric($args['postid']) ){
187 WPF()->notice->add('Cannot update post data', 'error');
188 return FALSE;
189 }
190 $args['postid'] = intval($args['postid']);
191 if( !$post = $this->get_post($args['postid']) ){ WPF()->notice->add('No Posts found for update', 'error'); return FALSE; }
192
193 if( !is_user_logged_in() ){
194 if( !isset($post['email']) || !$post['email'] ){
195 WPF()->notice->add('Permission denied', 'error');
196 return FALSE;
197 }
198 elseif( !wpforo_current_guest( $post['email'] ) ){
199 WPF()->notice->add('You are not allowed to edit this post', 'error');
200 return FALSE;
201 }
202 if( !$args['name'] || !$args['email'] ){
203 WPF()->notice->add('Please insert required fields!', 'error');
204 return FALSE;
205 }
206 else{
207 WPF()->member->set_guest_cookies( $args );
208 }
209 }
210
211 $args['userid'] = $post['userid'];
212 $args['status'] = $post['status'];
213
214 if( isset($args['userid']) && $args['userid'] == 0 && isset($args['name']) && isset($args['email']) ) $guestposting = true;
215
216 $args = apply_filters('wpforo_edit_post_data_filter', $args);
217 if(empty($args)) return FALSE;
218
219 extract($args, EXTR_OVERWRITE);
220
221 if( !$guestposting ){
222 $diff = current_time( 'timestamp', 1 ) - strtotime($post['created']);
223 if( !(WPF()->perm->forum_can('er', $post['forumid']) ||
224 (WPF()->current_userid == $post['userid'] && WPF()->perm->forum_can('eor', $post['forumid'])) )
225 ){
226 WPF()->notice->add('You don\'t have permission to edit post from this forum', 'error');
227 return FALSE;
228 }
229
230 if(!WPF()->perm->forum_can('er', $post['forumid']) &&
231 WPF()->post->options['eor_durr'] !== 0 &&
232 $diff > WPF()->post->options['eor_durr']){
233 WPF()->notice->add('The time to edit this post is expired.', 'error');
234 return FALSE;
235 }
236 }
237
238 $title = (isset($title) ? wpforo_text( trim($title), 250, false ) : '');
239 $body = ( isset($body) ? preg_replace('#</pre>[\r\n\t\s\0]*<pre>#isu', "\r\n", $body) : '' );
240
241 if(isset($forumid)) $forumid = intval($forumid);
242 if(isset($topicid)) $topicid = intval($topicid);
243 if(isset($parentid)) $parentid = intval($parentid);
244 if(isset($title)) $title = sanitize_text_field(trim($title));
245 if(isset($slug)) $slug = sanitize_title($slug);
246 if(isset($created)) $created = sanitize_text_field($created);
247 if(isset($userid)) $userid = intval($userid);
248 if(isset($body)) $body = wpforo_kses(trim($body), 'post');
249 if(isset($status)) $status = intval($status);
250 if(isset($private)) $private = intval($private);
251 if(isset($name)) $name = strip_tags(trim($name));
252 if(isset($email)) $email = strip_tags(trim($email));
253
254 $title = ( isset($title) ? stripslashes($title) : stripslashes($post['title']) );
255 $body = ( (isset($body) && $body) ? stripslashes($body) : stripslashes($post['body']) );
256 $status = ( isset($status) ? $status : intval($post['status']) );
257 $name = ( isset($name) ? stripslashes($name) : stripslashes($post['name']) );
258 $email = ( isset($email) ? stripslashes($email) : stripslashes($post['email']) );
259
260 if( FALSE !== WPF()->db->update(
261 WPF()->tables->posts,
262 array(
263 'title' => $title,
264 'body' => $body,
265 'modified' => current_time( 'mysql', 1 ),
266 'status' => $status,
267 'name' => $name,
268 'email' => $email,
269 ),
270 array('postid' => $postid),
271 array('%s','%s','%s','%d','%s','%s'),
272 array('%d')
273 )
274 ){
275 do_action( 'wpforo_after_edit_post', array( 'postid' => $postid, 'topicid' => $topicid, 'title' => $title, 'body' => $body, 'status' => $status, 'private' => $private, 'name' => $name, 'email' => $email) );
276
277 wpforo_clean_cache('post', $postid, $post);
278 WPF()->notice->add('This post successfully edited', 'success');
279 return $postid;
280 }
281
282 WPF()->notice->add('Reply request error', 'error');
283 return FALSE;
284 }
285
286 #################################################################################
287 /**
288 * Delete post from DB
289 *
290 * Returns true if successfully deleted or false.
291 *
292 * @since 1.0.0
293 *
294 * @return bool
295 */
296
297 function delete($postid, $delete_cache = true){
298 $postid = intval($postid);
299
300 if( !$post = $this->get_post($postid) ) return true;
301
302 do_action('wpforo_before_delete_post', $post);
303
304 $diff = current_time( 'timestamp', 1 ) - strtotime($post['created']);
305 if( !(WPF()->perm->forum_can('dr', $post['forumid']) ||
306 (WPF()->current_userid == $post['userid'] &&
307 WPF()->perm->forum_can('dor', $post['forumid']) )) ){
308 WPF()->notice->add('You don\'t have permission to delete post from this forum', 'error');
309 return FALSE;
310 }
311
312 if( !WPF()->perm->forum_can('dr', $post['forumid']) &&
313 WPF()->post->options['dor_durr'] !== 0 &&
314 $diff > WPF()->post->options['dor_durr'] ){
315 WPF()->notice->add('The time to delete this post is expired.', 'error');
316 return FALSE;
317 }
318 //Find and delete default atatchments before deleting post
319 $this->delete_attachments( $postid );
320
321 //Delete post
322 if( WPF()->db->delete(WPF()->tables->posts, array( 'postid' => intval($postid) ), array( '%d' )) ){
323 $last_post = $this->get_posts( array('topicid' => intval($post['topicid']), 'orderby' => '`created` DESC, `postid` DESC', 'row_count' => 1, 'status' => 0, 'private' => 0) );
324 if(is_array($last_post) && !empty($last_post)){
325 $last_post = $last_post[0];
326 }else{
327 $last_post = array( 'created' => '0000-00-00 00:00:00', 'userid' => 0, 'postid' => 0 );
328 }
329
330 WPF()->db->delete(
331 WPF()->tables->likes, array( 'postid' => $postid ), array( '%d' )
332 );
333 WPF()->db->delete(
334 WPF()->tables->votes, array( 'postid' => $postid ), array( '%d' )
335 );
336
337 $answ_incr = '';
338 $comm_incr = '';
339 $forum = WPF()->forum->get_forum($post['forumid']);
340 if( isset($forum['cat_layout']) && $forum['cat_layout'] == 3 ){
341 if($post['parentid']){
342 $comm_incr = ', `comments` = IF( (`comments` - 1) < 0, 0, `comments` - 1 ) ';
343 }else{
344 $answ_incr = ', `answers` = IF( (`answers` - 1) < 0, 0, `answers` - 1 ) ';
345 }
346 }
347
348 if(WPF()->db->query( "UPDATE IGNORE ".WPF()->tables->topics." SET `modified` = '" . esc_sql($last_post['modified']) . "', `last_post` = " . intval($last_post['postid']) . ", `posts` = IF( (`posts` - 1) < 0, 0, `posts` - 1 ) $answ_incr WHERE `topicid` = " . intval( $post['topicid'] ))){
349 if( WPF()->db->query( "UPDATE IGNORE `".WPF()->tables->forums."` SET `last_post_date` = '" . esc_sql($last_post['created']) . "', `last_userid` = " . intval($last_post['userid']) . ", `last_postid` = " . intval($last_post['postid']) . ", `posts` = IF( (`posts` - 1) < 0, 0, `posts` - 1 ) WHERE `forumid` = " . intval( $post['forumid'] ))){
350 if( WPF()->db->query( "UPDATE IGNORE `".WPF()->tables->profiles."` SET `posts` = IF( (`posts` - 1) < 0, 0, `posts` - 1 ) $answ_incr $comm_incr WHERE `userid` = " . intval($post['userid']) ) ){
351 WPF()->member->reset($post['userid']);
352 WPF()->notice->add('This post successfully deleted', 'success');
353 }
354 }
355 }
356
357 do_action('wpforo_after_delete_post', $post);
358
359 if( $post['is_first_post'] ) return WPF()->topic->delete($post['topicid']);
360 if( $delete_cache ) wpforo_clean_cache('post', $postid, $post);
361 return TRUE;
362 }
363
364 WPF()->notice->add('Post delete error', 'error');
365 return FALSE;
366 }
367
368 #################################################################################
369 /**
370 * array get_post(id(num))
371 *
372 * Returns array from defined and default arguments.
373 *
374 * @since 1.0.0
375 *
376 * @return array
377 */
378 function get_post($postid){
379
380 $post = array();
381 $cache = WPF()->cache->on('memory_cashe');
382
383 if( $cache && isset(self::$cache['post'][$postid]) ){
384 return self::$cache['post'][$postid];
385 }
386
387 $sql = "SELECT * FROM `".WPF()->tables->posts."` WHERE `postid` = " . intval($postid);
388 $post = WPF()->db->get_row($sql, ARRAY_A);
389 if(!empty($post)) $post['userid'] = intval($post['userid']);
390
391 if( isset($post['forumid']) && $post['forumid'] && !WPF()->perm->forum_can('vf', $post['forumid']) ){
392 return array();
393 }
394
395 if( isset($post['status']) && $post['status'] && !wpforo_is_owner($post['userid'], $post['email'])){
396 if( isset($post['forumid']) && $post['forumid'] && !WPF()->perm->forum_can('au', $post['forumid']) ){
397 return array();
398 }
399 }
400
401 if($cache && isset($postid)){
402 self::$cache['post'][$postid] = $post;
403 }
404
405 $post = apply_filters('wpforo_get_post', $post);
406 return $post;
407 }
408
409 /**
410 * Returns merged arguments array from defined and default arguments.
411 *
412 * @since 1.0.0
413 *
414 * @param array
415 *
416 * @return array
417 */
418 function get_posts($args = array(), &$items_count = 0){
419
420 $cache = WPF()->cache->on('object_cashe');
421
422 $default = array(
423 'include' => array(), // array( 2, 10, 25 )
424 'exclude' => array(), // array( 2, 10, 25 )
425
426 'topicid' => NULL, // topic id in DB
427 'forumid' => NULL, // forum id in DB
428 'parentid' => -1, // parent post id
429 'userid' => NULL, // user id in DB
430 'orderby' => '`is_first_post` DESC, `created` ASC, `postid` ASC', // forumid, order, parentid
431 'order' => '', // ASC DESC
432 'offset' => NULL, // this use when you give row_count
433 'row_count' => NULL, // 4 or 1 ...
434 'status' => NULL, // 0 or 1 ...
435 'private' => NULL, // 0 or 1 ...
436 'email' => NULL, // example@example.com ...
437 'check_private' => TRUE,
438 'where' => NULL,
439 'owner' => NULL,
440 'cache_type' => 'sql', // sql or args
441 );
442
443 $request = $args;
444 if( empty($args['orderby']) ) $args['order'] = '';
445
446 $args = wpforo_parse_args( $args, $default );
447
448 if(is_array($args) && !empty($args)){
449
450 extract($args, EXTR_OVERWRITE);
451
452 if( $row_count === 0 ) return array();
453
454 $include = wpforo_parse_args( $include );
455 $exclude = wpforo_parse_args( $exclude );
456
457 $guest = array();
458 $wheres = array();
459 $table_as_prefix = '`'.WPF()->tables->posts.'`.';
460 if(!is_user_logged_in()) $guest = WPF()->member->get_guest_cookies();
461
462 if(!empty($include)) $wheres[] = $table_as_prefix . "`postid` IN(" . implode(', ', array_map('intval', $include)) . ")";
463 if(!empty($exclude)) $wheres[] = $table_as_prefix . "`postid` NOT IN(" . implode(', ', array_map('intval', $exclude)) . ")";
464
465
466 if(!is_null($topicid)) $wheres[] = $table_as_prefix . "`topicid` = " . intval($topicid);
467 if($parentid != -1) $wheres[] = $table_as_prefix . "`parentid` = " . intval($parentid);
468 if(!is_null($userid)) $wheres[] = $table_as_prefix . "`userid` = " . intval($userid);
469 if(!is_null($status)) $wheres[] = $table_as_prefix . "`status` = " . intval($status);
470 if(!is_null($private)) $wheres[] = $table_as_prefix . "`private` = " . intval($private);
471 if(!is_null($email)) $wheres[] = $table_as_prefix . "`email` = '" . esc_sql($email) . "' ";
472 if(!is_null($where)) $wheres[] = $table_as_prefix . $where;
473
474 if( isset($forumid) && $forumid ){
475 if( WPF()->perm->forum_can('au', $forumid) ){
476 if(!is_null($status)) $wheres[] = $table_as_prefix . " `status` = " . intval($status);
477 }
478 elseif( isset(WPF()->current_userid) && WPF()->current_userid ){
479 $wheres[] = " ( " . $table_as_prefix . "`status` = 0 OR (" . $table_as_prefix . "`status` = 1 AND " . $table_as_prefix . "`userid` = " .intval(WPF()->current_userid). ") )";
480 }
481 elseif( wpfval($guest, 'email') ){
482 $wheres[] = " ( " . $table_as_prefix . "`status` = 0 OR (" . $table_as_prefix . "`status` = 1 AND " . $table_as_prefix . "`email` = '" . sanitize_email($guest['email']) . "') )";
483 }
484 else{
485 $wheres[] = " " . $table_as_prefix . "`status` = 0";
486 }
487 }
488
489 $sql = "SELECT * FROM `".WPF()->tables->posts."`";
490 if(!empty($wheres)){
491 $sql .= " WHERE " . implode(" AND ", $wheres);
492 }
493 $sql .= " ORDER BY $orderby " . $order;
494 $item_count_sql = preg_replace('#SELECT.+?FROM#isu', 'SELECT count(*) FROM', $sql);
495
496 if( $item_count_sql ) $items_count = WPF()->db->get_var($item_count_sql);
497
498 if($row_count != NULL){
499 if($offset != NULL){
500 $sql .= esc_sql(" LIMIT $offset,$row_count");
501 }else{
502 $sql .= esc_sql(" LIMIT $row_count");
503 }
504 }
505
506 if( $cache ){
507 $object_key = md5( $sql . WPF()->current_user_groupid );
508 $object_cache = WPF()->cache->get($object_key);
509 if(!empty($object_cache)){
510 $items_count = $object_cache['items_count'];
511 return $object_cache['items'];
512 }
513 else{
514 $hach = serialize($request);
515 $cache_args_key = md5( $hach . WPF()->current_user_groupid );
516 $object_cache = WPF()->cache->get($cache_args_key, 'loop', 'post');
517 if(!empty($object_cache)){
518 $items_count = $object_cache['items_count'];
519 return $object_cache['items'];
520 }
521 }
522 }
523
524 $posts = WPF()->db->get_results($sql, ARRAY_A);
525 $posts = apply_filters('wpforo_get_posts', $posts);
526
527 if( $check_private ){
528 foreach($posts as $key => $post){
529 if( isset($post['forumid']) && !WPF()->perm->forum_can('vf', $post['forumid']) ){
530 unset($posts[$key]);
531 }
532 if( isset($post['forumid']) && isset($post['private']) && $post['private'] && !$owner ){
533 if(!WPF()->perm->forum_can('vp', $post['forumid'])){
534 if(is_null($owner)){
535 $topic_userid = wpforo_topic($post['topicid'], 'userid');
536 if(!wpforo_is_owner($topic_userid) && !wpforo_is_owner($post['userid'])){
537 unset($posts[$key]);
538 }
539 }else{
540 unset($posts[$key]);
541 }
542 }
543 }
544 if( isset($post['forumid']) && isset($post['status']) && $post['status'] && !wpforo_is_owner($post['userid'], $post['email']) ){
545 if( !WPF()->perm->forum_can('au', $post['forumid']) ){
546 unset($posts[$key]);
547 }
548 }
549 }
550 }
551
552 if($cache && isset($object_key) && !empty($posts)){
553 self::$cache['posts'][$object_key]['items'] = $posts;
554 self::$cache['posts'][$object_key]['items_count'] = $items_count;
555 if(isset($cache_args_key) && $cache_type == 'args' ){
556 WPF()->cache->create_custom( $request, $posts, 'post', $items_count );
557 }
558 }
559 return $posts;
560 }
561 }
562
563 function get_posts_filtered( $args = array() ){
564 $posts = array();
565 $posts = $this->get_posts( $args );
566 if( !empty($posts) ){
567 foreach($posts as $key => $post){
568 if( isset($post['forumid']) && !WPF()->perm->forum_can('vf', $post['forumid']) ){
569 unset($posts[$key]);
570 }
571 if( isset($posts[$key]) && isset($post['forumid']) && isset($post['private']) && $post['private'] && !wpforo_is_owner($post['userid'], $post['email']) ){
572 if( !WPF()->perm->forum_can('vp', $post['forumid']) ){
573 unset($posts[$key]);
574 }
575 }
576 if( isset($posts[$key]) && isset($post['forumid']) && isset($post['status']) && $post['status'] && !wpforo_is_owner($post['userid'], $post['email']) ){
577 if( !WPF()->perm->forum_can('au', $post['forumid']) ){
578 unset($posts[$key]);
579 }
580 }
581 }
582 }
583 return $posts;
584 }
585
586
587 function search( $args = array(), &$items_count = 0 ){
588 if(!is_array($args)) $args = array('needle' => $args);
589
590 $default = array(
591 'needle' => '', // search needle
592 'forumids' => array(), // array( 2, 10, 25 )
593 'date_period' => 0, // topic id in DB
594 'type' => 'entire-posts', // search type ( entire-posts | titles-only | user-posts | user-topics )
595 'orderby' => 'relevancy', // Sort Search Results by ( relevancy | date | user | forum )
596 'order' => 'DESC', // Sort Search Results ( ASC | DESC )
597 'offset' => NULL, // this use when you give row_count
598 'row_count' => NULL // 4 or 1 ...
599 );
600
601 $args = wpforo_parse_args( $args, $default );
602
603 if( !empty($args) ){
604 extract($args, EXTR_OVERWRITE);
605
606 if($order == 'desc'){ $order = 'desc'; }
607 elseif($order == 'asc'){ $order = 'asc'; }
608 else{ $order = 'desc'; }
609
610 $date_period = intval($date_period);
611
612 $selects = array('p.`postid`', 't.`topicid`', 't.`private`', 't.`status`', 't.`forumid`', 'p.`userid`', 't.`title`', 'p.`created`', 'p.`body`' );
613 $innerjoins = array('INNER JOIN `'.WPF()->tables->topics.'` t ON t.`topicid` = p.`topicid`');
614 $wheres = array();
615 $orders = array();
616
617 if(!empty($forumids)) $wheres[] = "t.`forumid` IN(" . implode(', ', array_map('intval', $forumids)) . ")";
618 if( $date_period != 0 ){
619 $date = date( 'Y-m-d H:i:s', current_time( 'timestamp', 1 ) - ($date_period * 24 * 60 * 60) );
620 if($date) $wheres[] = "p.`created` > '".esc_sql($date)."'";
621 }
622
623 if($needle){
624
625 $needle = trim( trim( str_replace(' ', '* ', $needle) ), '*' ) . "*";
626 $needle = esc_sql(substr(sanitize_text_field($needle), 0, 60));
627
628 if($type == 'entire-posts'){
629 $selects[] = "MATCH(t.`title`) AGAINST('$needle' IN BOOLEAN MODE) + MATCH(p.`title`) AGAINST('$needle' IN BOOLEAN MODE) + MATCH(p.`body`) AGAINST('$needle' IN BOOLEAN MODE) AS matches";
630 $wheres[] = "( MATCH(t.`title`) AGAINST('$needle' IN BOOLEAN MODE) OR MATCH(p.`title`, p.`body`) AGAINST('$needle' IN BOOLEAN MODE) )";
631 $orders[] = "MATCH(t.`title`) AGAINST('$needle') + MATCH(p.`title`) AGAINST('$needle') + MATCH(p.`body`) AGAINST('$needle')";
632 $orders[] = "MATCH(t.`title`) AGAINST('$needle' IN BOOLEAN MODE) + MATCH(p.`title`) AGAINST('$needle' IN BOOLEAN MODE) + MATCH(p.`body`) AGAINST('$needle' IN BOOLEAN MODE)";
633 }elseif($type == 'titles-only'){
634 $selects[] = "MATCH(t.`title`) AGAINST('$needle' IN BOOLEAN MODE) + MATCH(p.`title`) AGAINST('$needle' IN BOOLEAN MODE) AS matches";
635 $wheres[] = "( MATCH(t.`title`) AGAINST('$needle' IN BOOLEAN MODE) OR MATCH(p.`title`) AGAINST('$needle' IN BOOLEAN MODE) )";
636 $orders[] = "MATCH(t.`title`) AGAINST('$needle') + MATCH(p.`title`) AGAINST('$needle')";
637 $orders[] = "MATCH(t.`title`) AGAINST('$needle' IN BOOLEAN MODE) + MATCH(p.`title`) AGAINST('$needle' IN BOOLEAN MODE)";
638 }elseif($type == 'user-posts' || $type == 'user-topics'){
639 $innerjoins[] = "INNER JOIN `".WPF()->db->users."` u ON u.`ID` = p.`userid`";
640 $wheres[] = "( u.`user_login` LIKE '$needle' OR u.`user_email` LIKE '$needle' OR u.`display_name` LIKE '$needle' )";
641 if($type == 'user-topics') $wheres[] = "`is_first_post` = 1";
642 }
643 }
644
645 if($orderby == 'date'){
646 $orders = array('p.`created`');
647 }elseif($orderby == 'user'){
648 $orders = array('p.`userid`');
649 }elseif($orderby == 'forum'){
650 $orders = array('t.`forumid`');
651 }
652
653 $sql = "SELECT COUNT(p.`postid`) FROM `".WPF()->tables->posts."` p ".implode(' ', $innerjoins);
654 if(!empty($wheres)) $sql .= " WHERE " . implode( " AND ", $wheres );
655 $items_count = WPF()->db->get_var($sql);
656
657 $sql = "SELECT ".implode(', ', $selects)." FROM `".WPF()->tables->posts."` p ".implode(' ', $innerjoins);
658 if(!empty($wheres)) $sql .= " WHERE " . implode( " AND ", $wheres );
659 if(!empty($orders)) $sql .= " ORDER BY ".implode(' '.strtoupper($order).', ', $orders)." ".strtoupper($order);
660
661 if($row_count != NULL){
662 if($offset != NULL){
663 $sql .= esc_sql(" LIMIT $offset,$row_count");
664 }else{
665 $sql .= esc_sql(" LIMIT $row_count");
666 }
667 }
668
669 $posts = WPF()->db->get_results($sql, ARRAY_A);
670 foreach($posts as $key => $post){
671 if( !WPF()->perm->forum_can( 'vf', $post['forumid'] ) ) unset($posts[$key]);
672 if( $post['private'] && !WPF()->perm->forum_can( 'vp', $post['forumid'] ) ) unset($posts[$key]);
673 if( $post['status'] && !WPF()->perm->forum_can( 'au', $post['forumid'] ) ) unset($posts[$key]);
674 }
675 return $posts;
676 }else{
677 return array();
678 }
679 }
680
681 /**
682 * return likes count by post id
683 *
684 * Return likes count
685 *
686 * @since 1.0.0
687 *
688 * @param int
689 *
690 * @return int
691 */
692 function get_post_likes_count($postid){
693 return WPF()->db->get_var("SELECT COUNT(l.`likeid`) FROM `".WPF()->tables->likes."` l, `".WPF()->db->users."` u WHERE `l`.`userid` = `u`.ID AND `l`.`postid` = ".intval($postid) );
694 }
695
696 /**
697 * return usernames who likes this post
698 *
699 * Return array with username
700 *
701 * @since 1.0.0
702 *
703 * @param int
704 *
705 * @return array
706 */
707 function get_likers_usernames($postid){
708 return WPF()->db->get_results("SELECT u.ID, u.display_name FROM `".WPF()->tables->likes."` l, `".WPF()->db->users."` u WHERE `l`.`userid` = `u`.ID AND `l`.`postid` = ".intval($postid)." ORDER BY l.`userid` = " . intval(WPF()->current_userid) . " DESC, l.`likeid` DESC LIMIT 3", ARRAY_A);
709 }
710
711 /**
712 * return like ID or null
713 *
714 * @since 1.0.0
715 *
716 * @param int int
717 *
718 * @return null or like id
719 */
720 function is_liked($postid, $userid){
721 $returned_value = WPF()->db->get_var("SELECT likeid FROM `".WPF()->tables->likes."` WHERE `postid` = ".intval($postid)." AND `userid` = ".intval($userid) );
722 if(is_null($returned_value)){
723 return FALSE;
724 }else{
725 return $returned_value;
726 }
727 }
728
729 /**
730 * return votes sum by post id
731 *
732 * Return votes count
733 *
734 * @since 1.0.0
735 *
736 * @param int
737 *
738 * @return int
739 */
740 function get_post_votes_sum($postid){
741 $sum = WPF()->db->get_var("SELECT sum(`reaction`) FROM `".WPF()->tables->votes."` WHERE `postid` = ".intval($postid) );
742 if($sum == null){
743 $sum = 0;
744 }
745 return $sum;
746 }
747
748
749 /**
750 * return forum slug
751 *
752 * string (slug)
753 *
754 * @since 1.0.0
755 *
756 * @param int
757 *
758 * @return string or false
759 */
760
761 function get_forumslug_byid($postid){
762
763 $cache = WPF()->cache->on('memory_cashe');
764
765 if( $cache && isset(self::$cache['forum_slug'][$postid]) ){
766 return self::$cache['forum_slug'][$postid];
767 }
768
769 $slug = WPF()->db->get_var("SELECT `slug` FROM ".WPF()->tables->forums." WHERE `forumid` =(SELECT forumid FROM `".WPF()->tables->topics."` WHERE `topicid` =(SELECT `topicid` FROM `".WPF()->tables->posts."` WHERE postid = ".intval($postid)."))");
770
771 if($cache && isset($postid)){
772 self::$cache['forum_slug'][$postid] = $slug;
773 }
774
775 if($slug){
776 return $slug;
777 }else{
778 return FALSE;
779 }
780 }
781
782
783 /**
784 * return topic slug
785 *
786 * string (slug)
787 *
788 * @since 1.0.0
789 *
790 * @param int
791 *
792 * @return string or false
793 */
794
795 function get_topicslug_byid( $postid ){
796
797 $cache = WPF()->cache->on('memory_cashe');
798
799 if( $cache && isset(self::$cache['topic_slug'][$postid]) ){
800 return self::$cache['topic_slug'][$postid];
801 }
802
803 $slug = WPF()->db->get_var("SELECT `slug` FROM ".WPF()->tables->topics." WHERE `topicid` =(SELECT `topicid` FROM `".WPF()->tables->posts."` WHERE postid = ".intval($postid).")");
804
805 if($cache && isset($postid)){
806 self::$cache['topic_slug'][$postid] = $slug;
807 }
808
809 if($slug){
810 return $slug;
811 }else{
812 return FALSE;
813 }
814 }
815
816 /**
817 * return post full url by id
818 *
819 * @since 1.0.0
820 *
821 * @param int $postid
822 *
823 * @return string $url
824 */
825 function get_post_url( $arg, $absolute = true ){
826
827 $position = array();
828
829 if( isset($arg) && !is_array($arg) ){
830 $postid = wpforo_bigintval($arg);
831 $post = $this->get_post($postid);
832 }
833 elseif( !empty($arg) && isset($arg['postid']) ){
834 $post = $arg;
835 $postid = $post['postid'];
836 }
837
838 if( is_array($post) && !empty($post) && $postid ){
839 $url = $this->get_forumslug_byid($postid) . '/' . $this->get_topicslug_byid($postid);
840 if( $post['topicid'] ){
841 if( !$position ) $position = WPF()->db->get_var("SELECT COUNT(`postid`) FROM `".WPF()->tables->posts."` WHERE `topicid` = ".wpforo_bigintval($post['topicid'])." AND `postid` <= " . ( $post['parentid'] && WPF()->forum->get_layout($post['forumid']) == 3 ? wpforo_bigintval($post['parentid']) : wpforo_bigintval($postid) ) );
842 if( $position <= WPF()->post->options['posts_per_page'] ) return wpforo_home_url($url, false, $absolute ) . "#post-" . wpforo_bigintval($postid);
843 if( $position && WPF()->post->options['posts_per_page'] ) {
844 $paged = ceil($position / WPF()->post->options['posts_per_page']);
845 }
846 else{
847 $paged = 1;
848 }
849 return wpforo_home_url( $url . "/paged/" . $paged, false, $absolute ) ."#post-" . wpforo_bigintval($postid);
850 }
851 }
852
853 return wpforo_home_url();
854 }
855
856
857 /**
858 * return 0 or 1
859 *
860 * @since 1.0.0
861 *
862 * @param int $postid
863 */
864 function is_answered( $postid ){
865 $is_answered = WPF()->db->get_var( WPF()->db->prepare(
866 " SELECT is_answer
867 FROM `".WPF()->tables->posts."`
868 WHERE postid = %d
869 ",
870 intval($postid)
871 ) );
872 return $is_answered;
873 }
874
875 function is_approved( $postid ){
876 $post = WPF()->db->get_var( "SELECT `status` FROM ".WPF()->tables->posts." WHERE `postid` = " . intval($postid) );
877 if( $post ) return FALSE;
878 return TRUE;
879 }
880
881 function get_count( $args = array() ){
882 $sql = "SELECT COUNT(*) FROM `".WPF()->tables->posts."`";
883 if($args && is_array($args)){
884 $wheres = array();
885 foreach ($args as $key => $value) $wheres[] = "`$key` = '" . esc_sql($value) . "'";
886 if($wheres) $sql .= " WHERE " . implode(' AND ', $wheres);
887 }
888 return WPF()->db->get_var($sql);
889 }
890
891 function unapproved_count(){
892 return WPF()->db->get_var( "SELECT COUNT(*) FROM `".WPF()->tables->posts."` WHERE `status` = 1" );
893 }
894
895 function get_attachment_id( $filename ){
896 $attach_id = WPF()->db->get_var( "SELECT `post_id` FROM `".WPF()->db->postmeta."` WHERE `meta_key` = '_wp_attached_file' AND `meta_value` LIKE '%" . esc_sql($filename) . "' LIMIT 1");
897 return $attach_id;
898 }
899
900 function delete_attachments( $postid ){
901 $post = $this->get_post($postid);
902 if( isset($post['body']) && $post['body'] ){
903 if( preg_match_all('|\/wpforo\/default_attachments\/([^\s\"\]]+)|is', $post['body'], $attachments, PREG_SET_ORDER) ){
904 $upload_dir = wp_upload_dir();
905 $default_attachments_dir = $upload_dir['basedir'] . '/wpforo/default_attachments/';
906 foreach( $attachments as $attachment ){
907 $filename = trim($attachment[1]);
908 $file = $default_attachments_dir . $filename;
909 if( file_exists($file) ){
910 $posts = WPF()->db->get_var( "SELECT COUNT(*) as posts FROM `".WPF()->tables->posts."` WHERE `body` LIKE '%" . esc_sql( $attachment[0] ) . "%'" );
911 if( is_numeric($posts) && $posts == 1 ){
912 $attachmentid = $this->get_attachment_id( '/' . $filename );
913 if ( !wp_delete_attachment( $attachmentid ) ){
914 @unlink($file);
915 }
916 }
917 }
918 }
919 }
920 }
921 }
922
923 public function status( $postid, $status ){
924
925
926 if( !$postid = wpforo_bigintval($postid) ) return false;
927 if( !$post = $this->get_post($postid) ) return false;
928
929 if( $post['is_first_post'] ) return WPF()->topic->status($post['topicid'], $status);
930
931 if( false !== WPF()->db->update(
932 WPF()->tables->posts,
933 array( 'status' => intval($status) ),
934 array( 'postid' => $postid ),
935 array( '%d' ),
936 array( '%d' )
937 )){
938 if($status) {
939 $this->last_post($post, 'remove');
940 } else {
941 $this->last_post($post, 'add');
942 }
943 do_action( 'wpforo_post_status_update', $postid, $status );
944 wpforo_clean_cache('post', $postid);
945 WPF()->notice->add('Done!', 'success');
946 return true;
947 }
948
949 WPF()->notice->add('error: Change Status action', 'error');
950 return false;
951 }
952
953 public function last_post($post, $action = 'add'){
954 if( !empty($post) && isset($post['postid']) && isset($post['topicid']) && isset($post['forumid']) && isset($post['userid']) && isset($post['created']) ){
955 extract($post, EXTR_OVERWRITE);
956 if( $action == 'add' ){
957 $answ_incr = '';
958 $layout = WPF()->forum->get_layout($post['forumid']);
959 if($layout == 3){
960 $answ_incr = ', `answers` = `answers` + 1 ';
961 }
962 WPF()->db->query( "UPDATE `".WPF()->tables->forums."` SET `last_topicid` = ". intval($topicid) .", `last_postid` = ". intval($postid) .", `last_post_date` = '".esc_sql($created)."', `last_userid` = " . intval($userid) . ", `posts` = `posts` + 1 WHERE `forumid` = " . intval($forumid) );
963 WPF()->db->query( "UPDATE `".WPF()->tables->topics."` SET `modified` = '" . esc_sql($created) . "', `last_post` = ". intval($postid) .", `posts` = `posts` + 1 $answ_incr WHERE `topicid` = " . intval($topicid) );
964 }
965 elseif($action == 'remove'){
966 //rebuild forum and topic last post info, don't include unapproved and private posts.
967 }
968 }
969 }
970
971 public function get_liked_posts( $args = array(), &$items_count ){
972
973 $default = array(
974 'userid' => NULL,
975 'order' => 'DESC',
976 'offset' => NULL,
977 'row_count' => NULL,
978 'where' => NULL,
979 'var' => NULL
980 );
981
982 $posts = array();
983 if(!wpfval($args, 'userid')) return array();
984 $args = wpforo_parse_args( $args, $default );
985 if(is_array($args) && !empty($args)){
986 extract($args, EXTR_OVERWRITE);
987 if( $row_count === 0 ) return array();
988 $items_count = WPF()->db->get_var("SELECT COUNT(*) FROM `".WPF()->tables->likes."` WHERE `userid` = " . intval($userid) );
989 $liked_posts = WPF()->db->get_col("SELECT `postid` FROM `".WPF()->tables->likes."` WHERE `userid` = " . intval($userid) ." ORDER BY `likeid` " . esc_sql($order) . " LIMIT " . intval($offset) . ", " . intval($row_count));
990 if(empty($liked_posts)){
991 $items_count = WPF()->db->get_var("SELECT COUNT(*) FROM `".WPF()->tables->votes."` WHERE `userid` = " . intval($userid) );
992 $liked_posts = WPF()->db->get_col("SELECT `postid` FROM `".WPF()->tables->votes."` WHERE `userid` = " . intval($userid) ." AND `reaction` = 1 ORDER BY `voteid` " . esc_sql($order) . " LIMIT " . intval($offset) . ", " . intval($row_count));
993 }
994 if(!empty($liked_posts)){
995 if($var == 'postid'){
996 return $liked_posts;
997 }
998 else{
999 $liked_posts = implode(',', $liked_posts);
1000 $post_args = array( 'include' => $liked_posts, 'status' => 0, 'private' => 0 );
1001 $posts = $this->get_posts( $post_args );
1002 }
1003 }
1004 }
1005 return $posts;
1006 }
1007
1008
1009 }