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

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

998 lines 46.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 * Plugin Name: wpForo
4 * Plugin URI: https://wpforo.com
5 * Description: WordPress Forum plugin. wpForo is a full-fledged forum solution for your community. Comes with multiple modern forum layouts.
6 * Author: gVectors Team (A. Chakhoyan, R. Hovhannisyan)
7 * Author URI: https://gvectors.com/
8 * Version: 1.7.0
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.7.0');
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', 'activity', 'forums', 'languages', 'likes', 'phrases', 'posts', 'post_revisions', 'profiles',
39 'subscribes', 'topics', 'tags', 'usergroups', 'views', 'visits', 'votes' );
40 public $upload_dir_folders = array();
41
42 public $db;
43 public $addons = array();
44 public $current_url;
45 public $GET;
46 public $current_object;
47 public $menu = array();
48 public $data = array();
49 public $default;
50
51 public $wp_current_user = array();
52 public $current_user = array();
53 public $current_usermeta = array();
54 public $current_user_groupid = 4;
55 public $current_user_secondary_groupids = '';
56 public $current_userid = 0;
57 public $current_username = '';
58 public $current_user_email = '';
59 public $current_user_display_name = '';
60 public $current_user_status = '';
61 public $current_user_accesses = array();
62
63 public $use_trailing_slashes;
64 public $use_home_url;
65 public $excld_urls;
66 public $base_permastruct;
67 public $permastruct;
68 public $url;
69 public $pageid;
70
71 public $general_options;
72 public $features;
73 public $tools_antispam;
74 public $tools_cleanup;
75 public $tools_misc;
76 public $tools_legal;
77
78 public $sql_cache;
79 public $action;
80 public $cache;
81 public $phrase;
82 public $forum;
83 public $topic;
84 public $post;
85 public $usergroup;
86 public $member;
87 public $perm;
88 public $sbscrb;
89 public $tpl;
90 public $notice;
91 public $api;
92 public $log;
93 public $feed;
94 public $form;
95 public $moderation;
96 public $activity;
97 public $revision;
98 public $seo;
99 public $add;
100
101 public $member_tpls;
102
103 public static function instance(){
104 if ( is_null(self::$_instance) ) self::$_instance = new self();
105 return self::$_instance;
106 }
107
108 private function __construct(){
109 global $wpdb;
110 $this->db = $wpdb;
111 $this->file = __FILE__;
112 $this->error = NULL;
113 $this->locale = get_locale();
114 $this->basename = plugin_basename($this->file);
115
116 $this->init_db_tables();
117 $this->includes();
118 $this->init_defaults();
119 $this->reset_current_object();
120 $this->init_options();
121 $this->setup();
122 $this->init_hooks();
123
124 $this->sql_cache = new wpForoSqlCache();
125 $this->action = new wpForoAction();
126 $this->cache = new wpForoCache();
127 $this->phrase = new wpForoPhrase();
128 $this->forum = new wpForoForum();
129 $this->topic = new wpForoTopic();
130 $this->post = new wpForoPost();
131 $this->usergroup = new wpForoUsergroup();
132 $this->member = new wpForoMember();
133 $this->perm = new wpForoPermissions();
134 $this->sbscrb = new wpForoSubscribe();
135 $this->tpl = new wpForoTemplate();
136 $this->notice = new wpForoNotices();
137 $this->api = new wpForoAPI();
138 $this->log = new wpForoLogs();
139 $this->feed = new wpForoFeed();
140 $this->form = new wpForoForm();
141 $this->moderation = new wpForoModeration();
142 $this->activity = new wpForoActivity();
143 $this->revision = new wpForoRevision();
144 $this->seo = new wpForoSEO();
145 $this->add = new stdClass(); // Integrations
146 }
147
148 private function init_hooks(){
149 add_action('admin_init', array($this, 'admin_init'));
150 add_action('init', array($this, 'init'));
151 }
152
153 private function init_db_tables($blog_id = 0){
154 $this->db->query("SET SESSION group_concat_max_len = 1000000");
155 $blog_id = apply_filters('wpforo_current_blog_id', $blog_id);
156 $this->tables = new stdClass;
157 if(!$blog_id) $blog_id = $this->db->blogid;
158 $this->blog_prefix = $this->db->get_blog_prefix( $blog_id );
159 $this->_tables = apply_filters('wpforo_init_db_tables', $this->_tables);
160 foreach ( $this->_tables as $table )
161 $this->tables->$table = $this->blog_prefix . $this->prefix . $table;
162 }
163
164 private function includes(){
165 require_once( WPFORO_DIR . '/wpf-includes/wpf-hooks.php' );
166 require_once( WPFORO_DIR . '/wpf-includes/functions.php' );
167 require_once( WPFORO_DIR . '/wpf-includes/functions-integration.php' );
168 require_once( WPFORO_DIR . '/wpf-includes/functions-template.php' );
169 if(wpforo_is_admin()) {
170 require_once( WPFORO_DIR . '/wpf-includes/functions-installation.php' );
171 require_once( WPFORO_DIR .'/wpf-admin/admin.php' );
172 }
173
174 require_once( WPFORO_DIR . '/wpf-includes/class-sqlcache.php' );
175 require_once( WPFORO_DIR . '/wpf-includes/class-actions.php' );
176 require_once( WPFORO_DIR . '/wpf-includes/class-cache.php' );
177 require_once( WPFORO_DIR . '/wpf-includes/class-forums.php' );
178 require_once( WPFORO_DIR . '/wpf-includes/class-topics.php' );
179 require_once( WPFORO_DIR . '/wpf-includes/class-posts.php' );
180 require_once( WPFORO_DIR . '/wpf-includes/class-usergroups.php' );
181 require_once( WPFORO_DIR . '/wpf-includes/class-members.php' );
182 require_once( WPFORO_DIR . '/wpf-includes/class-permissions.php' );
183 require_once( WPFORO_DIR . '/wpf-includes/class-phrases.php');
184 require_once( WPFORO_DIR . '/wpf-includes/class-subscribes.php' );
185 require_once( WPFORO_DIR . '/wpf-includes/class-template.php' );
186 require_once( WPFORO_DIR . '/wpf-includes/class-notices.php' );
187 require_once( WPFORO_DIR . '/wpf-includes/class-logs.php' );
188 require_once( WPFORO_DIR . '/wpf-includes/class-api.php' );
189 require_once( WPFORO_DIR . '/wpf-includes/class-feed.php' );
190 require_once( WPFORO_DIR . '/wpf-includes/class-forms.php' );
191 require_once( WPFORO_DIR . '/wpf-includes/class-moderation.php' );
192 require_once( WPFORO_DIR . '/wpf-includes/class-activity.php' );
193 require_once( WPFORO_DIR . '/wpf-includes/class-revisions.php' );
194 require_once( WPFORO_DIR . '/wpf-includes/class-seo.php' );
195 }
196
197 public function admin_init(){
198 if( wpforo_is_admin() ){
199
200 $this->check_database();
201
202 if( strpos( wpforo_get_request_uri(), 'user-new.php' ) === false ){
203 $sql = "SELECT `groupid` FROM ". $this->tables->profiles ." WHERE `userid` = " . wpforo_bigintval($this->current_userid);
204 if( !$current_groupid = $this->db->get_var($sql) ){
205 $this->member->synchronize_user($this->current_userid);
206 }
207 }
208
209 if( !$this->forum->manage() && wpforo_current_user_is('admin') ){
210 $this->member->set_usergroup($this->current_userid, 1);
211 }
212 }
213 }
214
215 public function check_database(){
216
217 //Make sure all users profiles are created
218 if( !wpforo_feature('user-synch') && get_option('wpforo_version') ){
219 $users = $this->db->get_var("SELECT COUNT(*) FROM `".$this->db->users."`");
220 $profiles = $this->db->get_var("SELECT COUNT(*) FROM `" . $this->tables->profiles."`");
221 $delta = $users - $profiles;
222 if( $users > 100 && $delta > 2 ){ add_action( 'admin_notices', 'wpforo_profile_notice', 10 ); }
223 }
224 //Make sure tables structures are correct for current version
225 $wpforo_version_db = get_option('wpforo_version_db');
226 if( !$wpforo_version_db || version_compare( $wpforo_version_db, WPFORO_VERSION, '<') ){
227 if( 'tables' != wpfval($_GET, 'view') ){
228 $db_note = false;
229 $problems = wpforo_database_check();
230 if( !empty($problems) ) {
231 foreach( $problems as $table_name => $problem ){
232 if( wpfval($problem, 'fields') ) $db_note = true;
233 if( wpfval($problem, 'exists') ) $db_note = true;
234 }
235 if( $db_note ) {
236 add_action( 'admin_notices', 'wpforo_database_notice', 10 );
237 }
238 } else {
239 update_option('wpforo_version_db', WPFORO_VERSION );
240 }
241 }
242 }
243 }
244
245 public function init(){
246 do_action( 'wpforo_before_init' );
247 $this->init_current_url();
248 $this->phrase->init();
249 $this->perm->init();
250 $this->member->init_current_user();
251
252 $this->init_current_object();
253 $this->perm->init_current_user_accesses();
254 $this->moderation->init();
255 $this->tpl->init();
256 $this->api->hooks();
257 add_action('wp_ajax_wpforo_deactivate', array($this, 'deactivate'));
258 do_action( 'wpforo_after_init' );
259 }
260
261 public function init_current_url(){
262 $url = wpforo_get_request_uri();
263 if( is_wpforo_shortcode_page() ){
264 $url = wpforo_home_url();
265 if( $atts = get_wpforo_shortcode_atts() ){
266 $args = shortcode_atts( array(
267 'item' => 'forum',
268 'id' => 0,
269 'slug' => '',
270 ), $atts );
271
272 if( $args['item'] === 'profile' && !$args['id'] ) $args['id'] = $this->current_userid;
273
274 if( $args['id'] || $args['slug'] ){
275 $getid = ( $args['slug'] ? $args['slug'] : $args['id'] );
276 if( $args['item'] === 'topic' ){
277 $url = $this->topic->get_topic_url($getid);
278 }elseif( $args['item'] === 'profile' ){
279 $url = $this->member->get_profile_url($getid);
280 }else{
281 $url = $this->forum->get_forum_url($getid);
282 }
283 }elseif( $args['item'] === 'signin' ){
284 $url = wpforo_home_url('?foro=signin');
285 }elseif( $args['item'] === 'signup' ){
286 $url = wpforo_home_url('?foro=signup');
287 }elseif( $args['item'] === 'lostpassword' ){
288 $url = wpforo_home_url('?foro=lostpassword');
289 }
290 }
291 }
292
293 $url = wpforo_fix_url($url);
294 $url = preg_replace('#\#[^/?&]*$#isu', '', $url);
295 parse_str( parse_url($url, PHP_URL_QUERY), $get );
296
297 $this->current_url = apply_filters('wpforo_init_current_url', $url);
298 $this->GET = apply_filters('wpforo_init_current_url_GET', $get);
299 }
300
301 private function init_defaults(){
302 date_default_timezone_set('UTC');
303 ini_set( 'date.timezone', 'UTC' );
304
305 $this->default = new stdClass;
306
307 $this->default->use_home_url = 0;
308 $this->default->excld_urls = '';
309 $this->default->permastruct = 'community';
310
311 $this->default->current_object = array(
312 'template' => '',
313 'layout' => 1,
314 'og_text' => '',
315 'paged' => 1,
316 'items_count' => 0,
317 'items_per_page' => 15,
318 'is_404' => false,
319 'user_is_same_current_user' => false,
320 'orderby' => null,
321 'members' => array(),
322 'categories' => array(),
323 'topics' => array(),
324 'posts' => array(),
325 'user' => array(),
326 'userid' => 0,
327 'user_nicename' => '',
328 'forum' => array(),
329 'forumid' => 0,
330 'forum_slug' => '',
331 'forum_desc' => '',
332 'forum_meta_key' => '',
333 'forum_meta_desc' => '',
334 'topic' => array(),
335 'topicid' => 0,
336 'topic_slug' => '',
337 'tags' => array()
338 );
339
340 $blogname = get_option('blogname', '');
341 $this->default->general_options = array(
342 'title' => $blogname . ' ' . __('Forum', 'wpforo'),
343 'description' => $blogname . ' ' . __('Discussion Board', 'wpforo'),
344 'lang' => 1
345 );
346
347 $this->default->features = array(
348 'user-admin-bar' => 0,
349 'page-title' => 1,
350 'top-bar' => 1,
351 'top-bar-search' => 1,
352 'breadcrumb' => 1,
353 'footer-stat' => 1,
354 'notifications' => 1,
355 'notifications-live' => 0,
356 'notifications-bar' => 1,
357 'mention-nicknames' => 1,
358 'content-do_shortcode' => 0,
359 'view-logging' => 1,
360 'track-logging' => 1,
361 'goto-unread' => 1,
362 'goto-unread-button' => 0,
363 'author-link' => 0,
364 'comment-author-link' => 0,
365 'user-register' => 1,
366 'user-register-email-confirm' => 1,
367 'register-url' => 0,
368 'login-url' => 0,
369 'resetpass-url' => 1, //In most cases incompatible with security and antispam plugins
370 'replace-avatar' => 1,
371 'avatars' => 1,
372 'custom-avatars' => 1,
373 'signature' => 1,
374 'rating' => 1,
375 'rating_title' => 1,
376 'member_cashe' => 1,
377 'object_cashe' => 1,
378 'html_cashe' => 0,
379 'memory_cashe' => 1,
380 'seo-title' => 1,
381 'seo-meta' => 1,
382 'seo-profile' => 1,
383 'rss-feed' => 1,
384 'font-awesome' => 1,
385 'bp_profile' => 0,
386 'bp_activity' => 1,
387 'bp_notification' => 1,
388 'bp_forum_tab' => 1,
389 'um_profile' => 0,
390 'um_forum_tab' => 1,
391 'um_notification' => 1,
392 'user-synch' => 0,
393 'role-synch' => 1,
394 'output-buffer' => 1,
395 'wp-date-format' => 0,
396 'subscribe_conf' => 1,
397 'subscribe_checkbox_on_post_editor' => 1,
398 'subscribe_checkbox_default_status' => 0,
399 'attach-media-lib' => 1,
400 'debug-mode' => 0,
401 'copyright' => 1
402 );
403
404 $this->default->tools_antispam = array(
405 'spam_filter' => 1,
406 'spam_filter_level_topic' => mt_rand(30, 60),
407 'spam_filter_level_post' => mt_rand(30, 60),
408 'spam_user_ban' => 0,
409 'new_user_max_posts' => 5,
410 'unapprove_post_if_user_is_new' => 0,
411 'spam_user_ban_notification' => 1,
412 'min_number_post_to_attach' => 3,
413 'min_number_post_to_link' => 0,
414 'spam_file_scanner' => 1,
415 'limited_file_ext' => 'pdf|doc|docx|txt|htm|html|rtf|xml|xls|xlsx|zip|rar|tar|gz|bzip|7z',
416 'exclude_file_ext' => 'pdf|doc|docx|txt',
417 'rc_site_key' => '',
418 'rc_secret_key' => '',
419 'rc_theme' => 'light',
420 'rc_login_form' => 0,
421 'rc_reg_form' => 0,
422 'rc_lostpass_form' => 0,
423 'rc_wpf_login_form' => 1,
424 'rc_wpf_reg_form' => 1,
425 'rc_wpf_lostpass_form' => 1,
426 'rc_topic_editor' => 1,
427 'rc_post_editor' => 1,
428 'html' => 'embed(src width height name pluginspage type wmode allowFullScreen allowScriptAccess flashVars),',
429 );
430
431 $this->default->tools_cleanup = array(
432 'user_reg_days_ago' => 7,
433 'auto_cleanup_users' => 0,
434 'usergroup' => array ( 1 => '0', 5 => '0', 2 => '1', 3 => '0' )
435 );
436
437 $this->default->tools_misc = array(
438 'dofollow' => '',
439 'noindex' => '',
440 'admin_note' => '',
441 'admin_note_groups' => array( 1, 2, 3, 4, 5 ),
442 'admin_note_pages' => array('forum')
443 );
444
445 $this->default->tools_legal = array(
446 'rules_checkbox' => 0,
447 'rules_text' => NULL,
448 'page_terms' => '',
449 'page_privacy' => '',
450 'forum_privacy_text' => NULL,
451 'checkbox_terms_privacy' => 0,
452 'checkbox_email_password' => 1,
453 'checkbox_forum_privacy' => 0,
454 'checkbox_fb_login' => 1,
455 'contact_page_url' => NULL,
456 'cookies' => 1
457 );
458
459 $this->default->stats = array(
460 'forums' => 0,
461 'topics' => 0,
462 'posts' => 0,
463 'members' => 0,
464 'online_members_count' => 0,
465 'last_post_title' => '',
466 'last_post_url' => '',
467 'newest_member_dname' => '',
468 'newest_member_profile_url' => ''
469 );
470 }
471
472 private function reset_current_object(){
473 $this->current_object = $this->default->current_object;
474 }
475
476 private function init_options(){
477 $permalink_structure = get_option('permalink_structure');
478
479 $this->use_trailing_slashes = ( '/' == substr($permalink_structure, -1, 1) );
480
481 //OPTIONS
482 $this->use_home_url = get_wpf_option('wpforo_use_home_url', $this->default->use_home_url);
483 $this->excld_urls = get_wpf_option('wpforo_excld_urls', $this->default->excld_urls);
484
485 $this->permastruct = trim( get_wpf_option('wpforo_permastruct', $this->default->permastruct), '/' );
486 $this->permastruct = preg_replace('#^/?index\.php/?#isu', '', $this->permastruct);
487 $this->permastruct = trim($this->permastruct, '/');
488
489 $this->base_permastruct = (!$this->use_home_url ? $this->permastruct : '');
490 $this->base_permastruct = rtrim( ( strpos($permalink_structure, 'index.php') !== FALSE ? '/index.php/' . $this->base_permastruct : '/' . $this->base_permastruct ), '/\\' );
491 $this->url = esc_url( home_url( $this->user_trailingslashit($this->base_permastruct) ) );
492 $this->pageid = get_wpf_option( 'wpforo_pageid', 0);
493
494 $this->general_options = get_wpf_option( 'wpforo_general_options', $this->default->general_options);
495 $this->features = get_wpf_option('wpforo_features', $this->default->features);
496 $this->tools_antispam = get_wpf_option('wpforo_tools_antispam', $this->default->tools_antispam);
497 $this->tools_cleanup = get_wpf_option('wpforo_tools_cleanup', $this->default->tools_cleanup);
498 $this->tools_misc = get_wpf_option('wpforo_tools_misc', $this->default->tools_misc);
499 $this->tools_legal = get_wpf_option('wpforo_tools_legal', $this->default->tools_legal);
500
501 //CONSTANTS
502 define('WPFORO_BASE_PERMASTRUCT', $this->base_permastruct );
503 define('WPFORO_BASE_URL', $this->url );
504 }
505
506 private function setup(){
507 if( wpforo_is_admin() ){
508 register_activation_hook($this->basename, 'do_wpforo_activation');
509 register_deactivation_hook($this->basename, 'do_wpforo_deactivation');
510 }
511 }
512
513 public function user_trailingslashit($url) {
514 $rtrimed_url = '';
515 $url_append_vars = '';
516 if( preg_match('#^(.+?)(/?[?&].*)?$#isu', $url, $match) ){
517 if( wpfval($match, 1) ) $rtrimed_url = rtrim($match[1], '/\\');
518 if( wpfval($match, 2) ) $url_append_vars = '?' . trim($match[2], '?&/\\');
519 if( $rtrimed_url ) {
520 $home_url = rtrim( preg_replace('#/?\?.*$#isu', '', home_url()), '/\\' );
521 if( $rtrimed_url == $home_url ){
522 $url = $rtrimed_url . '/';
523 }else{
524 $url = ( $this->use_trailing_slashes ? $rtrimed_url . '/' : $rtrimed_url );
525 }
526 }
527 }
528 return $url . $url_append_vars;
529 }
530
531 public function strip_url_paged_var($url){
532 $patterns = array(
533 '#/'. preg_quote( $this->tpl->slugs['paged'] ) .'/?\d*/?#isu',
534 '#[\&\?]wpfpaged=\d*#isu'
535 );
536 $url = preg_replace($patterns, '', $url);
537 $url = $this->user_trailingslashit($url);
538 return $url;
539 }
540
541 public function statistic( $mode = 'get', $template = 'all' ){
542 if( $mode === 'get' ){
543 if( $cached_stat = get_option('wpforo_stat' ) ){
544 $cached_stat['online_members_count'] = $this->member->online_members_count();
545 if( wpfval($cached_stat, 'forums') && wpfval($cached_stat, 'topics') && wpfval($cached_stat, 'posts') ){
546 return $cached_stat;
547 }
548 }
549 }
550
551 if( $mode === 'get' || $template === 'all' ) {
552 $stats['forums'] = $this->forum->get_count( array('is_cat' => 0) );
553 $stats['topics'] = $this->topic->get_count();
554 $stats['posts'] = $this->post->get_count();
555 $stats['members'] = $this->member->get_count();
556 $stats['online_members_count'] = $this->member->online_members_count();
557 $row_count = apply_filters('wpforo_get_statistic_row_count', 20);
558
559 $posts = $this->topic->get_topics(array('orderby' => 'modified', 'order' => 'DESC', 'row_count' => $row_count, 'private' => 0, 'status' => 0, 'permgroup' => 4 ));
560 $first = key($posts);
561 if ( isset($posts[$first]) && !empty($posts[$first]) && $this->perm->forum_can('vf', $posts[$first]['forumid'], 4) ) {
562 $stats['last_post_title'] = $posts[$first]['title'];
563 $stats['last_post_url'] = $this->post->get_post_url($posts[$first]['last_post']);
564 }
565
566 $members = $this->member->get_members(array('orderby' => 'userid', 'order' => 'DESC', 'row_count' => 1, 'groupids' => $this->usergroup->get_visible_usergroup_ids()));
567 if (isset($members[0]) && !empty($members[0])) {
568 $stats['newest_member_dname'] = wpforo_user_dname($members[0]);
569 $stats['newest_member_profile_url'] = $this->member->get_profile_url($members[0]['ID']);
570 }
571 }else{
572 $stats = get_wpf_option('wpforo_stat', $this->default->stats);
573 switch ($template){
574 case 'forum':
575 $stats['forums'] = $this->forum->get_count( array('is_cat' => 0) );
576 break;
577 case 'topic':
578 $stats['topics'] = $this->topic->get_count();
579 $posts = $this->topic->get_topics(array('orderby' => 'modified', 'order' => 'DESC', 'row_count' => 1));
580 if ( isset($posts[0]) && !empty($posts[0]) && $this->perm->forum_can('vf', $posts[0]['forumid']) ) {
581 $stats['last_post_title'] = $posts[0]['title'];
582 $stats['last_post_url'] = $this->post->get_post_url($posts[0]['last_post']);
583 }
584 break;
585 case 'post':
586 $stats['posts'] = $this->post->get_count();
587 $posts = $this->topic->get_topics(array('orderby' => 'modified', 'order' => 'DESC', 'row_count' => 1));
588 if ( isset($posts[0]) && !empty($posts[0]) && $this->perm->forum_can('vf', $posts[0]['forumid']) ) {
589 $stats['last_post_title'] = $posts[0]['title'];
590 $stats['last_post_url'] = $this->post->get_post_url($posts[0]['last_post']);
591 }
592 break;
593 case 'user':
594 $stats['members'] = $this->member->get_count();
595 $stats['online_members_count'] = $this->member->online_members_count();
596
597 $members = $this->member->get_members(array('orderby' => 'userid', 'order' => 'DESC', 'row_count' => 1, 'groupids' => $this->usergroup->get_visible_usergroup_ids()));
598 if (isset($members[0]) && !empty($members[0])) {
599 $stats['newest_member_dname'] = wpforo_user_dname($members[0]);
600 $stats['newest_member_profile_url'] = $this->member->get_profile_url($members[0]['ID']);
601 }
602 break;
603 }
604 }
605
606 $stats = apply_filters('wpforo_get_statistic_array_filter', $stats);
607 $stats = wpforo_array_args_cast_and_merge($stats, $this->default->stats);
608 update_option( 'wpforo_stat', $stats );
609 return $stats;
610 }
611
612 public function init_current_object(){
613 $this->current_object['items_per_page'] = $this->post->get_option_items_per_page();
614 $url = $this->current_url;
615 $get = $this->GET;
616
617 if( !is_wpforo_page($url) ) return;
618
619 $current_url = wpforo_get_url_query_vars_str($url);
620
621 if( $this->use_home_url ) $this->permastruct = '';
622
623 $current_object = array();
624 if( wpfval($get, 'wpfs') || 'search' == wpfval($get, 'foro') ) $current_object['template'] = 'search';
625 if( wpfval($get, 'wpforo') || wpfval($get, 'foro') ){
626 $request = ( wpfval($get, 'wpforo') ) ? wpfval($get, 'wpforo') : wpfval($get, 'foro');
627 switch( $request ){
628 case 'signup':
629 if(!is_user_logged_in()) $current_object['template'] = 'register';
630 break;
631 case 'signin':
632 if(!is_user_logged_in()) $current_object['template'] = 'login';
633 break;
634 case 'lostpassword':
635 if(!is_user_logged_in()) $current_object['template'] = 'lostpassword';
636 break;
637 case 'resetpassword':
638 $current_object['template'] = 'resetpassword';
639 break;
640 case 'page':
641 $current_object['template'] = 'page';
642 break;
643 case 'logout':
644 wp_logout();
645 wp_redirect( wpforo_home_url( preg_replace('#\?.*$#is', '', wpforo_get_request_uri()) ) );
646 exit();
647 break;
648 }
649 }
650
651 $wpf_url = preg_replace( '#^/?'.preg_quote($this->permastruct).'#isu', '' , $current_url, 1 );
652 $wpf_url = preg_replace('#/?\?.*$#isu', '', $wpf_url);
653 $wpf_url_parse = array_filter( explode('/', trim($wpf_url, '/')) );
654 $wpf_url_parse = array_reverse($wpf_url_parse);
655
656 if(in_array($this->tpl->slugs['paged'], $wpf_url_parse)){
657 foreach($wpf_url_parse as $key => $value){
658 if( $value === $this->tpl->slugs['paged']){
659 unset($wpf_url_parse[$key]);
660 break;
661 }
662 if(is_numeric($value)) $paged = intval($value);
663
664 unset($wpf_url_parse[$key]);
665 }
666 }
667 if( $_paged = intval( wpfval($get, 'wpfpaged') ) ) $paged = $_paged;
668 $current_object['paged'] = (isset($paged) && $paged > 0) ? $paged : 1;
669 $current_object['orderby'] = wpfval($get, 'orderby');
670
671 $wpf_url_parse = array_values($wpf_url_parse);
672
673 if( !wpfval($current_object, 'template') )
674 $current_object = apply_filters('wpforo_before_init_current_object', $current_object, $wpf_url_parse);
675
676 if( !wpfval($current_object, 'template') ) {
677 if(in_array($this->tpl->slugs['members'], $wpf_url_parse) && $wpf_url_parse[0] == $this->tpl->slugs['members']){
678 $current_object['template'] = 'members';
679 $current_object['items_per_page'] = $this->member->options['members_per_page'];
680
681 if( !empty($_GET['_wpfms']) ){
682 $users_include = array();
683 $search_fields_names = $this->member->get_search_fields_names(false);
684
685 $wpfms = (isset($_GET['wpfms'])) ? sanitize_text_field($_GET['wpfms']) : '';
686 if($wpfms){
687 $users_include = $this->member->search($wpfms, $search_fields_names);
688 }else{
689 if( $filters = array_filter($_GET) ){
690 $args = array();
691 foreach ($filters as $filter_key => $filter){
692 if( in_array($filter_key, (array) $search_fields_names) && !is_array($filter) ){
693 $args[$filter_key] = $filter;
694 }
695 }
696 $users_include = $this->member->filter($args);
697 }
698 }
699
700 $users_include = apply_filters('wpforo_member_search_users_include', $users_include);
701 }
702 $args = array(
703 'offset' => ($current_object['paged'] - 1) * $current_object['items_per_page'],
704 'row_count' => $current_object['items_per_page'],
705 'orderby' => 'posts',
706 'order' => 'DESC',
707 'groupids' => $this->usergroup->get_visible_usergroup_ids()
708 );
709 if(!empty($users_include)) $args['include'] = $users_include;
710 $current_object['members'] = $this->member->get_members($args, $current_object['items_count']);
711 if(isset($users_include) && empty($users_include)){ $current_object['members'] = array(); $current_object['items_count'] = 0; }
712
713 }elseif(in_array($this->tpl->slugs['recent'], $wpf_url_parse) && $wpf_url_parse[0] == $this->tpl->slugs['recent']){
714 $current_object['template'] = 'recent';
715 $current_object['items_per_page'] = $this->post->options['topics_per_page'];
716 }elseif(in_array($this->tpl->slugs['tags'], $wpf_url_parse) && $wpf_url_parse[0] == $this->tpl->slugs['tags']){
717 $current_object['template'] = 'tags';
718 $current_object['items_per_page'] = $this->post->options['tags_per_page'];
719
720 $args = array(
721 'offset' => ($current_object['paged'] - 1) * $current_object['items_per_page'],
722 'row_count' => $current_object['items_per_page']
723 );
724 $current_object['tags'] = $this->topic->get_tags($args, $current_object['items_count']);
725 }elseif(in_array($this->tpl->slugs['profile'], $wpf_url_parse)){
726 $current_object['template'] = 'profile';
727 foreach($wpf_url_parse as $value){
728 if( $value == $this->tpl->slugs['profile']) break;
729 if( $this->member->options['url_structure'] === 'id' ) $current_object['userid'] = $value; else $current_object['user_nicename'] = $value;
730 }
731 }elseif(in_array($this->tpl->slugs['account'], $wpf_url_parse)){
732 $current_object['template'] = 'account';
733 foreach($wpf_url_parse as $value){
734 if( $value == $this->tpl->slugs['account']) break;
735 if( $this->member->options['url_structure'] === 'id' ) $current_object['userid'] = $value; else $current_object['user_nicename'] = $value;
736 }
737 }elseif(in_array($this->tpl->slugs['activity'], $wpf_url_parse)){
738 $current_object['template'] = 'activity';
739 foreach($wpf_url_parse as $value){
740 if( $value == $this->tpl->slugs['activity']) break;
741 if( $this->member->options['url_structure'] === 'id' ) $current_object['userid'] = $value; else $current_object['user_nicename'] = $value;
742 }
743 }elseif(in_array($this->tpl->slugs['subscriptions'], $wpf_url_parse)){
744 $current_object['template'] = 'subscriptions';
745 foreach($wpf_url_parse as $value){
746 if( $value == $this->tpl->slugs['subscriptions']) break;
747 if( $this->member->options['url_structure'] === 'id' ) $current_object['userid'] = $value; else $current_object['user_nicename'] = $value;
748 }
749 }else{
750 $current_object['template'] = 'forum';
751 if( isset($wpf_url_parse[0]) ){
752 if( isset($wpf_url_parse[1]) ){
753 $current_object['topic_slug'] = $wpf_url_parse[0];
754 $current_object['forum_slug'] = $wpf_url_parse[1];
755 $current_object['template'] = 'post';
756 }else{
757 $current_object['forum_slug'] = $wpf_url_parse[0];
758 $current_object['template'] = 'topic';
759 }
760 }
761 }
762 }
763
764 if( in_array( $current_object['template'], array('profile', 'account', 'activity', 'subscriptions') )
765 && !isset($current_object['user_nicename']) && !isset($current_object['userid']) ){
766 $current_object['userid'] = $this->current_userid;
767 }
768
769 if( wpfval($current_object, 'userid') || wpfval($current_object, 'user_nicename') ){
770 $args = array();
771 if(isset($current_object['userid'])) $args['userid'] = $current_object['userid'];
772 if(isset($current_object['user_nicename'])) $args['user_nicename'] = $current_object['user_nicename'];
773 $selected_user = $this->member->get_member($args);
774 if(isset($current_object['userid']) && empty($selected_user)) $selected_user = $this->member->get_member(array('user_nicename' => $current_object['userid']));
775 if(!empty($selected_user)){
776 $current_object['user'] = $selected_user;
777 $current_object['userid'] = $selected_user['ID'];
778 $current_object['user_nicename'] = $selected_user['user_nicename'];
779 $current_object['user_is_same_current_user'] = !empty($this->current_userid) && $selected_user['ID'] == $this->current_userid;
780
781 switch($current_object['template']){
782 case 'activity':
783 $args = array(
784 'offset' => ($current_object['paged'] - 1) * $this->current_object['items_per_page'],
785 'row_count' => $this->current_object['items_per_page'],
786 'userid' => $current_object['userid'],
787 'orderby' => '`created` DESC, `postid` DESC',
788 'check_private' => true
789 );
790 $current_object['items_count'] = 0;
791 $current_object['activities'] = $this->post->get_posts( $args, $current_object['items_count']);
792 break;
793 case 'subscriptions':
794 $args = array(
795 'offset' => ($current_object['paged'] - 1) * $this->current_object['items_per_page'],
796 'row_count' => $this->current_object['items_per_page'],
797 'userid' => $current_object['userid'],
798 'order' => 'DESC'
799 );
800 $current_object['items_count'] = 0;
801 $current_object['subscribes'] = $this->sbscrb->get_subscribes( $args, $current_object['items_count']);
802 break;
803 }
804
805 }else{
806 $current_object['is_404'] = true;
807 }
808 }
809
810 if( wpfval($current_object, 'topic_slug') ){
811 $topic = $this->topic->get_topic(array('slug' => $current_object['topic_slug']), false);
812 if(!empty($topic)){
813
814 $topic_forumid = intval( wpfval($topic, 'forumid') );
815 $is_owner = wpforo_is_owner($topic['userid'], $topic['email']);
816
817 if( $topic_forumid && (
818 !WPF()->perm->forum_can('vf', $topic_forumid) ||
819 ( !$is_owner && !WPF()->perm->forum_can('vt', $topic_forumid) ) ||
820 ( wpfval($topic, 'private') && !$is_owner && !WPF()->perm->forum_can('vp', $topic_forumid) ) ||
821 ( wpfval($topic, 'status') && !$is_owner && !WPF()->perm->forum_can('au', $topic_forumid) )
822 ) ){
823 if( is_user_logged_in() ){
824 $current_object['is_404'] = true;
825 }else{
826 wp_redirect( wpforo_login_url() );
827 exit();
828 }
829 }else{
830 $current_object['topic'] = $topic;
831 $current_object['topicid'] = $topic['topicid'];
832 $current_object['og_text'] = (string) wpfval($topic, 'title');
833 }
834
835 }else{
836 $current_object['is_404'] = true;
837 }
838 }
839
840 if( wpfval($current_object, 'forum_slug') ){
841 $args = ( empty($topic) ? array('slug' => $current_object['forum_slug']) : $topic['forumid'] );
842 if( $forum = $this->forum->get_forum( $args ) ){
843 if( $forum['is_cat'] ) $current_object['template'] = 'forum';
844 $current_object['forum'] = $forum;
845 $current_object['forumid'] = $forum['forumid'];
846 $current_object['forum_desc'] = $forum['description'];
847 $current_object['forum_meta_key'] = $forum['meta_key'];
848 $current_object['forum_meta_desc'] = $forum['meta_desc'];
849 $current_object['og_text'] = $forum['title'];
850 $current_object['layout'] = $this->forum->get_layout( $forum );
851
852 if( $current_object['template'] == 'topic' ){
853 $current_object['items_per_page'] = $this->post->options['topics_per_page'];
854 $args = array(
855 'offset' => ($current_object['paged'] - 1) * $current_object['items_per_page'],
856 'row_count' => $current_object['items_per_page'],
857 'forumid' => $current_object['forumid'],
858 'orderby' => 'type, modified',
859 'order' => 'DESC'
860 );
861 $current_object['topics'] = $this->topic->get_topics( $args, $current_object['items_count'] );
862 }
863 }else{
864 $current_object['is_404'] = true;
865 }
866 }
867
868 if( in_array($current_object['template'], array('forum', 'topic')) ){
869 if( !empty($forum) ){
870 $current_object['categories'] = array( $forum );
871 }else{
872 $current_object['categories'] = $this->forum->get_forums( array( "type" => 'category' ) );
873 }
874 }
875
876 if ( $current_object['template'] == 'post' && ! empty( $forum ) && ! empty( $topic ) ) {
877 $current_object['items_per_page'] = $this->post->get_option_items_per_page($current_object['layout']);
878
879 $args = array(
880 'forumid' => $forum['forumid'],
881 'topicid' => $topic['topicid'],
882 'offset' => ( $current_object['paged'] - 1 ) * $current_object['items_per_page'],
883 'row_count' => $current_object['items_per_page']
884 );
885 if( $current_object['layout'] == 4 ){
886 $args['parentid'] = 0;
887 }elseif( $current_object['layout'] == 3 ){
888 $args['parentid'] = 0;
889 switch ( $current_object['orderby'] ) {
890 case 'oldest':
891 $args['orderby'] = '`is_first_post` DESC, `is_answer` DESC, `created` ASC, `postid` ASC';
892 break;
893 case 'newest':
894 $args['orderby'] = '`is_first_post` DESC, `is_answer` DESC, `modified` DESC, `postid` DESC';
895 break;
896 default:
897 $args['orderby'] = '`is_first_post` DESC, `is_answer` DESC, `votes` DESC, `created` ASC, `postid` ASC';
898 break;
899 }
900 }
901 if( $this->post->get_option_union_first_post($current_object['layout']) ) $args['union_first_post'] = true;
902 $current_object['posts'] = $this->post->get_posts( $args, $current_object['items_count']);
903 }
904
905 $this->current_object = wpforo_parse_args($current_object, $this->current_object);
906
907 $this->current_object = apply_filters('wpforo_after_init_current_object', $this->current_object, $wpf_url_parse);
908
909 if( $this->current_object['items_count']
910 && $this->current_object['paged'] > 1
911 && (($this->current_object['paged'] - 1) * $this->current_object['items_per_page']) >= $this->current_object['items_count']
912 ){
913 wp_redirect( $this->strip_url_paged_var( $this->current_url ) );
914 exit();
915 }
916 }
917
918 public function is_installed(){
919 return (bool) get_option('wpforo_version');
920 }
921
922 public function deactivate(){
923 $response = array('code' => 0);
924 $json = filter_input(INPUT_POST, 'deactivateData');
925 if ($json) {
926 parse_str($json, $data);
927
928 $blogTitle = get_option('blogname');
929 $to = 'feedback@wpforo.com';
930 $subject = '[wpForo Feedback - ' . WPFORO_VERSION . ']';
931 $headers = array();
932 $contentType = 'text/html';
933 $fromName = apply_filters('wp_mail_from_name', $blogTitle);
934 $fromName = html_entity_decode($fromName, ENT_QUOTES);
935 $siteUrl = get_site_url();
936 $parsedUrl = parse_url($siteUrl);
937 $domain = isset($parsedUrl['host']) ? $parsedUrl['host'] : '';
938 $fromEmail = 'no-reply@' . $domain;
939 $headers[] = "Content-Type: $contentType; charset=UTF-8";
940 $headers[] = "From: " . $fromName . " <" . $fromEmail . "> \r\n";
941 $message = "Dismiss and never show again";
942
943 if(isset($data['never_show']) && ($v = intval($data['never_show']))){
944 update_option('wpforo_deactivation_dialog_never_show', $v);
945 $response['code'] = 'dismiss_and_deactivate';
946 }elseif(isset($data['deactivation_reason']) && ($reason = trim($data['deactivation_reason']))){
947 $subject .= ' - ' . $reason;
948 $message = "<strong>Deactivation reason:</strong> " . $reason . "\r\n" . "<br/>";
949 if (isset($data['deactivation_reason_desc']) && ($reasonDesc = trim($data['deactivation_reason_desc']))) {
950 $message .= "<strong>Deactivation reason description:</strong> " . $reasonDesc . "\r\n" . "<br/>";
951 }
952 if (isset($data['deactivation_feedback_email']) && ($feedback_email = trim($data['deactivation_feedback_email']))) {
953 $to = 'support@wpforo.com';
954 $message .= "<strong>Feedback Email:</strong> " . $feedback_email . "\r\n" . "<br/>";
955 }
956 $subject = html_entity_decode($subject, ENT_QUOTES);
957 $message = html_entity_decode($message, ENT_QUOTES);
958 $response['code'] = 'send_and_deactivate';
959 }
960
961 wp_mail($to, $subject, $message, $headers);
962 }
963 wp_die(json_encode($response));
964 }
965 }
966
967 /**
968 * Main instance of wpForo.
969 *
970 * Returns the main instance of WPF to prevent the need to use globals.
971 *
972 * @since 1.4.3
973 * @return wpForo
974 */
975 if ( !function_exists('WPF') ){
976 function WPF() {
977 return wpForo::instance();
978 }
979 }
980
981 // Global for backwards compatibility.
982 $GLOBALS['wpforo'] = WPF();
983
984 //ADDONS/////////////////////////////////////////////////////
985 WPF()->addons = array(
986 '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/'),
987 '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/'),
988 '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/'),
989 '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/'),
990 '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/'),
991 '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/'),
992 '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/'),
993 '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/'),
994 'emoticons' => array('version' => '1.0.0', 'requires' => '1.6.3', 'class' => 'wpForoSmiles', 'title' => 'wpForo Emoticons', 'thumb' => WPFORO_URL . '/wpf-assets/addons/wpforo-emoticons/header.png', 'desc' => __('Adds awesome Sticker and Emoticons packs to editor. Allows to create new custom emoticons packs.', 'wpforo'), 'url' => 'https://gvectors.com/product/wpforo-emoticons/'),
995 );
996 $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'));}
997 /////////////////////////////////////////////////////////////
998 }