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-forums.php

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

999 lines 38.7 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
6 class wpForoForum{
7 public $default;
8 public $options;
9 public $cans;
10
11 static $cache = array( 'forums' => array(), 'forum' => array(), 'item' => array() );
12
13 public function __construct(){
14 $this->init_defaults();
15 $this->init_options();
16 }
17
18 private function init_defaults(){
19 $this->default = new stdClass;
20
21 $this->default->options = array(
22 'layout_qa_intro_topics_toggle' => 1,
23 'layout_extended_intro_topics_toggle' => 1,
24 'layout_qa_intro_topics_count' => 3,
25 'layout_extended_intro_topics_count' => 5,
26 'layout_qa_intro_topics_length' => 90,
27 'layout_extended_intro_topics_length' => 45,
28 );
29
30 $this->default->cans = array (
31 'vf' => 'Can view forum',
32 'ct' => 'Can create topic',
33 'vt' => 'Can view topic',
34 'et' => 'Can edit topic',
35 'dt' => 'Can delete topic',
36 'cr' => 'Can post reply',
37 'vr' => 'Can view replies',
38 'er' => 'Can edit replies',
39 'dr' => 'Can delete replies',
40 'eot' => 'Can edit own topic',
41 'eor' => 'Can edit own reply',
42 'dot' => 'Can delete own topic',
43 'dor' => 'Can delete own reply',
44 'l' => 'Can like',
45 'r' => 'Can report',
46 's' => 'Can set topic sticky',
47 'p' => 'Can set topic private',
48 'op' => 'Can set own topic private',
49 'vp' => 'Can view private topic',
50 'au' => 'Can approve/unapprove content',
51 'sv' => 'Can set topic solved',
52 'osv' => 'Can set own topic solved',
53 'v' => 'Can vote',
54 'a' => 'Can attach file',
55 'va' => 'Can view attached files',
56 'at' => 'Can set topic answered',
57 'oat' => 'Can set own topic answered',
58 'cot' => 'Can close topic',
59 'mt' => 'Can move topic',
60 'ccp' => 'Can create poll',
61 'cvp' => 'Can vote poll',
62 'cvpr' => 'Can view poll result',
63 );
64 }
65
66 private function init_options(){
67 $this->options = get_wpf_option('wpforo_forum_options', $this->default->options);
68 $this->cans = apply_filters('wpforo_forum_cans', $this->default->cans);
69 }
70
71 public function get_cache( $var ){
72 if( isset(self::$cache[$var]) ) return self::$cache[$var];
73 }
74
75 private function unique_slug($slug, $parentid = 0, $forumid = 0){
76 $new_slug = wpforo_text($slug, 250, false);
77 $forumid = intval($forumid);
78 $i = 2;
79 while( WPF()->db->get_var("SELECT `forumid` FROM ".WPF()->tables->forums." WHERE `slug` = '" . esc_sql($new_slug) . "'" . ($forumid ? ' AND `forumid` != '. intval($forumid) : '')) ){
80 if( !isset($parent_slug) && $parentid = intval($parentid) ){
81 $parent_slug = WPF()->db->get_var("SELECT `slug` FROM ".WPF()->tables->forums." WHERE `forumid` = " . intval($parentid) );
82 $new_slug = $parent_slug . "-" . wpforo_text($slug, 250, false);
83 }else{
84 $new_slug = wpforo_text($slug, 250, false) . '-' . $i;
85 }
86 $i++;
87 }
88 return $new_slug;
89 }
90
91 public function add( $args = array(), $checkperm = TRUE ){
92 if( $checkperm && !WPF()->perm->usergroup_can('cf') ){
93 WPF()->notice->add('Permission denied for add forum', 'error');
94 return FALSE;
95 }
96
97 if( empty($args) && empty($_REQUEST['forum']) ) return FALSE;
98 if( empty($args) && !empty($_REQUEST['forum']) ) $args = $_REQUEST['forum'];
99
100 extract($args, EXTR_OVERWRITE);
101
102 if( !isset($title) || !$title ){
103 WPF()->notice->add('Please insert required fields!', 'error');
104 return FALSE;
105 }
106
107 $title = sanitize_text_field($title);
108 $title = wpforo_text($title, 250, false);
109 $description = (isset($description) ? wpforo_kses($description, 'post') : '');
110 $permission = (isset($permission) && is_array($permission)) ? serialize(array_map('sanitize_text_field', $permission)) : 'a:5:{i:1;s:4:"full";i:2;s:9:"moderator";i:3;s:8:"standard";i:4;s:9:"read_only";i:5;s:8:"standard";}';
111 $meta_key = (isset($meta_key)) ? sanitize_text_field($meta_key) : '';
112 $meta_desc = (isset($meta_desc)) ? sanitize_text_field($meta_desc) : '';
113 $parentid = (isset($parentid)) ? intval($parentid) : 0;
114 $slug = (isset($slug) && $slug) ? sanitize_title($slug) : ((isset($title)) ? sanitize_title($title) : md5(time()));
115 $slug = $this->unique_slug($slug, $parentid);
116 $icon = (isset($icon)) ? sanitize_text_field($icon) : '';
117 $topics = (isset($topics)) ? intval($topics) : 0;
118 $posts = (isset($posts)) ? intval($posts) : 0;
119 $order = (isset($order)) ? intval($order) : 0;
120 $cat_layout = (isset($cat_layout)) ? intval($cat_layout) : 1;
121 $status = (isset($status)) ? intval($status) : 1;
122 $is_cat = (isset($is_cat)) ? intval($is_cat) : 0;
123 if(!$parentid) $is_cat = 1;
124
125 if($parentid) {
126 $cat_layout = WPF()->db->get_var("SELECT `cat_layout` FROM `".WPF()->tables->forums."` WHERE `forumid` = " . intval($parentid) );
127 $cat_layout = intval($cat_layout);
128 }
129
130 if( WPF()->db->insert(
131 WPF()->tables->forums,
132 array(
133 'title' => stripslashes($title),
134 'slug' => $slug,
135 'description' => stripslashes($description),
136 'parentid' => $parentid,
137 'icon' => $icon,
138 'topics' => $topics,
139 'posts' => $posts,
140 'permissions' => $permission,
141 'meta_key' => $meta_key,
142 'meta_desc' => $meta_desc,
143 'status' => $status,
144 'is_cat' => $is_cat,
145 'cat_layout' => $cat_layout,
146 'order' => $order
147 ),
148 array('%s','%s','%s','%d','%s','%d','%d','%s','%s','%s','%d','%d','%d','%d')
149 )
150 ){
151 $forumid = WPF()->db->insert_id;
152 $this->delete_tree_cache();
153 wpforo_clean_cache();
154 WPF()->notice->add('Your forum successfully added', 'success');
155 return $forumid;
156 }
157
158 WPF()->notice->add('Can\'t add forum', 'error');
159 return FALSE;
160 }
161
162 public function edit( $args = array() ){
163 if( !WPF()->perm->usergroup_can('ef') ){
164 WPF()->notice->add('Permission denied for edit forum', 'error');
165 return FALSE;
166 }
167
168 if( empty($args) && empty($_REQUEST['forum']) ) return FALSE;
169 if( empty($args) && !empty($_REQUEST['forum']) ) $args = $_REQUEST['forum'];
170 if( !isset($args['forumid']) && isset($_GET['id']) ) $args['forumid'] = $_GET['id'];
171
172 extract($args, EXTR_OVERWRITE);
173
174 if( !isset($forumid) || !$forumid ){
175 WPF()->notice->add('Forum update error', 'error');
176 return FALSE;
177 }
178
179 if ( !$forum = $this->get_forum($forumid) ){
180 WPF()->notice->add('Forum update error', 'error');
181 return FALSE;
182 }
183
184 if( !isset($title) || !$title ){
185 WPF()->notice->add('Please insert required fields!', 'error');
186 return FALSE;
187 }
188
189 $forumid = intval($forumid);
190 $title = sanitize_text_field($title);
191 $title = wpforo_text($title, 250, false);
192 $description = wpforo_kses($description, 'post');
193 $permission = (isset($permission) && is_array($permission)) ? serialize(array_map('sanitize_text_field', $permission)) : 'a:5:{i:1;s:4:"full";i:2;s:9:"moderator";i:3;s:8:"standard";i:4;s:9:"read_only";i:5;s:8:"standard";}';
194 $meta_key = (isset($meta_key)) ? sanitize_text_field($meta_key) : '';
195 $meta_desc = (isset($meta_desc)) ? sanitize_text_field($meta_desc) : '';
196 $parentid = (isset($parentid)) ? ( $forumid == $parentid ? intval($forum['parentid']) : intval($parentid) ) : 0;
197 $slug = (isset($slug)) ? sanitize_title($slug) : ((isset($title)) ? sanitize_title($title) : md5(time()));
198 $slug = $this->unique_slug($slug, $parentid, $forumid);
199 $icon = (isset($icon)) ? sanitize_text_field($icon) : '';
200 $topics = (isset($topics)) ? intval($topics) : 0;
201 $posts = (isset($posts)) ? intval($posts) : 0;
202 $order = (isset($order)) ? intval($order) : 0;
203 $cat_layout = (isset($cat_layout)) ? intval($cat_layout) : 1;
204 $status = (isset($status)) ? intval($status) : 1;
205 $is_cat = (isset($is_cat)) ? intval($is_cat) : 0;
206 if(!$parentid) $is_cat = 1;
207
208 if($parentid) {
209 $cat_layout = WPF()->db->get_var("SELECT `cat_layout` FROM `".WPF()->tables->forums."` WHERE `forumid` = " . intval($parentid) );
210 $cat_layout = intval($cat_layout);
211 }
212
213 if( FALSE !== WPF()->db->update(
214 WPF()->tables->forums,
215 array(
216 'title' => stripslashes($title),
217 'slug' => $slug,
218 'description' => stripslashes($description),
219 'parentid' => $parentid,
220 'icon' => $icon,
221 'permissions' => $permission,
222 'meta_key' => $meta_key,
223 'meta_desc' => $meta_desc,
224 'status' => $status,
225 'is_cat' => $is_cat,
226 'cat_layout' => $cat_layout
227 ),
228 array('forumid' => $forumid),
229 array('%s','%s','%s','%d','%s','%s','%s','%s','%d','%d','%d'),
230 array('%d')
231 )
232 ){
233 if( isset($cat_layout) ){
234 $childs = array();
235 $this->get_childs($forumid, $childs);
236 $sql = "UPDATE `".WPF()->tables->forums."` SET `cat_layout` = ".intval($cat_layout)." WHERE `forumid` IN(". implode(',', array_map('intval', $childs)).")";
237 WPF()->db->query($sql);
238 }
239 $this->delete_tree_cache();
240 wpforo_clean_cache();
241 WPF()->notice->add('Forum successfully updated', 'success');
242 return $forumid;
243 }
244
245 WPF()->notice->add('Forum update error', 'error');
246 return FALSE;
247 }
248
249 public function delete($forumid = 0){
250 $forumid = intval($forumid);
251 if(!$forumid && isset( $_REQUEST['id'] ) ) $forumid = intval($_REQUEST['id']);
252
253 if( !WPF()->perm->usergroup_can('df') ){
254 WPF()->notice->add('Permission denied for delete forum', 'error');
255 return FALSE;
256 }
257
258 $childs = array();
259 $this->get_childs($forumid, $childs);
260 $forumids = implode(',', array_map('intval', $childs));
261
262 // START delete topic posts include first post
263 if( $topicids = WPF()->db->get_col( "SELECT `topicid` FROM ".WPF()->tables->topics." WHERE `forumid` IN(". esc_sql($forumids) .")" ) ){
264 foreach($topicids as $topicid){
265 WPF()->topic->delete($topicid, false);
266 }
267 }
268 // END delete topic posts include first post
269
270 if(WPF()->db->query( "DELETE FROM ".WPF()->tables->forums." WHERE `forumid` IN(". esc_sql($forumids) .")" )){
271 $this->delete_tree_cache();
272 wpforo_clean_cache();
273 WPF()->notice->add('Your forum successfully deleted', 'success');
274 return TRUE;
275 }
276
277 WPF()->notice->add('Forum deleting error', 'error');
278 return FALSE;
279 }
280
281 public function merge($forumid = 0, $mergeid = 0){
282 $forumid = intval($forumid);
283 $mergeid = intval($mergeid);
284
285 if(!$forumid && isset( $_REQUEST['id'] ) ) $forumid = intval($_REQUEST['id']);
286 if(!$mergeid && isset( $_REQUEST['forum']['mergeid'] ) ) $mergeid = intval($_REQUEST['forum']['mergeid']);
287
288 if( !$forumid || !$mergeid ) return false;
289
290 if( $child_forumids = $this->get_child_forums( $forumid ) ){
291 $forumids = trim( implode(',', array_map('intval', $child_forumids)) );
292 if( $forumids ){
293 $merge_layout = $this->get_layout($mergeid);
294
295 if(!WPF()->db->query( "UPDATE ".WPF()->tables->forums." SET `parentid` = " . intval($mergeid) . ", `cat_layout` = " . intval($merge_layout) . " WHERE `forumid` IN(". esc_sql($forumids) .")" )){
296 WPF()->notice->add('Forum merging error', 'error');
297 return FALSE;
298 }
299 }
300 }
301
302 WPF()->db->update(
303 WPF()->tables->topics,
304 array( 'forumid' => $mergeid ),
305 array( 'forumid' => $forumid ),
306 array( '%d' ),
307 array( '%d' )
308 );
309 WPF()->db->update(
310 WPF()->tables->posts,
311 array( 'forumid' => $mergeid ),
312 array( 'forumid' => $forumid ),
313 array( '%d' ),
314 array( '%d' )
315 );
316
317 $this->rebuild_last_infos($mergeid);
318 $this->rebuild_stats($mergeid);
319
320 if(WPF()->db->delete( WPF()->tables->forums, array( 'forumid' => $forumid ), array( '%d' ) )){
321 $this->delete_tree_cache();
322 wpforo_clean_cache('forum');
323 WPF()->notice->add('Forum is successfully merged', 'success');
324 return TRUE;
325 }
326
327 WPF()->notice->add('Forum merging error', 'error');
328 return FALSE;
329 }
330
331 public function rebuild_last_infos($forumid){
332 if( !$forumid = intval($forumid) ) return false;
333
334 $last_topicid = 0;
335 $last_postid = 0;
336 $last_userid = 0;
337 $last_post_date = '0000-00-00 00:00:00';
338
339 if($last_topics = WPF()->topic->get_topics( array('forumid' => $forumid, 'orderby' => 'topicid', 'order' => 'DESC', 'row_count' => 1) )){
340 $last_topic = $last_topics[0];
341 $last_topicid = $last_topic['topicid'];
342 }
343
344 $sql = "SELECT `postid` FROM `".WPF()->tables->posts."` WHERE `forumid` = %d ORDER BY `is_first_post` ASC, `created` DESC, `postid` DESC LIMIT 1";
345 if( $last_postid = WPF()->db->get_var( WPF()->db->prepare($sql, $forumid) ) ){
346 if( $last_post_data = WPF()->post->get_post($last_postid) ){
347 $last_postid = $last_post_data['postid'];
348 $last_userid = $last_post_data['userid'];
349 $last_post_date = $last_post_data['created'];
350 }
351 }else{
352 $last_postid = 0;
353 }
354
355 WPF()->db->update(
356 WPF()->tables->forums,
357 array('last_topicid' => $last_topicid, 'last_postid' => $last_postid, 'last_userid' => $last_userid, 'last_post_date' => $last_post_date),
358 array('forumid' => $forumid),
359 array('%d','%d','%d','%s'),
360 array('%d')
361 );
362
363 wpforo_clean_cache('forum');
364 }
365
366 public function rebuild_stats($forumid){
367 if( !$forumid = intval($forumid) ) return false;
368 $topics = WPF()->topic->get_count( array('forumid' => $forumid, 'status' => 0) );
369 $posts = WPF()->post->get_count( array('forumid' => $forumid, 'status' => 0) );
370
371 if( false !== WPF()->db->update(
372 WPF()->tables->forums,
373 array('topics' => $topics, 'posts' => $posts ),
374 array('forumid' => $forumid),
375 array('%d', '%d'),
376 array('%d')
377 ) ) {
378 wpforo_clean_cache('forum');
379 return true;
380 }
381 return false;
382 }
383
384 function get_forum( $args ){
385
386 $cache = WPF()->cache->on('memory_cashe');
387
388 if(is_array($args)){
389 $default = array(
390 'forumid' => NULL, // forumid
391 'slug' => '', // slug
392 'status' => NULL, // status forum 1 OR 0
393 'cat_layout' => 1, // forum layout
394 'type' => 'all' // category, forum
395 );
396 }else{
397 $default = array(
398 'forumid' => ( is_numeric($args) ? intval($args) : NULL ), // forumid
399 'slug' => ( !is_numeric($args) ? $args : '' ), // slug
400 'cat_layout' => 1, // forum layout
401 'status' => NULL, // status forum 1 OR 0
402 'type' => 'all' // category, forum
403 );
404 }
405 $args = wpforo_parse_args( $args, $default );
406
407 if( $cache && !empty($args['forumid']) ){
408 if( !empty(self::$cache['forum'][$args['forumid']]) ){
409 return self::$cache['forum'][$args['forumid']];
410 }
411 }
412
413 if( $cache && !empty($args['slug']) ){
414 if( !empty(self::$cache['forum'][addslashes($args['slug'])]) ){
415 return self::$cache['forum'][addslashes($args['slug'])];
416 }
417 }
418 if(!empty($args)){
419 extract($args, EXTR_OVERWRITE);
420 $sql = "SELECT * FROM `".WPF()->tables->forums."`";
421 $wheres = array();
422 if($forumid != NULL) $wheres[] = "`forumid` = " . intval($forumid);
423 if($status != NULL) $wheres[] = "`status` = " . intval($status);
424 if($type == 'category'){
425 $wheres[] = "`is_cat` = 1";
426 }elseif($type == 'forum'){
427 $wheres[] = "`is_cat` = 0";
428 }
429 if($slug != '') $wheres[] = "`slug` = '" . esc_sql($slug) . "'";
430
431 if(!empty($wheres)){
432 $sql .= " WHERE " . implode( " AND ", $wheres );
433 }
434 $forum = WPF()->db->get_row($sql, ARRAY_A);
435 if(!empty($forum)) {
436 $forum['url'] = $this->get_forum_url( $forum );
437 }
438 $forum = apply_filters('wpforo_get_forum', $forum);
439 if($cache && isset($forumid)){
440 self::$cache['forum'][addslashes($forum['slug'])] = $forum;
441 return self::$cache['forum'][$forum['forumid']] = $forum;
442 }
443 else{
444 return $forum;
445 }
446 }
447 }
448
449 function get_forums($args = array(), &$items_count = 0 ){
450
451 $cache = WPF()->cache->on('object_cashe');
452
453 $default = array(
454 'include' => array(), // array( 2, 10, 25 )
455 'exclude' => array(), // array( 2, 10, 25 )
456 'parent_include' => array(), // array( 2, 10, 25 )
457 'parent_exclude' => array(), // array( 2, 10, 25 )
458 'parentid' => NULL,
459 'parent_slug' => '',
460 'status' => NULL,
461 'type' => 'all', // category, forum
462 'orderby' => 'order', // order by `field`
463 'order' => 'ASC', // ASC DESC
464 'offset' => NULL, // OFFSET
465 'row_count' => NULL, // ROW COUNT
466 );
467
468 $args = wpforo_parse_args( $args, $default );
469 if(is_array($args) && !empty($args)){
470
471 extract($args, EXTR_OVERWRITE);
472
473 $include = wpforo_parse_args( $include );
474 $exclude = wpforo_parse_args( $exclude );
475 $parent_include = wpforo_parse_args( $parent_include );
476 $parent_exclude = wpforo_parse_args( $parent_exclude );
477
478 $sql = "SELECT * FROM `".WPF()->tables->forums."`";
479 $wheres = array();
480
481 if(!empty($include)) $wheres[] = "`forumid` IN(" . implode(', ', array_map('intval', $include)) . ")";
482 if(!empty($exclude)) $wheres[] = "`forumid` NOT IN(" . implode(', ', array_map('intval', $exclude)) . ")";
483 if(!empty($parent_include)) $wheres[] = "`parentid` IN(" . implode(', ', array_map('intval', $parent_include)) . ")";
484 if(!empty($parent_exclude)) $wheres[] = "`parentid` NOT IN(" . implode(', ', array_map('intval', $parent_exclude)) . ")";
485 if($parentid != NULL) $wheres[] = " `parentid` = " . intval($parentid);
486 if($status != NULL) $wheres[] = " `status` = " . intval($status);
487
488 if($type == 'category'){
489 $wheres[] = " `is_cat` = 1";
490 }elseif($type == 'forum'){
491 $wheres[] = " `is_cat` = 0";
492 }
493
494 if($parent_slug != '') $wheres[] = "`slug` = '" . esc_sql($parent_slug) . "'";
495
496 if(!empty($wheres)) $sql .= " WHERE " . implode( " AND ", $wheres );
497
498 $item_count_sql = preg_replace('#SELECT.+?FROM#isu', 'SELECT count(*) FROM', $sql);
499 if( $item_count_sql ) $items_count = WPF()->db->get_var($item_count_sql);
500
501 $sql .= esc_sql(" ORDER BY `$orderby` " . $order);
502
503 if($row_count != NULL){
504 if($offset != NULL){
505 $sql .= esc_sql(" LIMIT $offset,$row_count");
506 }else{
507 $sql .= esc_sql(" LIMIT $row_count");
508 }
509 }
510
511 if( $cache ){ $object_key = md5( $sql . WPF()->current_user_groupid ); $object_cache = WPF()->cache->get( $object_key ); if(!empty($object_cache)){$items_count = $object_cache['items_count']; return $object_cache['items'];}}
512
513 $forums = WPF()->db->get_results($sql, ARRAY_A);
514 $forums = apply_filters('wpforo_get_topics', $forums);
515
516 if($cache && isset($object_key) && !empty($forums)){
517 self::$cache['forums'][$object_key]['items'] = $forums;
518 self::$cache['forums'][$object_key]['items_count'] = $items_count;
519 }
520 return $forums;
521 }
522 }
523
524 function search($needle, $fields = array()){
525
526 if($needle){
527 $needle = sanitize_text_field($needle);
528 if(empty($fields)){
529 $fields = array(
530 'title',
531 'description',
532 'meta_key',
533 'meta_desc'
534 );
535 }
536
537 $sql = "SELECT `forumid` FROM `".WPF()->tables->forums."`";
538 $wheres = array();
539
540 foreach($fields as $field){
541 $wheres[] = "`" . esc_sql($field) . "` LIKE '%" . esc_sql($needle) . "%'";
542 }
543
544 $sql .= " WHERE " . implode(" OR ", $wheres);
545 return WPF()->db->get_col($sql);
546 }
547
548 return array();
549 }
550
551 function update_hierarchy(){
552 if(is_array($_REQUEST['forum']) && !empty($_REQUEST['forum'])){
553 $i = 0;
554 foreach($_REQUEST['forum'] as $hierarchy){
555
556 extract($hierarchy);
557
558 if(!isset($forumid) || !$forumid = intval($forumid) ) continue;
559
560 if(FALSE !== WPF()->db->update(
561 WPF()->tables->forums,
562 array(
563 'parentid' => (isset($parentid) ? intval($parentid) : 0),
564 'order' => (isset($order) ? intval($order) : 0),
565 ),
566 array( 'forumid' => intval($forumid) ),
567 array(
568 '%d',
569 '%d'
570 ),
571 array( '%d' )
572 )) $i++;
573
574 if(isset($parentid) && $parentid = intval($parentid) ){
575 $cat_layout = WPF()->db->get_var("SELECT `cat_layout` FROM `".WPF()->tables->forums."` WHERE `forumid` = " . intval($parentid));
576 WPF()->db->query("UPDATE `".WPF()->tables->forums."` SET `cat_layout` = " . intval($cat_layout) . " WHERE `forumid` = " . intval($forumid));
577 }
578
579 }
580
581 WPF()->db->query("UPDATE `".WPF()->tables->forums."` SET `is_cat` = 0");
582 WPF()->db->query("UPDATE `".WPF()->tables->forums."` SET `is_cat` = 1 WHERE `parentid` = 0");
583
584 if($i){
585 $this->delete_tree_cache();
586 WPF()->notice->add('Forum hierarchy successfully updated', 'success');
587 }else{
588 WPF()->notice->add('Cannot update forum hierarchy', 'error');
589 }
590
591 }
592 }
593
594 function get_childs($forumid, &$data){
595 if(empty($data)) $data[] = $forumid;
596 $sub_forums = WPF()->db->get_results("SELECT `forumid` FROM ".WPF()->tables->forums." WHERE `parentid` = ".intval($forumid) ." AND `forumid` <> " . intval($forumid), ARRAY_A);
597 if(!empty($sub_forums)){
598 foreach($sub_forums as $sub_forum){
599 $data[] = $sub_forum['forumid'];
600 $this->get_childs($sub_forum['forumid'], $data);
601 }
602 }
603 }
604
605
606 // get forums tree for drop down menu
607
608 /**
609 * Returns depth for this item.
610 *
611 * @since 1.0.0
612 *
613 * @param int item id
614 *
615 * @param int before calling the function $depth = 0
616 */
617 function count_depth($forumid, &$depth){
618 $parentid = WPF()->db->get_var("SELECT `parentid` FROM `".WPF()->tables->forums."` WHERE `forumid` = ".intval($forumid) ." AND `parentid` <> " . intval($forumid));
619
620 if($parentid){
621 $depth++;
622 $this->count_depth($parentid, $depth);
623 }
624 }
625
626 function get_child_forums($parent){
627 $children = WPF()->db->get_results("SELECT `forumid` AS childid FROM `".WPF()->tables->forums."` WHERE `parentid` = ".intval($parent)." AND `forumid` <> ".intval($parent)." ORDER BY `order`", ARRAY_A);
628 if(!empty($children)){
629 foreach( $children as $child ){
630 $data[] = $child['childid'];
631 }
632 return $data;
633 }else{
634 return array();
635 }
636 }
637
638 function forum_list( $forumids, $type = 'select_box', $selected = array(), $cats = TRUE, $disabled = array() ){
639 static $old_depth;
640 $disabled = (array) $disabled;
641 $selected = (array) $selected;
642
643 foreach ( $forumids as $forumid ) {
644 if( !$forumid || !WPF()->perm->forum_can('vf', $forumid) ) continue;
645
646 $depth = 0;
647 $this->count_depth($forumid, $depth);
648 $name = WPF()->db->get_var("SELECT `title` FROM `".WPF()->tables->forums."` WHERE `forumid` = ".intval($forumid));
649 if($type == 'select_box'){ ?>
650 <option value="<?php echo intval($forumid) ?>" <?php echo( (!$cats && $depth == 0 || (!empty($disabled) && in_array($forumid, $disabled)) ) ? ' disabled ': ''); echo ( in_array($forumid, $selected) ? ' selected ' : '' ) ?> > <?php echo esc_html(str_repeat( '— ', $depth ) . trim($name)) ?></option><?php
651 }elseif($type == 'drag_menu'){
652 $cur_forum = WPF()->db->get_row("SELECT `cat_layout`, `topics`, `posts` FROM `".WPF()->tables->forums."` WHERE `forumid` = ".intval($forumid), ARRAY_A);
653 $cat_layout_name = ( $cur_forum['cat_layout'] == 2 ? 'Simplified Layout' : ( $cur_forum['cat_layout'] == 3 ? 'QA Layout' : 'Extended Layout' ) ); ?>
654
655 <li id="menu-item-<?php echo intval($forumid) ?>" class="menu-item menu-item-depth-<?php echo esc_attr($depth) ?>">
656 <input id="forumid-<?php echo intval($forumid) ?>" type="hidden" name="forum[<?php echo intval($forumid) ?>][forumid]"/>
657 <input id="parentid-<?php echo intval($forumid) ?>" type="hidden" name="forum[<?php echo intval($forumid) ?>][parentid]"/>
658 <input id="order-<?php echo intval($forumid) ?>" type="hidden" name="forum[<?php echo intval($forumid) ?>][order]"/>
659 <dl class="menu-item-bar">
660 <dt class="menu-item-handle forum_width">
661 <span class="item-title forumtitle"><span style="font-weight:400; cursor:help;" title="Forum ID"><?php echo $forumid; ?> &nbsp;|&nbsp;</span> <?php echo esc_html($name) ?></span>
662 <span class="item-controls">
663 <span class="wpforo-cat-layout"><?php echo ( $depth != 0 ? __('Topics', 'wpforo') . '&nbsp;(' . intval($cur_forum['topics']) . ')&nbsp;,&nbsp;' . __('Posts', 'wpforo') . '&nbsp;(' . intval($cur_forum['posts']) . ')&nbsp; | &nbsp;' : '' ) ?><?php echo ( $depth == 0 ? '(&nbsp;<i>' . esc_html($cat_layout_name) . '</i>&nbsp;)&nbsp; | &nbsp;' : '' ); ?></span>
664 <span class="menu_add"><a href="<?php echo admin_url( 'admin.php?page=wpforo-forums&action=add&parentid=' . intval($forumid) ) ?>" > <img src="<?php echo WPFORO_URL ?>/wpf-assets/images/icons/plus<?php echo ((!$depth) ? '-dark' : ''); ?>.png" title="<?php if( $depth ) : _e('Add a new Subforum', 'wpforo'); else: _e('Add a new Forum in this Category', 'wpforo'); endif; ?>"/></a></span> &nbsp;|&nbsp;
665 <span class="menu_edit"><a href="<?php echo admin_url( 'admin.php?page=wpforo-forums&id=' . intval($forumid) . '&action=edit' ) ?>"><img src="<?php echo WPFORO_URL ?>/wpf-assets/images/icons/pencil<?php echo ((!$depth) ? '-dark' : ''); ?>.png" title="<?php _e('edit', 'wpforo') ?>"/></a></span>&nbsp;|&nbsp;
666 <?php if( WPF()->perm->usergroup_can('df') ): ?>
667 <span class="menu_delete"><a href="<?php echo admin_url( 'admin.php?page=wpforo-forums&id=' . intval($forumid) . '&action=del' ) ?>"><img src="<?php echo WPFORO_URL ?>/wpf-assets/images/icons/trash<?php echo ((!$depth) ? '-dark' : ''); ?>.png" title="<?php _e('delete', 'wpforo') ?>"/></a></span>&nbsp;|&nbsp;
668 <?php endif; ?>
669 <span class="menu_view"><a href="<?php echo esc_url(wpforo_forum($forumid, 'url')); ?>" > <img src="<?php echo WPFORO_URL ?>/wpf-assets/images/icons/eye<?php echo ((!$depth) ? '-dark' : ''); ?>.png" title="<?php _e('View', 'wpforo') ?>"/> </a> </span>
670
671 </span>
672 </dt>
673 </dl>
674 <ul class="menu-item-transport"></ul>
675 </li>
676
677 <?php
678 }elseif($type == 'front_list'){
679 if(isset($old_depth) && $old_depth == $depth) echo '</dd><dd>';
680 if(isset($old_depth) && $old_depth < $depth) echo '<dl><dd>';
681 if(isset($old_depth) && $old_depth > $depth) echo '</dd></dl>';
682 $old_depth = $depth;
683 if(isset(WPF()->current_object) && isset(WPF()->current_object['forumid'])){
684 if( $forumid == WPF()->current_object['forumid'] ){
685 echo'<span class="wpf-dl-item wpf-dl-current"><i class="far fa-comments"></i><strong>'.esc_html($name).'</strong><a href="' . esc_url( wpforo_forum($forumid, 'url') ) . '" >&nbsp;&raquo;</a></span>';
686 }
687 else{
688 echo'<span class="wpf-dl-item"><a href="'.esc_url( wpforo_forum($forumid, 'url') ).'" ><i class="far fa-comments"></i>'.esc_html($name).'</a></span>';
689 }
690 }
691 else{
692 echo'<span class="wpf-dl-item"><a href="'.esc_url( wpforo_forum($forumid, 'url') ).'" ><i class="far fa-comments"></i>'.esc_html($name).'</a></span>';
693 }
694 }elseif($type == 'subscribe_manager_form'){
695 ?>
696 <li>
697 <?php if($depth > 0) :
698 $forum_topic_attr = '';
699 $forum_attr = '';
700 if ( key_exists($forumid, $selected) ){
701 if( $selected[$forumid] == 'forum-topic' ){
702 $forum_topic_attr = ' checked ';
703 }elseif ( $selected[$forumid] == 'forum' ){
704 $forum_attr = ' checked ';
705 }
706 }
707 ?>
708 <div class="wpf-sbs-div wpf-sbs-checkbox">
709 <input id="wpf_sbs_allposts_<?php echo $forumid ?>" type="checkbox" name="wpforo[forums][<?php echo $forumid ?>]" value="forum-topic" <?php echo $forum_topic_attr ?>><label class="wpf-sbsp" for="wpf_sbs_allposts_<?php echo $forumid ?>"><?php wpforo_phrase('topics and posts') ?></label>
710 <input id="wpf_sbs_alltopics_<?php echo $forumid ?>" type="checkbox" name="wpforo[forums][<?php echo $forumid ?>]" value="forum" <?php echo $forum_attr ?>><label class="wpf-sbst" for="wpf_sbs_alltopics_<?php echo $forumid ?>"><?php wpforo_phrase('topics') ?></label>
711 </div>
712 <?php endif; ?>
713 <div class="wpf-sbs-div wpf-sbs-form-title<?php echo ($depth > 0) ? ' wpf-sbs-forum' : ' wpf-sbs-cat'; ?>"><?php echo esc_html(str_repeat( '— ', $depth )) . trim($name) ?></div>
714 </li>
715 <?php
716 }
717 $subforums = $this->get_child_forums($forumid);
718 if( !empty($subforums) ){
719 $this->forum_list($subforums, $type, $selected, true, $disabled);
720 }
721 }
722 }
723
724 function tree($type = 'select_box', $cats = TRUE, $selected = array(), $cache = true, $disabled = array())
725 {
726 $disabled = (array)$disabled;
727 $selected = (array)$selected;
728 $parentids = WPF()->db->get_col("SELECT `forumid` FROM `".WPF()->tables->forums."` WHERE `parentid` = 0 ORDER BY `order`");
729 if (!empty($parentids)) {
730 if ($cache && !wpforo_is_admin()) {
731 $key = md5(serialize($parentids) . $type . (int)$cats . WPF()->current_user_groupid);
732 $html = get_option('wpforo_forum_tree_' . $key);
733 $pattern_strip_selected = '#(<(?:option|input)[^<>]*?)[\r\n\t\s]*(?:selected|checked)[^\r\n\t\s]*?((?:[\r\n\t\s][^<>]*)?>)#isu';
734
735 if ($html) {
736 if( $type == 'select_box' || $type == 'subscribe_manager_form' ) $html = preg_replace($pattern_strip_selected, '$1$2', $html);
737 if($selected){
738 if($type == 'select_box'){
739 foreach ($selected as $sfid){
740 $html = str_replace('value="'.$sfid.'"', 'value="'.$sfid.'" selected ', $html);
741 }
742 }elseif ($type == 'subscribe_manager_form'){
743 foreach ($selected as $forumid => $stype){
744 $html = preg_replace('#(name=[\'"]wpforo\[forums\]\['.intval($forumid).'\][\'"][^<>]*?value=[\'"]'.preg_quote($stype).'[\'"]|value=[\'"]'.preg_quote($stype).'[\'"][^<>]*?name=[\'"]wpforo\[forums\]\['.intval($forumid).'\][\'"])#isu', '$1 checked', $html);
745 }
746 }
747 }
748 echo $html;
749 } elseif (function_exists('ob_start')) {
750 ob_start();
751 $this->forum_list($parentids, $type, $selected, $cats, $disabled);
752 $html = ob_get_clean();
753 $cache_html = ( $type == 'select_box' ? preg_replace($pattern_strip_selected, '$1$2', $html) : $html );
754 if ($type != 'drag_menu') update_option('wpforo_forum_tree_' . $key, $cache_html);
755 echo $html;
756 }
757 } else {
758 $this->forum_list($parentids, $type, $selected, $cats, $disabled);
759 }
760 }
761 }
762
763 public function delete_tree_cache() {
764 WPF()->db->query("DELETE FROM " . WPF()->db->options . " WHERE `option_name` LIKE 'wpforo_forum_tree_%'");
765 }
766
767 function parentid( $topicid = 0 ){
768 if(isset($_GET['page']) && $_GET['page'] == 'wpforo-forums'){
769 if( isset($_GET['id'])) return WPF()->db->get_var("SELECT `parentid` FROM `".WPF()->tables->forums."` WHERE `forumid` = ".intval($_GET['id']));
770 }
771 elseif( isset($_GET['page']) && $_GET['page'] == 'wpforo-topics' ){
772 if( isset($_GET['id'])) return WPF()->db->get_var( "SELECT `forumid` FROM `".WPF()->tables->topics."` WHERE `topicid` = ".wpforo_bigintval($_GET['id']));
773 }else{
774 if( $topicid ) return WPF()->db->get_var( "SELECT `forumid` FROM `".WPF()->tables->topics."` WHERE `topicid` = ".wpforo_bigintval($topicid));
775 }
776 }
777
778 function permissions(){
779 $access_arr = WPF()->perm->get_accesses();
780 if(!empty( $access_arr )){
781
782 if(isset($_GET['id'])){
783 if($permissions_srlz = WPF()->db->get_var("SELECT `permissions` FROM `".WPF()->tables->forums."` WHERE `forumid` = ".intval($_GET['id']))){
784 $permissions_arr = unserialize($permissions_srlz);
785 }
786 }
787
788 if($usergroups = WPF()->db->get_results("SELECT `groupid`, `name` FROM `".WPF()->tables->usergroups."`", ARRAY_A)){
789 foreach($usergroups as $usergroup){
790 extract($usergroup, EXTR_OVERWRITE);
791 echo '
792 <tr>
793 <td>'.esc_html($name).'</td>
794 <td>
795 <select name="forum[permission]['.intval($groupid).']">';
796 foreach($access_arr as $value){
797
798 echo '<option value="'.esc_attr($value['access']).'" '.
799 ((isset($permissions_arr[$groupid]) && $value['access'] == $permissions_arr[$groupid])
800 || (!isset($permissions_arr[$groupid])
801 && (($name == 'Guest' && $value['access'] == 'read_only')
802 || ($name == 'Registered' && $value['access'] == 'standard')
803 || ($name == 'Customer' && $value['access'] == 'standard')
804 || ($name == 'Moderator' && $value['access'] == 'moderator')
805 || ($name == 'Admin' && $value['access'] == 'full')
806 || ($name != 'Guest' && $name != 'Registered' && $name != 'Customer' && $name != 'Moderator' && $name != 'Admin' && $value['access'] == 'standard') )) ? ' selected ' : '').'>'.esc_html( __( $value['title'], 'wpforo') ).'</option>';
807 }
808 echo'
809 </select>
810 </td>
811 </tr>
812 ';
813 }
814
815
816
817 }
818 }
819 }
820
821 /**
822 * array get_counts(array or id(num))
823 *
824 * @since 1.0.0
825 *
826 * @param array defined arguments array for returning
827 *
828 * @return int count topics
829 */
830 function get_counts($forumids){
831
832 if( !empty($forumids) ){
833
834 $wheres = '';
835
836 if(!is_array($forumids)){
837 $wheres = "`forumid` = " . intval($forumids);
838 }else{
839 $wheres = "`forumid` IN(" . implode(', ', array_map('intval', $forumids)) . ")";
840 }
841
842 $sql = "SELECT SUM(`topics`) as topics, SUM(`posts`) as posts FROM `".WPF()->tables->forums."` WHERE " . $wheres;
843 return WPF()->db->get_row($sql, ARRAY_A);
844
845 }
846
847 return 0;
848 }
849
850 /**
851 * array get_layout(array)
852 *
853 * @since 1.0.0
854 *
855 * @param array defined arguments array for returning
856 *
857 * @return int layout id
858 */
859 function get_layout($args){
860 if(is_array($args)){
861 $default = array(
862 'forumid' => NULL, // forum id
863 'topicid' => NULL, // topic id
864 'postid' => NULL, // post id
865 );
866 }else{
867 $default = array(
868 'forumid' => $args, // forumid
869 'topicid' => NULL, // topic id
870 'postid' => NULL, // post id
871 );
872 }
873 $args = wpforo_parse_args( $args, $default );
874 if(!empty($args)){
875 extract($args, EXTR_OVERWRITE);
876
877 if( $args['forumid'] ){
878 $sql = "SELECT `cat_layout` FROM `".WPF()->tables->forums."` WHERE `forumid` = " . intval($args['forumid']);
879 $cat_layout = WPF()->db->get_var($sql);
880 return ( $cat_layout ? $cat_layout : 1 );
881 }elseif( $args['topicid'] ){
882 $sql = "SELECT `forumid` FROM `".WPF()->tables->topics."` WHERE `topicid` = " . intval($args['topicid']);
883 $forumid = WPF()->db->get_var($sql);
884 return $this->get_layout(array( 'forumid' => $forumid ));
885 }elseif( $args['postid'] ){
886 $sql = "SELECT `forumid` FROM `".WPF()->tables->posts."` WHERE `postid` = " . intval($args['postid']);
887 $forumid = WPF()->db->get_var($sql);
888 return $this->get_layout(array( 'forumid' => $forumid ));
889 }
890 }
891
892 }
893
894 function get_forum_url($forum){
895
896 if( !is_array($forum) ){
897 if(is_numeric($forum)){
898 $forum = $this->get_forum($forum);
899 }else{
900 $forum = array('slug' => $forum);
901 }
902 }
903
904 if( is_array($forum) && !empty($forum) ){
905 return wpforo_home_url( utf8_uri_encode($forum['slug']) );
906 }else{
907 return wpforo_home_url();
908 }
909 }
910
911 function get_all_relative_ids($forumid, &$relative_ids){
912 $forum = WPF()->db->get_row("SELECT `parentid`, `forumid` FROM `".WPF()->tables->forums."` WHERE `forumid` = ".intval($forumid), ARRAY_A);
913
914 if($forum['parentid']){
915 $relative_ids[] = $forum['forumid'];
916 $this->get_all_relative_ids($forum['parentid'], $relative_ids);
917 }else{
918 $relative_ids[] = $forum['forumid'];
919 $relative_ids = array_reverse($relative_ids);
920 }
921 }
922
923 function get_count( $args = array() ){
924 $sql = "SELECT COUNT(*) FROM `".WPF()->tables->forums."`";
925 if( !empty($args) ){
926 $wheres = array();
927 foreach ($args as $key => $value) $wheres[] = "`$key` = " . intval($value);
928 if($wheres) $sql .= " WHERE " . implode(' AND ', $wheres);
929 }
930 return WPF()->db->get_var($sql);
931 }
932
933 function get_lastinfo( $ids = array() ){
934 $lastinfo = array();
935 if(!empty($ids)){
936 $ids = implode(',', array_map('intval', $ids));
937 $lastinfo = WPF()->db->get_row( "SELECT `userid` as last_userid, `topicid` as last_topicid, `postid` as last_postid, `created` as last_post_date FROM `".WPF()->tables->posts."` WHERE forumid IN(" . $ids .") ORDER BY `created` DESC LIMIT 1", ARRAY_A);
938 }
939 return $lastinfo;
940 }
941
942 function forums(){
943 $forums = $this->get_forums( array('parentid' => 0) );
944 return $this->children($forums);
945 }
946
947 function children($forums, $parentId = 0, $level = 0) {
948 if(empty($forums) || !is_array($forums)) return;
949 $items = array();
950 $level = $level + 1;
951 foreach ($forums as $forum) {
952 if ( !isset($forum['forumid']) || !WPF()->perm->forum_can('vf', $forum['forumid'])) continue;
953 $forum['level'] = $level + 1;
954 if ($forum['parentid'] == $parentId) {
955 $children = $this->children($forums, $forum['forumid'], $level);
956 if ($children) {
957 $forum['children'] = $children;
958 }
959 $items[] = $forum;
960 }
961 }
962 return $items;
963 }
964
965 function dropdown( $forums = array() ){
966 if( empty($forums) ){
967 $forums = $this->forums();
968 }
969 foreach( $forums as $forum ){
970 if( isset($forum['level']) ) $forum['level'] = $forum['level'] - 2;
971 $prefix = ( $forum['level'] == 0 ) ? '' : str_repeat( '&mdash;', $forum['level']);
972 echo '<option value="' . esc_attr( $forum['forumid'] ) . '"> ' . $prefix . '&nbsp;' . esc_html($forum['title']) . '</option>';
973 if( !empty($forum['children']) ){
974 $this->dropdown( $forum['children'] );
975 }
976 }
977 }
978
979 function private_forum( $forumid, $usergroups = array() ){
980 if( $forumid ){
981 if( empty($usergroups) ) {
982 $groupid = WPF()->current_user_groupid;
983 $usergroups = array( $groupid );
984 }
985 elseif( is_numeric($usergroups) ){
986 $usergroups = array( $usergroups );
987 }
988 if( !empty($usergroups) && is_array($usergroups) ){
989 foreach( $usergroups as $usergroup ){
990 if( !WPF()->perm->forum_can('vf', $forumid, $usergroup) ){
991 return true;
992 }
993 }
994 }
995 }
996 return false;
997 }
998
999 }