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

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

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