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

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

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