PluginProbe
wpForo Forum / 1.9.2
wpForo Forum v1.9.2
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.9.2, at wpforo.php

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