PluginProbe
wpForo Forum / 1.4.1
wpForo Forum v1.4.1
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.1, at wpforo.php

513 lines 24.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 * Plugin Name: Forum - 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.1
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.1');
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' => 1,
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 register_deactivation_hook($this->basename, 'do_wpforo_deactivation');
209 }
210 }
211
212 public function user_trailingslashit($url) {
213 $rtrimed_url = '';
214 $url_append_vars = '';
215 if( preg_match('#(^.+?)(/?\?.*$|$)#isu', $url, $match) ){
216 if(isset($match[1]) && $match[1]) $rtrimed_url = rtrim($match[1], '/\\');
217 if(isset($match[2]) && $match[2]) $url_append_vars = trim($match[2], '/\\');
218 if( $rtrimed_url ) {
219 $home_url = rtrim( preg_replace('#/?\?.*$#isu', '', home_url()), '/\\' );
220 if( $rtrimed_url == $home_url ){
221 $url = $rtrimed_url . '/';
222 }else{
223 $url = ( $this->use_trailing_slashes ? $rtrimed_url . '/' : $rtrimed_url );
224 }
225 }
226 }
227 return $url . $url_append_vars;
228 }
229
230 public function statistic( $mode = 'get', $template = 'all' ){
231
232 if( $mode == 'get' ){
233 if( $cached_stat = get_option('wpforo_stat') ) return $cached_stat;
234 }
235
236 if( $mode == 'get' || $template == 'all' ) {
237 $stats['forums'] = $this->forum->get_count();
238 $stats['topics'] = $this->topic->get_count();
239 $stats['posts'] = $this->post->get_count();
240 $stats['members'] = $this->member->get_count();
241 $stats['online_members_count'] = $this->member->online_members_count();
242
243 $posts = $this->topic->get_topics(array('orderby' => 'modified', 'order' => 'DESC', 'row_count' => 1));
244 if ( isset($posts[0]) && !empty($posts[0]) && $this->perm->forum_can('vf', $posts[0]['forumid']) ) {
245 $stats['last_post_title'] = $posts[0]['title'];
246 $stats['last_post_url'] = $this->post->get_post_url($posts[0]['last_post']);
247 }
248
249 $members = $this->member->get_members(array('orderby' => 'userid', 'order' => 'DESC', 'row_count' => 1));
250 if (isset($members[0]) && !empty($members[0])) {
251 $stats['newest_member_dname'] = $members[0]['display_name'] ? $members[0]['display_name'] : urldecode($members[0]['user_nicename']);
252 $stats['newest_member_profile_url'] = $this->member->get_profile_url($members[0]['ID']);
253 }
254 }else{
255 $stats = get_wpf_option('wpforo_stat', $this->default->stats);
256 switch ($template){
257 case 'forum':
258 $stats['forums'] = $this->forum->get_count();
259 break;
260 case 'topic':
261 $stats['topics'] = $this->topic->get_count();
262 $posts = $this->topic->get_topics(array('orderby' => 'modified', 'order' => 'DESC', 'row_count' => 1));
263 if ( isset($posts[0]) && !empty($posts[0]) && $this->perm->forum_can('vf', $posts[0]['forumid']) ) {
264 $stats['last_post_title'] = $posts[0]['title'];
265 $stats['last_post_url'] = $this->post->get_post_url($posts[0]['last_post']);
266 }
267 break;
268 case 'post':
269 $stats['posts'] = $this->post->get_count();
270 $posts = $this->topic->get_topics(array('orderby' => 'modified', 'order' => 'DESC', 'row_count' => 1));
271 if ( isset($posts[0]) && !empty($posts[0]) && $this->perm->forum_can('vf', $posts[0]['forumid']) ) {
272 $stats['last_post_title'] = $posts[0]['title'];
273 $stats['last_post_url'] = $this->post->get_post_url($posts[0]['last_post']);
274 }
275 break;
276 case 'user':
277 $stats['members'] = $this->member->get_count();
278 $stats['online_members_count'] = $this->member->online_members_count();
279
280 $members = $this->member->get_members(array('orderby' => 'userid', 'order' => 'DESC', 'row_count' => 1));
281 if (isset($members[0]) && !empty($members[0])) {
282 $stats['newest_member_dname'] = $members[0]['display_name'] ? $members[0]['display_name'] : urldecode($members[0]['user_nicename']);
283 $stats['newest_member_profile_url'] = $this->member->get_profile_url($members[0]['ID']);
284 }
285 break;
286 }
287 }
288
289 $stats = array_merge($this->default->stats, $stats);
290 $stats = apply_filters('wpforo_get_statistic_array_filter', $stats);
291 update_option( 'wpforo_stat', $stats );
292 return $stats;
293 }
294
295 public function init_current_object($url = ''){
296 $this->current_object = array('template' => '', 'paged' => 1, 'is_404' => false, 'user_is_same_current_user' => false);
297 if(!$url) $url = wpforo_get_request_uri();
298
299 if( !is_wpforo_page($url) ) return;
300
301 $current_url = wpforo_get_url_query_vars_str($url);
302
303 if( $this->use_home_url ) $this->permastruct = '';
304
305 $current_object = array();
306 $current_object['template'] = '';
307 $current_object['is_404'] = false;
308 $current_object['user_is_same_current_user'] = false;
309
310 if(isset($_GET['wpfs'])) $current_object['template'] = 'search';
311 if( isset($_GET['wpforo']) ){
312 switch($_GET['wpforo']){
313 case 'signup':
314 if(!is_user_logged_in()) $current_object['template'] = 'register';
315 break;
316 case 'signin':
317 if(!is_user_logged_in()) $current_object['template'] = 'login';
318 break;
319 case 'lostpassword':
320 if(!is_user_logged_in()) $current_object['template'] = 'lostpassword';
321 break;
322 case 'resetpassword':
323 $current_object['template'] = 'resetpassword';
324 break;
325 case 'logout':
326 wp_logout();
327 wp_redirect( wpforo_home_url( preg_replace('#\?.*$#is', '', wpforo_get_request_uri()) ) );
328 exit();
329 break;
330 }
331 }
332
333 $wpf_url = preg_replace( '#^/?'.preg_quote($this->permastruct).'#isu', '' , $current_url, 1 );
334 $wpf_url = preg_replace('#/?\?.*$#isu', '', $wpf_url);
335 $wpf_url_parse = array_filter( explode('/', trim($wpf_url, '/')) );
336 $wpf_url_parse = array_reverse($wpf_url_parse);
337
338 if(in_array('paged', $wpf_url_parse)){
339 foreach($wpf_url_parse as $key => $value){
340 if( $value == 'paged'){
341 unset($wpf_url_parse[$key]);
342 break;
343 }
344 if(is_numeric($value)) $paged = intval($value);
345
346 unset($wpf_url_parse[$key]);
347 }
348 }
349 if(isset($_GET['wpfpaged']) && intval($_GET['wpfpaged'])) $paged = intval($_GET['wpfpaged']);
350 $current_object['paged'] = (isset($paged) && $paged) ? $paged : 1;
351
352 $wpf_url_parse = array_values($wpf_url_parse);
353
354 if( !isset($current_object['template']) || !$current_object['template'] )
355 $current_object = apply_filters('wpforo_before_init_current_object', $current_object, $wpf_url_parse);
356
357 if( !isset($current_object['template']) || !$current_object['template'] ) {
358 if(in_array('members', $wpf_url_parse) && $wpf_url_parse[0] == 'members'){
359 $current_object['template'] = 'members';
360 }elseif(in_array('profile', $wpf_url_parse)){
361 $current_object['template'] = 'profile';
362 foreach($wpf_url_parse as $value){
363 if( $value == 'profile') break;
364 if(is_numeric($value)) $current_object['userid'] = $value; else $current_object['username'] = $value;
365 }
366 }elseif(in_array('account', $wpf_url_parse)){
367 $current_object['template'] = 'account';
368 foreach($wpf_url_parse as $value){
369 if( $value == 'account') break;
370 if(is_numeric($value)) $current_object['userid'] = $value; else $current_object['username'] = $value;
371 }
372 }elseif(in_array('activity', $wpf_url_parse)){
373 $current_object['template'] = 'activity';
374 foreach($wpf_url_parse as $value){
375 if( $value == 'activity') break;
376 if(is_numeric($value)) $current_object['userid'] = $value; else $current_object['username'] = $value;
377 }
378 }elseif(in_array('subscriptions', $wpf_url_parse)){
379 $current_object['template'] = 'subscriptions';
380 foreach($wpf_url_parse as $value){
381 if( $value == 'subscriptions') break;
382 if(is_numeric($value)) $current_object['userid'] = $value; else $current_object['username'] = $value;
383 }
384 }else{
385 $current_object['template'] = 'forum';
386 if( isset($wpf_url_parse[0]) ){
387 if( isset($wpf_url_parse[1]) ){
388 $current_object['topic_slug'] = $wpf_url_parse[0];
389 $current_object['forum_slug'] = $wpf_url_parse[1];
390 $current_object['template'] = 'post';
391 }else{
392 $current_object['forum_slug'] = $wpf_url_parse[0];
393 $current_object['template'] = 'topic';
394 }
395 }
396 }
397 }
398
399 if( isset($current_object['userid']) || isset($current_object['username']) ){
400 $args = array();
401 if(isset($current_object['userid'])) $args['userid'] = $current_object['userid'];
402 if(isset($current_object['username'])) $args['username'] = $current_object['username'];
403 $selected_user = $this->member->get_member($args);
404 if(isset($current_object['userid']) && empty($selected_user)) $selected_user = $this->member->get_member(array('username' => $current_object['userid']));
405 if(!empty($selected_user)){
406 $current_object['user'] = $selected_user;
407 $current_object['userid'] = $selected_user['ID'];
408 $current_object['username'] = $selected_user['user_nicename'];
409 $current_object['user_is_same_current_user'] = !empty($this->current_userid) && $selected_user['ID'] == $this->current_userid;
410
411 switch($current_object['template']){
412 case 'activity':
413 $args = array(
414 'offset' => ($current_object['paged'] - 1) * $this->post->options['posts_per_page'],
415 'row_count' => $this->post->options['posts_per_page'],
416 'userid' => $current_object['userid'],
417 'order' => 'DESC',
418 'check_private' => true
419 );
420 $current_object['items_count'] = 0;
421 $current_object['activities'] = $this->post->get_posts( $args, $current_object['items_count']);
422 break;
423 case 'subscriptions':
424 $args = array(
425 'offset' => ($current_object['paged'] - 1) * $this->post->options['posts_per_page'],
426 'row_count' => $this->post->options['posts_per_page'],
427 'userid' => $current_object['userid'],
428 'order' => 'DESC'
429 );
430 $current_object['items_count'] = 0;
431 $current_object['subscribes'] = $this->sbscrb->get_subscribes( $args, $current_object['items_count']);
432 break;
433 }
434
435 }else{
436 $current_object['is_404'] = true;
437 $current_object['user'] = array();
438 $current_object['userid'] = 0;
439 $current_object['username'] = '';
440 }
441 }
442
443 if(isset($current_object['forum_slug']) && $current_object['forum_slug']){
444 $forum = $this->forum->get_forum(array('slug' => $current_object['forum_slug']), TRUE);
445 if(!empty($forum)){
446 $current_object['forum'] = $forum;
447 $current_object['forumid'] = $forum['forumid'];
448 $current_object['forum_desc'] = $forum['description'];
449 $current_object['forum_meta_key'] = $forum['meta_key'];
450 $current_object['forum_meta_desc'] = $forum['meta_desc'];
451 }else{
452 $current_object['is_404'] = true;
453 $current_object['forum'] = array();
454 $current_object['forumid'] = 0;
455 $current_object['forum_desc'] = '';
456 $current_object['forum_meta_key'] = '';
457 $current_object['forum_meta_desc'] = '';
458 }
459 }
460
461 if(isset($current_object['topic_slug']) && $current_object['topic_slug']){
462 $topic = $this->topic->get_topic(array('slug' => $current_object['topic_slug']));
463 if(!empty($topic)){
464 $current_object['topic'] = $topic;
465 $current_object['topicid'] = $topic['topicid'];
466 }elseif( $this->current_object['status'] == 'unapproved' && !is_user_logged_in() ){
467 wp_redirect( wpforo_login_url() );
468 exit();
469 }else{
470 $current_object['is_404'] = true;
471 $current_object['topic'] = array();
472 $current_object['topicid'] = 0;
473 }
474 }
475
476 $this->current_object = apply_filters('wpforo_after_init_current_object', $current_object, $wpf_url_parse);
477 }
478
479 public function is_installed(){
480 return (bool) get_option('wpforo_version');
481 }
482 }
483
484 $wpforo = new wpForo();
485 $wpforo->cache = new wpForoCache( $wpforo );
486 $wpforo->phrase = new wpForoPhrase( $wpforo );
487 $wpforo->forum = new wpForoForum( $wpforo );
488 $wpforo->topic = new wpForoTopic( $wpforo );
489 $wpforo->post = new wpForoPost( $wpforo );
490 $wpforo->usergroup = new wpForoUsergroup( $wpforo );
491 $wpforo->member = new wpForoMember( $wpforo );
492 $wpforo->perm = new wpForoPermissions( $wpforo );
493 $wpforo->sbscrb = new wpForoSubscribe( $wpforo );
494 $wpforo->tpl = new wpForoTemplate( $wpforo );
495 $wpforo->notice = new wpForoNotices();
496 $wpforo->feed = new wpForoFeed( $wpforo );
497 $wpforo->moderation = new wpForoModeration( $wpforo );
498 if(wpforo_is_admin()) include( WPFORO_DIR .'/wpf-admin/admin.php' );
499 $GLOBALS['wpforo'] = $wpforo;
500 add_action('init', array($wpforo, 'init'));
501
502 //ADDONS/////////////////////////////////////////////////////
503 $wpforo->addons = array(
504 '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/'),
505 '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/'),
506 '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/'),
507 '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/'),
508 '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/'),
509 '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/'),
510 );
511 $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'));}
512 /////////////////////////////////////////////////////////////
513 }