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

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

519 lines 24.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 * Plugin Name: Forums - wpForo
4 * Plugin URI: https://wpforo.com
5 * Description: Forums wpForo is a new generation of forum plugins. It's full-fledged forum solution for your community. Comes with multiple modern forum layouts.
6 * Author: gVectors Team (A. Chakhoyan, R. Hovhannisyan)
7 * Author URI: https://gvectors.com/
8 * Version: 1.4.2
9 * Text Domain: wpforo
10 * Domain Path: /wpf-languages
11 */
12
13 //Exit if accessed directly
14 if( !defined( 'ABSPATH' ) ) exit;
15 if( !defined( 'WPFORO_VERSION' ) ) define('WPFORO_VERSION', '1.4.2');
16
17 function wpforo_load_plugin_textdomain() { load_plugin_textdomain( 'wpforo', FALSE, basename( dirname( __FILE__ ) ) . '/wpf-languages/' ); }
18 add_action( 'plugins_loaded', 'wpforo_load_plugin_textdomain' );
19
20 if( !class_exists( 'wpForo' ) ) {
21
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 include( WPFORO_DIR . '/wpf-includes/wpf-hooks.php' );
28 include( WPFORO_DIR . '/wpf-includes/wpf-actions.php');
29 include( WPFORO_DIR . '/wpf-includes/functions.php' );
30 if(wpforo_is_admin()) {
31 include( WPFORO_DIR . '/wpf-includes/functions-installation.php' );
32 }
33 include( WPFORO_DIR . '/wpf-includes/functions-integration.php' );
34 include( WPFORO_DIR . '/wpf-includes/functions-template.php' );
35 include( WPFORO_DIR . '/wpf-includes/class-cache.php' );
36 include( WPFORO_DIR . '/wpf-includes/class-forums.php' );
37 include( WPFORO_DIR . '/wpf-includes/class-topics.php' );
38 include( WPFORO_DIR . '/wpf-includes/class-posts.php' );
39 include( WPFORO_DIR . '/wpf-includes/class-usergroups.php' );
40 include( WPFORO_DIR . '/wpf-includes/class-members.php' );
41 include( WPFORO_DIR . '/wpf-includes/class-permissions.php' );
42 include( WPFORO_DIR . '/wpf-includes/class-phrases.php');
43 include( WPFORO_DIR . '/wpf-includes/class-subscribes.php' );
44 include( WPFORO_DIR . '/wpf-includes/class-template.php' );
45 include( WPFORO_DIR . '/wpf-includes/class-notices.php' );
46 include( WPFORO_DIR . '/wpf-includes/class-feed.php' );
47 include( WPFORO_DIR . '/wpf-includes/class-moderation.php' );
48
49 class wpForo{
50
51 public $options = array();
52 public $db;
53 public $phrases;
54 public $access;
55 public $usergroup;
56 public $theme;
57 public $addons = array();
58 public $current_object;
59 public $menu = array();
60 public $form = array();
61 public $default;
62
63 public function __construct(){
64 $this->init_defaults();
65 $this->init_options();
66 $this->setup();
67 }
68
69 public function init(){
70 $this->cache->init();
71 $this->member->init_current_user();
72 $this->init_current_object();
73 $this->moderation->init();
74 $this->tpl->init_member_templates();
75 $this->tpl->init_nav_menu();
76 add_action( 'wp_loaded', 'wpforo_actions');
77 }
78
79 private function init_defaults(){
80 $this->default = new stdClass;
81
82 $this->default->use_home_url = 0;
83 $this->default->excld_urls = '';
84 $this->default->permastruct = 'community';
85
86 $blogname = get_option('blogname', '');
87 $this->default->general_options = array(
88 'title' => $blogname . ' ' . __('Forum', 'wpforo'),
89 'description' => $blogname . ' ' . __('Discussion Board', 'wpforo'),
90 'lang' => 1
91 );
92
93 $this->default->features = array(
94 'user-admin-bar' => 0,
95 'page-title' => 1,
96 'top-bar' => 1,
97 'top-bar-search' => 1,
98 'breadcrumb' => 1,
99 'footer-stat' => 1,
100 'view-logging' => 1,
101 'author-link' => 0,
102 'comment-author-link' => 0,
103 'user-register' => 1,
104 'user-register-email-confirm' => 0,
105 'register-url' => 0,
106 'login-url' => 0,
107 'resetpass-url' => 0, //In most cases incompatible with security and antispam plugins
108 'replace-avatar' => 1,
109 'avatars' => 1,
110 'custom-avatars' => 1,
111 'signature' => 1,
112 'rating' => 1,
113 'rating_title' => 1,
114 'member_cashe' => 1,
115 'object_cashe' => 1,
116 'html_cashe' => 0,
117 'memory_cashe' => 1,
118 'seo-title' => 1,
119 'seo-meta' => 1,
120 'seo-profile' => 1,
121 'rss-feed' => 1,
122 'font-awesome' => 1,
123 'user-synch' => 0,
124 'output-buffer' => 1,
125 'wp-date-format' => 0,
126 'subscribe_conf' => 1,
127 'subscribe_checkbox_on_post_editor' => 1,
128 'subscribe_checkbox_default_status' => 0,
129 'attach-media-lib' => 1,
130 'debug-mode' => 0,
131 'copyright' => 1
132 );
133
134 $this->default->tools_antispam = array(
135 'spam_filter' => 1,
136 'spam_filter_level_topic' => mt_rand(30, 60),
137 'spam_filter_level_post' => mt_rand(30, 60),
138 'spam_user_ban' => 0,
139 'new_user_max_posts' => 5,
140 'spam_user_ban_notification' => 1,
141 'min_number_post_to_attach' => 3,
142 'min_number_post_to_link' => 0,
143 'limited_file_ext' => 'pdf|doc|docx|txt|htm|html|rtf|xml|xls|xlsx|zip|rar|tar|gz|bzip|7z'
144 );
145
146 $this->default->tools_cleanup = array(
147 'user_reg_days_ago' => 7,
148 'auto_cleanup_users' => 0,
149 'usergroup' => array ( 1 => '0', 5 => '0', 2 => '1', 3 => '0' )
150 );
151
152 $this->default->stats = array(
153 'forums' => 0,
154 'topics' => 0,
155 'posts' => 0,
156 'members' => 0,
157 'online_members_count' => 0,
158 'last_post_title' => '',
159 'last_post_url' => '',
160 'newest_member_dname' => '',
161 'newest_member_profile_url' => ''
162 );
163 }
164
165 private function init_options(){
166 global $wpdb;
167 $this->db = $wpdb;
168 $this->file = __FILE__;
169 $this->error = NULL;
170 $this->basename = plugin_basename( $this->file );
171
172 $permalink_structure = get_option('permalink_structure');
173
174 $this->use_trailing_slashes = ( '/' == substr($permalink_structure, -1, 1) );
175
176 //OPTIONS
177 $this->use_home_url = get_wpf_option('wpforo_use_home_url', $this->default->use_home_url);
178 $this->excld_urls = get_wpf_option('wpforo_excld_urls', $this->default->excld_urls);
179
180 $this->permastruct = trim( get_wpf_option('wpforo_permastruct', $this->default->permastruct), '/' );
181 $this->permastruct = preg_replace('#^/?index\.php/?#isu', '', $this->permastruct);
182 $this->permastruct = trim($this->permastruct, '/');
183
184 $this->base_permastruct = (!$this->use_home_url ? $this->permastruct : '');
185 $this->base_permastruct = rtrim( ( strpos($permalink_structure, 'index.php') !== FALSE ? '/index.php/' . $this->base_permastruct : '/' . $this->base_permastruct ), '/\\' );
186 $this->url = esc_url( home_url( $this->user_trailingslashit($this->base_permastruct) ) );
187 $this->pageid = get_wpf_option( 'wpforo_pageid');
188
189 $this->general_options = get_wpf_option( 'wpforo_general_options', $this->default->general_options);
190 $this->features = get_wpf_option('wpforo_features', $this->default->features);
191 $this->tools_antispam = get_wpf_option('wpforo_tools_antispam', $this->default->tools_antispam);
192 $this->tools_cleanup = get_wpf_option('wpforo_tools_cleanup', $this->default->tools_cleanup);
193
194 //CONSTANTS
195 define('WPFORO_BASE_PERMASTRUCT', $this->base_permastruct );
196 define('WPFORO_BASE_URL', $this->url );
197 }
198
199 private function setup(){
200 if( wpforo_is_admin() ){
201 register_activation_hook($this->basename, 'do_wpforo_activation');
202 if( !wpforo_feature('user-synch') && get_option('wpforo_version') ){
203 $users = $this->db->get_var("SELECT COUNT(*) FROM `" . $this->db->prefix . "users`");
204 $profiles = $this->db->get_var("SELECT COUNT(*) FROM `" . $this->db->prefix . "wpforo_profiles`");
205 $delta = $users - $profiles;
206 if( $users > 100 && $delta > 2 ){ add_action( 'admin_notices', 'wpforo_profile_notice' ); }
207 }
208 $db_version = get_option('wpforo_version_db');
209 if( !$db_version || version_compare( $db_version, WPFORO_VERSION, '<') ){
210 add_action( 'admin_notices', 'wpforo_update_db_notice' );
211 }
212 register_deactivation_hook($this->basename, 'do_wpforo_deactivation');
213 }
214 }
215
216 public function user_trailingslashit($url) {
217 $rtrimed_url = '';
218 $url_append_vars = '';
219 if( preg_match('#(^.+?)(/?\?.*$|$)#isu', $url, $match) ){
220 if(isset($match[1]) && $match[1]) $rtrimed_url = rtrim($match[1], '/\\');
221 if(isset($match[2]) && $match[2]) $url_append_vars = trim($match[2], '/\\');
222 if( $rtrimed_url ) {
223 $home_url = rtrim( preg_replace('#/?\?.*$#isu', '', home_url()), '/\\' );
224 if( $rtrimed_url == $home_url ){
225 $url = $rtrimed_url . '/';
226 }else{
227 $url = ( $this->use_trailing_slashes ? $rtrimed_url . '/' : $rtrimed_url );
228 }
229 }
230 }
231 return $url . $url_append_vars;
232 }
233
234 public function statistic( $mode = 'get', $template = 'all' ){
235
236 if( $mode == 'get' ){
237 if( $cached_stat = get_option('wpforo_stat') ) return $cached_stat;
238 }
239
240 if( $mode == 'get' || $template == 'all' ) {
241 $stats['forums'] = $this->forum->get_count();
242 $stats['topics'] = $this->topic->get_count();
243 $stats['posts'] = $this->post->get_count();
244 $stats['members'] = $this->member->get_count();
245 $stats['online_members_count'] = $this->member->online_members_count();
246
247 $posts = $this->topic->get_topics(array('orderby' => 'modified', 'order' => 'DESC', 'row_count' => 1));
248 if ( isset($posts[0]) && !empty($posts[0]) && $this->perm->forum_can('vf', $posts[0]['forumid']) ) {
249 $stats['last_post_title'] = $posts[0]['title'];
250 $stats['last_post_url'] = $this->post->get_post_url($posts[0]['last_post']);
251 }
252
253 $members = $this->member->get_members(array('orderby' => 'userid', 'order' => 'DESC', 'row_count' => 1));
254 if (isset($members[0]) && !empty($members[0])) {
255 $stats['newest_member_dname'] = $members[0]['display_name'] ? $members[0]['display_name'] : urldecode($members[0]['user_nicename']);
256 $stats['newest_member_profile_url'] = $this->member->get_profile_url($members[0]['ID']);
257 }
258 }else{
259 $stats = get_wpf_option('wpforo_stat', $this->default->stats);
260 switch ($template){
261 case 'forum':
262 $stats['forums'] = $this->forum->get_count();
263 break;
264 case 'topic':
265 $stats['topics'] = $this->topic->get_count();
266 $posts = $this->topic->get_topics(array('orderby' => 'modified', 'order' => 'DESC', 'row_count' => 1));
267 if ( isset($posts[0]) && !empty($posts[0]) && $this->perm->forum_can('vf', $posts[0]['forumid']) ) {
268 $stats['last_post_title'] = $posts[0]['title'];
269 $stats['last_post_url'] = $this->post->get_post_url($posts[0]['last_post']);
270 }
271 break;
272 case 'post':
273 $stats['posts'] = $this->post->get_count();
274 $posts = $this->topic->get_topics(array('orderby' => 'modified', 'order' => 'DESC', 'row_count' => 1));
275 if ( isset($posts[0]) && !empty($posts[0]) && $this->perm->forum_can('vf', $posts[0]['forumid']) ) {
276 $stats['last_post_title'] = $posts[0]['title'];
277 $stats['last_post_url'] = $this->post->get_post_url($posts[0]['last_post']);
278 }
279 break;
280 case 'user':
281 $stats['members'] = $this->member->get_count();
282 $stats['online_members_count'] = $this->member->online_members_count();
283
284 $members = $this->member->get_members(array('orderby' => 'userid', 'order' => 'DESC', 'row_count' => 1));
285 if (isset($members[0]) && !empty($members[0])) {
286 $stats['newest_member_dname'] = $members[0]['display_name'] ? $members[0]['display_name'] : urldecode($members[0]['user_nicename']);
287 $stats['newest_member_profile_url'] = $this->member->get_profile_url($members[0]['ID']);
288 }
289 break;
290 }
291 }
292
293 $stats = array_merge($this->default->stats, $stats);
294 $stats = apply_filters('wpforo_get_statistic_array_filter', $stats);
295 update_option( 'wpforo_stat', $stats );
296 return $stats;
297 }
298
299 public function init_current_object($url = ''){
300 $this->current_object = array('template' => '', 'paged' => 1, 'is_404' => false, 'user_is_same_current_user' => false);
301 if(!$url) $url = wpforo_get_request_uri();
302
303 if( !is_wpforo_page($url) ) return;
304
305 $current_url = wpforo_get_url_query_vars_str($url);
306
307 if( $this->use_home_url ) $this->permastruct = '';
308
309 $current_object = array();
310 $current_object['template'] = '';
311 $current_object['is_404'] = false;
312 $current_object['user_is_same_current_user'] = false;
313
314 if(isset($_GET['wpfs'])) $current_object['template'] = 'search';
315 if( isset($_GET['wpforo']) ){
316 switch($_GET['wpforo']){
317 case 'signup':
318 if(!is_user_logged_in()) $current_object['template'] = 'register';
319 break;
320 case 'signin':
321 if(!is_user_logged_in()) $current_object['template'] = 'login';
322 break;
323 case 'lostpassword':
324 if(!is_user_logged_in()) $current_object['template'] = 'lostpassword';
325 break;
326 case 'resetpassword':
327 $current_object['template'] = 'resetpassword';
328 break;
329 case 'logout':
330 wp_logout();
331 wp_redirect( wpforo_home_url( preg_replace('#\?.*$#is', '', wpforo_get_request_uri()) ) );
332 exit();
333 break;
334 }
335 }
336
337 $wpf_url = preg_replace( '#^/?'.preg_quote($this->permastruct).'#isu', '' , $current_url, 1 );
338 $wpf_url = preg_replace('#/?\?.*$#isu', '', $wpf_url);
339 $wpf_url_parse = array_filter( explode('/', trim($wpf_url, '/')) );
340 $wpf_url_parse = array_reverse($wpf_url_parse);
341
342 if(in_array('paged', $wpf_url_parse)){
343 foreach($wpf_url_parse as $key => $value){
344 if( $value == 'paged'){
345 unset($wpf_url_parse[$key]);
346 break;
347 }
348 if(is_numeric($value)) $paged = intval($value);
349
350 unset($wpf_url_parse[$key]);
351 }
352 }
353 if(isset($_GET['wpfpaged']) && intval($_GET['wpfpaged'])) $paged = intval($_GET['wpfpaged']);
354 $current_object['paged'] = (isset($paged) && $paged) ? $paged : 1;
355
356 $wpf_url_parse = array_values($wpf_url_parse);
357
358 if( !isset($current_object['template']) || !$current_object['template'] )
359 $current_object = apply_filters('wpforo_before_init_current_object', $current_object, $wpf_url_parse);
360
361 if( !isset($current_object['template']) || !$current_object['template'] ) {
362 if(in_array('members', $wpf_url_parse) && $wpf_url_parse[0] == 'members'){
363 $current_object['template'] = 'members';
364 }elseif(in_array('recent', $wpf_url_parse) && $wpf_url_parse[0] == 'recent'){
365 $current_object['template'] = 'recent';
366 }elseif(in_array('profile', $wpf_url_parse)){
367 $current_object['template'] = 'profile';
368 foreach($wpf_url_parse as $value){
369 if( $value == 'profile') break;
370 if(is_numeric($value)) $current_object['userid'] = $value; else $current_object['username'] = $value;
371 }
372 }elseif(in_array('account', $wpf_url_parse)){
373 $current_object['template'] = 'account';
374 foreach($wpf_url_parse as $value){
375 if( $value == 'account') break;
376 if(is_numeric($value)) $current_object['userid'] = $value; else $current_object['username'] = $value;
377 }
378 }elseif(in_array('activity', $wpf_url_parse)){
379 $current_object['template'] = 'activity';
380 foreach($wpf_url_parse as $value){
381 if( $value == 'activity') break;
382 if(is_numeric($value)) $current_object['userid'] = $value; else $current_object['username'] = $value;
383 }
384 }elseif(in_array('subscriptions', $wpf_url_parse)){
385 $current_object['template'] = 'subscriptions';
386 foreach($wpf_url_parse as $value){
387 if( $value == 'subscriptions') break;
388 if(is_numeric($value)) $current_object['userid'] = $value; else $current_object['username'] = $value;
389 }
390 }else{
391 $current_object['template'] = 'forum';
392 if( isset($wpf_url_parse[0]) ){
393 if( isset($wpf_url_parse[1]) ){
394 $current_object['topic_slug'] = $wpf_url_parse[0];
395 $current_object['forum_slug'] = $wpf_url_parse[1];
396 $current_object['template'] = 'post';
397 }else{
398 $current_object['forum_slug'] = $wpf_url_parse[0];
399 $current_object['template'] = 'topic';
400 }
401 }
402 }
403 }
404
405 if( isset($current_object['userid']) || isset($current_object['username']) ){
406 $args = array();
407 if(isset($current_object['userid'])) $args['userid'] = $current_object['userid'];
408 if(isset($current_object['username'])) $args['username'] = $current_object['username'];
409 $selected_user = $this->member->get_member($args);
410 if(isset($current_object['userid']) && empty($selected_user)) $selected_user = $this->member->get_member(array('username' => $current_object['userid']));
411 if(!empty($selected_user)){
412 $current_object['user'] = $selected_user;
413 $current_object['userid'] = $selected_user['ID'];
414 $current_object['username'] = $selected_user['user_nicename'];
415 $current_object['user_is_same_current_user'] = !empty($this->current_userid) && $selected_user['ID'] == $this->current_userid;
416
417 switch($current_object['template']){
418 case 'activity':
419 $args = array(
420 'offset' => ($current_object['paged'] - 1) * $this->post->options['posts_per_page'],
421 'row_count' => $this->post->options['posts_per_page'],
422 'userid' => $current_object['userid'],
423 'order' => 'DESC',
424 'check_private' => true
425 );
426 $current_object['items_count'] = 0;
427 $current_object['activities'] = $this->post->get_posts( $args, $current_object['items_count']);
428 break;
429 case 'subscriptions':
430 $args = array(
431 'offset' => ($current_object['paged'] - 1) * $this->post->options['posts_per_page'],
432 'row_count' => $this->post->options['posts_per_page'],
433 'userid' => $current_object['userid'],
434 'order' => 'DESC'
435 );
436 $current_object['items_count'] = 0;
437 $current_object['subscribes'] = $this->sbscrb->get_subscribes( $args, $current_object['items_count']);
438 break;
439 }
440
441 }else{
442 $current_object['is_404'] = true;
443 $current_object['user'] = array();
444 $current_object['userid'] = 0;
445 $current_object['username'] = '';
446 }
447 }
448
449 if(isset($current_object['forum_slug']) && $current_object['forum_slug']){
450 $forum = $this->forum->get_forum(array('slug' => $current_object['forum_slug']), TRUE);
451 if(!empty($forum)){
452 $current_object['forum'] = $forum;
453 $current_object['forumid'] = $forum['forumid'];
454 $current_object['forum_desc'] = $forum['description'];
455 $current_object['forum_meta_key'] = $forum['meta_key'];
456 $current_object['forum_meta_desc'] = $forum['meta_desc'];
457 }else{
458 $current_object['is_404'] = true;
459 $current_object['forum'] = array();
460 $current_object['forumid'] = 0;
461 $current_object['forum_desc'] = '';
462 $current_object['forum_meta_key'] = '';
463 $current_object['forum_meta_desc'] = '';
464 }
465 }
466
467 if(isset($current_object['topic_slug']) && $current_object['topic_slug']){
468 $topic = $this->topic->get_topic(array('slug' => $current_object['topic_slug']));
469 if(!empty($topic)){
470 $current_object['topic'] = $topic;
471 $current_object['topicid'] = $topic['topicid'];
472 }elseif( $this->current_object['status'] == 'unapproved' && !is_user_logged_in() ){
473 wp_redirect( wpforo_login_url() );
474 exit();
475 }else{
476 $current_object['is_404'] = true;
477 $current_object['topic'] = array();
478 $current_object['topicid'] = 0;
479 }
480 }
481
482 $this->current_object = apply_filters('wpforo_after_init_current_object', $current_object, $wpf_url_parse);
483 }
484
485 public function is_installed(){
486 return (bool) get_option('wpforo_version');
487 }
488 }
489
490 $wpforo = new wpForo();
491 $wpforo->cache = new wpForoCache( $wpforo );
492 $wpforo->phrase = new wpForoPhrase( $wpforo );
493 $wpforo->forum = new wpForoForum( $wpforo );
494 $wpforo->topic = new wpForoTopic( $wpforo );
495 $wpforo->post = new wpForoPost( $wpforo );
496 $wpforo->usergroup = new wpForoUsergroup( $wpforo );
497 $wpforo->member = new wpForoMember( $wpforo );
498 $wpforo->perm = new wpForoPermissions( $wpforo );
499 $wpforo->sbscrb = new wpForoSubscribe( $wpforo );
500 $wpforo->tpl = new wpForoTemplate( $wpforo );
501 $wpforo->notice = new wpForoNotices();
502 $wpforo->feed = new wpForoFeed( $wpforo );
503 $wpforo->moderation = new wpForoModeration( $wpforo );
504 if(wpforo_is_admin()) include( WPFORO_DIR .'/wpf-admin/admin.php' );
505 $GLOBALS['wpforo'] = $wpforo;
506 add_action('init', array($wpforo, 'init'));
507
508 //ADDONS/////////////////////////////////////////////////////
509 $wpforo->addons = array(
510 'embeds' => array('version' => '1.0.4', 'requires' => '1.4.0', 'class' => 'wpForoEmbeds', 'title' => 'Embeds', 'thumb' => WPFORO_URL . '/wpf-assets/addons/' . 'embeds' . '/header.png', 'desc' => __('Allows to embed hundreds of video, social network, audio and photo content providers in forum topics and posts.', 'wpforo'), 'url' => 'https://gvectors.com/product/wpforo-embeds/'),
511 'ucf' => array('version' => '1.0.0', 'requires' => '1.4.0', 'class' => 'WpforoUcf', 'title' => 'User Custom Fields', 'thumb' => WPFORO_URL . '/wpf-assets/addons/' . 'ucf' . '/header.png', 'desc' => __('Advanced user profile builder system. Allows to add new fields and manage profile page. Creates custom Registration, Account, Member Search forms.', 'wpforo'), 'url' => 'https://gvectors.com/product/wpforo-user-custom-fields/'),
512 'attachments' => array('version' => '1.1.2', 'requires' => '1.4.0', 'class' => 'wpForoAttachments', 'title' => 'Advanced Attachments', 'thumb' => WPFORO_URL . '/wpf-assets/addons/' . 'attachments' . '/header.png', 'desc' => __('Adds an advanced file attachment system to forum topics and posts. AJAX powered media uploading and displaying system with user specific library.', 'wpforo'), 'url' => 'https://gvectors.com/product/wpforo-advanced-attachments/'),
513 'cross' => array('version' => '1.0.3', 'requires' => '1.4.0', 'class' => 'wpForoCrossPosting', 'title' => '"Forum - Blog" Cross Posting', 'thumb' => WPFORO_URL . '/wpf-assets/addons/' . 'cross' . '/header.png', 'desc' => __('Blog to Forum and Forum to Blog content synchronization. Blog posts with Forum topics and Blog comments with Forum replies.', 'wpforo'), 'url' => 'https://gvectors.com/product/wpforo-cross-posting/'),
514 'pm' => array('version' => '1.0.3', 'requires' => '1.4.0', 'class' => 'wpForoPMs', 'title' => 'Private Messages', 'thumb' => WPFORO_URL . '/wpf-assets/addons/' . 'pm' . '/header.png', 'desc' => __('Provides a safe way to communicate directly with other members. Messages are private and can only be viewed by conversation participants.', 'wpforo'), 'url' => 'https://gvectors.com/product/wpforo-private-messages/'),
515 'ad-manager' => array('version' => '1.0.0', 'requires' => '1.4.0', 'class' => 'wpForoAD', 'title' => 'Ads Manager', 'thumb' => WPFORO_URL . '/wpf-assets/addons/' . 'ad-manager' . '/header.png', 'desc' => __('Ads Manager is a powerful yet simple advertisement management system, that allows you to add adverting banners between forums, topics and posts.', 'wpforo'), 'url' => 'https://gvectors.com/product/wpforo-ad-manager/'),
516 );
517 $wp_version = get_bloginfo('version'); if (version_compare($wp_version, '4.2.0', '>=')) { add_action('wp_ajax_dismiss_wpforo_addon_note', array($wpforo->notice, 'dismissAddonNote')); add_action('admin_notices', array($wpforo->notice, 'addonNote'));}
518 /////////////////////////////////////////////////////////////
519 }