PluginProbe
wpForo Forum / 3.2.1
wpForo Forum v3.2.1
3.2.1 3.2.0 3.1.7 3.1.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 All 141 releases
← All changes | wpforo.php +1660 -710 1.4.10 → 3.2.1 View file →
@@ -1,710 +1,1660 @@
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 (A. Chakhoyan, R. Hovhannisyan)
7 -* Author URI: https://gvectors.com/
8 -* Version: 1.4.10
9 -* Text Domain: wpforo
10 -* Domain Path: /wpf-languages
11 -*/
12 -
13 -//Exit if accessed directly
14 -if( !defined( 'ABSPATH' ) ) exit;
15 -if( !defined( 'WPFORO_VERSION' ) ) define('WPFORO_VERSION', '1.4.10');
16 -
17 -function wpforo_load_plugin_textdomain() { load_plugin_textdomain( 'wpforo', FALSE, basename( dirname( __FILE__ ) ) . '/wpf-languages/' ); }
18 -add_action( 'plugins_loaded', 'wpforo_load_plugin_textdomain' );
19 -
20 -if( !class_exists( 'wpForo' ) ) {
21 -
22 - define('WPFORO_DIR', rtrim( plugin_dir_path( __FILE__ ), '/' ));
23 - define('WPFORO_URL', rtrim( plugins_url( '', __FILE__ ), '/' ));
24 - define('WPFORO_FOLDER', rtrim( plugin_basename(dirname(__FILE__)), '/'));
25 - define('WPFORO_BASENAME', plugin_basename(__FILE__)); //wpforo/wpforo.php
26 -
27 - final class wpForo{
28 - private static $_instance = NULL;
29 -
30 - public $file;
31 - public $basename;
32 - public $error;
33 - public $locale;
34 -
35 - public $tables;
36 - public $blog_prefix;
37 - private $prefix = "wpforo_";
38 - private $_tables = array( 'accesses', 'forums', 'languages', 'likes', 'phrases', 'posts', 'profiles',
39 - 'subscribes', 'topics', 'usergroups', 'views', 'visits', 'votes' );
40 -
41 - public $db;
42 - public $addons = array();
43 - public $current_url;
44 - public $current_object;
45 - public $menu = array();
46 - public $form = array();
47 - public $default;
48 -
49 - public $current_user = array();
50 - public $current_user_groupid = 4;
51 - public $current_userid = 0;
52 - public $current_username = '';
53 - public $current_user_email = '';
54 - public $current_user_display_name = '';
55 - public $current_user_status = '';
56 -
57 - public $use_trailing_slashes;
58 - public $use_home_url;
59 - public $excld_urls;
60 - public $base_permastruct;
61 - public $permastruct;
62 - public $url;
63 - public $pageid;
64 -
65 - public $general_options;
66 - public $features;
67 - public $tools_antispam;
68 - public $tools_cleanup;
69 - public $tools_misc;
70 - public $tools_legal;
71 -
72 - public $cache;
73 - public $phrase;
74 - public $forum;
75 - public $topic;
76 - public $post;
77 - public $usergroup;
78 - public $member;
79 - public $perm;
80 - public $sbscrb;
81 - public $tpl;
82 - public $notice;
83 - public $api;
84 - public $feed;
85 - public $moderation;
86 - public $add;
87 -
88 - public $member_tpls;
89 -
90 - public static function instance(){
91 - if ( is_null(self::$_instance) ) self::$_instance = new self();
92 - return self::$_instance;
93 - }
94 -
95 - private function __construct(){
96 - global $wpdb;
97 - $this->db = $wpdb;
98 - $this->file = __FILE__;
99 - $this->error = NULL;
100 - $this->locale = get_locale();
101 - $this->basename = plugin_basename($this->file);
102 -
103 - $this->init_db_tables();
104 - $this->includes();
105 - $this->init_defaults();
106 - $this->init_options();
107 - $this->setup();
108 - $this->init_hooks();
109 -
110 - $this->cache = new wpForoCache();
111 - $this->phrase = new wpForoPhrase();
112 - $this->forum = new wpForoForum();
113 - $this->topic = new wpForoTopic();
114 - $this->post = new wpForoPost();
115 - $this->usergroup = new wpForoUsergroup();
116 - $this->member = new wpForoMember();
117 - $this->perm = new wpForoPermissions();
118 - $this->sbscrb = new wpForoSubscribe();
119 - $this->tpl = new wpForoTemplate();
120 - $this->notice = new wpForoNotices();
121 - $this->api = new wpForoAPI();
122 - $this->feed = new wpForoFeed();
123 - $this->moderation = new wpForoModeration();
124 - $this->add = new stdClass(); // Integrations
125 - }
126 -
127 - private function init_hooks(){
128 - add_action('admin_init', array($this, 'admin_init'));
129 - add_action('init', array($this, 'init'));
130 - add_action('wp_loaded', 'wpforo_actions');
131 - add_action('wp', array($this, 'init_shortcode_page'));
132 - }
133 -
134 - private function init_db_tables($blog_id = 0){
135 - $blog_id = apply_filters('wpforo_current_blog_id', $blog_id);
136 - $this->tables = new stdClass;
137 - if(!$blog_id) $blog_id = $this->db->blogid;
138 - $this->blog_prefix = $this->db->get_blog_prefix( $blog_id );
139 - $this->_tables = apply_filters('wpforo_init_db_tables', $this->_tables);
140 - foreach ( $this->_tables as $table )
141 - $this->tables->$table = $this->blog_prefix . $this->prefix . $table;
142 - }
143 -
144 - private function includes(){
145 - include( WPFORO_DIR . '/wpf-includes/wpf-hooks.php' );
146 - include( WPFORO_DIR . '/wpf-includes/wpf-actions.php');
147 - include( WPFORO_DIR . '/wpf-includes/functions.php' );
148 - include( WPFORO_DIR . '/wpf-includes/functions-integration.php' );
149 - include( WPFORO_DIR . '/wpf-includes/functions-template.php' );
150 - if(wpforo_is_admin()) {
151 - include( WPFORO_DIR . '/wpf-includes/functions-installation.php' );
152 - include( WPFORO_DIR .'/wpf-admin/admin.php' );
153 - }
154 -
155 - include( WPFORO_DIR . '/wpf-includes/class-cache.php' );
156 - include( WPFORO_DIR . '/wpf-includes/class-forums.php' );
157 - include( WPFORO_DIR . '/wpf-includes/class-topics.php' );
158 - include( WPFORO_DIR . '/wpf-includes/class-posts.php' );
159 - include( WPFORO_DIR . '/wpf-includes/class-usergroups.php' );
160 - include( WPFORO_DIR . '/wpf-includes/class-members.php' );
161 - include( WPFORO_DIR . '/wpf-includes/class-permissions.php' );
162 - include( WPFORO_DIR . '/wpf-includes/class-phrases.php');
163 - include( WPFORO_DIR . '/wpf-includes/class-subscribes.php' );
164 - include( WPFORO_DIR . '/wpf-includes/class-template.php' );
165 - include( WPFORO_DIR . '/wpf-includes/class-notices.php' );
166 - include( WPFORO_DIR . '/wpf-includes/class-api.php' );
167 - include( WPFORO_DIR . '/wpf-includes/class-feed.php' );
168 - include( WPFORO_DIR . '/wpf-includes/class-moderation.php' );
169 - }
170 -
171 - public function admin_init(){
172 - if( wpforo_is_admin() ){
173 - if( !wpforo_feature('user-synch') && get_option('wpforo_version') ){
174 - $users = $this->db->get_var("SELECT COUNT(*) FROM `".$this->db->users."`");
175 - $profiles = $this->db->get_var("SELECT COUNT(*) FROM `" . $this->tables->profiles."`");
176 - $delta = $users - $profiles;
177 - if( $users > 100 && $delta > 2 ){ add_action( 'admin_notices', 'wpforo_profile_notice' ); }
178 - }
179 - $db_version = get_option('wpforo_version_db');
180 - if( !$db_version || version_compare( $db_version, WPFORO_VERSION, '<') ){
181 - add_action( 'admin_notices', 'wpforo_update_db_notice' );
182 - }
183 - }
184 - }
185 -
186 - public function init(){
187 - $this->phrase->init();
188 - $this->member->init_current_user();
189 - $this->perm->init();
190 -
191 - $this->init_current_object();
192 - $this->moderation->init();
193 - $this->tpl->init();
194 - $this->api->hooks();
195 - }
196 -
197 - public function init_shortcode_page(){
198 - if(wpforo_is_admin()) return;
199 -
200 - if( is_wpforo_shortcode_page() ){
201 - $url = wpforo_home_url();
202 -
203 - if( $atts = get_wpforo_shortcode_atts() ){
204 - $args = shortcode_atts( array(
205 - 'item' => 'forum',
206 - 'id' => 0,
207 - 'slug' => '',
208 - ), $atts );
209 -
210 - if( $args['id'] || $args['slug'] ){
211 - $getid = ( $args['slug'] ? $args['slug'] : $args['id'] );
212 - if( $args['item'] == 'topic' ){
213 - $url = $this->topic->get_topic_url($getid);
214 - }elseif( $args['item'] == 'profile' ){
215 - $url = $this->member->get_profile_url($getid);
216 - }else{
217 - $url = $this->forum->get_forum_url($getid);
218 - }
219 - }
220 - }
221 -
222 - $this->init_current_object($url);
223 - $this->tpl->init_nav_menu();
224 - }
225 -
226 - }
227 -
228 - private function init_defaults(){
229 - $this->default = new stdClass;
230 -
231 - $this->default->use_home_url = 0;
232 - $this->default->excld_urls = '';
233 - $this->default->permastruct = 'community';
234 -
235 - $blogname = get_option('blogname', '');
236 - $this->default->general_options = array(
237 - 'title' => $blogname . ' ' . __('Forum', 'wpforo'),
238 - 'description' => $blogname . ' ' . __('Discussion Board', 'wpforo'),
239 - 'lang' => 1
240 - );
241 -
242 - $this->default->features = array(
243 - 'user-admin-bar' => 0,
244 - 'page-title' => 1,
245 - 'top-bar' => 1,
246 - 'top-bar-search' => 1,
247 - 'breadcrumb' => 1,
248 - 'footer-stat' => 1,
249 - 'mention-nicknames' => 1,
250 - 'content-do_shortcode' => 0,
251 - 'view-logging' => 1,
252 - 'author-link' => 0,
253 - 'comment-author-link' => 0,
254 - 'user-register' => 1,
255 - 'user-register-email-confirm' => 1,
256 - 'register-url' => 0,
257 - 'login-url' => 0,
258 - 'resetpass-url' => 0, //In most cases incompatible with security and antispam plugins
259 - 'replace-avatar' => 1,
260 - 'avatars' => 1,
261 - 'custom-avatars' => 1,
262 - 'signature' => 1,
263 - 'rating' => 1,
264 - 'rating_title' => 1,
265 - 'member_cashe' => 1,
266 - 'object_cashe' => 1,
267 - 'html_cashe' => 0,
268 - 'memory_cashe' => 1,
269 - 'seo-title' => 1,
270 - 'seo-meta' => 1,
271 - 'seo-profile' => 1,
272 - 'rss-feed' => 1,
273 - 'font-awesome' => 1,
274 - 'user-synch' => 0,
275 - 'bp_profile' => 0,
276 - 'bp_activity' => 1,
277 - 'bp_notification' => 1,
278 - 'bp_forum_tab' => 1,
279 - 'output-buffer' => 1,
280 - 'wp-date-format' => 0,
281 - 'subscribe_conf' => 1,
282 - 'subscribe_checkbox_on_post_editor' => 1,
283 - 'subscribe_checkbox_default_status' => 0,
284 - 'attach-media-lib' => 1,
285 - 'debug-mode' => 0,
286 - 'copyright' => 1
287 - );
288 -
289 - $this->default->tools_antispam = array(
290 - 'spam_filter' => 1,
291 - 'spam_filter_level_topic' => mt_rand(30, 60),
292 - 'spam_filter_level_post' => mt_rand(30, 60),
293 - 'spam_user_ban' => 0,
294 - 'new_user_max_posts' => 5,
295 - 'spam_user_ban_notification' => 1,
296 - 'min_number_post_to_attach' => 3,
297 - 'min_number_post_to_link' => 0,
298 - 'spam_file_scanner' => 1,
299 - 'limited_file_ext' => 'pdf|doc|docx|txt|htm|html|rtf|xml|xls|xlsx|zip|rar|tar|gz|bzip|7z',
300 - 'exclude_file_ext' => 'pdf|doc|docx|txt',
301 - 'rc_site_key' => '',
302 - 'rc_secret_key' => '',
303 - 'rc_theme' => 'light',
304 - 'rc_login_form' => 0,
305 - 'rc_reg_form' => 0,
306 - 'rc_lostpass_form' => 0,
307 - 'rc_wpf_login_form' => 1,
308 - 'rc_wpf_reg_form' => 1,
309 - 'rc_wpf_lostpass_form' => 1,
310 - 'rc_topic_editor' => 1,
311 - 'rc_post_editor' => 1,
312 - 'html' => 'embed(src width height name pluginspage type wmode allowFullScreen allowScriptAccess flashVars),',
313 - );
314 -
315 - $this->default->tools_cleanup = array(
316 - 'user_reg_days_ago' => 7,
317 - 'auto_cleanup_users' => 0,
318 - 'usergroup' => array ( 1 => '0', 5 => '0', 2 => '1', 3 => '0' )
319 - );
320 -
321 - $this->default->tools_misc = array(
322 - 'dofollow' => '',
323 - 'noindex' => ''
324 - );
325 -
326 - $this->default->tools_legal = array(
327 - 'rules_checkbox' => 0,
328 - 'rules_text' => NULL,
329 - 'page_terms' => '',
330 - 'page_privacy' => '',
331 - 'forum_privacy_text' => NULL,
332 - 'checkbox_terms_privacy' => 0,
333 - 'checkbox_email_password' => 1,
334 - 'checkbox_forum_privacy' => 0,
335 - 'checkbox_fb_login' => 1,
336 - 'contact_page_url' => NULL,
337 - 'cookies' => 1
338 - );
339 -
340 - $this->default->stats = array(
341 - 'forums' => 0,
342 - 'topics' => 0,
343 - 'posts' => 0,
344 - 'members' => 0,
345 - 'online_members_count' => 0,
346 - 'last_post_title' => '',
347 - 'last_post_url' => '',
348 - 'newest_member_dname' => '',
349 - 'newest_member_profile_url' => ''
350 - );
351 - }
352 -
353 - private function init_options(){
354 - $permalink_structure = get_option('permalink_structure');
355 -
356 - $this->use_trailing_slashes = ( '/' == substr($permalink_structure, -1, 1) );
357 -
358 - //OPTIONS
359 - $this->use_home_url = get_wpf_option('wpforo_use_home_url', $this->default->use_home_url);
360 - $this->excld_urls = get_wpf_option('wpforo_excld_urls', $this->default->excld_urls);
361 -
362 - $this->permastruct = trim( get_wpf_option('wpforo_permastruct', $this->default->permastruct), '/' );
363 - $this->permastruct = preg_replace('#^/?index\.php/?#isu', '', $this->permastruct);
364 - $this->permastruct = trim($this->permastruct, '/');
365 -
366 - $this->base_permastruct = (!$this->use_home_url ? $this->permastruct : '');
367 - $this->base_permastruct = rtrim( ( strpos($permalink_structure, 'index.php') !== FALSE ? '/index.php/' . $this->base_permastruct : '/' . $this->base_permastruct ), '/\\' );
368 - $this->url = esc_url( home_url( $this->user_trailingslashit($this->base_permastruct) ) );
369 - $this->pageid = get_wpf_option( 'wpforo_pageid');
370 -
371 - $this->general_options = get_wpf_option( 'wpforo_general_options', $this->default->general_options);
372 - $this->features = get_wpf_option('wpforo_features', $this->default->features);
373 - $this->tools_antispam = get_wpf_option('wpforo_tools_antispam', $this->default->tools_antispam);
374 - $this->tools_cleanup = get_wpf_option('wpforo_tools_cleanup', $this->default->tools_cleanup);
375 - $this->tools_misc = get_wpf_option('wpforo_tools_misc', $this->default->tools_misc);
376 - $this->tools_legal = get_wpf_option('wpforo_tools_legal', $this->default->tools_legal);
377 -
378 - //CONSTANTS
379 - define('WPFORO_BASE_PERMASTRUCT', $this->base_permastruct );
380 - define('WPFORO_BASE_URL', $this->url );
381 - }
382 -
383 - private function setup(){
384 - if( wpforo_is_admin() ){
385 - register_activation_hook($this->basename, 'do_wpforo_activation');
386 - register_deactivation_hook($this->basename, 'do_wpforo_deactivation');
387 - }
388 - }
389 -
390 - public function user_trailingslashit($url) {
391 - $rtrimed_url = '';
392 - $url_append_vars = '';
393 - if( preg_match('#(^.+?)(/?\?.*$|$)#isu', $url, $match) ){
394 - if(isset($match[1]) && $match[1]) $rtrimed_url = rtrim($match[1], '/\\');
395 - if(isset($match[2]) && $match[2]) $url_append_vars = trim($match[2], '/\\');
396 - if( $rtrimed_url ) {
397 - $home_url = rtrim( preg_replace('#/?\?.*$#isu', '', home_url()), '/\\' );
398 - if( $rtrimed_url == $home_url ){
399 - $url = $rtrimed_url . '/';
400 - }else{
401 - $url = ( $this->use_trailing_slashes ? $rtrimed_url . '/' : $rtrimed_url );
402 - }
403 - }
404 - }
405 - return $url . $url_append_vars;
406 - }
407 -
408 - public function statistic( $mode = 'get', $template = 'all' ){
409 -
410 - if( $mode == 'get' ){
411 - if( $cached_stat = get_option('wpforo_stat' ) ){
412 - $cached_stat['online_members_count'] = $this->member->online_members_count();
413 - return $cached_stat;
414 - }
415 - }
416 -
417 - if( $mode == 'get' || $template == 'all' ) {
418 - $stats['forums'] = $this->forum->get_count( array('is_cat' => 0) );
419 - $stats['topics'] = $this->topic->get_count();
420 - $stats['posts'] = $this->post->get_count();
421 - $stats['members'] = $this->member->get_count();
422 - $stats['online_members_count'] = $this->member->online_members_count();
423 -
424 - $posts = $this->topic->get_topics(array('orderby' => 'modified', 'order' => 'DESC', 'row_count' => 20, 'private' => 0, 'status' => 0, 'permgroup' => 4 ));
425 - $first = key($posts);
426 - if ( isset($posts[$first]) && !empty($posts[$first]) && $this->perm->forum_can('vf', $posts[$first]['forumid'], 4) ) {
427 - $stats['last_post_title'] = $posts[$first]['title'];
428 - $stats['last_post_url'] = $this->post->get_post_url($posts[$first]['last_post']);
429 - }
430 -
431 - $members = $this->member->get_members(array('orderby' => 'userid', 'order' => 'DESC', 'row_count' => 1));
432 - if (isset($members[0]) && !empty($members[0])) {
433 - $stats['newest_member_dname'] = wpforo_make_dname($members[0]['display_name'], $members[0]['user_nicename']);
434 - $stats['newest_member_profile_url'] = $this->member->get_profile_url($members[0]['ID']);
435 - }
436 - }else{
437 - $stats = get_wpf_option('wpforo_stat', $this->default->stats);
438 - switch ($template){
439 - case 'forum':
440 - $stats['forums'] = $this->forum->get_count( array('is_cat' => 0) );
441 - break;
442 - case 'topic':
443 - $stats['topics'] = $this->topic->get_count();
444 - $posts = $this->topic->get_topics(array('orderby' => 'modified', 'order' => 'DESC', 'row_count' => 1));
445 - if ( isset($posts[0]) && !empty($posts[0]) && $this->perm->forum_can('vf', $posts[0]['forumid']) ) {
446 - $stats['last_post_title'] = $posts[0]['title'];
447 - $stats['last_post_url'] = $this->post->get_post_url($posts[0]['last_post']);
448 - }
449 - break;
450 - case 'post':
451 - $stats['posts'] = $this->post->get_count();
452 - $posts = $this->topic->get_topics(array('orderby' => 'modified', 'order' => 'DESC', 'row_count' => 1));
453 - if ( isset($posts[0]) && !empty($posts[0]) && $this->perm->forum_can('vf', $posts[0]['forumid']) ) {
454 - $stats['last_post_title'] = $posts[0]['title'];
455 - $stats['last_post_url'] = $this->post->get_post_url($posts[0]['last_post']);
456 - }
457 - break;
458 - case 'user':
459 - $stats['members'] = $this->member->get_count();
460 - $stats['online_members_count'] = $this->member->online_members_count();
461 -
462 - $members = $this->member->get_members(array('orderby' => 'userid', 'order' => 'DESC', 'row_count' => 1));
463 - if (isset($members[0]) && !empty($members[0])) {
464 - $stats['newest_member_dname'] = wpforo_make_dname($members[0]['display_name'], $members[0]['user_nicename']);
465 - $stats['newest_member_profile_url'] = $this->member->get_profile_url($members[0]['ID']);
466 - }
467 - break;
468 - }
469 - }
470 -
471 - $stats = array_merge($this->default->stats, $stats);
472 - $stats = apply_filters('wpforo_get_statistic_array_filter', $stats);
473 - update_option( 'wpforo_stat', $stats );
474 - return $stats;
475 - }
476 -
477 - public function init_current_object($url = ''){
478 - $this->current_object = array('template' => '', 'paged' => 1, 'is_404' => false, 'user_is_same_current_user' => false);
479 - if(!$url) $url = wpforo_get_request_uri();
480 -
481 - if( !is_wpforo_page($url) ) return;
482 -
483 - $this->current_url = $url;
484 - $current_url = wpforo_get_url_query_vars_str($url);
485 -
486 - if( $this->use_home_url ) $this->permastruct = '';
487 -
488 - $current_object = array();
489 - $current_object['template'] = '';
490 - $current_object['is_404'] = false;
491 - $current_object['user_is_same_current_user'] = false;
492 -
493 - if(isset($_GET['wpfs'])) $current_object['template'] = 'search';
494 - if( isset($_GET['wpforo']) ){
495 - switch($_GET['wpforo']){
496 - case 'signup':
497 - if(!is_user_logged_in()) $current_object['template'] = 'register';
498 - break;
499 - case 'signin':
500 - if(!is_user_logged_in()) $current_object['template'] = 'login';
501 - break;
502 - case 'lostpassword':
503 - if(!is_user_logged_in()) $current_object['template'] = 'lostpassword';
504 - break;
505 - case 'resetpassword':
506 - $current_object['template'] = 'resetpassword';
507 - break;
508 - case 'page':
509 - $current_object['template'] = 'page';
510 - break;
511 - case 'logout':
512 - wp_logout();
513 - wp_redirect( wpforo_home_url( preg_replace('#\?.*$#is', '', wpforo_get_request_uri()) ) );
514 - exit();
515 - break;
516 - }
517 - }
518 -
519 - $wpf_url = preg_replace( '#^/?'.preg_quote($this->permastruct).'#isu', '' , $current_url, 1 );
520 - $wpf_url = preg_replace('#/?\?.*$#isu', '', $wpf_url);
521 - $wpf_url_parse = array_filter( explode('/', trim($wpf_url, '/')) );
522 - $wpf_url_parse = array_reverse($wpf_url_parse);
523 -
524 - if(in_array('paged', $wpf_url_parse)){
525 - foreach($wpf_url_parse as $key => $value){
526 - if( $value == 'paged'){
527 - unset($wpf_url_parse[$key]);
528 - break;
529 - }
530 - if(is_numeric($value)) $paged = intval($value);
531 -
532 - unset($wpf_url_parse[$key]);
533 - }
534 - }
535 - if(isset($_GET['wpfpaged']) && intval($_GET['wpfpaged'])) $paged = intval($_GET['wpfpaged']);
536 - $current_object['paged'] = (isset($paged) && $paged) ? $paged : 1;
537 -
538 - $wpf_url_parse = array_values($wpf_url_parse);
539 -
540 - if( !isset($current_object['template']) || !$current_object['template'] )
541 - $current_object = apply_filters('wpforo_before_init_current_object', $current_object, $wpf_url_parse);
542 -
543 - if( !isset($current_object['template']) || !$current_object['template'] ) {
544 - if(in_array('members', $wpf_url_parse) && $wpf_url_parse[0] == 'members'){
545 - $current_object['template'] = 'members';
546 - }elseif(in_array('recent', $wpf_url_parse) && $wpf_url_parse[0] == 'recent'){
547 - $current_object['template'] = 'recent';
548 - }elseif(in_array('profile', $wpf_url_parse)){
549 - $current_object['template'] = 'profile';
550 - foreach($wpf_url_parse as $value){
551 - if( $value == 'profile') break;
552 - if(is_numeric($value)) $current_object['userid'] = $value; else $current_object['user_nicename'] = $value;
553 - }
554 - }elseif(in_array('account', $wpf_url_parse)){
555 - $current_object['template'] = 'account';
556 - foreach($wpf_url_parse as $value){
557 - if( $value == 'account') break;
558 - if(is_numeric($value)) $current_object['userid'] = $value; else $current_object['user_nicename'] = $value;
559 - }
560 - }elseif(in_array('activity', $wpf_url_parse)){
561 - $current_object['template'] = 'activity';
562 - foreach($wpf_url_parse as $value){
563 - if( $value == 'activity') break;
564 - if(is_numeric($value)) $current_object['userid'] = $value; else $current_object['user_nicename'] = $value;
565 - }
566 - }elseif(in_array('subscriptions', $wpf_url_parse)){
567 - $current_object['template'] = 'subscriptions';
568 - foreach($wpf_url_parse as $value){
569 - if( $value == 'subscriptions') break;
570 - if(is_numeric($value)) $current_object['userid'] = $value; else $current_object['user_nicename'] = $value;
571 - }
572 - }else{
573 - $current_object['template'] = 'forum';
574 - if( isset($wpf_url_parse[0]) ){
575 - if( isset($wpf_url_parse[1]) ){
576 - $current_object['topic_slug'] = $wpf_url_parse[0];
577 - $current_object['forum_slug'] = $wpf_url_parse[1];
578 - $current_object['template'] = 'post';
579 - }else{
580 - $current_object['forum_slug'] = $wpf_url_parse[0];
581 - $current_object['template'] = 'topic';
582 - }
583 - }
584 - }
585 - }
586 -
587 - if( in_array( $current_object['template'], array('profile', 'account', 'activity', 'subscriptions') )
588 - && !isset($current_object['user_nicename']) && !isset($current_object['userid']) ){
589 - $current_object = wpforo_find_current_user_data( $current_object );
590 - }
591 -
592 - if( isset($current_object['userid']) || isset($current_object['user_nicename']) ){
593 - $args = array();
594 - if(isset($current_object['userid'])) $args['userid'] = $current_object['userid'];
595 - if(isset($current_object['user_nicename'])) $args['user_nicename'] = $current_object['user_nicename'];
596 - $selected_user = $this->member->get_member($args);
597 - if(isset($current_object['userid']) && empty($selected_user)) $selected_user = $this->member->get_member(array('user_nicename' => $current_object['userid']));
598 - if(!empty($selected_user)){
599 - $current_object['user'] = $selected_user;
600 - $current_object['userid'] = $selected_user['ID'];
601 - $current_object['user_nicename'] = $selected_user['user_nicename'];
602 - $current_object['user_is_same_current_user'] = !empty($this->current_userid) && $selected_user['ID'] == $this->current_userid;
603 -
604 - switch($current_object['template']){
605 - case 'activity':
606 - $args = array(
607 - 'offset' => ($current_object['paged'] - 1) * $this->post->options['posts_per_page'],
608 - 'row_count' => $this->post->options['posts_per_page'],
609 - 'userid' => $current_object['userid'],
610 - 'orderby' => '`created` DESC, `postid` DESC',
611 - 'check_private' => true
612 - );
613 - $current_object['items_count'] = 0;
614 - $current_object['activities'] = $this->post->get_posts( $args, $current_object['items_count']);
615 - break;
616 - case 'subscriptions':
617 - $args = array(
618 - 'offset' => ($current_object['paged'] - 1) * $this->post->options['posts_per_page'],
619 - 'row_count' => $this->post->options['posts_per_page'],
620 - 'userid' => $current_object['userid'],
621 - 'order' => 'DESC'
622 - );
623 - $current_object['items_count'] = 0;
624 - $current_object['subscribes'] = $this->sbscrb->get_subscribes( $args, $current_object['items_count']);
625 - break;
626 - }
627 -
628 - }else{
629 - $current_object['is_404'] = true;
630 - $current_object['user'] = array();
631 - $current_object['userid'] = 0;
632 - $current_object['user_nicename'] = '';
633 - }
634 - }
635 -
636 - if(isset($current_object['forum_slug']) && $current_object['forum_slug']){
637 - $forum = $this->forum->get_forum( array('slug' => $current_object['forum_slug']) );
638 - if(!empty($forum)){
639 - $current_object['forum'] = $forum;
640 - $current_object['forumid'] = $forum['forumid'];
641 - $current_object['forum_desc'] = $forum['description'];
642 - $current_object['forum_meta_key'] = $forum['meta_key'];
643 - $current_object['forum_meta_desc'] = $forum['meta_desc'];
644 - $current_object['og_text'] = $forum['title'];
645 - }else{
646 - $current_object['is_404'] = true;
647 - $current_object['forum'] = array();
648 - $current_object['forumid'] = 0;
649 - $current_object['forum_desc'] = '';
650 - $current_object['forum_meta_key'] = '';
651 - $current_object['forum_meta_desc'] = '';
652 - $current_object['og_text'] = '';
653 - }
654 - }
655 -
656 - if(isset($current_object['topic_slug']) && $current_object['topic_slug']){
657 - $topic = $this->topic->get_topic(array('slug' => $current_object['topic_slug']));
658 - if(!empty($topic)){
659 - $current_object['topic'] = $topic;
660 - $current_object['topicid'] = $topic['topicid'];
661 - $current_object['og_text'] = ( wpfval($topic, 'title') ? $topic['title'] : '' );
662 - }elseif( $this->current_object['status'] == 'unapproved' && !is_user_logged_in() ){
663 - wp_redirect( wpforo_login_url() );
664 - exit();
665 - }else{
666 - $current_object['is_404'] = true;
667 - $current_object['topic'] = array();
668 - $current_object['topicid'] = 0;
669 - }
670 - }
671 -
672 - $this->current_object = apply_filters('wpforo_after_init_current_object', $current_object, $wpf_url_parse);
673 - }
674 -
675 - public function is_installed(){
676 - return (bool) get_option('wpforo_version');
677 - }
678 - }
679 -
680 - /**
681 - * Main instance of wpForo.
682 - *
683 - * Returns the main instance of WPF to prevent the need to use globals.
684 - *
685 - * @since 1.4.3
686 - * @return wpForo
687 - */
688 - if ( !function_exists('WPF') ){
689 - function WPF() {
690 - return wpForo::instance();
691 - }
692 - }
693 -
694 - // Global for backwards compatibility.
695 - $GLOBALS['wpforo'] = WPF();
696 -
697 - //ADDONS/////////////////////////////////////////////////////
698 - WPF()->addons = array(
699 - 'embeds' => array('version' => '1.0.4', 'requires' => '1.4.0', 'class' => 'wpForoEmbeds', 'title' => 'Embeds', 'thumb' => WPFORO_URL . '/wpf-assets/addons/' . 'embeds' . '/header.png', 'desc' => __('Allows to embed hundreds of video, social network, audio and photo content providers in forum topics and posts.', 'wpforo'), 'url' => 'https://gvectors.com/product/wpforo-embeds/'),
700 - 'polls' => array('version' => '1.0.0', 'requires' => '1.4.3', 'class' => 'wpForoPoll', 'title' => 'Polls', 'thumb' => WPFORO_URL . '/wpf-assets/addons/' . 'polls' . '/header.png', 'desc' => __('wpForo Polls is a complete addon to help forum members create, vote and manage polls effectively. Comes with poll specific permissions and settings.', 'wpforo'), 'url' => 'https://gvectors.com/product/wpforo-polls/'),
701 - 'mycred' => array('version' => '1.0.0', 'requires' => '1.4.3', 'class' => 'myCRED_Hook_wpForo', 'title' => 'MyCRED Integration', 'thumb' => WPFORO_URL . '/wpf-assets/addons/' . 'mycred' . '/header.png', 'desc' => __('Awards myCRED points for forum activity. Integrates myCRED Badges and Ranks. Converts wpForo topic and posts, likes to myCRED points.', 'wpforo'), 'url' => 'https://gvectors.com/product/wpforo-mycred/'),
702 - 'ucf' => array('version' => '1.0.0', 'requires' => '1.4.0', 'class' => 'WpforoUcf', 'title' => 'User Custom Fields', 'thumb' => WPFORO_URL . '/wpf-assets/addons/' . 'ucf' . '/header.png', 'desc' => __('Advanced user profile builder system. Allows to add new fields and manage profile page. Creates custom Registration, Account, Member Search forms.', 'wpforo'), 'url' => 'https://gvectors.com/product/wpforo-user-custom-fields/'),
703 - 'attachments' => array('version' => '1.1.2', 'requires' => '1.4.0', 'class' => 'wpForoAttachments', 'title' => 'Advanced Attachments', 'thumb' => WPFORO_URL . '/wpf-assets/addons/' . 'attachments' . '/header.png', 'desc' => __('Adds an advanced file attachment system to forum topics and posts. AJAX powered media uploading and displaying system with user specific library.', 'wpforo'), 'url' => 'https://gvectors.com/product/wpforo-advanced-attachments/'),
704 - 'pm' => array('version' => '1.0.3', 'requires' => '1.4.0', 'class' => 'wpForoPMs', 'title' => 'Private Messages', 'thumb' => WPFORO_URL . '/wpf-assets/addons/' . 'pm' . '/header.png', 'desc' => __('Provides a safe way to communicate directly with other members. Messages are private and can only be viewed by conversation participants.', 'wpforo'), 'url' => 'https://gvectors.com/product/wpforo-private-messages/'),
705 - 'cross' => array('version' => '1.0.3', 'requires' => '1.4.0', 'class' => 'wpForoCrossPosting', 'title' => '"Forum - Blog" Cross Posting', 'thumb' => WPFORO_URL . '/wpf-assets/addons/' . 'cross' . '/header.png', 'desc' => __('Blog to Forum and Forum to Blog content synchronization. Blog posts with Forum topics and Blog comments with Forum replies.', 'wpforo'), 'url' => 'https://gvectors.com/product/wpforo-cross-posting/'),
706 - 'ad-manager' => array('version' => '1.0.0', 'requires' => '1.4.0', 'class' => 'wpForoAD', 'title' => 'Ads Manager', 'thumb' => WPFORO_URL . '/wpf-assets/addons/' . 'ad-manager' . '/header.png', 'desc' => __('Ads Manager is a powerful yet simple advertisement management system, that allows you to add adverting banners between forums, topics and posts.', 'wpforo'), 'url' => 'https://gvectors.com/product/wpforo-ad-manager/'),
707 - );
708 - $wp_version = get_bloginfo('version'); if (version_compare($wp_version, '4.2.0', '>=')) { add_action('wp_ajax_dismiss_wpforo_addon_note', array(WPF()->notice, 'dismissAddonNote')); add_action('admin_notices', array(WPF()->notice, 'addonNote'));}
709 - /////////////////////////////////////////////////////////////
710 -}
1 +<?php
2 +/*
3 +* Plugin Name: wpForo
4 +* Plugin URI: https://wpforo.com
5 +* Description: WordPress Forum plugin. wpForo is the only AI powered forum solution for your community. Modern design and 5 forum layouts.
6 +* Author: gVectors Team
7 +* Author URI: https://gvectors.com/
8 +* Version: 3.2.1
9 +* Requires at least: 5.2
10 +* Requires PHP: 7.1
11 +* Text Domain: wpforo
12 +* Domain Path: /languages
13 +*/
14 +
15 +namespace wpforo;
16 +
17 +define( 'WPFORO_VERSION', '3.2.1' );
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 +define( 'WPFORO_BASEFOLDER', basename(WPFORO_DIR) ); // "wpforo"
26 +
27 +require_once WPFORO_DIR . "/autoload.php";
28 +
29 +use stdClass;
30 +use wpdb;
31 +use wpforo\classes\Actions;
32 +use wpforo\classes\Activity;
33 +use wpforo\classes\AIChatbot;
34 +use wpforo\classes\AIClient;
35 +use wpforo\classes\AIContentModeration;
36 +use wpforo\classes\AILogs;
37 +use wpforo\classes\AIWordPressIndexer;
38 +use wpforo\classes\API;
39 +use wpforo\classes\Blocks;
40 +use wpforo\classes\Boards;
41 +use wpforo\classes\Cache;
42 +use wpforo\classes\Feed;
43 +use wpforo\classes\Forms;
44 +use wpforo\classes\Forums;
45 +use wpforo\classes\Logs;
46 +use wpforo\classes\Members;
47 +use wpforo\classes\Moderation;
48 +use wpforo\classes\Notices;
49 +use wpforo\classes\Permissions;
50 +use wpforo\classes\Phrases;
51 +use wpforo\classes\PluginsOrdering;
52 +use wpforo\classes\PostMeta;
53 +use wpforo\classes\Posts;
54 +use wpforo\classes\RamCache;
55 +use wpforo\classes\SEO;
56 +use wpforo\classes\Settings;
57 +use wpforo\classes\TaskManager;
58 +use wpforo\classes\EmailQueue;
59 +use wpforo\classes\Template;
60 +use wpforo\classes\Topics;
61 +use wpforo\classes\UserGroups;
62 +use wpforo\classes\VectorStorageManager;
63 +use wpforo\modules\bookmarks\Bookmarks;
64 +use wpforo\modules\reactions\Reactions;
65 +use wpforo\modules\revisions\Revisions;
66 +use wpforo\modules\subscriptions\Subscriptions;
67 +
68 +new PluginsOrdering( WPFORO_BASENAME );
69 +
70 +final class wpforo {
71 + private static $_instance = null;
72 +
73 + /** @var wpdb * */
74 + public $db;
75 + public $default;
76 +
77 + public $blog_prefix = "wp_";
78 + public $base_prefix = "wpforo_";
79 + public $prefix = "wpforo_";
80 + public $_base_tables = [
81 + 'boards',
82 + 'usergroups',
83 + 'profiles',
84 + 'logs',
85 + 'follows',
86 + 'bookmarks',
87 + 'accesses',
88 + 'email_queue',
89 + ];
90 + public $_tables = [
91 + 'activity',
92 + 'ai_cache',
93 + 'ai_chat_conversations',
94 + 'ai_chat_messages',
95 + 'ai_embeddings',
96 + 'ai_embeddings_cache',
97 + 'ai_logs',
98 + 'ai_moderation',
99 + 'ai_tasks',
100 + 'ai_task_logs',
101 + 'forums',
102 + 'languages',
103 + 'phrases',
104 + 'postmeta',
105 + 'posts',
106 + 'post_revisions',
107 + 'subscribes',
108 + 'topics',
109 + 'tags',
110 + 'visits',
111 + 'reactions',
112 + ];
113 + public $tables;
114 + private $_folders = [
115 + 'assets',
116 + 'attachments',
117 + 'avatars',
118 + 'covers',
119 + 'cache',
120 + 'default_attachments',
121 + 'emoticons',
122 + ];
123 + public $folders = [];
124 +
125 + public $current_url;
126 + public $canonical_url;
127 + public $GET = [];
128 + public $current_object;
129 +
130 + public $wp_current_user = null;
131 + public $current_user = [];
132 + public $current_usermeta = [];
133 + public $current_user_groupid = 4;
134 + public $current_user_groupids = [ 4 ];
135 + public $current_user_secondary_groupids = [];
136 + public $current_userid = 0;
137 + public $current_user_login = '';
138 + public $current_user_email = '';
139 + public $current_user_display_name = '';
140 + public $current_user_status = '';
141 + public $current_user_accesses = [];
142 + public $session_token = '';
143 +
144 + public $tools_cleanup;
145 + public $tools_misc;
146 + public $locale = 'en_US';
147 +
148 + public $dissmissed;
149 +
150 + /** @var Settings */
151 + public $settings;
152 + /** @var Actions */
153 + public $action;
154 + /** @var Activity */
155 + public $activity;
156 + /** @var API */
157 + public $api;
158 + /** @var AIClient */
159 + public $ai_client;
160 + /** @var AIChatbot */
161 + public $ai_chatbot;
162 + /** @var VectorStorageManager */
163 + public $vector_storage;
164 + /** @var TaskManager */
165 + public $task_manager;
166 + /** @var AIContentModeration */
167 + public $ai_content_moderation;
168 + /** @var AILogs */
169 + public $ai_logs;
170 + /** @var AIWordPressIndexer */
171 + public $ai_wp_indexer;
172 + /** @var Boards */
173 + public $board;
174 + /** @var Cache */
175 + public $cache;
176 + /** @var Feed */
177 + public $feed;
178 + /** @var Forms */
179 + public $form;
180 + /** @var Forums */
181 + public $forum;
182 + /** @var Logs */
183 + public $log;
184 + /** @var Members */
185 + public $member;
186 + /** @var Moderation */
187 + public $moderation;
188 + /** @var Notices */
189 + public $notice;
190 + /** @var Permissions */
191 + public $perm;
192 + /** @var Phrases */
193 + public $phrase;
194 + /** @var PostMeta */
195 + public $postmeta;
196 + /** @var Posts */
197 + public $post;
198 + /** @var Blocks */
199 + public $blocks;
200 + /** @var RamCache */
201 + public $ram_cache;
202 + /** @var Revisions */
203 + public $revision;
204 + /** @var Reactions */
205 + public $reaction;
206 + /** @var Bookmarks */
207 + public $bookmark;
208 + /** @var SEO */
209 + public $seo;
210 + /** @var Subscriptions */
211 + public $sbscrb;
212 + /** @var EmailQueue */
213 + public $email_queue;
214 + /** @var Template */
215 + public $tpl;
216 + /** @var Topics */
217 + public $topic;
218 + /** @var UserGroups */
219 + public $usergroup;
220 +
221 + public static function instance() {
222 + if( is_null( self::$_instance ) ) self::$_instance = new self();
223 +
224 + return self::$_instance;
225 + }
226 +
227 + private function init_db() {
228 + global $wpdb;
229 + $this->db = $wpdb;
230 + }
231 +
232 + public function is_db_mysql8() {
233 + if( preg_match( '#([\d.]+)-MariaDB#iu', (string) $this->db->get_var( "SELECT VERSION()" ), $match ) ) {
234 + $use_mysql8 = version_compare( $match[1], '10.2.6', '>=' );
235 + } else {
236 + $use_mysql8 = version_compare( $this->db->db_version(), '8.0.0', '>=' );
237 + }
238 +
239 + return apply_filters( 'wpforo_use_mysql8', $use_mysql8 );
240 + }
241 +
242 + private function __construct() {
243 + $this->init_db();
244 + $this->init_hooks();
245 + }
246 +
247 + public function generate_prefix( $boardid ) {
248 + $boardid = intval( $boardid );
249 +
250 + return $this->base_prefix . ( $boardid ? $boardid . '_' : '' );
251 + }
252 +
253 + private function init_prefix() {
254 + $boardid = $this->board->get_current( 'boardid' );
255 + $this->prefix = $this->generate_prefix( $boardid );
256 + }
257 +
258 + public function change_board( $args = [] ) {
259 + if( is_null( $this->board ) ) return;
260 +
261 + do_action( 'wpforo_before_change_board', $args );
262 +
263 + $boardid = $this->board->get_current( 'boardid' );
264 + $is_inited = (bool) wpfval( $this->board->is_inited, $boardid );
265 + $this->board->init_current( $args );
266 +
267 + if( ! $is_inited || $boardid !== $this->board->get_current( 'boardid' ) ) {
268 + $this->ram_cache->reset();
269 +
270 + $this->init_prefix();
271 + $this->init_tables();
272 + $this->init_folders();
273 + $this->init_options();
274 +
275 + do_action( 'wpforo_after_change_board', $args );
276 + }
277 + }
278 +
279 + private function init_base_classes() {
280 + $this->requires();
281 + $this->init_defaults();
282 + $this->reset_current_object();
283 + $this->init_base_tables();
284 + $this->init_folders();
285 +
286 + do_action( 'wpforo_before_init_base_classes' );
287 +
288 + $this->settings = new Settings();
289 + $this->tpl = new Template();
290 + $this->ram_cache = new RamCache();
291 + $this->cache = new Cache();
292 + $this->action = new Actions();
293 + $this->board = new Boards();
294 + $this->usergroup = new UserGroups();
295 + $this->member = new Members();
296 + $this->perm = new Permissions();
297 + $this->notice = new Notices();
298 +
299 + $this->moderation = new Moderation();
300 + $this->phrase = new Phrases();
301 + $this->blocks = new Blocks();
302 +
303 + do_action( 'wpforo_after_init_base_classes' );
304 + }
305 +
306 + private function init_classes() {
307 + do_action( 'wpforo_before_init_classes' );
308 +
309 + $this->activity = new Activity();
310 + $this->api = new API();
311 + // AIClient: Initialize globally for both admin and front-end features
312 + // (semantic search, antispam, auto-translation, etc.)
313 + $this->ai_client = new AIClient();
314 + // AIChatbot: AI-powered chat functionality in AI Assistant widget
315 + $this->ai_chatbot = new AIChatbot();
316 + // VectorStorageManager: Unified abstraction for vector storage (local/cloud)
317 + $this->vector_storage = new VectorStorageManager();
318 + // TaskManager: Initialize for AI task scheduling and execution
319 + $this->task_manager = new TaskManager();
320 + // AIContentModeration: Central class for AI-powered content moderation
321 + $this->ai_content_moderation = AIContentModeration::get_instance();
322 + // AILogs: Logging of all AI actions for admin visibility
323 + $this->ai_logs = new AILogs();
324 + // AIWordPressIndexer: WordPress content type indexing for AI search
325 + $this->ai_wp_indexer = new AIWordPressIndexer();
326 + $this->feed = new Feed();
327 + $this->form = new Forms();
328 + $this->forum = new Forums();
329 + $this->log = new Logs();
330 + $this->postmeta = new PostMeta();
331 + $this->post = new Posts();
332 + $this->seo = new SEO();
333 + $this->topic = new Topics();
334 + $this->reaction = new Reactions();
335 + $this->bookmark = new Bookmarks();
336 + $this->sbscrb = new Subscriptions();
337 + $this->email_queue = new EmailQueue();
338 + if( wpforo_is_module_enabled( 'revisions' ) ) $this->revision = new Revisions();
339 +
340 + do_action( 'wpforo_after_init_classes' );
341 + }
342 +
343 + public function set_locale( $locale ) {
344 + $this->locale = $locale;
345 + do_action( 'wpforo_after_set_locale', $locale );
346 + }
347 +
348 + private function init_hooks() {
349 + add_action( 'wpforo_after_init_folders', function( $folders ) {
350 + $this->create_folders( $folders );
351 + }, 9999 );
352 + add_action(
353 + 'after_setup_theme',
354 + function() {
355 + do_action( 'wpforo_before_base_init' );
356 + $this->init_base_classes();
357 + if( ! $this->is_installed() ) $this->init();
358 + },
359 + 0
360 + );
361 + add_action( 'change_locale', [ $this, 'set_locale' ] );
362 + add_action( 'init', function() { $this->set_locale( get_locale() ); } );
363 + add_action( 'widgets_init', function() {
364 + $boards = $this->board->get_boards( [ 'status' => true ] );
365 + foreach( $boards as $board ) {
366 + register_sidebar(
367 + [
368 + 'id' => sprintf(
369 + 'wpforo_%1$ssidebar',
370 + $board['boardid'] ? $board['boardid'] . '_' : ''
371 + ),
372 + 'name' => __( 'wpForo Sidebar', 'wpforo' ) . ' - ( ' . $board['title'] . ' )',
373 + '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' ),
374 + 'before_widget' => '<aside id="%1$s" class="footer-widget-col %2$s clearfix">',
375 + 'after_widget' => '</aside>',
376 + 'before_title' => '<h3 class="widget-title">',
377 + 'after_title' => '</h3>',
378 + ]
379 + );
380 + }
381 +
382 + register_widget( 'wpforo\widgets\Forums' );
383 + register_widget( 'wpforo\widgets\Profile' );
384 + register_widget( 'wpforo\widgets\Search' );
385 + register_widget( 'wpforo\widgets\OnlineMembers' );
386 + register_widget( 'wpforo\widgets\RecentTopics' );
387 + register_widget( 'wpforo\widgets\RecentPosts' );
388 + register_widget( 'wpforo\widgets\Tags' );
389 + } );
390 + add_filter( 'plugin_locale', function( $locale, $domain ) {
391 + if( $domain === 'wpforo' && defined( 'DOING_AJAX' ) && DOING_AJAX ) $locale = $this->locale;
392 +
393 + return $locale;
394 + }, 10, 2 );
395 + add_action( 'wpforo_after_init_classes', function() {
396 + if( wpforo_setting( 'email', 'disable_new_user_admin_notification' ) ) {
397 + remove_action( 'after_password_reset', 'wp_password_change_notification' );
398 +
399 + remove_action( 'register_new_user', 'wp_send_new_user_notifications' );
400 + add_action( 'register_new_user', 'wpforo_send_new_user_notifications' );
401 +
402 + remove_action( 'edit_user_created_user', 'wp_send_new_user_notifications' );
403 + add_action( 'edit_user_created_user', 'wpforo_send_new_user_notifications', 10, 2 );
404 +
405 + remove_action( 'network_site_new_created_user', 'wp_send_new_user_notifications' );
406 + add_action( 'network_site_new_created_user', 'wpforo_send_new_user_notifications' );
407 +
408 + remove_action( 'network_site_users_created_user', 'wp_send_new_user_notifications' );
409 + add_action( 'network_site_new_created_user', 'wpforo_send_new_user_notifications' );
410 +
411 + remove_action( 'network_user_new_created_user', 'wp_send_new_user_notifications' );
412 + add_action( 'network_user_new_created_user', 'wpforo_send_new_user_notifications' );
413 + }
414 + } );
415 +
416 + // WP Cron: Ensure classes are initialized early for cron hook callbacks
417 + if ( wp_doing_cron() || isset( $_GET['doing_wp_cron'] ) ) {
418 + add_action( 'init', [ $this, 'init' ], 1 ); // Priority 1 - before cron runs
419 + } elseif( is_admin() || strpos( (string) $_SERVER['REQUEST_URI'], '/peepsoajax/' ) === 0 || preg_match(
420 + '#^/?(?:([^\s/?&=<>:\'\"*\\\|]*/)(?1)*)?[^\s/?&=<>:\'\"*\\\|]+\.(?:php|js|css|jpe?g|png|gif|bmp|webp|svg|tiff)/?(?:\?[^/]*)?$#iu',
421 + (string) $_SERVER['REQUEST_URI']
422 + ) ) {
423 + add_action( 'init', [ $this, 'init' ], 99 );
424 + add_action( 'admin_init', [ $this, 'admin_init' ] );
425 + } elseif( strpos( (string) $_SERVER['REQUEST_URI'], '/wp-json/' ) !== false ) {
426 + add_filter( 'rest_authentication_errors', function( $r ) {
427 + $this->init();
428 +
429 + return $r;
430 + }, 9999 );
431 + } else {
432 + add_action( 'wp', [ $this, 'init' ], 99 );
433 + }
434 + add_action( 'switch_blog', [ $this, 'after_switch_blog' ], 10, 2 );
435 + add_action( 'wpforo_before_init', [ $this, 'change_board' ] );
436 + add_action( 'wpforo_after_init_current_url', [ $this, 'change_board' ] );
437 + }
438 +
439 + public function after_switch_blog( $new_blog_id, $prev_blog_id ) {
440 + if( intval( $new_blog_id ) !== intval( $prev_blog_id ) ) {
441 + $this->init_base_tables();
442 + $this->init_tables();
443 + $this->init_folders();
444 + }
445 + }
446 +
447 + private function init_base_tables() {
448 + $this->db->query( "SET SESSION group_concat_max_len = 1000000" );
449 + $blog_id = apply_filters( 'wpforo_current_blog_id', 0 );
450 + $this->tables = new stdClass;
451 + if( ! $blog_id ) $blog_id = $this->db->blogid;
452 + $this->blog_prefix = $this->db->get_blog_prefix( $blog_id );
453 + $this->_base_tables = apply_filters( 'wpforo_init_base_tables', $this->_base_tables );
454 + foreach( $this->_base_tables as $table ) $this->tables->$table = $this->fix_table_name( $table );
455 + }
456 +
457 + private function init_tables() {
458 + $this->_tables = apply_filters( 'wpforo_init_tables', $this->_tables );
459 + foreach( $this->_tables as $table ) $this->tables->$table = $this->fix_table_name( $table );
460 + }
461 +
462 + public function get_active_boards_tables( $basename ) {
463 + $tables = [];
464 + if( $boardids = $this->board->get_active_boardids() ) {
465 + foreach( $boardids as $boardid ) $tables[] = $this->fix_table_name( $basename, $this->generate_prefix( $boardid ) );
466 + }
467 +
468 + return array_unique( $tables );
469 + }
470 +
471 + /**
472 + * @param string $basename
473 + *
474 + * @return string
475 + */
476 + public function fix_table_name( $basename, $prefix = null ) {
477 + return $this->blog_prefix . ( in_array( $basename, $this->_base_tables, true ) ? $this->base_prefix : ( is_null( $prefix ) ? $this->prefix : $prefix ) ) . $basename;
478 + }
479 +
480 + public function fix_dir_sep( $dir ) {
481 + $dir = str_replace( [ '/', '\\', '\\\\' ], DIRECTORY_SEPARATOR, $dir );
482 +
483 + return rtrim( trim( (string) $dir ), DIRECTORY_SEPARATOR );
484 + }
485 +
486 + public function fix_url_sep( $url ) {
487 + return trim( str_replace( [ '/', '\\', '\\\\' ], '/', (string) $url ) );
488 + }
489 +
490 + private function init_folders() {
491 + $this->_folders = apply_filters( 'wpforo_init_folders', $this->_folders );
492 + $boardid = ( is_callable( [ $this->board, 'get_current' ] ) ? $this->board->get_current( 'boardid' ) : 0 );
493 + $upload_dir = wp_get_upload_dir();
494 +
495 + // In many cases people leave the website URL protocol as http, but website works with https
496 + // In this case colors.css and phrases.js are not loaded because of http blocking by browser
497 + $upload_dir['baseurl'] = is_ssl() ? str_replace( 'http://', 'https://', $upload_dir['baseurl'] ) : $upload_dir['baseurl'];
498 +
499 + $this->folders['wp_upload'] = [
500 + 'dir' => $this->fix_dir_sep( $upload_dir['basedir'] ),
501 + 'url' => $this->fix_url_sep( $upload_dir['baseurl'] ),
502 + ];
503 + $this->folders['wp_upload']['url//'] = preg_replace( '#^https?:#i', '', (string) $this->folders['wp_upload']['url'] );
504 + $this->folders['upload'] = [
505 + 'dir' => $this->folders['wp_upload']['dir'] . DIRECTORY_SEPARATOR . "wpforo" . ( $boardid ? '_' . $boardid : '' ),
506 + 'url' => $this->folders['wp_upload']['url'] . "/wpforo" . ( $boardid ? '_' . $boardid : '' ),
507 + 'url//' => $this->folders['wp_upload']['url//'] . "/wpforo" . ( $boardid ? '_' . $boardid : '' ),
508 + ];
509 + foreach( $this->_folders as $folder ) {
510 + $this->folders[ $folder ] = [
511 + 'dir' => $this->folders['upload']['dir'] . DIRECTORY_SEPARATOR . trim( $this->fix_dir_sep( (string) $folder ), DIRECTORY_SEPARATOR ),
512 + 'url' => $this->folders['upload']['url'] . "/" . trim( $this->fix_url_sep( (string) $folder ), '/' ),
513 + 'url//' => $this->folders['upload']['url//'] . "/" . trim( $this->fix_url_sep( (string) $folder ), '/' ),
514 + ];
515 + }
516 +
517 + $this->folders = apply_filters( 'wpforo_working_folders', $this->folders );
518 +
519 + do_action( 'wpforo_after_init_folders', $this->folders );
520 + }
521 +
522 + private function create_folders( array $folders = [] ): void {
523 + if( ! $folders ) $folders = WPF()->folders;
524 + foreach( $folders as $folder ) {
525 + $dir = ( is_scalar( $folder ) ? $folder : ( array_key_exists( 'dir', $folder ) ? (string) $folder['dir'] : '' ) );
526 + if( $dir && ! is_dir( $dir ) ) {
527 + if( wp_mkdir_p( $dir ) ) {
528 + wpforo_write_file( "$dir/index.html", "" );
529 + wpforo_write_file( "$dir/robots.txt", "User-agent: *\nDisallow: /" );
530 + }
531 + }
532 + }
533 + }
534 +
535 + private function requires() {
536 + require_once WPFORO_DIR . '/includes/functions.php';
537 + require_once WPFORO_DIR . '/includes/functions-template.php';
538 + require_once WPFORO_DIR . '/includes/hooks.php';
539 + require_once WPFORO_DIR . '/includes/installation.php';
540 + require_once WPFORO_DIR . '/integrations/functions.php';
541 + if( wpforo_is_admin() ) require_once WPFORO_DIR . '/admin/index.php';
542 + }
543 +
544 + public function admin_init() {
545 + if( wpforo_is_admin() ) {
546 + $this->change_board();
547 +
548 + $this->check_issues();
549 +
550 + if( strpos( wpforo_get_request_uri(), 'user-new.php' ) === false ) {
551 + if( ! $this->member->get_groupid( $this->current_userid ) ) {
552 + $this->member->synchronize_user( $this->current_userid );
553 + }
554 + }
555 +
556 + if( ! $this->usergroup->can_manage_forum() && wpforo_current_user_is( 'admin' ) ) {
557 + $this->member->set_groupid( $this->current_userid, 1 );
558 + }
559 + }
560 + }
561 +
562 + public function check_issues() {
563 + //Make sure all users profiles are created
564 + if( $this->is_installed() ) {
565 + if( apply_filters( 'wpforo_profile_synchronization_notice', true ) ) {
566 + if( is_multisite() ) {
567 + $sql = "SELECT COUNT(`user_id`) FROM `" . WPF()->db->usermeta . "` WHERE `meta_key` LIKE '" . WPF(
568 + )->blog_prefix . "capabilities' AND `user_id` NOT IN( SELECT `userid` FROM `" . WPF()->tables->profiles . "` )";
569 + } else {
570 + $sql = "SELECT COUNT(`ID`) as user_id FROM `" . WPF()->db->users . "` WHERE `ID` NOT IN( SELECT `userid` FROM `" . WPF()->tables->profiles . "` )";
571 + }
572 + if( (int) $this->db->get_var( $sql ) ) add_action( 'admin_notices', 'wpforo_profile_notice', 10 );
573 + }
574 + }
575 + //Make sure tables structures are correct for current version
576 + $wpforo_version_db = wpforo_get_option( 'version_db', null, false );
577 + if( ! $wpforo_version_db || version_compare( $wpforo_version_db, WPFORO_VERSION, '<' ) || wpforo_setting( 'general', 'debug_mode' ) ) {
578 + if( 'tables' !== wpfval( $_GET, 'view' ) ) {
579 + $db_note = false;
580 + $problems = wpforo_database_check();
581 + if( ! empty( $problems ) ) {
582 + foreach( $problems as $key => $problem ) {
583 + if( wpfval( $problem, 'fields' ) ) $db_note = true;
584 + if( wpfval( $problem, 'exists' ) ) $db_note = true;
585 + if( $key === 'data' ) $db_note = true;
586 + }
587 + if( $db_note ) {
588 + add_action( 'admin_notices', 'wpforo_database_notice', 10 );
589 + }
590 + } else {
591 + wpforo_update_option( 'version_db', WPFORO_VERSION );
592 + }
593 + }
594 + }
595 + //Check cache plugins
596 + $not_excluded_plugins = WPF()->cache->cache_plugins_status();
597 + if( ! empty( $not_excluded_plugins ) ) {
598 + add_action( 'admin_notices', 'wpforo_cache_information', 10 );
599 + }
600 + }
601 +
602 + public function init() {
603 + do_action( 'wpforo_before_init' );
604 + $this->init_classes();
605 + $this->init_current_url();
606 + do_action( 'wpforo_core_inited' );
607 + $this->init_current_object();
608 + do_action( 'wpforo_after_init' );
609 + }
610 +
611 + public function shortcode_atts_to_url( $atts ) {
612 + if( is_null( $this->forum ) ) $this->init_classes();
613 +
614 + $url = wpforo_home_url();
615 +
616 + $args = shortcode_atts(
617 + [
618 + 'boardid' => 0,
619 + 'item' => 'forum',
620 + 'id' => 0,
621 + 'slug' => '',
622 + ],
623 + (array) $atts
624 + );
625 +
626 + WPF()->change_board( $args['boardid'] );
627 +
628 + if( $args['item'] === 'profile' && ! $args['id'] ) $args['id'] = $this->current_userid;
629 +
630 + if( $args['item'] === 'add-topic' ) {
631 + $forum = $this->forum->get_forum( ( $args['slug'] ?: $args['id'] ) );
632 + $forumid = (int) wpfval( $forum, 'is_cat' ) ? 0 : (int) wpfval( $forum, 'forumid' );
633 + $url = wpforo_home_url( wpforo_settings_get_slug( 'add-topic' ) . '/' . $forumid );
634 + } elseif( $args['item'] === 'recent' ) {
635 + $url = wpforo_settings_get_slug( 'recent' ) . '/';
636 + if( trim( (string) $args['slug'] ) ) $url .= '?view=' . wpforo_settings_get_slug( $args['slug'] );
637 + $url = wpforo_home_url( $url );
638 + } elseif( $args['item'] === 'members' ) {
639 + $url = wpforo_members_url();
640 + } elseif( $args['id'] || $args['slug'] ) {
641 + $getid = ( $args['slug'] ?: $args['id'] );
642 + if( $args['item'] === 'topic' ) {
643 + $url = $this->topic->get_url( $getid );
644 + } elseif( $args['item'] === 'profile' ) {
645 + $url = $this->member->get_profile_url( $getid );
646 + } elseif( $args['item'] === 'account' ) {
647 + $url = $this->member->get_profile_url( $getid, 'account' );
648 + } elseif( $args['item'] === 'activity' ) {
649 + $url = $this->member->get_profile_url( $getid, 'activity' );
650 + } elseif( $args['item'] === 'favored' ) {
651 + $url = $this->member->get_profile_url( $getid, 'favored' );
652 + } elseif( $args['item'] === 'subscriptions' ) {
653 + $url = $this->member->get_profile_url( $getid, 'subscriptions' );
654 + } elseif( $args['item'] === 'messages' ) {
655 + $url = $this->member->get_profile_url( $getid, 'messages' );
656 + } else {
657 + $url = $this->forum->get_forum_url( $getid );
658 + }
659 + } elseif( $args['item'] === 'login' ) {
660 + $url = wpforo_login_url();
661 + } elseif( $args['item'] === 'register' ) {
662 + $url = wpforo_register_url();
663 + } elseif( $args['item'] === 'lostpassword' ) {
664 + $url = wpforo_lostpassword_url();
665 + }
666 +
667 + return $url;
668 + }
669 +
670 + public function init_current_url( $atts = [] ) {
671 + if( is_null( $this->post ) ) $this->init_classes();
672 +
673 + if( is_scalar( $atts ) ) {
674 + $url = $atts;
675 + $atts = [];
676 + } else {
677 + $url = wpforo_get_request_uri();
678 + }
679 + if( $atts || is_wpforo_shortcode_page( $url ) ) {
680 + if( $atts || ( $atts = get_wpforo_shortcode_atts( '', $url ) ) ) {
681 + $url = $this->shortcode_atts_to_url( $atts );
682 + } else {
683 + $url = wpforo_home_url();
684 + }
685 + }
686 +
687 + if( is_wpforo_url( $url ) && preg_match( '#/' . preg_quote( wpforo_settings_get_slug( 'postid' ) ) . '/(\d+)/?$#isu', strtok( $url, '?' ), $matches ) ) {
688 + $post_url = $this->post->get_full_url( $matches[1] );
689 + if( $post_url !== wpforo_home_url() ) {
690 + $url = $post_url;
691 + $this->canonical_url = $this->post->get_url( $matches[1] );
692 + }
693 + } elseif( is_wpforo_url( $url ) && preg_match( '#/' . preg_quote( wpforo_settings_get_slug( 'topicid' ) ) . '/(\d+)/?$#isu', strtok( $url, '?' ), $matches ) ) {
694 + $topic_url = $this->topic->get_full_url( $matches[1] );
695 + if( $topic_url !== wpforo_home_url() ) {
696 + $url = $topic_url;
697 + $this->canonical_url = $this->topic->get_url( $matches[1] );
698 + }
699 + }
700 +
701 + if( function_exists( 'pll_default_language' ) ) {
702 + $qvar = wpforo_get_url_query_vars_str( $url );
703 + $qvar = preg_replace( '#^' . preg_quote( pll_default_language() ) . '/#', '', $qvar );
704 + $url = $this->user_trailingslashit( home_url( $qvar ) );
705 + }
706 +
707 + $url = wpforo_fix_url( $url );
708 + $url = preg_replace( '#\#[^/?&]*$#iu', '', $url );
709 + parse_str( (string) parse_url( $url, PHP_URL_QUERY ), $get );
710 + $get = array_merge( (array) $get, $_GET );
711 + $get = wp_unslash( $get );
712 +
713 + if( ! $this->canonical_url ) $this->canonical_url = $this->current_url;
714 +
715 + $this->current_url = apply_filters( 'wpforo_init_current_url', $url );
716 + $this->GET = apply_filters( 'wpforo_init_current_url_GET', $get );
717 +
718 + if( ! $this->canonical_url ) $this->canonical_url = $this->current_url;
719 + if( strpos( $this->canonical_url, '?wpfin=tag' ) === false && strpos( $this->canonical_url, '?view=' ) === false ) {
720 + $this->canonical_url = preg_replace( '#\?.*$#isu', '', $this->canonical_url );
721 + }
722 + $this->canonical_url = apply_filters( 'wpforo_init_canonical_url', $this->canonical_url );
723 +
724 + do_action( 'wpforo_after_init_current_url', $atts );
725 + }
726 +
727 + private function init_defaults() {
728 + $this->default = new stdClass;
729 +
730 + $this->default->current_object = [
731 + 'route' => '',
732 + 'template' => '',
733 + 'qvars' => [],
734 + 'args' => [],
735 + 'layout' => 1,
736 + 'og_text' => '',
737 + 'paged' => 1,
738 + 'items_count' => 0,
739 + 'items_per_page' => 15,
740 + 'is_404' => false,
741 + 'user_is_same_current_user' => false,
742 + 'orderby' => null,
743 + 'members' => [],
744 + 'categories' => [],
745 + 'topics' => [],
746 + 'posts' => [],
747 + 'user' => [],
748 + 'userid' => 0,
749 + 'user_nicename' => '',
750 + 'forum' => [],
751 + 'forumid' => 0,
752 + 'forum_slug' => '',
753 + 'forum_desc' => '',
754 + 'forum_meta_key' => '',
755 + 'forum_meta_desc' => '',
756 + 'topic' => [],
757 + 'topicid' => 0,
758 + 'topic_slug' => '',
759 + 'tags' => [],
760 + 'load_tinymce' => false,
761 + ];
762 +
763 + $this->default->tools_cleanup = [
764 + 'user_reg_days_ago' => 7,
765 + 'auto_cleanup_users' => 0,
766 + 'usergroup' => [ 1 => '0', 5 => '0', 2 => '1', 3 => '0' ],
767 + ];
768 +
769 + $this->default->tools_misc = [
770 + 'admin_note' => '',
771 + 'admin_note_groups' => [ 1, 2, 3, 4, 5 ],
772 + 'admin_note_pages' => [ 'forum' ],
773 + ];
774 +
775 + $this->default->stats = [
776 + 'forums' => 0,
777 + 'topics' => 0,
778 + 'posts' => 0,
779 + 'members' => 0,
780 + 'online_members_count' => 0,
781 + 'last_post_title' => '',
782 + 'last_post_url' => '',
783 + 'newest_member' => [],
784 + 'newest_member_dname' => '',
785 + 'newest_member_profile_url' => '',
786 + ];
787 +
788 + $this->default->dissmissed = [
789 + 'recaptcha_backend_note' => 0,
790 + 'recaptcha_note' => 0,
791 + 'addons_css_update' => 0,
792 + ];
793 + }
794 +
795 + private function reset_current_object() {
796 + $this->current_object = $this->default->current_object;
797 + }
798 +
799 + private function init_options() {
800 + $this->tools_cleanup = wpforo_get_option( 'tools_cleanup', $this->default->tools_cleanup );
801 + $this->tools_misc = wpforo_get_option( 'tools_misc', $this->default->tools_misc );
802 + $this->dissmissed = wpforo_get_option( 'dissmissed', $this->default->dissmissed );
803 + }
804 +
805 + public function can_use_trailing_slashes() {
806 + return '/' === substr( (string) get_option( 'permalink_structure', '' ), - 1, 1 );
807 + }
808 +
809 + public function user_trailingslashit( $url ) {
810 + $rtrimed_url = '';
811 + $url_append_vars = '';
812 + if( preg_match( '#^(.+?)(/?[?&].*)?$#isu', $url, $match ) ) {
813 + if( wpfval( $match, 1 ) ) $rtrimed_url = rtrim( $match[1], '/\\' );
814 + if( wpfval( $match, 2 ) ) $url_append_vars = '?' . trim( $match[2], '?&/\\' );
815 + if( $rtrimed_url ) {
816 + $home_url = rtrim( preg_replace( '#/?\?.*$#isu', '', home_url() ), '/\\' );
817 + if( $rtrimed_url == $home_url ) {
818 + $url = $rtrimed_url . '/';
819 + } else {
820 + $url = $rtrimed_url . ( wpforo_ram_get( [ $this, 'can_use_trailing_slashes' ] ) ? '/' : '' );
821 + }
822 + }
823 + }
824 +
825 + return $url . $url_append_vars;
826 + }
827 +
828 + public function strip_url_paged_var( $url ) {
829 + $patterns = [
830 + '#/' . preg_quote( wpforo_settings_get_slug( 'paged' ) ) . '/?\d*/?#isu',
831 + '#[&?]wpfpaged=\d*#iu',
832 + ];
833 + $url = preg_replace( $patterns, '', (string) $url );
834 +
835 + return $this->user_trailingslashit( $url );
836 + }
837 +
838 + public function statistic_cache_clean() {
839 + $this->db->query( "DELETE FROM `" . $this->db->options . "` WHERE `option_name` REGEXP '^" . wpforo_prefix( 'stat_[0-9]+' ) . "'" );
840 + }
841 +
842 + public function statistic( $mode = 'get', $template = 'all' ) {
843 + $key = 'stat_' . $this->current_user_groupid;
844 + if( $mode === 'get' ) {
845 + if( $cached_stat = wpforo_get_option( $key, [], false ) ) {
846 + $cached_stat['online_members_count'] = $this->member->online_members_count();
847 + if( wpfkey( $cached_stat, 'forums' ) && wpfkey( $cached_stat, 'topics' ) && wpfkey( $cached_stat, 'posts' ) ) {
848 + return wpforo_array_args_cast_and_merge( $cached_stat, $this->default->stats );
849 + }
850 + }
851 + }
852 +
853 + if( $mode === 'get' || $template === 'all' ) {
854 + $stats['forums'] = $this->forum->get_count( [ 'is_cat' => 0 ] );
855 + $stats['topics'] = $this->topic->get_count();
856 + $stats['posts'] = $this->post->get_count();
857 + $member_status = [ 'p.`status`' => $this->member->get_inlist_enabled_statuses() ];
858 + $stats['members'] = $this->member->get_count( $member_status );
859 + $stats['online_members_count'] = $this->member->online_members_count();
860 + $row_count = apply_filters( 'wpforo_get_statistic_row_count', 1 );
861 +
862 + $posts = $this->topic->get_topics( [ 'orderby' => 'modified', 'order' => 'DESC', 'row_count' => $row_count, 'private' => 0, 'status' => 0, 'permgroup' => 4 ] );
863 + $first = key( $posts );
864 + if( !is_null( $first ) && ! empty( $posts[ $first ] ) && $this->perm->forum_can( 'vf', $posts[ $first ]['forumid'] ) ) {
865 + $stats['last_post_title'] = $posts[ $first ]['title'];
866 + $stats['last_post_url'] = $this->post->get_url( $posts[ $first ]['last_post'] );
867 + }
868 +
869 + $newest_member = $this->member->get_newest_member();
870 + if( ! empty( $newest_member ) ) {
871 + $stats['newest_member'] = $newest_member;
872 + $stats['newest_member_dname'] = wpforo_user_dname( $newest_member );
873 + $stats['newest_member_profile_url'] = $newest_member['profile_url'];
874 + }
875 + } else {
876 + $stats = wpforo_get_option( $key, $this->default->stats, false );
877 + switch( $template ) {
878 + case 'forum':
879 + $stats['forums'] = $this->forum->get_count( [ 'is_cat' => 0 ] );
880 + break;
881 + case 'topic':
882 + $stats['topics'] = $this->topic->get_count();
883 + $posts = $this->topic->get_topics( [ 'orderby' => 'modified', 'order' => 'DESC', 'row_count' => 1 ] );
884 + if( isset( $posts[0] ) && ! empty( $posts[0] ) && $this->perm->forum_can( 'vf', $posts[0]['forumid'] ) ) {
885 + $stats['last_post_title'] = $posts[0]['title'];
886 + $stats['last_post_url'] = $this->post->get_url( $posts[0]['last_post'] );
887 + }
888 + break;
889 + case 'post':
890 + $stats['posts'] = $this->post->get_count();
891 + $posts = $this->topic->get_topics( [ 'orderby' => 'modified', 'order' => 'DESC', 'row_count' => 1 ] );
892 + if( isset( $posts[0] ) && ! empty( $posts[0] ) && $this->perm->forum_can( 'vf', $posts[0]['forumid'] ) ) {
893 + $stats['last_post_title'] = $posts[0]['title'];
894 + $stats['last_post_url'] = $this->post->get_url( $posts[0]['last_post'] );
895 + }
896 + break;
897 + case 'user':
898 + //$member_status = [ 'p.`status`' => $this->member->get_inlist_enabled_statuses() ];
899 + //$stats['members'] = $this->member->get_count( $member_status );
900 + $stats['members'] = $this->member->get_count();
901 + $stats['online_members_count'] = $this->member->online_members_count();
902 +
903 + $newest_member = $this->member->get_newest_member( false );
904 + if( ! empty( $newest_member ) ) {
905 + $stats['newest_member'] = $newest_member;
906 + $stats['newest_member_dname'] = wpforo_user_dname( $newest_member );
907 + $stats['newest_member_profile_url'] = $newest_member['profile_url'];
908 + }
909 + break;
910 + }
911 + }
912 +
913 + $stats = apply_filters( 'wpforo_get_statistic_array_filter', $stats );
914 + $stats = wpforo_array_args_cast_and_merge( $stats, $this->default->stats );
915 + wpforo_update_option( $key, $stats );
916 +
917 + return $stats;
918 + }
919 +
920 + public function init_current_object() {
921 + $this->reset_current_object();
922 + $this->current_object['items_per_page'] = $this->post->get_option_items_per_page();
923 + $url = $this->current_url;
924 + $get = $this->GET;
925 +
926 + if( ! is_wpforo_page( $url ) ) return;
927 +
928 + $current_url = wpforo_get_url_query_vars_str( $url );
929 +
930 + $current_object = [];
931 + if( wpfkey( $get, 'wpfs' ) || wpfval( $get, 'foro' ) === 'search' ) $this->current_object['template'] = 'search';
932 + if( wpfval( $get, 'wpforo' ) || wpfval( $get, 'foro' ) ) {
933 + $request = ( wpfval( $get, 'wpforo' ) ) ? wpfval( $get, 'wpforo' ) : wpfval( $get, 'foro' );
934 + if( $request === 'page' ) $this->current_object['template'] = 'page';
935 + }
936 +
937 + $template_key = '';
938 + $wpf_url = preg_replace( '#/?\?.*$#isu', '', $current_url );
939 + $wpf_url_parse = array_values( array_filter( explode( '/', trim( (string) $wpf_url, '/' ) ) ) );
940 + if( array_key_exists( 0, $wpf_url_parse ) && in_array( $wpf_url_parse[0], $this->board->routes ) ) {
941 + $this->current_object['route'] = $wpf_url_parse[0];
942 + unset( $wpf_url_parse[0] );
943 +
944 + if( in_array( $this->current_object['route'], $this->board->base_routes, true ) ) {
945 + $this->current_object['template'] = ( $template_key = wpforo_settings_get_slug_key( $this->current_object['route'] ) ) !== 'member' ? $template_key : '';
946 +
947 + $current_object['qvars'] = $wpf_url_parse;
948 + $current_object['qvars'] = array_values( $current_object['qvars'] );
949 +
950 + if( $this->current_object['template'] === 'register' ) {
951 + $this->form->current['template'] = 'register';
952 + $this->form->current['value'] = array_merge(
953 + (array) wpfval( $this->form->current, 'value' ),
954 + (array) wpfval( $_POST, 'wpfreg' ),
955 + (array) wpfval( $_POST, 'data' )
956 + );
957 + $this->form->current['value']['user_login'] = sanitize_user( (string) wpfval( $_POST, 'wpfreg', 'user_login' ) );
958 + $this->form->current['value']['user_email'] = sanitize_email( (string) wpfval( $_POST, 'wpfreg', 'user_email' ) );
959 + $this->form->current['varname'] = 'wpfreg';
960 + } elseif( $this->current_object['template'] === 'logout' && $this->current_userid ) {
961 + $this->action->logout();
962 + }
963 + }
964 +
965 + if( $this->current_userid && in_array( $this->current_object['template'], [ 'register', 'login', 'lostpassword' ], true ) && ! wpforo_is_admin() ) wpforo_redirect_to();
966 + }
967 + $wpf_url_parse = array_reverse( $wpf_url_parse );
968 +
969 + if( in_array( wpforo_settings_get_slug( 'paged' ), $wpf_url_parse ) ) {
970 + foreach( $wpf_url_parse as $key => $value ) {
971 + if( $value === wpforo_settings_get_slug( 'paged' ) ) {
972 + unset( $wpf_url_parse[ $key ] );
973 + break;
974 + }
975 + if( is_numeric( $value ) ) $paged = intval( $value );
976 +
977 + unset( $wpf_url_parse[ $key ] );
978 + }
979 + }
980 + if( $_paged = intval( wpfval( $get, 'wpfpaged' ) ) ) $paged = $_paged;
981 + $current_object['paged'] = ( isset( $paged ) && $paged > 0 ) ? $paged : 1;
982 + $current_object['orderby'] = wpfval( $get, 'orderby' );
983 +
984 + $wpf_url_parse = array_values( $wpf_url_parse );
985 +
986 + if( ! $this->current_object['template'] ) {
987 + $current_object = apply_filters( 'wpforo_before_init_current_object', $current_object, $wpf_url_parse );
988 + if( wpfkey( $current_object, 'template' ) ) $this->current_object['template'] = (string) wpfval( $current_object, 'template' );
989 + }
990 +
991 + if( ! $this->current_object['template'] ) {
992 + $templates = $template_key === 'member' ? $this->tpl->get_member_templates_list() : $this->tpl->get_templates_list();
993 + if( $templates ) {
994 + if( $template_key === 'member' ) {
995 + if( count( $wpf_url_parse ) > 1 ) {
996 + $nickname = end( $wpf_url_parse );
997 + $profile_route = prev( $wpf_url_parse );
998 + array_pop( $wpf_url_parse );
999 + array_pop( $wpf_url_parse );
1000 + array_push( $wpf_url_parse, $nickname, $profile_route );
1001 + } else {
1002 + if( ! in_array( end( $wpf_url_parse ), array_map( 'wpforo_settings_get_slug', $templates ) ) ) $wpf_url_parse[] = wpforo_settings_get_slug( 'profile' );
1003 + }
1004 + }
1005 + $__slug = end( $wpf_url_parse );
1006 + foreach( $templates as $template ) {
1007 + if( $__slug === wpforo_settings_get_slug( $template ) ) {
1008 + $this->current_object['template'] = $template;
1009 + $current_object['qvars'] = $wpf_url_parse;
1010 + array_pop( $current_object['qvars'] );
1011 + $current_object['qvars'] = array_reverse( $current_object['qvars'] );
1012 + break;
1013 + }
1014 + }
1015 +
1016 + if( $template_key === 'member' ) {
1017 + if( ! $this->current_object['template'] && ! $wpf_url_parse ) {
1018 + if( $this->current_userid ) {
1019 + $this->current_object['template'] = 'profile';
1020 + } else {
1021 + wp_safe_redirect( wpforo_login_url() );
1022 + exit();
1023 + }
1024 + } elseif( ! wpforo_is_member_template( $this->current_object['template'] ) ) {
1025 + $this->current_object['template'] = '';
1026 + $current_object['qvars'] = [];
1027 + }
1028 + }
1029 + }
1030 + }
1031 +
1032 + if( ! $this->current_object['template'] ) {
1033 + $this->current_object['template'] = 'forum';
1034 + $this->form->current['varname'] = 'thread';
1035 + if( isset( $wpf_url_parse[0] ) ) {
1036 + if( isset( $wpf_url_parse[1] ) ) {
1037 + $current_object['topic_slug'] = $wpf_url_parse[0];
1038 + $current_object['forum_slug'] = $wpf_url_parse[1];
1039 + $this->current_object['template'] = 'post';
1040 + $this->form->current['varname'] = 'post';
1041 + } else {
1042 + $current_object['forum_slug'] = $wpf_url_parse[0];
1043 + $this->current_object['template'] = 'topic';
1044 + $this->form->current['varname'] = 'thread';
1045 + }
1046 + }
1047 + }
1048 +
1049 + $current_object = apply_filters( 'wpforo_after_init_current_template', $current_object, $wpf_url_parse, $get );
1050 + if( wpfkey( $current_object, 'template' ) ) $this->current_object['template'] = (string) wpfval( $current_object, 'template' );
1051 +
1052 + if( $this->current_object['template'] ) {
1053 + if( wpforo_is_member_template( $this->current_object['template'] ) ) {
1054 + if( ! wpfval( $current_object, 'userid' ) && ! wpfval( $current_object, 'user_nicename' ) ) {
1055 + if( $qvar0 = wpfval( $current_object['qvars'], 0 ) ) {
1056 + if( wpforo_setting( 'profiles', 'url_structure' ) === 'id' ) {
1057 + $current_object['userid'] = $qvar0;
1058 + } else {
1059 + $current_object['user_nicename'] = $qvar0;
1060 + }
1061 + } else {
1062 + if( $this->current_userid ) {
1063 + $current_object['userid'] = $this->current_userid;
1064 + } else {
1065 + wp_safe_redirect( wpforo_login_url() );
1066 + exit();
1067 + }
1068 + }
1069 + }
1070 +
1071 + // redirect old type of member urls to new one
1072 + if( $template_key !== 'member' ) {
1073 + if( count( $current_object['qvars'] ) === 1 ) {
1074 + $redirect = wpforo_url(
1075 + array_shift( $current_object['qvars'] ) . ( $this->current_object['template'] !== 'profile' ? '/' . wpforo_settings_get_slug( $this->current_object['template'] ) : '' ),
1076 + 'member'
1077 + );
1078 + } else {
1079 + $redirect = wpforo_url(
1080 + array_shift( $current_object['qvars'] ) . '/' . wpforo_settings_get_slug( $this->current_object['template'] ) . '/' . implode( '/', $current_object['qvars'] ),
1081 + 'member'
1082 + );
1083 + }
1084 + wp_safe_redirect( $redirect );
1085 + exit();
1086 + }
1087 + // redirection
1088 +
1089 + } elseif( $this->current_object['template'] === 'search' ) {
1090 + $args = [
1091 + 'needle' => sanitize_text_field( wpfval( $get, 'wpfs' ) ),
1092 + 'type' => sanitize_text_field( wpfval( $get, 'wpfin' ) ),
1093 + 'date_period' => intval( wpfval( $get, 'wpfd' ) ),
1094 + 'forumids' => (array) wpfval( $get, 'wpff' ),
1095 + 'offset' => ( $current_object['paged'] - 1 ) * $this->current_object['items_per_page'],
1096 + 'row_count' => $this->current_object['items_per_page'],
1097 + 'orderby' => 'relevancy',
1098 + 'order' => 'desc',
1099 + 'postids' => [],
1100 + ];
1101 + if( ! empty( $get['wpfob'] ) ) {
1102 + $args['orderby'] = wpforo_sanitize_orderby( $get['wpfob'], 'search', 'relevancy' );
1103 + } elseif( in_array( wpfval( $args, 'type' ), [ 'tag', 'user-posts', 'user-topics' ], true ) ) {
1104 + $args['orderby'] = 'date';
1105 + }
1106 + $wpfo = strtolower( (string) wpfval( $get, 'wpfo' ) );
1107 + if( in_array( $wpfo, [ 'asc', 'desc' ], true ) ) $args['order'] = $wpfo;
1108 + $sdata = array_filter( (array) wpfval( $get, 'data' ) );
1109 + $args['postids'] = $this->postmeta->search( $sdata );
1110 + $current_object['args'] = $args;
1111 + if( $sdata && ! $args['postids'] ) {
1112 + $current_object['items_count'] = 0;
1113 + $current_object['posts'] = [];
1114 + } else {
1115 + $current_object['posts'] = $this->post->search( $args, $current_object['items_count'] );
1116 + }
1117 + } elseif( $this->current_object['template'] === 'recent' ) {
1118 + $args = [];
1119 + $view = false;
1120 + $current_object['items_count'] = 0;
1121 + if( ! empty( WPF()->GET['view'] ) ) $view = sanitize_title( WPF()->GET['view'] );
1122 + if( ! empty( WPF()->GET['wpff'] ) ) $args['forumid'] = intval( WPF()->GET['wpff'] );
1123 + if( ! empty( WPF()->GET['prefixid'] ) ) {
1124 + $args['prefixid'] = intval( WPF()->GET['prefixid'] );
1125 + }
1126 +
1127 + $type = ( $view && $view !== 'unapproved' ? 'topics' : wpforo_setting( 'topics', 'recent_posts_type' ) );
1128 + if( $view === 'unapproved' ) $type = 'posts';
1129 + if( $view === 'prefix' ) $type = 'topics';
1130 +
1131 + if( ! WPF()->current_userid || ! WPF()->usergroup->can( 'aum' ) ) {
1132 + $args['private'] = 0;
1133 + $args['status'] = 0;
1134 + }
1135 + $days = apply_filters( 'wpforo_recent_posts_limit', 30 );
1136 +
1137 + $end_date = time() - ( intval( $days ) * 24 * 60 * 60 );
1138 + if( $type === 'topics' ) {
1139 + $current_object['items_per_page'] = wpforo_setting( 'topics', 'topics_per_page' );
1140 +
1141 + if( wpfval( $args, 'prefixid' ) ) $args['prefix'] = (int) wpfval( $args, 'prefixid' );
1142 + $args['where'] = "`modified` > '" . gmdate( 'Y-m-d H:i:s', $end_date ) . "'";
1143 + $args['orderby'] = ( ! empty( WPF()->GET['wpfob'] ) ) ? wpforo_sanitize_orderby( WPF()->GET['wpfob'], 'topics', 'modified' ) : 'modified';
1144 + $args['order'] = 'DESC';
1145 + $args['offset'] = ( $current_object['paged'] - 1 ) * $current_object['items_per_page'];
1146 + $args['row_count'] = $current_object['items_per_page'];
1147 +
1148 + switch( $view ) {
1149 + case 'unread':
1150 + $args['read'] = false;
1151 + break;
1152 + case 'no-replies':
1153 + $args['where'] = null;
1154 + $args['include'] = wpforo_get_not_replied_topicids();
1155 + break;
1156 + case 'solved':
1157 + $args['solved'] = 1;
1158 + break;
1159 + case 'unsolved':
1160 + $args['solved'] = 0;
1161 + break;
1162 + case 'closed':
1163 + $args['closed'] = 1;
1164 + break;
1165 + case 'opened':
1166 + $args['closed'] = 0;
1167 + break;
1168 + case 'sticky':
1169 + $args['type'] = 1;
1170 + break;
1171 + case 'private':
1172 + $args['private'] = 1;
1173 + break;
1174 + case 'unapproved':
1175 + $args['status'] = 1;
1176 + break;
1177 + case 'prefix':
1178 + $args['where'] = null;
1179 + break;
1180 + }
1181 + $topics = $view === 'no-replies' && empty( $args['include'] ) ? [] : WPF()->topic->get_topics( $args, $current_object['items_count'] );
1182 + if( $topics ) {
1183 + $intro_posts = wpforo_setting( 'topics', 'layout_extended_intro_posts_count' );
1184 + if( $intro_posts < 1 ) {
1185 + $intro_posts = null;
1186 + } else {
1187 + $intro_posts = ( $intro_posts > 1 ) ? ( $intro_posts - 1 ) : 0;
1188 + }
1189 + foreach( $topics as $key => $topic ) {
1190 + $topics[ $key ]['replies'] = [];
1191 + $topics[ $key ]['member'] = wpforo_member( $topic );
1192 + $topics[ $key ]['forum'] = wpforo_forum( $topic['forumid'] );
1193 + if( isset( $topic['last_post'] ) && $topic['last_post'] != 0 ) {
1194 + $topics[ $key ]['last_post'] = wpforo_post( $topic['last_post'] );
1195 + $topics[ $key ]['last_poster'] = wpforo_member( $topics[ $key ]['last_post'] );
1196 + }
1197 + if( isset( $topic['first_postid'] ) && $topic['first_postid'] != 0 ) {
1198 + $topics[ $key ]['first_post'] = wpforo_post( $topic['first_postid'] );
1199 +
1200 + $topics[ $key ]['first_poster'] = wpforo_member( $topics[ $key ]['first_post'] );
1201 + if( ! $view && apply_filters( 'wpforo_recent_topics_intro', true, $topic ) ) {
1202 + $topics[ $key ]['replies'] = WPF()->post->get_posts(
1203 + [ 'topicid' => $topic['topicid'], 'orderby' => '`is_first_post` ASC, `created` DESC, `postid` DESC', 'row_count' => $intro_posts ]
1204 + );
1205 + }
1206 + }
1207 + $topics[ $key ]['topic_url'] = wpforo_topic( $topic['topicid'], 'url' );
1208 + $topics[ $key ]['topic_posturl'] = ( $view === 'unread' && wpfval( $topics[ $key ]['last_post'], 'url' ) ) ? $topics[ $key ]['last_post']['url'] : WPF()->topic->get_url(
1209 + $topic['topicid']
1210 + );
1211 + }
1212 + $args['intro_posts'] = $intro_posts;
1213 + }
1214 + $current_object['topics'] = $topics;
1215 + } else {
1216 + $current_object['items_per_page'] = wpforo_setting( 'topics', 'posts_per_page' );
1217 +
1218 + if( $view !== 'unapproved' ) $args['where'] = "`created` > '" . gmdate( 'Y-m-d H:i:s', $end_date ) . "'";
1219 + $args['orderby'] = ( ! empty( WPF()->GET['wpfob'] ) ) ? wpforo_sanitize_orderby( WPF()->GET['wpfob'], 'posts', 'created' ) : 'created';
1220 + $args['order'] = 'DESC';
1221 + $args['offset'] = ( $current_object['paged'] - 1 ) * $current_object['items_per_page'];
1222 + $args['row_count'] = $current_object['items_per_page'];
1223 + if( $view === 'unapproved' ) {
1224 + $args['status'] = 1;
1225 + }
1226 + $current_object['posts'] = WPF()->post->get_posts( $args, $current_object['items_count'] );
1227 + }
1228 + $args['view'] = $view;
1229 + $args['type'] = $type;
1230 + $current_object['args'] = $args;
1231 + } elseif( $this->current_object['template'] === 'recent-activity' ) {
1232 + $current_object['items_per_page'] = 20;
1233 + $current_object['items_count'] = 0;
1234 +
1235 + // Get filter parameters from URL
1236 + $activity_type = ! empty( WPF()->GET['type'] ) ? sanitize_text_field( WPF()->GET['type'] ) : 'all';
1237 + $period = ! empty( WPF()->GET['period'] ) ? sanitize_text_field( WPF()->GET['period'] ) : 'week';
1238 +
1239 + // Calculate date_from based on period
1240 + $date_from = null;
1241 + switch( $period ) {
1242 + case 'day':
1243 + $date_from = time() - ( 24 * 60 * 60 );
1244 + break;
1245 + case 'week':
1246 + $date_from = time() - ( 7 * 24 * 60 * 60 );
1247 + break;
1248 + case 'month':
1249 + $date_from = time() - ( 30 * 24 * 60 * 60 );
1250 + break;
1251 + case 'all':
1252 + default:
1253 + $date_from = null;
1254 + break;
1255 + }
1256 +
1257 + // Get enabled activity types from settings
1258 + $enabled_types = WPF()->settings->activity['enabled_types'] ?? [];
1259 +
1260 + // Build activity query args
1261 + $args = [
1262 + 'types_exclude' => [ 'new_reply' ], // Exclude notification-only types
1263 + 'orderby' => 'date',
1264 + 'order' => 'DESC',
1265 + 'offset' => ( $current_object['paged'] - 1 ) * $current_object['items_per_page'],
1266 + 'row_count' => $current_object['items_per_page'],
1267 + 'date_from' => $date_from,
1268 + ];
1269 +
1270 + // Filter by activity type
1271 + if( $activity_type !== 'all' ) {
1272 + $type_mapping = [
1273 + 'topic' => [ 'wpforo_topic', 'edit_topic' ],
1274 + 'reply' => [ 'wpforo_post', 'edit_post' ],
1275 + 'reaction' => [ 'new_like', 'new_dislike', 'new_up_vote', 'new_down_vote', 'new_reaction' ],
1276 + 'favorite' => [ 'new_favorite' ],
1277 + 'solved' => [ 'topic_solved' ],
1278 + 'closed' => [ 'topic_closed' ],
1279 + 'answer' => [ 'post_answer' ],
1280 + ];
1281 + if( isset( $type_mapping[ $activity_type ] ) ) {
1282 + // Intersect with enabled types to respect settings
1283 + $args['types_include'] = array_intersect( $type_mapping[ $activity_type ], $enabled_types );
1284 + }
1285 + } else {
1286 + // Show all enabled types
1287 + if( ! empty( $enabled_types ) ) {
1288 + $args['types_include'] = $enabled_types;
1289 + }
1290 + }
1291 +
1292 + $current_object['activities'] = WPF()->activity->get_activities( $args, $current_object['items_count'], true, true );
1293 + $current_object['args'] = [
1294 + 'activity_type' => $activity_type,
1295 + 'period' => $period,
1296 + ];
1297 + } elseif( $this->current_object['template'] === 'tags' ) {
1298 + $current_object['items_per_page'] = wpforo_setting( 'tags', 'per_page' );
1299 + // Tag sort: whitelist the URL key, then map to orderby/order. Never pass raw input to get_tags().
1300 + $tag_sort_map = [ 'count' => [ 'count', 'DESC' ], 'az' => [ 'tag', 'ASC' ], 'za' => [ 'tag', 'DESC' ] ];
1301 + $tag_sort_key = sanitize_key( (string) wpfval( $_GET, 'wpf_tag_sort' ) );
1302 + if( ! isset( $tag_sort_map[ $tag_sort_key ] ) ) $tag_sort_key = 'count';
1303 + $current_object['tag_sort'] = $tag_sort_key;
1304 + $args = [
1305 + 'orderby' => $tag_sort_map[ $tag_sort_key ][0],
1306 + 'order' => $tag_sort_map[ $tag_sort_key ][1],
1307 + 'offset' => ( $current_object['paged'] - 1 ) * $current_object['items_per_page'],
1308 + 'row_count' => $current_object['items_per_page'],
1309 + ];
1310 + $current_object['tags'] = $this->topic->get_tags( $args, $current_object['items_count'] );
1311 + } elseif( $this->current_object['template'] === 'members' ) {
1312 + $current_object['items_per_page'] = wpforo_setting( 'members', 'members_per_page' );
1313 +
1314 + $this->form->current['template'] = 'members';
1315 + $this->form->current['value'] = $get;
1316 + $this->form->current['varname'] = '';
1317 +
1318 + if( ! empty( $get['_wpfms'] ) ) {
1319 + $users_include = [];
1320 + $search_fields_names = $this->member->get_search_fields_names();
1321 +
1322 + $wpfms = ( isset( $get['wpfms'] ) ) ? sanitize_text_field( $get['wpfms'] ) : '';
1323 + if( $wpfms ) {
1324 + if( apply_filters( 'wpforo_member_search_provider', false, $wpfms, $search_fields_names, $get ) ) {
1325 + $users_include = apply_filters( 'wpforo_search_by_provider', [], $wpfms, $search_fields_names, $get );
1326 + } else {
1327 + $users_include = $this->member->search( $wpfms, $search_fields_names );
1328 + }
1329 + } else {
1330 + if( $filters = array_filter( $get, function( $v ) { return ! ( is_null( $v ) || $v === false || $v === '' ); } ) ) {
1331 + $filters = array_merge( array_filter( (array) wpfval( $get, 'data' ), function( $v ) { return ! ( is_null( $v ) || $v === false || $v === '' ); } ), $filters );
1332 + unset( $filters['data'] );
1333 + $args = [];
1334 + foreach( $filters as $filter_key => $filter ) {
1335 + if( in_array( $filter_key, $search_fields_names ) ) {
1336 + $args[ $filter_key ] = $filter;
1337 + }
1338 + }
1339 + if( apply_filters( 'wpforo_member_filter_provider', false, $args, $get ) ) {
1340 + $users_include = apply_filters( 'wpforo_filter_by_provider', [], $args, $get );
1341 + } else {
1342 + $users_include = $this->member->filter( $args );
1343 + }
1344 + }
1345 + }
1346 +
1347 + $users_include = apply_filters( 'wpforo_member_search_users_include', $users_include );
1348 + }
1349 + $member_status = $this->member->get_inlist_enabled_statuses();
1350 + $args = [
1351 + 'offset' => ( $current_object['paged'] - 1 ) * $current_object['items_per_page'],
1352 + 'row_count' => $current_object['items_per_page'],
1353 + 'status' => $member_status,
1354 + 'groupids' => $this->usergroup->get_visible_usergroup_ids(),
1355 + ];
1356 +
1357 + $orderby = wpfval( $get, 'wpfob' ) ? sanitize_text_field( $get['wpfob'] ) : wpforo_setting( 'members', 'list_order' );
1358 +
1359 + switch( $orderby ) {
1360 + case 'online_time':
1361 + $args['orderby'] = 'online_time';
1362 + $args['order'] = 'desc';
1363 + break;
1364 + case 'posts__asc':
1365 + $args['orderby'] = 'posts';
1366 + $args['order'] = 'ASC';
1367 + break;
1368 + case 'user_registered__asc':
1369 + $args['orderby'] = 'user_registered';
1370 + $args['order'] = 'ASC';
1371 + break;
1372 + case 'user_registered__desc':
1373 + $args['orderby'] = 'user_registered';
1374 + $args['order'] = 'DESC';
1375 + break;
1376 + case 'display_name__asc':
1377 + $args['orderby'] = 'display_name';
1378 + $args['order'] = 'ASC';
1379 + break;
1380 + case 'display_name__desc':
1381 + $args['orderby'] = 'display_name';
1382 + $args['order'] = 'DESC';
1383 + break;
1384 + default:
1385 + $args['orderby'] = 'posts';
1386 + $args['order'] = 'DESC';
1387 + break;
1388 + }
1389 + if( ! empty( $users_include ) ) $args['include'] = $users_include;
1390 + $args = apply_filters( 'wpforo_current_object_members_args_filter', $args, $get );
1391 + $current_object['members'] = $this->member->get_members( $args, $current_object['items_count'] );
1392 + if( isset( $users_include ) && empty( $users_include ) ) {
1393 + $current_object['members'] = [];
1394 + $current_object['items_count'] = 0;
1395 + }
1396 + } elseif( $this->current_object['template'] === 'add-topic' ) {
1397 + if( $qvar0 = (int) wpfval( $current_object['qvars'], 0 ) ) {
1398 + $forum = (array) $this->forum->get_forum( $qvar0 );
1399 + if( ! $forum || (int) wpfval( $forum, 'is_cat' ) ) {
1400 + wp_safe_redirect( wpforo_home_url( wpforo_settings_get_slug( 'add-topic' ) ), 301 );
1401 + exit();
1402 + }
1403 + }
1404 + }
1405 + }
1406 +
1407 + if( wpfval( $current_object, 'userid' ) || wpfval( $current_object, 'user_nicename' ) ) {
1408 + $args = [];
1409 + if( isset( $current_object['userid'] ) ) $args['userid'] = $current_object['userid'];
1410 + if( isset( $current_object['user_nicename'] ) ) $args['user_nicename'] = $current_object['user_nicename'];
1411 + $selected_user = $this->member->get_member( $args );
1412 + if( isset( $current_object['userid'] ) && empty( $selected_user ) ) $selected_user = $this->member->get_member( [ 'user_nicename' => $current_object['userid'] ] );
1413 + $selected_user = apply_filters( 'wpforo_init_current_selected_user', $selected_user );
1414 + if( $selected_user ) {
1415 + $current_object['user'] = $selected_user;
1416 + $current_object['userid'] = $selected_user['userid'];
1417 + $current_object['user_nicename'] = $selected_user['user_nicename'];
1418 + $current_object['user_is_same_current_user'] = ! empty( $this->current_userid ) && $selected_user['userid'] === $this->current_userid;
1419 +
1420 + if( $this->tpl->can_view_template( $this->current_object['template'], $current_object['user'] ) ) {
1421 + switch( $this->current_object['template'] ) {
1422 + case 'activity':
1423 + $args = [
1424 + 'offset' => ( $current_object['paged'] - 1 ) * $this->current_object['items_per_page'],
1425 + 'row_count' => $this->current_object['items_per_page'],
1426 + 'userid' => $current_object['userid'],
1427 + 'orderby' => '`created` DESC, `postid` DESC',
1428 + 'check_private' => true,
1429 + 'is_first_post' => wpfval( $this->GET, 'filter' ) ? $this->GET['filter'] === 'topics' : null,
1430 + ];
1431 + $current_object['items_count'] = 0;
1432 + $current_object['activities'] = $this->post->get_posts( $args, $current_object['items_count'] );
1433 + break;
1434 + case 'favored':
1435 + $current_object['filter'] = strtolower( (string) wpfval( WPF()->GET, 'filter' ) );
1436 + if( ! in_array( $current_object['filter'], [ 'likes', 'dislikes' ], true ) ) $current_object['filter'] = 'bookmarks';
1437 + if( $current_object['filter'] === 'likes' ) {
1438 + $postids = $this->reaction->get_reactions_col(
1439 + 'postid',
1440 + [
1441 + 'userid' => $current_object['userid'],
1442 + 'type_include' => 'up',
1443 + ]
1444 + );
1445 + } elseif( $current_object['filter'] === 'dislikes' ) {
1446 + $postids = $this->reaction->get_reactions_col(
1447 + 'postid',
1448 + [
1449 + 'userid' => $current_object['userid'],
1450 + 'type_include' => 'down',
1451 + ]
1452 + );
1453 + } else {
1454 + $postids = $this->bookmark->get_bookmarks_col(
1455 + 'postid',
1456 + [
1457 + 'userid' => $current_object['userid'],
1458 + 'boardid' => $this->board->get_current( 'boardid' ),
1459 + 'status' => true,
1460 + ]
1461 + );
1462 + }
1463 +
1464 + if( $postids ) {
1465 + $args = [
1466 + 'offset' => ( $current_object['paged'] - 1 ) * $this->current_object['items_per_page'],
1467 + 'row_count' => $this->current_object['items_per_page'],
1468 + 'orderby' => '`created` DESC, `postid` DESC',
1469 + 'check_private' => true,
1470 + 'include' => $postids,
1471 + ];
1472 + $current_object['items_count'] = 0;
1473 + $current_object['favored_posts'] = $this->post->get_posts( $args, $current_object['items_count'] );
1474 + } else {
1475 + $current_object['items_count'] = 0;
1476 + $current_object['favored_posts'] = [];
1477 + }
1478 + break;
1479 + case 'account':
1480 + $this->form->current['template'] = 'account';
1481 + $this->form->current['varname'] = 'member';
1482 + $this->form->current['value'] = array_merge( $current_object['user'], (array) wpfval( $_POST, 'member' ) );
1483 + break;
1484 + default:
1485 + $this->form->current['template'] = 'profile';
1486 + $this->form->current['value'] = $current_object['user'];
1487 + break;
1488 + }
1489 + } else {
1490 + if( ! $this->current_userid ) {
1491 + wp_safe_redirect( wpforo_login_url() );
1492 + exit();
1493 + }
1494 + $current_object['is_404'] = true;
1495 + }
1496 +
1497 + } else {
1498 + $current_object['is_404'] = true;
1499 + }
1500 + }
1501 +
1502 + if( wpfval( $current_object, 'topic_slug' ) ) {
1503 + $topic = $this->topic->get_topic( [ 'slug' => $current_object['topic_slug'] ], false );
1504 + if( ! empty( $topic ) ) {
1505 + $topic_forumid = intval( wpfval( $topic, 'forumid' ) );
1506 + $is_owner = wpforo_is_owner( $topic['userid'], $topic['email'] );
1507 +
1508 + if( apply_filters( 'wpforo_current_object_topic_protect', true, $topic ) && $topic_forumid && ( ! $this->perm->forum_can(
1509 + 'vf',
1510 + $topic_forumid
1511 + ) || ( ! $is_owner && ! $this->perm->forum_can( 'vt', $topic_forumid ) ) || ( wpfval( $topic, 'private' ) && ! $is_owner && ! $this->perm->forum_can(
1512 + 'vp',
1513 + $topic_forumid
1514 + ) ) || ( wpfval( $topic, 'status' ) && ! $is_owner && ! $this->perm->forum_can( 'au', $topic_forumid ) ) ) ) {
1515 + if( ! $this->current_userid ) {
1516 + wp_safe_redirect( wpforo_login_url() );
1517 + exit();
1518 + }
1519 + $current_object['is_404'] = true;
1520 + } else {
1521 + $current_object['topic'] = $topic;
1522 + $current_object['topicid'] = $topic['topicid'];
1523 + $current_object['og_text'] = (string) wpfval( $topic, 'title' );
1524 + }
1525 + } else {
1526 + $current_object['is_404'] = true;
1527 + }
1528 + }
1529 +
1530 + if( wpfval( $current_object, 'forum_slug' ) ) {
1531 + $args = ( empty( $topic ) ? [ 'slug' => $current_object['forum_slug'] ] : $topic['forumid'] );
1532 + if( $forum = $this->forum->get_forum( $args ) ) {
1533 + if( ! empty( $topic ) && strtolower( (string) $current_object['forum_slug'] ) !== strtolower( (string) $forum['slug'] ) ) {
1534 + wp_safe_redirect( $this->topic->get_url( $topic, $forum ), 301 );
1535 + exit();
1536 + }
1537 + if( $forum['is_cat'] ) $this->current_object['template'] = 'forum';
1538 + $current_object['forum'] = $forum;
1539 + $current_object['forumid'] = $forum['forumid'];
1540 + $current_object['forum_desc'] = $forum['description'];
1541 + $current_object['forum_meta_key'] = $forum['meta_key'];
1542 + $current_object['forum_meta_desc'] = $forum['meta_desc'];
1543 + $current_object['og_text'] = $forum['title'];
1544 + $current_object['layout'] = $this->forum->get_layout( $forum );
1545 +
1546 + if( $this->current_object['template'] === 'topic' ) {
1547 + $current_object['items_per_page'] = wpforo_setting( 'topics', 'topics_per_page' );
1548 + $args = [
1549 + 'offset' => ( $current_object['paged'] - 1 ) * $current_object['items_per_page'],
1550 + 'row_count' => $current_object['items_per_page'],
1551 + 'forumid' => $current_object['forumid'],
1552 + 'orderby' => 'type, modified',
1553 + 'order' => 'DESC',
1554 + ];
1555 + $args = apply_filters( 'wpforo_topic_list_args', $args );
1556 + $current_object['topics'] = $this->topic->get_topics( $args, $current_object['items_count'] );
1557 + }
1558 + } else {
1559 + $current_object['is_404'] = true;
1560 + }
1561 + }
1562 +
1563 + if( in_array( $this->current_object['template'], [ 'forum', 'topic' ] ) ) {
1564 + if( ! empty( $forum ) ) {
1565 + $current_object['categories'] = [ $forum ];
1566 + } else {
1567 + $current_object['categories'] = $this->forum->get_forums( [ "type" => 'category' ] );
1568 + }
1569 + }
1570 +
1571 + if( $this->current_object['template'] === 'post' && ! empty( $forum ) && ! empty( $topic ) ) {
1572 + $current_object['items_per_page'] = $this->post->get_option_items_per_page( $current_object['layout'] );
1573 +
1574 + $args = [
1575 + 'forumid' => $forum['forumid'],
1576 + 'topicid' => $topic['topicid'],
1577 + 'offset' => ( $current_object['paged'] - 1 ) * $current_object['items_per_page'],
1578 + 'row_count' => $current_object['items_per_page'],
1579 + ];
1580 + if( $current_object['layout'] == 4 ) {
1581 + $args['parentid'] = 0;
1582 + } elseif( $current_object['layout'] == 3 ) {
1583 + $args['parentid'] = 0;
1584 + switch( $current_object['orderby'] ) {
1585 + case 'oldest':
1586 + $args['orderby'] = '`is_first_post` DESC, `is_answer` DESC, `created` ASC, `postid` ASC';
1587 + break;
1588 + case 'newest':
1589 + $args['orderby'] = '`is_first_post` DESC, `is_answer` DESC, `modified` DESC, `postid` DESC';
1590 + break;
1591 + default:
1592 + $args['orderby'] = '`is_first_post` DESC, `is_answer` DESC, `votes` DESC, `created` ASC, `postid` ASC';
1593 + break;
1594 + }
1595 + }
1596 + if( $this->post->get_option_union_first_post( $current_object['layout'] ) ) $args['union_first_post'] = true;
1597 + $args = apply_filters( 'wpforo_post_list_args', $args );
1598 + $current_object['posts'] = $this->post->get_posts( $args, $current_object['items_count'] );
1599 + }
1600 +
1601 + $this->current_object = wpforo_parse_args( $current_object, $this->current_object );
1602 +
1603 + $this->current_object = apply_filters( 'wpforo_after_init_current_object', $this->current_object, $wpf_url_parse );
1604 +
1605 + if( $this->current_object['template'] ) {
1606 + /**
1607 + * redirect not logged-in users to login page when that user no access to this page
1608 + */
1609 + if( ! $this->current_userid && $this->current_object['forumid'] && ( ( in_array( $this->current_object['template'], [ 'forum', 'topic' ] ) && ! $this->perm->forum_can(
1610 + 'vf',
1611 + $this->current_object['forumid']
1612 + ) ) || ( $this->current_object['template'] === 'post' && ! $this->perm->forum_can( 'vt', $this->current_object['forumid'] ) ) ) ) {
1613 + wp_safe_redirect( wpforo_login_url() );
1614 + exit();
1615 + }
1616 +
1617 + if( $this->current_object['template'] === 'cantlogin' ) {
1618 + if( $this->current_userid ) {
1619 + if( $this->current_user['status'] !== 'active' ) {
1620 + WPF()->ram_cache->set( 'USER_LOGIN_REFERER', WPF()->current_user_login );
1621 + wp_logout();
1622 + } else {
1623 + wp_safe_redirect( wpforo_home_url() );
1624 + }
1625 + } else {
1626 + wp_safe_redirect( wpforo_login_url() );
1627 + exit();
1628 + }
1629 + }
1630 +
1631 + /**
1632 + * redirect to the first page when paged var is greater items_count
1633 + */
1634 + 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'] ) {
1635 + wp_safe_redirect( $this->strip_url_paged_var( $this->current_url ), 301 );
1636 + exit();
1637 + }
1638 + } else {
1639 + $this->current_object['is_404'] = true;
1640 + }
1641 + }
1642 +
1643 + public function get_version() {
1644 + return wpforo_get_option( 'version', null, false );
1645 + }
1646 +
1647 + public function need_activation() {
1648 + return WPFORO_VERSION !== $this->get_version();
1649 + }
1650 +
1651 + public function is_installed() {
1652 + return (bool) $this->get_version();
1653 + }
1654 +
1655 + public function can_use_this_slug( $slug ) {
1656 + $return = ! in_array( $slug, $this->settings->slugs, true ) && ! in_array( $slug, array_keys( $this->settings->slugs ), true );
1657 +
1658 + return apply_filters( 'wpforo_can_use_this_slug', $return, $slug );
1659 + }
1660 +}