PluginProbe
wpForo Forum / 2.4.6
wpForo Forum v2.4.6
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 / wpforo.php

wpforo.php in wpForo Forum 2.4.6, at wpforo.php

1,520 lines 57.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 * Plugin Name: wpForo
4 * Plugin URI: https://wpforo.com
5 * Description: WordPress Forum plugin. wpForo is a full-fledged forum solution for your community. Comes with multiple modern forum layouts.
6 * Author: gVectors Team
7 * Author URI: https://gvectors.com/
8 * Version: 2.4.6
9 * Text Domain: wpforo
10 * Domain Path: /languages
11 */
12
13 namespace wpforo;
14
15 define( 'WPFORO_VERSION', '2.4.6' );
16
17 //Exit if accessed directly
18 if( ! defined( 'ABSPATH' ) ) exit;
19
20 define( 'WPFORO_DIR', rtrim( plugin_dir_path( __FILE__ ), '/' ) );
21 define( 'WPFORO_URL', rtrim( plugins_url( '', __FILE__ ), '/' ) );
22 define( 'WPFORO_BASENAME', plugin_basename( __FILE__ ) ); //wpforo/wpforo.php
23
24 require_once WPFORO_DIR . "/autoload.php";
25
26 use stdClass;
27 use wpdb;
28 use wpforo\classes\Actions;
29 use wpforo\classes\Activity;
30 use wpforo\classes\API;
31 use wpforo\classes\Boards;
32 use wpforo\classes\Cache;
33 use wpforo\classes\Feed;
34 use wpforo\classes\Forms;
35 use wpforo\classes\Forums;
36 use wpforo\classes\Logs;
37 use wpforo\classes\Members;
38 use wpforo\classes\Moderation;
39 use wpforo\classes\Notices;
40 use wpforo\classes\Permissions;
41 use wpforo\classes\Phrases;
42 use wpforo\classes\PostMeta;
43 use wpforo\classes\Posts;
44 use wpforo\classes\RamCache;
45 use wpforo\classes\SEO;
46 use wpforo\classes\Settings;
47 use wpforo\classes\Template;
48 use wpforo\classes\Topics;
49 use wpforo\classes\UserGroups;
50 use wpforo\modules\bookmarks\Bookmarks;
51 use wpforo\modules\reactions\Reactions;
52 use wpforo\modules\revisions\Revisions;
53 use wpforo\modules\subscriptions\Subscriptions;
54
55 final class wpforo {
56 private static $_instance = null;
57
58 /** @var wpdb * */
59 public $db;
60 public $default;
61
62 public $blog_prefix = "wp_";
63 public $base_prefix = "wpforo_";
64 public $prefix = "wpforo_";
65 public $_base_tables = [
66 'boards',
67 'usergroups',
68 'profiles',
69 'logs',
70 'follows',
71 'bookmarks',
72 'accesses',
73 ];
74 public $_tables = [
75 'activity',
76 'forums',
77 'languages',
78 'phrases',
79 'postmeta',
80 'posts',
81 'post_revisions',
82 'subscribes',
83 'topics',
84 'tags',
85 'visits',
86 'reactions',
87 ];
88 public $tables;
89 private $_folders = [
90 'assets',
91 'attachments',
92 'avatars',
93 'covers',
94 'cache',
95 'default_attachments',
96 'emoticons',
97 ];
98 public $folders = [];
99
100 public $current_url;
101 public $canonical_url;
102 public $GET = [];
103 public $current_object;
104
105 public $wp_current_user = null;
106 public $current_user = [];
107 public $current_usermeta = [];
108 public $current_user_groupid = 4;
109 public $current_user_groupids = [ 4 ];
110 public $current_user_secondary_groupids = [];
111 public $current_userid = 0;
112 public $current_user_login = '';
113 public $current_user_email = '';
114 public $current_user_display_name = '';
115 public $current_user_status = '';
116 public $current_user_accesses = [];
117 public $session_token = '';
118
119 public $tools_cleanup;
120 public $tools_misc;
121 public $locale = 'en_US';
122
123 public $dissmissed;
124
125 /** @var Settings */
126 public $settings;
127 /** @var Actions */
128 public $action;
129 /** @var Activity */
130 public $activity;
131 /** @var API */
132 public $api;
133 /** @var Boards */
134 public $board;
135 /** @var Cache */
136 public $cache;
137 /** @var Feed */
138 public $feed;
139 /** @var Forms */
140 public $form;
141 /** @var Forums */
142 public $forum;
143 /** @var Logs */
144 public $log;
145 /** @var Members */
146 public $member;
147 /** @var Moderation */
148 public $moderation;
149 /** @var Notices */
150 public $notice;
151 /** @var Permissions */
152 public $perm;
153 /** @var Phrases */
154 public $phrase;
155 /** @var PostMeta */
156 public $postmeta;
157 /** @var Posts */
158 public $post;
159 /** @var RamCache */
160 public $ram_cache;
161 /** @var Revisions */
162 public $revision;
163 /** @var Reactions */
164 public $reaction;
165 /** @var Bookmarks */
166 public $bookmark;
167 /** @var SEO */
168 public $seo;
169 /** @var Subscriptions */
170 public $sbscrb;
171 /** @var Template */
172 public $tpl;
173 /** @var Topics */
174 public $topic;
175 /** @var UserGroups */
176 public $usergroup;
177
178 public static function instance() {
179 if( is_null( self::$_instance ) ) self::$_instance = new self();
180
181 return self::$_instance;
182 }
183
184 private function init_db() {
185 global $wpdb;
186 $this->db = $wpdb;
187 }
188
189 public function is_db_mysql8() {
190 if( preg_match( '#([\d.]+)-MariaDB#iu', (string) $this->db->get_var( "SELECT VERSION()" ), $match ) ) {
191 $use_mysql8 = version_compare( $match[1], '10.2.6', '>=' );
192 } else {
193 $use_mysql8 = version_compare( $this->db->db_version(), '8.0.0', '>=' );
194 }
195
196 return apply_filters( 'wpforo_use_mysql8', $use_mysql8 );
197 }
198
199 private function __construct() {
200 $this->init_db();
201 $this->init_hooks();
202 }
203
204 public function generate_prefix( $boardid ) {
205 $boardid = intval( $boardid );
206
207 return $this->base_prefix . ( $boardid ? $boardid . '_' : '' );
208 }
209
210 private function init_prefix() {
211 $boardid = $this->board->get_current( 'boardid' );
212 $this->prefix = $this->generate_prefix( $boardid );
213 }
214
215 public function change_board( $args = [] ) {
216 if( is_null( $this->board ) ) return;
217
218 do_action( 'wpforo_before_change_board', $args );
219
220 $boardid = $this->board->get_current( 'boardid' );
221 $is_inited = (bool) wpfval( $this->board->is_inited, $boardid );
222 $this->board->init_current( $args );
223
224 if( ! $is_inited || $boardid !== $this->board->get_current( 'boardid' ) ) {
225 $this->ram_cache->reset();
226
227 $this->init_prefix();
228 $this->init_tables();
229 $this->init_folders();
230 $this->init_options();
231
232 do_action( 'wpforo_after_change_board', $args );
233 }
234 }
235
236 private function init_base_classes() {
237 $this->requires();
238 $this->init_defaults();
239 $this->reset_current_object();
240 $this->init_base_tables();
241 $this->init_folders();
242
243 do_action( 'wpforo_before_init_base_classes' );
244
245 $this->settings = new Settings();
246 $this->tpl = new Template();
247 $this->ram_cache = new RamCache();
248 $this->cache = new Cache();
249 $this->action = new Actions();
250 $this->board = new Boards();
251 $this->usergroup = new UserGroups();
252 $this->member = new Members();
253 $this->perm = new Permissions();
254 $this->notice = new Notices();
255
256 $this->moderation = new Moderation();
257 $this->phrase = new Phrases();
258
259 do_action( 'wpforo_after_init_base_classes' );
260 }
261
262 private function init_classes() {
263 do_action( 'wpforo_before_init_classes' );
264
265 $this->activity = new Activity();
266 $this->api = new API();
267 $this->feed = new Feed();
268 $this->form = new Forms();
269 $this->forum = new Forums();
270 $this->log = new Logs();
271 $this->postmeta = new PostMeta();
272 $this->post = new Posts();
273 $this->seo = new SEO();
274 $this->topic = new Topics();
275 $this->reaction = new Reactions();
276 $this->bookmark = new Bookmarks();
277 $this->sbscrb = new Subscriptions();
278 if( wpforo_is_module_enabled( 'revisions' ) ) $this->revision = new Revisions();
279
280 do_action( 'wpforo_after_init_classes' );
281 }
282
283 public function set_locale( $locale ) {
284 $this->locale = $locale;
285 do_action( 'wpforo_after_set_locale', $locale );
286 }
287
288 private function init_hooks() {
289 add_action( 'wpforo_after_init_folders', function( $folders ) {
290 $this->create_folders( $folders );
291 }, 9999 );
292 add_action(
293 'after_setup_theme',
294 function() {
295 do_action( 'wpforo_before_base_init' );
296 $this->init_base_classes();
297 if( ! $this->is_installed() ) $this->init();
298 },
299 0
300 );
301 add_action( 'change_locale', [ $this, 'set_locale' ] );
302 add_action( 'init', function() { $this->set_locale( get_locale() ); } );
303 add_action( 'widgets_init', function() {
304 $boards = $this->board->get_boards( [ 'status' => true ] );
305 foreach( $boards as $board ) {
306 register_sidebar(
307 [
308 'id' => sprintf(
309 'wpforo_%1$ssidebar',
310 $board['boardid'] ? $board['boardid'] . '_' : ''
311 ),
312 'name' => __( 'wpForo Sidebar', 'wpforo' ) . ' - ( ' . $board['title'] . ' )',
313 'description' => __( "NOTE: If you're going to add widgets in this sidebar, please use 'Full Width' template for wpForo index page to avoid sidebar duplication.", 'wpforo' ),
314 'before_widget' => '<aside id="%1$s" class="footer-widget-col %2$s clearfix">',
315 'after_widget' => '</aside>',
316 'before_title' => '<h3 class="widget-title">',
317 'after_title' => '</h3>',
318 ]
319 );
320 }
321
322 register_widget( 'wpforo\widgets\Forums' );
323 register_widget( 'wpforo\widgets\Profile' );
324 register_widget( 'wpforo\widgets\Search' );
325 register_widget( 'wpforo\widgets\OnlineMembers' );
326 register_widget( 'wpforo\widgets\RecentTopics' );
327 register_widget( 'wpforo\widgets\RecentPosts' );
328 register_widget( 'wpforo\widgets\Tags' );
329 } );
330 add_filter( 'plugin_locale', function( $locale, $domain ) {
331 if( $domain === 'wpforo' && defined( 'DOING_AJAX' ) && DOING_AJAX ) $locale = $this->locale;
332
333 return $locale;
334 }, 10, 2 );
335 add_action( 'wpforo_after_init_classes', function() {
336 if( wpforo_setting( 'email', 'disable_new_user_admin_notification' ) ) {
337 remove_action( 'after_password_reset', 'wp_password_change_notification' );
338
339 remove_action( 'register_new_user', 'wp_send_new_user_notifications' );
340 add_action( 'register_new_user', 'wpforo_send_new_user_notifications' );
341
342 remove_action( 'edit_user_created_user', 'wp_send_new_user_notifications' );
343 add_action( 'edit_user_created_user', 'wpforo_send_new_user_notifications', 10, 2 );
344
345 remove_action( 'network_site_new_created_user', 'wp_send_new_user_notifications' );
346 add_action( 'network_site_new_created_user', 'wpforo_send_new_user_notifications' );
347
348 remove_action( 'network_site_users_created_user', 'wp_send_new_user_notifications' );
349 add_action( 'network_site_new_created_user', 'wpforo_send_new_user_notifications' );
350
351 remove_action( 'network_user_new_created_user', 'wp_send_new_user_notifications' );
352 add_action( 'network_user_new_created_user', 'wpforo_send_new_user_notifications' );
353 }
354 } );
355
356 if( is_admin() || strpos( (string) $_SERVER['REQUEST_URI'], '/peepsoajax/' ) === 0 || preg_match(
357 '#^/?(?:([^\s/?&=<>:\'\"*\\\|]*/)(?1)*)?[^\s/?&=<>:\'\"*\\\|]+\.(?:php|js|css|jpe?g|png|gif|bmp|webp|svg|tiff)/?(?:\?[^/]*)?$#iu',
358 (string) $_SERVER['REQUEST_URI']
359 ) ) {
360 add_action( 'init', [ $this, 'init' ], 99 );
361 add_action( 'admin_init', [ $this, 'admin_init' ] );
362 } elseif( strpos( (string) $_SERVER['REQUEST_URI'], '/wp-json/' ) !== false ) {
363 add_filter( 'rest_authentication_errors', function( $r ) {
364 $this->init();
365
366 return $r;
367 }, 9999 );
368 } else {
369 add_action( 'wp', [ $this, 'init' ], 99 );
370 }
371 add_action( 'switch_blog', [ $this, 'after_switch_blog' ], 10, 2 );
372 add_action( 'wpforo_before_init', [ $this, 'change_board' ] );
373 add_action( 'wpforo_after_init_current_url', [ $this, 'change_board' ] );
374 }
375
376 public function after_switch_blog( $new_blog_id, $prev_blog_id ) {
377 if( intval( $new_blog_id ) !== intval( $prev_blog_id ) ) {
378 $this->init_base_tables();
379 $this->init_tables();
380 $this->init_folders();
381 }
382 }
383
384 private function init_base_tables() {
385 $this->db->query( "SET SESSION group_concat_max_len = 1000000" );
386 $blog_id = apply_filters( 'wpforo_current_blog_id', 0 );
387 $this->tables = new stdClass;
388 if( ! $blog_id ) $blog_id = $this->db->blogid;
389 $this->blog_prefix = $this->db->get_blog_prefix( $blog_id );
390 $this->_base_tables = apply_filters( 'wpforo_init_base_tables', $this->_base_tables );
391 foreach( $this->_base_tables as $table ) $this->tables->$table = $this->fix_table_name( $table );
392 }
393
394 private function init_tables() {
395 $this->_tables = apply_filters( 'wpforo_init_tables', $this->_tables );
396 foreach( $this->_tables as $table ) $this->tables->$table = $this->fix_table_name( $table );
397 }
398
399 public function get_active_boards_tables( $basename ) {
400 $tables = [];
401 if( $boardids = $this->board->get_active_boardids() ) {
402 foreach( $boardids as $boardid ) $tables[] = $this->fix_table_name( $basename, $this->generate_prefix( $boardid ) );
403 }
404
405 return array_unique( $tables );
406 }
407
408 /**
409 * @param string $basename
410 *
411 * @return string
412 */
413 public function fix_table_name( $basename, $prefix = null ) {
414 return $this->blog_prefix . ( in_array( $basename, $this->_base_tables, true ) ? $this->base_prefix : ( is_null( $prefix ) ? $this->prefix : $prefix ) ) . $basename;
415 }
416
417 public function fix_dir_sep( $dir ) {
418 $dir = str_replace( [ '/', '\\', '\\\\' ], DIRECTORY_SEPARATOR, $dir );
419
420 return rtrim( trim( (string) $dir ), DIRECTORY_SEPARATOR );
421 }
422
423 public function fix_url_sep( $url ) {
424 return trim( str_replace( [ '/', '\\', '\\\\' ], '/', (string) $url ) );
425 }
426
427 private function init_folders() {
428 $this->_folders = apply_filters( 'wpforo_init_folders', $this->_folders );
429 $boardid = ( is_callable( [ $this->board, 'get_current' ] ) ? $this->board->get_current( 'boardid' ) : 0 );
430 $upload_dir = wp_get_upload_dir();
431
432 // In many cases people leave the website URL protocol as http, but website works with https
433 // In this case colors.css and phrases.js are not loaded because of http blocking by browser
434 $upload_dir['baseurl'] = is_ssl() ? str_replace( 'http://', 'https://', $upload_dir['baseurl'] ) : $upload_dir['baseurl'];
435
436 $this->folders['wp_upload'] = [
437 'dir' => $this->fix_dir_sep( $upload_dir['basedir'] ),
438 'url' => $this->fix_url_sep( $upload_dir['baseurl'] ),
439 ];
440 $this->folders['wp_upload']['url//'] = preg_replace( '#^https?:#i', '', (string) $this->folders['wp_upload']['url'] );
441 $this->folders['upload'] = [
442 'dir' => $this->folders['wp_upload']['dir'] . DIRECTORY_SEPARATOR . "wpforo" . ( $boardid ? '_' . $boardid : '' ),
443 'url' => $this->folders['wp_upload']['url'] . "/wpforo" . ( $boardid ? '_' . $boardid : '' ),
444 'url//' => $this->folders['wp_upload']['url//'] . "/wpforo" . ( $boardid ? '_' . $boardid : '' ),
445 ];
446 foreach( $this->_folders as $folder ) {
447 $this->folders[ $folder ] = [
448 'dir' => $this->folders['upload']['dir'] . DIRECTORY_SEPARATOR . trim( $this->fix_dir_sep( (string) $folder ), DIRECTORY_SEPARATOR ),
449 'url' => $this->folders['upload']['url'] . "/" . trim( $this->fix_url_sep( (string) $folder ), '/' ),
450 'url//' => $this->folders['upload']['url//'] . "/" . trim( $this->fix_url_sep( (string) $folder ), '/' ),
451 ];
452 }
453
454 $this->folders = apply_filters( 'wpforo_working_folders', $this->folders );
455
456 do_action( 'wpforo_after_init_folders', $this->folders );
457 }
458
459 private function create_folders( array $folders = [] ): void {
460 if( ! $folders ) $folders = WPF()->folders;
461 foreach( $folders as $folder ) {
462 $dir = ( is_scalar( $folder ) ? $folder : ( array_key_exists( 'dir', $folder ) ? (string) $folder['dir'] : '' ) );
463 if( $dir && ! is_dir( $dir ) ) {
464 if( wp_mkdir_p( $dir ) ) {
465 wpforo_write_file( "$dir/index.html", "" );
466 wpforo_write_file( "$dir/robots.txt", "User-agent: *\nDisallow: /" );
467 }
468 }
469 }
470 }
471
472 private function requires() {
473 require_once WPFORO_DIR . '/includes/functions.php';
474 require_once WPFORO_DIR . '/includes/functions-template.php';
475 require_once WPFORO_DIR . '/includes/hooks.php';
476 require_once WPFORO_DIR . '/includes/installation.php';
477 require_once WPFORO_DIR . '/integrations/functions.php';
478 if( wpforo_is_admin() ) require_once WPFORO_DIR . '/admin/index.php';
479 }
480
481 public function admin_init() {
482 if( wpforo_is_admin() ) {
483 $this->change_board();
484
485 $this->check_issues();
486
487 if( strpos( wpforo_get_request_uri(), 'user-new.php' ) === false ) {
488 if( ! $this->member->get_groupid( $this->current_userid ) ) {
489 $this->member->synchronize_user( $this->current_userid );
490 }
491 }
492
493 if( ! $this->usergroup->can_manage_forum() && wpforo_current_user_is( 'admin' ) ) {
494 $this->member->set_groupid( $this->current_userid, 1 );
495 }
496 }
497 }
498
499 public function check_issues() {
500 //Make sure all users profiles are created
501 if( $this->is_installed() ) {
502 if( apply_filters( 'wpforo_profile_synchronization_notice', true ) ) {
503 if( is_multisite() ) {
504 $sql = "SELECT COUNT(`user_id`) FROM `" . WPF()->db->usermeta . "` WHERE `meta_key` LIKE '" . WPF(
505 )->blog_prefix . "capabilities' AND `user_id` NOT IN( SELECT `userid` FROM `" . WPF()->tables->profiles . "` )";
506 } else {
507 $sql = "SELECT COUNT(`ID`) as user_id FROM `" . WPF()->db->users . "` WHERE `ID` NOT IN( SELECT `userid` FROM `" . WPF()->tables->profiles . "` )";
508 }
509 if( (int) $this->db->get_var( $sql ) ) add_action( 'admin_notices', 'wpforo_profile_notice', 10 );
510 }
511 }
512 //Make sure tables structures are correct for current version
513 $wpforo_version_db = wpforo_get_option( 'version_db', null, false );
514 if( ! $wpforo_version_db || version_compare( $wpforo_version_db, WPFORO_VERSION, '<' ) || wpforo_setting( 'general', 'debug_mode' ) ) {
515 if( 'tables' !== wpfval( $_GET, 'view' ) ) {
516 $db_note = false;
517 $problems = wpforo_database_check();
518 if( ! empty( $problems ) ) {
519 foreach( $problems as $key => $problem ) {
520 if( wpfval( $problem, 'fields' ) ) $db_note = true;
521 if( wpfval( $problem, 'exists' ) ) $db_note = true;
522 if( $key === 'data' ) $db_note = true;
523 }
524 if( $db_note ) {
525 add_action( 'admin_notices', 'wpforo_database_notice', 10 );
526 }
527 } else {
528 wpforo_update_option( 'version_db', WPFORO_VERSION );
529 }
530 }
531 }
532 //Check cache plugins
533 $not_excluded_plugins = WPF()->cache->cache_plugins_status();
534 if( ! empty( $not_excluded_plugins ) ) {
535 add_action( 'admin_notices', 'wpforo_cache_information', 10 );
536 }
537 }
538
539 public function init() {
540 do_action( 'wpforo_before_init' );
541 $this->init_classes();
542 $this->init_current_url();
543 do_action( 'wpforo_core_inited' );
544 $this->init_current_object();
545 do_action( 'wpforo_after_init' );
546 }
547
548 public function shortcode_atts_to_url( $atts ) {
549 if( is_null( $this->forum ) ) $this->init_classes();
550
551 $url = wpforo_home_url();
552
553 $args = shortcode_atts(
554 [
555 'boardid' => 0,
556 'item' => 'forum',
557 'id' => 0,
558 'slug' => '',
559 ],
560 (array) $atts
561 );
562
563 WPF()->change_board( $args['boardid'] );
564
565 if( $args['item'] === 'profile' && ! $args['id'] ) $args['id'] = $this->current_userid;
566
567 if( $args['item'] === 'add-topic' ) {
568 $forum = $this->forum->get_forum( ( $args['slug'] ?: $args['id'] ) );
569 $forumid = (int) wpfval( $forum, 'is_cat' ) ? 0 : (int) wpfval( $forum, 'forumid' );
570 $url = wpforo_home_url( wpforo_settings_get_slug( 'add-topic' ) . '/' . $forumid );
571 } elseif( $args['item'] === 'recent' ) {
572 $url = wpforo_settings_get_slug( 'recent' ) . '/';
573 if( trim( (string) $args['slug'] ) ) $url .= '?view=' . wpforo_settings_get_slug( $args['slug'] );
574 $url = wpforo_home_url( $url );
575 } elseif( $args['item'] === 'members' ) {
576 $url = wpforo_members_url();
577 } elseif( $args['id'] || $args['slug'] ) {
578 $getid = ( $args['slug'] ?: $args['id'] );
579 if( $args['item'] === 'topic' ) {
580 $url = $this->topic->get_url( $getid );
581 } elseif( $args['item'] === 'profile' ) {
582 $url = $this->member->get_profile_url( $getid );
583 } elseif( $args['item'] === 'account' ) {
584 $url = $this->member->get_profile_url( $getid, 'account' );
585 } elseif( $args['item'] === 'activity' ) {
586 $url = $this->member->get_profile_url( $getid, 'activity' );
587 } elseif( $args['item'] === 'favored' ) {
588 $url = $this->member->get_profile_url( $getid, 'favored' );
589 } elseif( $args['item'] === 'subscriptions' ) {
590 $url = $this->member->get_profile_url( $getid, 'subscriptions' );
591 } elseif( $args['item'] === 'messages' ) {
592 $url = $this->member->get_profile_url( $getid, 'messages' );
593 } else {
594 $url = $this->forum->get_forum_url( $getid );
595 }
596 } elseif( $args['item'] === 'login' ) {
597 $url = wpforo_login_url();
598 } elseif( $args['item'] === 'register' ) {
599 $url = wpforo_register_url();
600 } elseif( $args['item'] === 'lostpassword' ) {
601 $url = wpforo_lostpassword_url();
602 }
603
604 return $url;
605 }
606
607 public function init_current_url( $atts = [] ) {
608 if( is_null( $this->post ) ) $this->init_classes();
609
610 if( is_scalar( $atts ) ) {
611 $url = $atts;
612 $atts = [];
613 } else {
614 $url = wpforo_get_request_uri();
615 }
616 if( $atts || is_wpforo_shortcode_page( $url ) ) {
617 if( $atts || ( $atts = get_wpforo_shortcode_atts( '', $url ) ) ) {
618 $url = $this->shortcode_atts_to_url( $atts );
619 } else {
620 $url = wpforo_home_url();
621 }
622 }
623
624 if( is_wpforo_url( $url ) && preg_match( '#/' . preg_quote( wpforo_settings_get_slug( 'postid' ) ) . '/(\d+)/?$#isu', strtok( $url, '?' ), $matches ) ) {
625 $post_url = $this->post->get_full_url( $matches[1] );
626 if( $post_url !== wpforo_home_url() ) {
627 $url = $post_url;
628 $this->canonical_url = $this->post->get_url( $matches[1] );
629 }
630 } elseif( is_wpforo_url( $url ) && preg_match( '#/' . preg_quote( wpforo_settings_get_slug( 'topicid' ) ) . '/(\d+)/?$#isu', strtok( $url, '?' ), $matches ) ) {
631 $topic_url = $this->topic->get_full_url( $matches[1] );
632 if( $topic_url !== wpforo_home_url() ) {
633 $url = $topic_url;
634 $this->canonical_url = $this->topic->get_url( $matches[1] );
635 }
636 }
637
638 if( function_exists( 'pll_default_language' ) ) {
639 $qvar = wpforo_get_url_query_vars_str( $url );
640 $qvar = preg_replace( '#^' . preg_quote( pll_default_language() ) . '/#', '', $qvar );
641 $url = $this->user_trailingslashit( home_url( $qvar ) );
642 }
643
644 $url = wpforo_fix_url( $url );
645 $url = preg_replace( '#\#[^/?&]*$#iu', '', $url );
646 parse_str( (string) parse_url( $url, PHP_URL_QUERY ), $get );
647 $get = array_merge( (array) $get, $_GET );
648 $get = wp_unslash( $get );
649
650 if( ! $this->canonical_url ) $this->canonical_url = $this->current_url;
651
652 $this->current_url = apply_filters( 'wpforo_init_current_url', $url );
653 $this->GET = apply_filters( 'wpforo_init_current_url_GET', $get );
654
655 if( ! $this->canonical_url ) $this->canonical_url = $this->current_url;
656 if( strpos( $this->canonical_url, '?wpfin=tag' ) === false && strpos( $this->canonical_url, '?view=' ) === false ) {
657 $this->canonical_url = preg_replace( '#\?.*$#isu', '', $this->canonical_url );
658 }
659 $this->canonical_url = apply_filters( 'wpforo_init_canonical_url', $this->canonical_url );
660
661 do_action( 'wpforo_after_init_current_url', $atts );
662 }
663
664 private function init_defaults() {
665 $this->default = new stdClass;
666
667 $this->default->current_object = [
668 'route' => '',
669 'template' => '',
670 'qvars' => [],
671 'args' => [],
672 'layout' => 1,
673 'og_text' => '',
674 'paged' => 1,
675 'items_count' => 0,
676 'items_per_page' => 15,
677 'is_404' => false,
678 'user_is_same_current_user' => false,
679 'orderby' => null,
680 'members' => [],
681 'categories' => [],
682 'topics' => [],
683 'posts' => [],
684 'user' => [],
685 'userid' => 0,
686 'user_nicename' => '',
687 'forum' => [],
688 'forumid' => 0,
689 'forum_slug' => '',
690 'forum_desc' => '',
691 'forum_meta_key' => '',
692 'forum_meta_desc' => '',
693 'topic' => [],
694 'topicid' => 0,
695 'topic_slug' => '',
696 'tags' => [],
697 'load_tinymce' => false,
698 ];
699
700 $this->default->tools_cleanup = [
701 'user_reg_days_ago' => 7,
702 'auto_cleanup_users' => 0,
703 'usergroup' => [ 1 => '0', 5 => '0', 2 => '1', 3 => '0' ],
704 ];
705
706 $this->default->tools_misc = [
707 'admin_note' => '',
708 'admin_note_groups' => [ 1, 2, 3, 4, 5 ],
709 'admin_note_pages' => [ 'forum' ],
710 ];
711
712 $this->default->stats = [
713 'forums' => 0,
714 'topics' => 0,
715 'posts' => 0,
716 'members' => 0,
717 'online_members_count' => 0,
718 'last_post_title' => '',
719 'last_post_url' => '',
720 'newest_member' => [],
721 'newest_member_dname' => '',
722 'newest_member_profile_url' => '',
723 ];
724
725 $this->default->dissmissed = [
726 'recaptcha_backend_note' => 0,
727 'recaptcha_note' => 0,
728 'addons_css_update' => 0,
729 ];
730 }
731
732 private function reset_current_object() {
733 $this->current_object = $this->default->current_object;
734 }
735
736 private function init_options() {
737 $this->tools_cleanup = wpforo_get_option( 'tools_cleanup', $this->default->tools_cleanup );
738 $this->tools_misc = wpforo_get_option( 'tools_misc', $this->default->tools_misc );
739 $this->dissmissed = wpforo_get_option( 'dissmissed', $this->default->dissmissed );
740 }
741
742 public function can_use_trailing_slashes() {
743 return '/' === substr( (string) get_option( 'permalink_structure', '' ), - 1, 1 );
744 }
745
746 public function user_trailingslashit( $url ) {
747 $rtrimed_url = '';
748 $url_append_vars = '';
749 if( preg_match( '#^(.+?)(/?[?&].*)?$#isu', $url, $match ) ) {
750 if( wpfval( $match, 1 ) ) $rtrimed_url = rtrim( $match[1], '/\\' );
751 if( wpfval( $match, 2 ) ) $url_append_vars = '?' . trim( $match[2], '?&/\\' );
752 if( $rtrimed_url ) {
753 $home_url = rtrim( preg_replace( '#/?\?.*$#isu', '', home_url() ), '/\\' );
754 if( $rtrimed_url == $home_url ) {
755 $url = $rtrimed_url . '/';
756 } else {
757 $url = $rtrimed_url . ( wpforo_ram_get( [ $this, 'can_use_trailing_slashes' ] ) ? '/' : '' );
758 }
759 }
760 }
761
762 return $url . $url_append_vars;
763 }
764
765 public function strip_url_paged_var( $url ) {
766 $patterns = [
767 '#/' . preg_quote( wpforo_settings_get_slug( 'paged' ) ) . '/?\d*/?#isu',
768 '#[&?]wpfpaged=\d*#iu',
769 ];
770 $url = preg_replace( $patterns, '', (string) $url );
771
772 return $this->user_trailingslashit( $url );
773 }
774
775 public function statistic_cache_clean() {
776 $this->db->query( "DELETE FROM `" . $this->db->options . "` WHERE `option_name` REGEXP '^" . wpforo_prefix( 'stat_[0-9]+' ) . "'" );
777 }
778
779 public function statistic( $mode = 'get', $template = 'all' ) {
780 $key = 'stat_' . $this->current_user_groupid;
781 if( $mode === 'get' ) {
782 if( $cached_stat = wpforo_get_option( $key, [], false ) ) {
783 $cached_stat['online_members_count'] = $this->member->online_members_count();
784 if( wpfkey( $cached_stat, 'forums' ) && wpfkey( $cached_stat, 'topics' ) && wpfkey( $cached_stat, 'posts' ) ) {
785 return wpforo_array_args_cast_and_merge( $cached_stat, $this->default->stats );
786 }
787 }
788 }
789
790 if( $mode === 'get' || $template === 'all' ) {
791 $stats['forums'] = $this->forum->get_count( [ 'is_cat' => 0 ] );
792 $stats['topics'] = $this->topic->get_count();
793 $stats['posts'] = $this->post->get_count();
794 $member_status = [ 'p.`status`' => $this->member->get_inlist_enabled_statuses() ];
795 $stats['members'] = $this->member->get_count( $member_status );
796 $stats['online_members_count'] = $this->member->online_members_count();
797 $row_count = apply_filters( 'wpforo_get_statistic_row_count', 1 );
798
799 $posts = $this->topic->get_topics( [ 'orderby' => 'modified', 'order' => 'DESC', 'row_count' => $row_count, 'private' => 0, 'status' => 0, 'permgroup' => 4 ] );
800 $first = key( $posts );
801 if( isset( $posts[ $first ] ) && ! empty( $posts[ $first ] ) && $this->perm->forum_can( 'vf', $posts[ $first ]['forumid'] ) ) {
802 $stats['last_post_title'] = $posts[ $first ]['title'];
803 $stats['last_post_url'] = $this->post->get_url( $posts[ $first ]['last_post'] );
804 }
805
806 $newest_member = $this->member->get_newest_member();
807 if( ! empty( $newest_member ) ) {
808 $stats['newest_member'] = $newest_member;
809 $stats['newest_member_dname'] = wpforo_user_dname( $newest_member );
810 $stats['newest_member_profile_url'] = $newest_member['profile_url'];
811 }
812 } else {
813 $stats = wpforo_get_option( $key, $this->default->stats, false );
814 switch( $template ) {
815 case 'forum':
816 $stats['forums'] = $this->forum->get_count( [ 'is_cat' => 0 ] );
817 break;
818 case 'topic':
819 $stats['topics'] = $this->topic->get_count();
820 $posts = $this->topic->get_topics( [ 'orderby' => 'modified', 'order' => 'DESC', 'row_count' => 1 ] );
821 if( isset( $posts[0] ) && ! empty( $posts[0] ) && $this->perm->forum_can( 'vf', $posts[0]['forumid'] ) ) {
822 $stats['last_post_title'] = $posts[0]['title'];
823 $stats['last_post_url'] = $this->post->get_url( $posts[0]['last_post'] );
824 }
825 break;
826 case 'post':
827 $stats['posts'] = $this->post->get_count();
828 $posts = $this->topic->get_topics( [ 'orderby' => 'modified', 'order' => 'DESC', 'row_count' => 1 ] );
829 if( isset( $posts[0] ) && ! empty( $posts[0] ) && $this->perm->forum_can( 'vf', $posts[0]['forumid'] ) ) {
830 $stats['last_post_title'] = $posts[0]['title'];
831 $stats['last_post_url'] = $this->post->get_url( $posts[0]['last_post'] );
832 }
833 break;
834 case 'user':
835 //$member_status = [ 'p.`status`' => $this->member->get_inlist_enabled_statuses() ];
836 //$stats['members'] = $this->member->get_count( $member_status );
837 $stats['members'] = $this->member->get_count();
838 $stats['online_members_count'] = $this->member->online_members_count();
839
840 $newest_member = $this->member->get_newest_member( false );
841 if( ! empty( $newest_member ) ) {
842 $stats['newest_member'] = $newest_member;
843 $stats['newest_member_dname'] = wpforo_user_dname( $newest_member );
844 $stats['newest_member_profile_url'] = $newest_member['profile_url'];
845 }
846 break;
847 }
848 }
849
850 $stats = apply_filters( 'wpforo_get_statistic_array_filter', $stats );
851 $stats = wpforo_array_args_cast_and_merge( $stats, $this->default->stats );
852 wpforo_update_option( $key, $stats );
853
854 return $stats;
855 }
856
857 public function init_current_object() {
858 $this->reset_current_object();
859 $this->current_object['items_per_page'] = $this->post->get_option_items_per_page();
860 $url = $this->current_url;
861 $get = $this->GET;
862
863 if( ! is_wpforo_page( $url ) ) return;
864
865 $current_url = wpforo_get_url_query_vars_str( $url );
866
867 $current_object = [];
868 if( wpfkey( $get, 'wpfs' ) || wpfval( $get, 'foro' ) === 'search' ) $this->current_object['template'] = 'search';
869 if( wpfval( $get, 'wpforo' ) || wpfval( $get, 'foro' ) ) {
870 $request = ( wpfval( $get, 'wpforo' ) ) ? wpfval( $get, 'wpforo' ) : wpfval( $get, 'foro' );
871 if( $request === 'page' ) $this->current_object['template'] = 'page';
872 }
873
874 $template_key = '';
875 $wpf_url = preg_replace( '#/?\?.*$#isu', '', $current_url );
876 $wpf_url_parse = array_values( array_filter( explode( '/', trim( (string) $wpf_url, '/' ) ) ) );
877 if( array_key_exists( 0, $wpf_url_parse ) && in_array( $wpf_url_parse[0], $this->board->routes ) ) {
878 $this->current_object['route'] = $wpf_url_parse[0];
879 unset( $wpf_url_parse[0] );
880
881 if( in_array( $this->current_object['route'], $this->board->base_routes, true ) ) {
882 $this->current_object['template'] = ( $template_key = wpforo_settings_get_slug_key( $this->current_object['route'] ) ) !== 'member' ? $template_key : '';
883
884 $current_object['qvars'] = $wpf_url_parse;
885 $current_object['qvars'] = array_values( $current_object['qvars'] );
886
887 if( $this->current_object['template'] === 'register' ) {
888 $this->form->current['template'] = 'register';
889 $this->form->current['value']['user_login'] = sanitize_user( (string) wpfval( $_POST, 'wpfreg', 'user_login' ) );
890 $this->form->current['value']['user_email'] = sanitize_email( (string) wpfval( $_POST, 'wpfreg', 'user_email' ) );
891 $this->form->current['varname'] = 'wpfreg';
892 } elseif( $this->current_object['template'] === 'logout' && $this->current_userid ) {
893 $this->action->logout();
894 }
895 }
896
897 if( $this->current_userid && in_array( $this->current_object['template'], [ 'register', 'login', 'lostpassword' ], true ) && ! wpforo_is_admin() ) wpforo_redirect_to();
898 }
899 $wpf_url_parse = array_reverse( $wpf_url_parse );
900
901 if( in_array( wpforo_settings_get_slug( 'paged' ), $wpf_url_parse ) ) {
902 foreach( $wpf_url_parse as $key => $value ) {
903 if( $value === wpforo_settings_get_slug( 'paged' ) ) {
904 unset( $wpf_url_parse[ $key ] );
905 break;
906 }
907 if( is_numeric( $value ) ) $paged = intval( $value );
908
909 unset( $wpf_url_parse[ $key ] );
910 }
911 }
912 if( $_paged = intval( wpfval( $get, 'wpfpaged' ) ) ) $paged = $_paged;
913 $current_object['paged'] = ( isset( $paged ) && $paged > 0 ) ? $paged : 1;
914 $current_object['orderby'] = wpfval( $get, 'orderby' );
915
916 $wpf_url_parse = array_values( $wpf_url_parse );
917
918 if( ! $this->current_object['template'] ) {
919 $current_object = apply_filters( 'wpforo_before_init_current_object', $current_object, $wpf_url_parse );
920 if( wpfkey( $current_object, 'template' ) ) $this->current_object['template'] = (string) wpfval( $current_object, 'template' );
921 }
922
923 if( ! $this->current_object['template'] ) {
924 $templates = $template_key === 'member' ? $this->tpl->get_member_templates_list() : $this->tpl->get_templates_list();
925 if( $templates ) {
926 if( $template_key === 'member' ) {
927 if( count( $wpf_url_parse ) > 1 ) {
928 $nickname = end( $wpf_url_parse );
929 $profile_route = prev( $wpf_url_parse );
930 array_pop( $wpf_url_parse );
931 array_pop( $wpf_url_parse );
932 array_push( $wpf_url_parse, $nickname, $profile_route );
933 } else {
934 if( ! in_array( end( $wpf_url_parse ), array_map( 'wpforo_settings_get_slug', $templates ) ) ) $wpf_url_parse[] = wpforo_settings_get_slug( 'profile' );
935 }
936 }
937 $__slug = end( $wpf_url_parse );
938 foreach( $templates as $template ) {
939 if( $__slug === wpforo_settings_get_slug( $template ) ) {
940 $this->current_object['template'] = $template;
941 $current_object['qvars'] = $wpf_url_parse;
942 array_pop( $current_object['qvars'] );
943 $current_object['qvars'] = array_reverse( $current_object['qvars'] );
944 break;
945 }
946 }
947
948 if( $template_key === 'member' ) {
949 if( ! $this->current_object['template'] && ! $wpf_url_parse ) {
950 if( $this->current_userid ) {
951 $this->current_object['template'] = 'profile';
952 } else {
953 wp_safe_redirect( wpforo_login_url() );
954 exit();
955 }
956 } elseif( ! wpforo_is_member_template( $this->current_object['template'] ) ) {
957 $this->current_object['template'] = '';
958 $current_object['qvars'] = [];
959 }
960 }
961 }
962 }
963
964 if( ! $this->current_object['template'] ) {
965 $this->current_object['template'] = 'forum';
966 $this->form->current['varname'] = 'thread';
967 if( isset( $wpf_url_parse[0] ) ) {
968 if( isset( $wpf_url_parse[1] ) ) {
969 $current_object['topic_slug'] = $wpf_url_parse[0];
970 $current_object['forum_slug'] = $wpf_url_parse[1];
971 $this->current_object['template'] = 'post';
972 $this->form->current['varname'] = 'post';
973 } else {
974 $current_object['forum_slug'] = $wpf_url_parse[0];
975 $this->current_object['template'] = 'topic';
976 $this->form->current['varname'] = 'thread';
977 }
978 }
979 }
980
981 $current_object = apply_filters( 'wpforo_after_init_current_template', $current_object, $wpf_url_parse, $get );
982 if( wpfkey( $current_object, 'template' ) ) $this->current_object['template'] = (string) wpfval( $current_object, 'template' );
983
984 if( $this->current_object['template'] ) {
985 if( wpforo_is_member_template( $this->current_object['template'] ) ) {
986 if( ! wpfval( $current_object, 'userid' ) && ! wpfval( $current_object, 'user_nicename' ) ) {
987 if( $qvar0 = wpfval( $current_object['qvars'], 0 ) ) {
988 if( wpforo_setting( 'profiles', 'url_structure' ) === 'id' ) {
989 $current_object['userid'] = $qvar0;
990 } else {
991 $current_object['user_nicename'] = $qvar0;
992 }
993 } else {
994 if( $this->current_userid ) {
995 $current_object['userid'] = $this->current_userid;
996 } else {
997 wp_safe_redirect( wpforo_login_url() );
998 exit();
999 }
1000 }
1001 }
1002
1003 // redirect old type of member urls to new one
1004 if( $template_key !== 'member' ) {
1005 if( count( $current_object['qvars'] ) === 1 ) {
1006 $redirect = wpforo_url(
1007 array_shift( $current_object['qvars'] ) . ( $this->current_object['template'] !== 'profile' ? '/' . wpforo_settings_get_slug( $this->current_object['template'] ) : '' ),
1008 'member'
1009 );
1010 } else {
1011 $redirect = wpforo_url(
1012 array_shift( $current_object['qvars'] ) . '/' . wpforo_settings_get_slug( $this->current_object['template'] ) . '/' . implode( '/', $current_object['qvars'] ),
1013 'member'
1014 );
1015 }
1016 wp_safe_redirect( $redirect );
1017 exit();
1018 }
1019 // redirection
1020
1021 } elseif( $this->current_object['template'] === 'search' ) {
1022 $args = [
1023 'needle' => sanitize_text_field( wpfval( $get, 'wpfs' ) ),
1024 'type' => sanitize_text_field( wpfval( $get, 'wpfin' ) ),
1025 'date_period' => intval( wpfval( $get, 'wpfd' ) ),
1026 'forumids' => (array) wpfval( $get, 'wpff' ),
1027 'offset' => ( $current_object['paged'] - 1 ) * $this->current_object['items_per_page'],
1028 'row_count' => $this->current_object['items_per_page'],
1029 'orderby' => 'relevancy',
1030 'order' => 'desc',
1031 'postids' => [],
1032 ];
1033 if( ! empty( $get['wpfob'] ) ) {
1034 $args['orderby'] = sanitize_text_field( $get['wpfob'] );
1035 } elseif( in_array( wpfval( $args, 'type' ), [ 'tag', 'user-posts', 'user-topics' ], true ) ) {
1036 $args['orderby'] = 'date';
1037 }
1038 $wpfo = strtolower( (string) wpfval( $get, 'wpfo' ) );
1039 if( in_array( $wpfo, [ 'asc', 'desc' ], true ) ) $args['order'] = $wpfo;
1040 $sdata = array_filter( (array) wpfval( $get, 'data' ) );
1041 $args['postids'] = $this->postmeta->search( $sdata );
1042 $current_object['args'] = $args;
1043 if( $sdata && ! $args['postids'] ) {
1044 $current_object['items_count'] = 0;
1045 $current_object['posts'] = [];
1046 } else {
1047 $current_object['posts'] = $this->post->search( $args, $current_object['items_count'] );
1048 }
1049 } elseif( $this->current_object['template'] === 'recent' ) {
1050 $args = [];
1051 $view = false;
1052 $current_object['items_count'] = 0;
1053 if( ! empty( WPF()->GET['view'] ) ) $view = sanitize_title( WPF()->GET['view'] );
1054 if( ! empty( WPF()->GET['wpff'] ) ) $args['forumid'] = intval( WPF()->GET['wpff'] );
1055 if( ! empty( WPF()->GET['prefixid'] ) ) {
1056 $args['prefixid'] = intval( WPF()->GET['prefixid'] );
1057 }
1058
1059 $type = ( $view && $view !== 'unapproved' ? 'topics' : wpforo_setting( 'topics', 'recent_posts_type' ) );
1060 if( $view === 'unapproved' ) $type = 'posts';
1061 if( $view === 'prefix' ) $type = 'topics';
1062
1063 if( ! WPF()->current_userid || ! WPF()->usergroup->can( 'aum' ) ) {
1064 $args['private'] = 0;
1065 $args['status'] = 0;
1066 }
1067 $days = apply_filters( 'wpforo_recent_posts_limit', 30 );
1068
1069 $end_date = time() - ( intval( $days ) * 24 * 60 * 60 );
1070 if( $type === 'topics' ) {
1071 $current_object['items_per_page'] = wpforo_setting( 'topics', 'topics_per_page' );
1072
1073 if( wpfval( $args, 'prefixid' ) ) $args['prefix'] = (int) wpfval( $args, 'prefixid' );
1074 $args['where'] = "`modified` > '" . gmdate( 'Y-m-d H:i:s', $end_date ) . "'";
1075 $args['orderby'] = ( ! empty( WPF()->GET['wpfob'] ) ) ? sanitize_text_field( WPF()->GET['wpfob'] ) : 'modified';
1076 $args['order'] = 'DESC';
1077 $args['offset'] = ( $current_object['paged'] - 1 ) * $current_object['items_per_page'];
1078 $args['row_count'] = $current_object['items_per_page'];
1079
1080 switch( $view ) {
1081 case 'unread':
1082 $args['read'] = false;
1083 break;
1084 case 'no-replies':
1085 $args['where'] = null;
1086 $args['include'] = wpforo_get_not_replied_topicids();
1087 break;
1088 case 'solved':
1089 $args['solved'] = 1;
1090 break;
1091 case 'unsolved':
1092 $args['solved'] = 0;
1093 break;
1094 case 'closed':
1095 $args['closed'] = 1;
1096 break;
1097 case 'opened':
1098 $args['closed'] = 0;
1099 break;
1100 case 'sticky':
1101 $args['type'] = 1;
1102 break;
1103 case 'private':
1104 $args['private'] = 1;
1105 break;
1106 case 'unapproved':
1107 $args['status'] = 1;
1108 break;
1109 case 'prefix':
1110 $args['where'] = null;
1111 break;
1112 }
1113 $topics = $view === 'no-replies' && empty( $args['include'] ) ? [] : WPF()->topic->get_topics( $args, $current_object['items_count'] );
1114 if( $topics ) {
1115 $intro_posts = wpforo_setting( 'topics', 'layout_extended_intro_posts_count' );
1116 if( $intro_posts < 1 ) {
1117 $intro_posts = null;
1118 } else {
1119 $intro_posts = ( $intro_posts > 1 ) ? ( $intro_posts - 1 ) : 0;
1120 }
1121 foreach( $topics as $key => $topic ) {
1122 $topics[ $key ]['replies'] = [];
1123 $topics[ $key ]['member'] = wpforo_member( $topic );
1124 $topics[ $key ]['forum'] = wpforo_forum( $topic['forumid'] );
1125 if( isset( $topic['last_post'] ) && $topic['last_post'] != 0 ) {
1126 $topics[ $key ]['last_post'] = wpforo_post( $topic['last_post'] );
1127 $topics[ $key ]['last_poster'] = wpforo_member( $topics[ $key ]['last_post'] );
1128 }
1129 if( isset( $topic['first_postid'] ) && $topic['first_postid'] != 0 ) {
1130 $topics[ $key ]['first_post'] = wpforo_post( $topic['first_postid'] );
1131
1132 $topics[ $key ]['first_poster'] = wpforo_member( $topics[ $key ]['first_post'] );
1133 if( ! $view && apply_filters( 'wpforo_recent_topics_intro', true, $topic ) ) {
1134 $topics[ $key ]['replies'] = WPF()->post->get_posts(
1135 [ 'topicid' => $topic['topicid'], 'orderby' => '`is_first_post` ASC, `created` DESC, `postid` DESC', 'row_count' => $intro_posts ]
1136 );
1137 }
1138 }
1139 $topics[ $key ]['topic_url'] = wpforo_topic( $topic['topicid'], 'url' );
1140 $topics[ $key ]['topic_posturl'] = ( $view === 'unread' && wpfval( $topics[ $key ]['last_post'], 'url' ) ) ? $topics[ $key ]['last_post']['url'] : WPF()->topic->get_url(
1141 $topic['topicid']
1142 );
1143 }
1144 $args['intro_posts'] = $intro_posts;
1145 }
1146 $current_object['topics'] = $topics;
1147 } else {
1148 $current_object['items_per_page'] = wpforo_setting( 'topics', 'posts_per_page' );
1149
1150 if( $view !== 'unapproved' ) $args['where'] = "`created` > '" . gmdate( 'Y-m-d H:i:s', $end_date ) . "'";
1151 $args['orderby'] = ( ! empty( WPF()->GET['wpfob'] ) ) ? sanitize_text_field( WPF()->GET['wpfob'] ) : 'created';
1152 $args['order'] = 'DESC';
1153 $args['offset'] = ( $current_object['paged'] - 1 ) * $current_object['items_per_page'];
1154 $args['row_count'] = $current_object['items_per_page'];
1155 if( $view === 'unapproved' ) {
1156 $args['status'] = 1;
1157 }
1158 $current_object['posts'] = WPF()->post->get_posts( $args, $current_object['items_count'] );
1159 }
1160 $args['view'] = $view;
1161 $args['type'] = $type;
1162 $current_object['args'] = $args;
1163 } elseif( $this->current_object['template'] === 'tags' ) {
1164 $current_object['items_per_page'] = wpforo_setting( 'tags', 'per_page' );
1165 $args = [
1166 'offset' => ( $current_object['paged'] - 1 ) * $current_object['items_per_page'],
1167 'row_count' => $current_object['items_per_page'],
1168 ];
1169 $current_object['tags'] = $this->topic->get_tags( $args, $current_object['items_count'] );
1170 } elseif( $this->current_object['template'] === 'members' ) {
1171 $current_object['items_per_page'] = wpforo_setting( 'members', 'members_per_page' );
1172
1173 $this->form->current['template'] = 'members';
1174 $this->form->current['value'] = $get;
1175 $this->form->current['varname'] = '';
1176
1177 if( ! empty( $get['_wpfms'] ) ) {
1178 $users_include = [];
1179 $search_fields_names = $this->member->get_search_fields_names();
1180
1181 $wpfms = ( isset( $get['wpfms'] ) ) ? sanitize_text_field( $get['wpfms'] ) : '';
1182 if( $wpfms ) {
1183 if( apply_filters( 'wpforo_member_search_provider', false, $wpfms, $search_fields_names, $get ) ) {
1184 $users_include = apply_filters( 'wpforo_search_by_provider', [], $wpfms, $search_fields_names, $get );
1185 } else {
1186 $users_include = $this->member->search( $wpfms, $search_fields_names );
1187 }
1188 } else {
1189 if( $filters = array_filter( $get, function( $v ) { return ! ( is_null( $v ) || $v === false || $v === '' ); } ) ) {
1190 $filters = array_merge( array_filter( (array) wpfval( $get, 'data' ), function( $v ) { return ! ( is_null( $v ) || $v === false || $v === '' ); } ), $filters );
1191 unset( $filters['data'] );
1192 $args = [];
1193 foreach( $filters as $filter_key => $filter ) {
1194 if( in_array( $filter_key, $search_fields_names ) ) {
1195 $args[ $filter_key ] = $filter;
1196 }
1197 }
1198 if( apply_filters( 'wpforo_member_filter_provider', false, $args, $get ) ) {
1199 $users_include = apply_filters( 'wpforo_filter_by_provider', [], $args, $get );
1200 } else {
1201 $users_include = $this->member->filter( $args );
1202 }
1203 }
1204 }
1205
1206 $users_include = apply_filters( 'wpforo_member_search_users_include', $users_include );
1207 }
1208 $member_status = $this->member->get_inlist_enabled_statuses();
1209 $args = [
1210 'offset' => ( $current_object['paged'] - 1 ) * $current_object['items_per_page'],
1211 'row_count' => $current_object['items_per_page'],
1212 'status' => $member_status,
1213 'groupids' => $this->usergroup->get_visible_usergroup_ids(),
1214 ];
1215
1216 $orderby = wpfval( $get, 'wpfob' ) ? sanitize_text_field( $get['wpfob'] ) : wpforo_setting( 'members', 'list_order' );
1217
1218 switch( $orderby ) {
1219 case 'online_time':
1220 $args['orderby'] = 'online_time';
1221 $args['order'] = 'desc';
1222 break;
1223 case 'posts__asc':
1224 $args['orderby'] = 'posts';
1225 $args['order'] = 'ASC';
1226 break;
1227 case 'user_registered__asc':
1228 $args['orderby'] = 'user_registered';
1229 $args['order'] = 'ASC';
1230 break;
1231 case 'user_registered__desc':
1232 $args['orderby'] = 'user_registered';
1233 $args['order'] = 'DESC';
1234 break;
1235 case 'display_name__asc':
1236 $args['orderby'] = 'display_name';
1237 $args['order'] = 'ASC';
1238 break;
1239 case 'display_name__desc':
1240 $args['orderby'] = 'display_name';
1241 $args['order'] = 'DESC';
1242 break;
1243 default:
1244 $args['orderby'] = 'posts';
1245 $args['order'] = 'DESC';
1246 break;
1247 }
1248 if( ! empty( $users_include ) ) $args['include'] = $users_include;
1249 $args = apply_filters( 'wpforo_current_object_members_args_filter', $args, $get );
1250 $current_object['members'] = $this->member->get_members( $args, $current_object['items_count'] );
1251 if( isset( $users_include ) && empty( $users_include ) ) {
1252 $current_object['members'] = [];
1253 $current_object['items_count'] = 0;
1254 }
1255 } elseif( $this->current_object['template'] === 'add-topic' ) {
1256 if( $qvar0 = (int) wpfval( $current_object['qvars'], 0 ) ) {
1257 $forum = (array) $this->forum->get_forum( $qvar0 );
1258 if( ! $forum || (int) wpfval( $forum, 'is_cat' ) ) {
1259 wp_safe_redirect( wpforo_home_url( wpforo_settings_get_slug( 'add-topic' ) ), 301 );
1260 exit();
1261 }
1262 }
1263 }
1264 }
1265
1266 if( wpfval( $current_object, 'userid' ) || wpfval( $current_object, 'user_nicename' ) ) {
1267 $args = [];
1268 if( isset( $current_object['userid'] ) ) $args['userid'] = $current_object['userid'];
1269 if( isset( $current_object['user_nicename'] ) ) $args['user_nicename'] = $current_object['user_nicename'];
1270 $selected_user = $this->member->get_member( $args );
1271 if( isset( $current_object['userid'] ) && empty( $selected_user ) ) $selected_user = $this->member->get_member( [ 'user_nicename' => $current_object['userid'] ] );
1272 $selected_user = apply_filters( 'wpforo_init_current_selected_user', $selected_user );
1273 if( $selected_user ) {
1274 $current_object['user'] = $selected_user;
1275 $current_object['userid'] = $selected_user['userid'];
1276 $current_object['user_nicename'] = $selected_user['user_nicename'];
1277 $current_object['user_is_same_current_user'] = ! empty( $this->current_userid ) && $selected_user['userid'] === $this->current_userid;
1278
1279 if( $this->tpl->can_view_template( $this->current_object['template'], $current_object['user'] ) ) {
1280 switch( $this->current_object['template'] ) {
1281 case 'activity':
1282 $args = [
1283 'offset' => ( $current_object['paged'] - 1 ) * $this->current_object['items_per_page'],
1284 'row_count' => $this->current_object['items_per_page'],
1285 'userid' => $current_object['userid'],
1286 'orderby' => '`created` DESC, `postid` DESC',
1287 'check_private' => true,
1288 'is_first_post' => wpfval( $this->GET, 'filter' ) ? $this->GET['filter'] === 'topics' : null,
1289 ];
1290 $current_object['items_count'] = 0;
1291 $current_object['activities'] = $this->post->get_posts( $args, $current_object['items_count'] );
1292 break;
1293 case 'favored':
1294 $current_object['filter'] = strtolower( (string) wpfval( WPF()->GET, 'filter' ) );
1295 if( ! in_array( $current_object['filter'], [ 'likes', 'dislikes' ], true ) ) $current_object['filter'] = 'bookmarks';
1296 if( $current_object['filter'] === 'likes' ) {
1297 $postids = $this->reaction->get_reactions_col(
1298 'postid',
1299 [
1300 'userid' => $current_object['userid'],
1301 'type_include' => 'up',
1302 ]
1303 );
1304 } elseif( $current_object['filter'] === 'dislikes' ) {
1305 $postids = $this->reaction->get_reactions_col(
1306 'postid',
1307 [
1308 'userid' => $current_object['userid'],
1309 'type_include' => 'down',
1310 ]
1311 );
1312 } else {
1313 $postids = $this->bookmark->get_bookmarks_col(
1314 'postid',
1315 [
1316 'userid' => $current_object['userid'],
1317 'boardid' => $this->board->get_current( 'boardid' ),
1318 'status' => true,
1319 ]
1320 );
1321 }
1322
1323 if( $postids ) {
1324 $args = [
1325 'offset' => ( $current_object['paged'] - 1 ) * $this->current_object['items_per_page'],
1326 'row_count' => $this->current_object['items_per_page'],
1327 'orderby' => '`created` DESC, `postid` DESC',
1328 'check_private' => true,
1329 'include' => $postids,
1330 ];
1331 $current_object['items_count'] = 0;
1332 $current_object['favored_posts'] = $this->post->get_posts( $args, $current_object['items_count'] );
1333 } else {
1334 $current_object['items_count'] = 0;
1335 $current_object['favored_posts'] = [];
1336 }
1337 break;
1338 case 'account':
1339 $this->form->current['template'] = 'account';
1340 $this->form->current['varname'] = 'member';
1341 $this->form->current['value'] = array_merge( $current_object['user'], (array) wpfval( $_POST, 'member' ) );
1342 break;
1343 default:
1344 $this->form->current['template'] = 'profile';
1345 $this->form->current['value'] = $current_object['user'];
1346 break;
1347 }
1348 } else {
1349 if( ! $this->current_userid ) {
1350 wp_safe_redirect( wpforo_login_url() );
1351 exit();
1352 }
1353 $current_object['is_404'] = true;
1354 }
1355
1356 } else {
1357 $current_object['is_404'] = true;
1358 }
1359 }
1360
1361 if( wpfval( $current_object, 'topic_slug' ) ) {
1362 $topic = $this->topic->get_topic( [ 'slug' => $current_object['topic_slug'] ], false );
1363 if( ! empty( $topic ) ) {
1364 $topic_forumid = intval( wpfval( $topic, 'forumid' ) );
1365 $is_owner = wpforo_is_owner( $topic['userid'], $topic['email'] );
1366
1367 if( apply_filters( 'wpforo_current_object_topic_protect', true, $topic ) && $topic_forumid && ( ! $this->perm->forum_can(
1368 'vf',
1369 $topic_forumid
1370 ) || ( ! $is_owner && ! $this->perm->forum_can( 'vt', $topic_forumid ) ) || ( wpfval( $topic, 'private' ) && ! $is_owner && ! $this->perm->forum_can(
1371 'vp',
1372 $topic_forumid
1373 ) ) || ( wpfval( $topic, 'status' ) && ! $is_owner && ! $this->perm->forum_can( 'au', $topic_forumid ) ) ) ) {
1374 if( ! $this->current_userid ) {
1375 wp_safe_redirect( wpforo_login_url() );
1376 exit();
1377 }
1378 $current_object['is_404'] = true;
1379 } else {
1380 $current_object['topic'] = $topic;
1381 $current_object['topicid'] = $topic['topicid'];
1382 $current_object['og_text'] = (string) wpfval( $topic, 'title' );
1383 }
1384 } else {
1385 $current_object['is_404'] = true;
1386 }
1387 }
1388
1389 if( wpfval( $current_object, 'forum_slug' ) ) {
1390 $args = ( empty( $topic ) ? [ 'slug' => $current_object['forum_slug'] ] : $topic['forumid'] );
1391 if( $forum = $this->forum->get_forum( $args ) ) {
1392 if( ! empty( $topic ) && strtolower( (string) $current_object['forum_slug'] ) !== strtolower( (string) $forum['slug'] ) ) {
1393 wp_safe_redirect( $this->topic->get_url( $topic, $forum ), 301 );
1394 exit();
1395 }
1396 if( $forum['is_cat'] ) $this->current_object['template'] = 'forum';
1397 $current_object['forum'] = $forum;
1398 $current_object['forumid'] = $forum['forumid'];
1399 $current_object['forum_desc'] = $forum['description'];
1400 $current_object['forum_meta_key'] = $forum['meta_key'];
1401 $current_object['forum_meta_desc'] = $forum['meta_desc'];
1402 $current_object['og_text'] = $forum['title'];
1403 $current_object['layout'] = $this->forum->get_layout( $forum );
1404
1405 if( $this->current_object['template'] === 'topic' ) {
1406 $current_object['items_per_page'] = wpforo_setting( 'topics', 'topics_per_page' );
1407 $args = [
1408 'offset' => ( $current_object['paged'] - 1 ) * $current_object['items_per_page'],
1409 'row_count' => $current_object['items_per_page'],
1410 'forumid' => $current_object['forumid'],
1411 'orderby' => 'type, modified',
1412 'order' => 'DESC',
1413 ];
1414 $args = apply_filters( 'wpforo_topic_list_args', $args );
1415 $current_object['topics'] = $this->topic->get_topics( $args, $current_object['items_count'] );
1416 }
1417 } else {
1418 $current_object['is_404'] = true;
1419 }
1420 }
1421
1422 if( in_array( $this->current_object['template'], [ 'forum', 'topic' ] ) ) {
1423 if( ! empty( $forum ) ) {
1424 $current_object['categories'] = [ $forum ];
1425 } else {
1426 $current_object['categories'] = $this->forum->get_forums( [ "type" => 'category' ] );
1427 }
1428 }
1429
1430 if( $this->current_object['template'] === 'post' && ! empty( $forum ) && ! empty( $topic ) ) {
1431 $current_object['items_per_page'] = $this->post->get_option_items_per_page( $current_object['layout'] );
1432
1433 $args = [
1434 'forumid' => $forum['forumid'],
1435 'topicid' => $topic['topicid'],
1436 'offset' => ( $current_object['paged'] - 1 ) * $current_object['items_per_page'],
1437 'row_count' => $current_object['items_per_page'],
1438 ];
1439 if( $current_object['layout'] == 4 ) {
1440 $args['parentid'] = 0;
1441 } elseif( $current_object['layout'] == 3 ) {
1442 $args['parentid'] = 0;
1443 switch( $current_object['orderby'] ) {
1444 case 'oldest':
1445 $args['orderby'] = '`is_first_post` DESC, `is_answer` DESC, `created` ASC, `postid` ASC';
1446 break;
1447 case 'newest':
1448 $args['orderby'] = '`is_first_post` DESC, `is_answer` DESC, `modified` DESC, `postid` DESC';
1449 break;
1450 default:
1451 $args['orderby'] = '`is_first_post` DESC, `is_answer` DESC, `votes` DESC, `created` ASC, `postid` ASC';
1452 break;
1453 }
1454 }
1455 if( $this->post->get_option_union_first_post( $current_object['layout'] ) ) $args['union_first_post'] = true;
1456 $args = apply_filters( 'wpforo_post_list_args', $args );
1457 $current_object['posts'] = $this->post->get_posts( $args, $current_object['items_count'] );
1458 }
1459
1460 $this->current_object = wpforo_parse_args( $current_object, $this->current_object );
1461
1462 $this->current_object = apply_filters( 'wpforo_after_init_current_object', $this->current_object, $wpf_url_parse );
1463
1464 if( $this->current_object['template'] ) {
1465 /**
1466 * redirect not logged-in users to login page when that user no access to this page
1467 */
1468 if( ! $this->current_userid && $this->current_object['forumid'] && ( ( in_array( $this->current_object['template'], [ 'forum', 'topic' ] ) && ! $this->perm->forum_can(
1469 'vf',
1470 $this->current_object['forumid']
1471 ) ) || ( $this->current_object['template'] === 'post' && ! $this->perm->forum_can( 'vt', $this->current_object['forumid'] ) ) ) ) {
1472 wp_safe_redirect( wpforo_login_url() );
1473 exit();
1474 }
1475
1476 if( $this->current_object['template'] === 'cantlogin' ) {
1477 if( $this->current_userid ) {
1478 if( $this->current_user['status'] !== 'active' ) {
1479 WPF()->ram_cache->set( 'USER_LOGIN_REFERER', WPF()->current_user_login );
1480 wp_logout();
1481 } else {
1482 wp_safe_redirect( wpforo_home_url() );
1483 }
1484 } else {
1485 wp_safe_redirect( wpforo_login_url() );
1486 exit();
1487 }
1488 }
1489
1490 /**
1491 * redirect to the first page when paged var is greater items_count
1492 */
1493 if( $this->current_object['items_count'] && $this->current_object['paged'] > 1 && ( ( $this->current_object['paged'] - 1 ) * $this->current_object['items_per_page'] ) >= $this->current_object['items_count'] ) {
1494 wp_safe_redirect( $this->strip_url_paged_var( $this->current_url ), 301 );
1495 exit();
1496 }
1497 } else {
1498 $this->current_object['is_404'] = true;
1499 }
1500 }
1501
1502 public function get_version() {
1503 return wpforo_get_option( 'version', null, false );
1504 }
1505
1506 public function need_activation() {
1507 return WPFORO_VERSION !== $this->get_version();
1508 }
1509
1510 public function is_installed() {
1511 return (bool) $this->get_version();
1512 }
1513
1514 public function can_use_this_slug( $slug ) {
1515 $return = ! in_array( $slug, $this->settings->slugs, true ) && ! in_array( $slug, array_keys( $this->settings->slugs ), true );
1516
1517 return apply_filters( 'wpforo_can_use_this_slug', $return, $slug );
1518 }
1519 }
1520