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

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

510 lines 24.3 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.0
9 * Text Domain: wpforo
10 * Domain Path: /wpf-languages
11 */
12
13 // Exit if accessed directly
14 if( !defined( 'ABSPATH' ) ) exit;
15 if( !defined( 'WPFORO_VERSION' ) ) define('WPFORO_VERSION', '1.4.0');
16
17 function wpforo_load_plugin_textdomain() { load_plugin_textdomain( 'wpforo', FALSE, basename( dirname( __FILE__ ) ) . '/wpf-languages/' ); }
18 add_action( 'plugins_loaded', 'wpforo_load_plugin_textdomain' );
19
20 if( !class_exists( 'wpForo' ) ) {
21
22 define('WPFORO_DIR', rtrim( plugin_dir_path( __FILE__ ), '/' ));
23 define('WPFORO_URL', rtrim( plugins_url( '', __FILE__ ), '/' ));
24 define('WPFORO_FOLDER', rtrim( plugin_basename(dirname(__FILE__)), '/'));
25 define('WPFORO_BASENAME', plugin_basename(__FILE__)); //wpforo/wpforo.php
26
27 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 'author-link' => 0,
101 'comment-author-link' => 0,
102 'user-register' => 1,
103 'user-register-email-confirm' => 0,
104 'register-url' => 0,
105 'login-url' => 0,
106 'replace-avatar' => 1,
107 'avatars' => 1,
108 'custom-avatars' => 1,
109 'signature' => 1,
110 'rating' => 1,
111 'rating_title' => 1,
112 'member_cashe' => 1,
113 'object_cashe' => 1,
114 'html_cashe' => 0,
115 'memory_cashe' => 1,
116 'seo-title' => 1,
117 'seo-meta' => 1,
118 'seo-profile' => 1,
119 'font-awesome' => 1,
120 'user-synch' => 0,
121 'output-buffer' => 1,
122 'wp-date-format' => 0,
123 'subscribe_conf' => 1,
124 'subscribe_checkbox_on_post_editor' => 1,
125 'subscribe_checkbox_default_status' => 0,
126 'attach-media-lib' => 1,
127 'debug-mode' => 0,
128 'copyright' => 1
129 );
130
131 $this->default->tools_antispam = array(
132 'spam_filter' => 1,
133 'spam_filter_level_topic' => mt_rand(30, 60),
134 'spam_filter_level_post' => mt_rand(30, 60),
135 'spam_user_ban' => 0,
136 'new_user_max_posts' => 5,
137 'spam_user_ban_notification' => 1,
138 'min_number_post_to_attach' => 3,
139 'min_number_post_to_link' => 0,
140 'limited_file_ext' => 'pdf|doc|docx|txt|htm|html|rtf|xml|xls|xlsx|zip|rar|tar|gz|bzip|7z'
141 );
142
143 $this->default->tools_cleanup = array(
144 'user_reg_days_ago' => 7,
145 'auto_cleanup_users' => 0,
146 'usergroup' => array ( 1 => '0', 5 => '0', 2 => '1', 3 => '0' )
147 );
148
149 $this->default->stats = array(
150 'forums' => 0,
151 'topics' => 0,
152 'posts' => 0,
153 'members' => 0,
154 'online_members_count' => 0,
155 'last_post_title' => '',
156 'last_post_url' => '',
157 'newest_member_dname' => '',
158 'newest_member_profile_url' => ''
159 );
160 }
161
162 private function init_options(){
163 global $wpdb;
164 $this->db = $wpdb;
165 $this->file = __FILE__;
166 $this->error = NULL;
167 $this->basename = plugin_basename( $this->file );
168
169 $permalink_structure = get_option('permalink_structure');
170
171 $this->use_trailing_slashes = ( '/' == substr($permalink_structure, -1, 1) );
172
173 //OPTIONS
174 $this->use_home_url = get_wpf_option('wpforo_use_home_url', $this->default->use_home_url);
175 $this->excld_urls = get_wpf_option('wpforo_excld_urls', $this->default->excld_urls);
176
177 $this->permastruct = trim( get_wpf_option('wpforo_permastruct', $this->default->permastruct), '/' );
178 $this->permastruct = preg_replace('#^/?index\.php/?#isu', '', $this->permastruct);
179 $this->permastruct = trim($this->permastruct, '/');
180
181 $this->base_permastruct = (!$this->use_home_url ? $this->permastruct : '');
182 $this->base_permastruct = rtrim( ( strpos($permalink_structure, 'index.php') !== FALSE ? '/index.php/' . $this->base_permastruct : '/' . $this->base_permastruct ), '/\\' );
183 $this->url = esc_url( home_url( $this->user_trailingslashit($this->base_permastruct) ) );
184 $this->pageid = get_wpf_option( 'wpforo_pageid');
185
186 $this->general_options = get_wpf_option( 'wpforo_general_options', $this->default->general_options);
187 $this->features = get_wpf_option('wpforo_features', $this->default->features);
188 $this->tools_antispam = get_wpf_option('wpforo_tools_antispam', $this->default->tools_antispam);
189 $this->tools_cleanup = get_wpf_option('wpforo_tools_cleanup', $this->default->tools_cleanup);
190
191 //CONSTANTS
192 define('WPFORO_BASE_PERMASTRUCT', $this->base_permastruct );
193 define('WPFORO_BASE_URL', $this->url );
194 }
195
196 private function setup(){
197 if( wpforo_is_admin() ){
198 register_activation_hook($this->basename, 'do_wpforo_activation');
199 if( !wpforo_feature('user-synch') && get_option('wpforo_version') ){
200 $users = $this->db->get_var("SELECT COUNT(*) FROM `" . $this->db->prefix . "users`");
201 $profiles = $this->db->get_var("SELECT COUNT(*) FROM `" . $this->db->prefix . "wpforo_profiles`");
202 $delta = $users - $profiles;
203 if( $users > 100 && $delta > 2 ){ add_action( 'admin_notices', 'wpforo_profile_notice' ); }
204 }
205 register_deactivation_hook($this->basename, 'do_wpforo_deactivation');
206 }
207 }
208
209 public function user_trailingslashit($url) {
210 $rtrimed_url = '';
211 $url_append_vars = '';
212 if( preg_match('#(^.+?)(/?\?.*$|$)#isu', $url, $match) ){
213 if(isset($match[1]) && $match[1]) $rtrimed_url = rtrim($match[1], '/\\');
214 if(isset($match[2]) && $match[2]) $url_append_vars = trim($match[2], '/\\');
215 if( $rtrimed_url ) {
216 $home_url = rtrim( preg_replace('#/?\?.*$#isu', '', home_url()), '/\\' );
217 if( $rtrimed_url == $home_url ){
218 $url = $rtrimed_url . '/';
219 }else{
220 $url = ( $this->use_trailing_slashes ? $rtrimed_url . '/' : $rtrimed_url );
221 }
222 }
223 }
224 return $url . $url_append_vars;
225 }
226
227 public function statistic( $mode = 'get', $template = 'all' ){
228
229 if( $mode == 'get' ){
230 if( $cached_stat = get_option('wpforo_stat') ) return $cached_stat;
231 }
232
233 if( $mode == 'get' || $template == 'all' ) {
234 $stats['forums'] = $this->forum->get_count();
235 $stats['topics'] = $this->topic->get_count();
236 $stats['posts'] = $this->post->get_count();
237 $stats['members'] = $this->member->get_count();
238 $stats['online_members_count'] = $this->member->online_members_count();
239
240 $posts = $this->topic->get_topics(array('orderby' => 'modified', 'order' => 'DESC', 'row_count' => 1));
241 if ( isset($posts[0]) && !empty($posts[0]) && $this->perm->forum_can('vf', $posts[0]['forumid']) ) {
242 $stats['last_post_title'] = $posts[0]['title'];
243 $stats['last_post_url'] = $this->post->get_post_url($posts[0]['last_post']);
244 }
245
246 $members = $this->member->get_members(array('orderby' => 'userid', 'order' => 'DESC', 'row_count' => 1));
247 if (isset($members[0]) && !empty($members[0])) {
248 $stats['newest_member_dname'] = $members[0]['display_name'] ? $members[0]['display_name'] : urldecode($members[0]['user_nicename']);
249 $stats['newest_member_profile_url'] = $this->member->get_profile_url($members[0]['ID']);
250 }
251 }else{
252 $stats = get_wpf_option('wpforo_stat', $this->default->stats);
253 switch ($template){
254 case 'forum':
255 $stats['forums'] = $this->forum->get_count();
256 break;
257 case 'topic':
258 $stats['topics'] = $this->topic->get_count();
259 $posts = $this->topic->get_topics(array('orderby' => 'modified', 'order' => 'DESC', 'row_count' => 1));
260 if ( isset($posts[0]) && !empty($posts[0]) && $this->perm->forum_can('vf', $posts[0]['forumid']) ) {
261 $stats['last_post_title'] = $posts[0]['title'];
262 $stats['last_post_url'] = $this->post->get_post_url($posts[0]['last_post']);
263 }
264 break;
265 case 'post':
266 $stats['posts'] = $this->post->get_count();
267 $posts = $this->topic->get_topics(array('orderby' => 'modified', 'order' => 'DESC', 'row_count' => 1));
268 if ( isset($posts[0]) && !empty($posts[0]) && $this->perm->forum_can('vf', $posts[0]['forumid']) ) {
269 $stats['last_post_title'] = $posts[0]['title'];
270 $stats['last_post_url'] = $this->post->get_post_url($posts[0]['last_post']);
271 }
272 break;
273 case 'user':
274 $stats['members'] = $this->member->get_count();
275 $stats['online_members_count'] = $this->member->online_members_count();
276
277 $members = $this->member->get_members(array('orderby' => 'userid', 'order' => 'DESC', 'row_count' => 1));
278 if (isset($members[0]) && !empty($members[0])) {
279 $stats['newest_member_dname'] = $members[0]['display_name'] ? $members[0]['display_name'] : urldecode($members[0]['user_nicename']);
280 $stats['newest_member_profile_url'] = $this->member->get_profile_url($members[0]['ID']);
281 }
282 break;
283 }
284 }
285
286 $stats = array_merge($this->default->stats, $stats);
287 $stats = apply_filters('wpforo_get_statistic_array_filter', $stats);
288 update_option( 'wpforo_stat', $stats );
289 return $stats;
290 }
291
292 public function init_current_object($url = ''){
293 $this->current_object = array('template' => '', 'paged' => 1, 'is_404' => false, 'user_is_same_current_user' => false);
294 if(!$url) $url = wpforo_get_request_uri();
295
296 if( !is_wpforo_page($url) ) return;
297
298 $current_url = wpforo_get_url_query_vars_str($url);
299
300 if( $this->use_home_url ) $this->permastruct = '';
301
302 $current_object = array();
303 $current_object['template'] = '';
304 $current_object['is_404'] = false;
305 $current_object['user_is_same_current_user'] = false;
306
307 if(isset($_GET['wpfs'])) $current_object['template'] = 'search';
308 if( isset($_GET['wpforo']) ){
309 switch($_GET['wpforo']){
310 case 'signup':
311 if(!is_user_logged_in()) $current_object['template'] = 'register';
312 break;
313 case 'signin':
314 if(!is_user_logged_in()) $current_object['template'] = 'login';
315 break;
316 case 'lostpassword':
317 if(!is_user_logged_in()) $current_object['template'] = 'lostpassword';
318 break;
319 case 'resetpassword':
320 $current_object['template'] = 'resetpassword';
321 break;
322 case 'logout':
323 wp_logout();
324 wp_redirect( wpforo_home_url( preg_replace('#\?.*$#is', '', wpforo_get_request_uri()) ) );
325 exit();
326 break;
327 }
328 }
329
330 $wpf_url = preg_replace( '#^/?'.preg_quote($this->permastruct).'#isu', '' , $current_url, 1 );
331 $wpf_url = preg_replace('#/?\?.*$#isu', '', $wpf_url);
332 $wpf_url_parse = array_filter( explode('/', trim($wpf_url, '/')) );
333 $wpf_url_parse = array_reverse($wpf_url_parse);
334
335 if(in_array('paged', $wpf_url_parse)){
336 foreach($wpf_url_parse as $key => $value){
337 if( $value == 'paged'){
338 unset($wpf_url_parse[$key]);
339 break;
340 }
341 if(is_numeric($value)) $paged = intval($value);
342
343 unset($wpf_url_parse[$key]);
344 }
345 }
346 if(isset($_GET['wpfpaged']) && intval($_GET['wpfpaged'])) $paged = intval($_GET['wpfpaged']);
347 $current_object['paged'] = (isset($paged) && $paged) ? $paged : 1;
348
349 $wpf_url_parse = array_values($wpf_url_parse);
350
351 if( !isset($current_object['template']) || !$current_object['template'] )
352 $current_object = apply_filters('wpforo_before_init_current_object', $current_object, $wpf_url_parse);
353
354 if( !isset($current_object['template']) || !$current_object['template'] ) {
355 if(in_array('members', $wpf_url_parse) && $wpf_url_parse[0] == 'members'){
356 $current_object['template'] = 'members';
357 }elseif(in_array('profile', $wpf_url_parse)){
358 $current_object['template'] = 'profile';
359 foreach($wpf_url_parse as $value){
360 if( $value == 'profile') break;
361 if(is_numeric($value)) $current_object['userid'] = $value; else $current_object['username'] = $value;
362 }
363 }elseif(in_array('account', $wpf_url_parse)){
364 $current_object['template'] = 'account';
365 foreach($wpf_url_parse as $value){
366 if( $value == 'account') break;
367 if(is_numeric($value)) $current_object['userid'] = $value; else $current_object['username'] = $value;
368 }
369 }elseif(in_array('activity', $wpf_url_parse)){
370 $current_object['template'] = 'activity';
371 foreach($wpf_url_parse as $value){
372 if( $value == 'activity') break;
373 if(is_numeric($value)) $current_object['userid'] = $value; else $current_object['username'] = $value;
374 }
375 }elseif(in_array('subscriptions', $wpf_url_parse)){
376 $current_object['template'] = 'subscriptions';
377 foreach($wpf_url_parse as $value){
378 if( $value == 'subscriptions') break;
379 if(is_numeric($value)) $current_object['userid'] = $value; else $current_object['username'] = $value;
380 }
381 }else{
382 $current_object['template'] = 'forum';
383 if( isset($wpf_url_parse[0]) ){
384 if( isset($wpf_url_parse[1]) ){
385 $current_object['topic_slug'] = $wpf_url_parse[0];
386 $current_object['forum_slug'] = $wpf_url_parse[1];
387 $current_object['template'] = 'post';
388 }else{
389 $current_object['forum_slug'] = $wpf_url_parse[0];
390 $current_object['template'] = 'topic';
391 }
392 }
393 }
394 }
395
396 if( isset($current_object['userid']) || isset($current_object['username']) ){
397 $args = array();
398 if(isset($current_object['userid'])) $args['userid'] = $current_object['userid'];
399 if(isset($current_object['username'])) $args['username'] = $current_object['username'];
400 $selected_user = $this->member->get_member($args);
401 if(isset($current_object['userid']) && empty($selected_user)) $selected_user = $this->member->get_member(array('username' => $current_object['userid']));
402 if(!empty($selected_user)){
403 $current_object['user'] = $selected_user;
404 $current_object['userid'] = $selected_user['ID'];
405 $current_object['username'] = $selected_user['user_nicename'];
406 $current_object['user_is_same_current_user'] = !empty($this->current_userid) && $selected_user['ID'] == $this->current_userid;
407
408 switch($current_object['template']){
409 case 'activity':
410 $args = array(
411 'offset' => ($current_object['paged'] - 1) * $this->post->options['posts_per_page'],
412 'row_count' => $this->post->options['posts_per_page'],
413 'userid' => $current_object['userid'],
414 'order' => 'DESC',
415 'check_private' => true
416 );
417 $current_object['items_count'] = 0;
418 $current_object['activities'] = $this->post->get_posts( $args, $current_object['items_count']);
419 break;
420 case 'subscriptions':
421 $args = array(
422 'offset' => ($current_object['paged'] - 1) * $this->post->options['posts_per_page'],
423 'row_count' => $this->post->options['posts_per_page'],
424 'userid' => $current_object['userid'],
425 'order' => 'DESC'
426 );
427 $current_object['items_count'] = 0;
428 $current_object['subscribes'] = $this->sbscrb->get_subscribes( $args, $current_object['items_count']);
429 break;
430 }
431
432 }else{
433 $current_object['is_404'] = true;
434 $current_object['user'] = array();
435 $current_object['userid'] = 0;
436 $current_object['username'] = '';
437 }
438 }
439
440 if(isset($current_object['forum_slug']) && $current_object['forum_slug']){
441 $forum = $this->forum->get_forum(array('slug' => $current_object['forum_slug']), TRUE);
442 if(!empty($forum)){
443 $current_object['forum'] = $forum;
444 $current_object['forumid'] = $forum['forumid'];
445 $current_object['forum_desc'] = $forum['description'];
446 $current_object['forum_meta_key'] = $forum['meta_key'];
447 $current_object['forum_meta_desc'] = $forum['meta_desc'];
448 }else{
449 $current_object['is_404'] = true;
450 $current_object['forum'] = array();
451 $current_object['forumid'] = 0;
452 $current_object['forum_desc'] = '';
453 $current_object['forum_meta_key'] = '';
454 $current_object['forum_meta_desc'] = '';
455 }
456 }
457
458 if(isset($current_object['topic_slug']) && $current_object['topic_slug']){
459 $topic = $this->topic->get_topic(array('slug' => $current_object['topic_slug']));
460 if(!empty($topic)){
461 $current_object['topic'] = $topic;
462 $current_object['topicid'] = $topic['topicid'];
463 }elseif( $this->current_object['status'] == 'unapproved' && !is_user_logged_in() ){
464 wp_redirect( wpforo_login_url() );
465 exit();
466 }else{
467 $current_object['is_404'] = true;
468 $current_object['topic'] = array();
469 $current_object['topicid'] = 0;
470 }
471 }
472
473 $this->current_object = apply_filters('wpforo_after_init_current_object', $current_object, $wpf_url_parse);
474 }
475
476 public function is_installed(){
477 return (bool) get_option('wpforo_version');
478 }
479 }
480
481 $wpforo = new wpForo();
482 $wpforo->cache = new wpForoCache( $wpforo );
483 $wpforo->phrase = new wpForoPhrase( $wpforo );
484 $wpforo->forum = new wpForoForum( $wpforo );
485 $wpforo->topic = new wpForoTopic( $wpforo );
486 $wpforo->post = new wpForoPost( $wpforo );
487 $wpforo->usergroup = new wpForoUsergroup( $wpforo );
488 $wpforo->member = new wpForoMember( $wpforo );
489 $wpforo->perm = new wpForoPermissions( $wpforo );
490 $wpforo->sbscrb = new wpForoSubscribe( $wpforo );
491 $wpforo->tpl = new wpForoTemplate( $wpforo );
492 $wpforo->notice = new wpForoNotices();
493 $wpforo->feed = new wpForoFeed( $wpforo );
494 $wpforo->moderation = new wpForoModeration( $wpforo );
495 if(wpforo_is_admin()) include( WPFORO_DIR .'/wpf-admin/admin.php' );
496 $GLOBALS['wpforo'] = $wpforo;
497 add_action('init', array($wpforo, 'init'));
498
499 //ADDONS/////////////////////////////////////////////////////
500 $wpforo->addons = array(
501 '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/'),
502 '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/'),
503 '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/'),
504 '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/'),
505 '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/'),
506 '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/'),
507 );
508 $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'));}
509 /////////////////////////////////////////////////////////////
510 }