PluginProbe
wpForo Forum / 1.7.5
wpForo Forum v1.7.5
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.5, at wpforo.php

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