PluginProbe
wpForo Forum / 2.4.10
wpForo Forum v2.4.10
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.10, at wpforo.php

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