wpForo Forum - Version 1.6.5

Version Description

Download this release

Release Info

Developer Tomdever
Plugin Icon 128x128 wpForo Forum
Version 1.6.5
Comparing to
See all releases

Code changes from version 1.6.4 to 1.6.5

readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: gVectors Team
3
  Tags: forum, forums, forum plugin, WordPress forum plugin, community, discussion
4
  Requires at least: 4.1
5
  Tested up to: 5.2
6
- Stable tag: 1.6.4
7
  Requires PHP: 5.6 and higher
8
  License: GPLv2 or later
9
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
@@ -164,13 +164,17 @@ Find wpForo forum plugin addons on [gVectors Team website...](https://gvectors.c
164
 
165
  == Changelog ==
166
 
167
- = wpForo Forum 1.6.4 | 03.09.2019 =
168
 
169
- [wpForo Forum v1.6.4 Release Summary](https://wpforo.com/community/wpforo-announcements/wpforo-1-6-4-is-released/)
170
 
171
- * Fixed Bug: Spurious question marks in texts
172
- * Fixed Bug: Empty topic and reply titles
173
- * Fixed Bug: New registered users are not able to post new topics and replies if the email confirmation option is disabled.
 
 
 
 
174
 
175
  IMPORTANT NOTES for UPDATE
176
 
@@ -181,6 +185,14 @@ IMPORTANT NOTES for UPDATE
181
  - If you use CDN and found some issue please purge it.
182
 
183
 
 
 
 
 
 
 
 
 
184
 
185
  = wpForo Forum 1.6.3 | 01.09.2019 =
186
 
3
  Tags: forum, forums, forum plugin, WordPress forum plugin, community, discussion
4
  Requires at least: 4.1
5
  Tested up to: 5.2
6
+ Stable tag: 1.6.5
7
  Requires PHP: 5.6 and higher
8
  License: GPLv2 or later
9
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
164
 
165
  == Changelog ==
166
 
167
+ = wpForo Forum 1.6.5 | 15.09.2019 =
168
 
169
+ [wpForo Forum v1.6.5 Release Summary](https://wpforo.com/community/wpforo-announcements/wpforo-1-6-5-is-released/)
170
 
171
+ * Added: Filter to find inactive users in Forums > Members admin page
172
+ * Fixed Bug: Can't post new topics and replies "Empty Post" Error.
173
+ * Fixed Bug: Problems on IE 11 browser.
174
+ * Fixed Bug: Hide forums for non-permitted users in Threaded Layout
175
+ * Fixed Bug: PHP Notice: undefined variable in Settings > Members admin page
176
+ * Fixed Bug: Unconfirmed users become inactive
177
+ * Fixed Bug: Don't allow admins upload other file types in XML Phrases importer form. Security issue: Remote Code Execution (RCE) "Arbitrary File Upload".
178
 
179
  IMPORTANT NOTES for UPDATE
180
 
185
  - If you use CDN and found some issue please purge it.
186
 
187
 
188
+ = wpForo Forum 1.6.4 | 03.09.2019 =
189
+
190
+ [wpForo Forum v1.6.4 Release Summary](https://wpforo.com/community/wpforo-announcements/wpforo-1-6-4-is-released/)
191
+
192
+ * Fixed Bug: Spurious question marks in texts
193
+ * Fixed Bug: Empty topic and reply titles
194
+ * Fixed Bug: New registered users are not able to post new topics and replies if the email confirmation option is disabled.
195
+
196
 
197
  = wpForo Forum 1.6.3 | 01.09.2019 =
198
 
wpf-admin/tools-tabs/debug.php CHANGED
@@ -336,49 +336,54 @@ function wpforo_display_array_data( $array, $keys = array() ){
336
  }
337
 
338
  function wpforo_table_info( $table ){
339
- $result = WPF()->db->get_results("SHOW FULL COLUMNS FROM $table", ARRAY_A);
340
- $count = WPF()->db->get_var("SELECT COUNT(*) FROM $table");
341
- $status = WPF()->db->get_row("CHECK TABLE $table", ARRAY_A);
342
- echo '<table class="wpf-main-table-data"><tr><td>';
343
- echo '<table class="wpf-table-data wpf-tbl">';
344
- echo '<tr><td colspan="6" style="background:#999999; color: #ffffff;font-size:14px; line-height:26px"><b>' . $table . '</b> &nbsp;|&nbsp; Rows: ' . $count . ' &nbsp;|&nbsp; Status: ' . $status['Msg_text'] . '</td></tr>';
345
- foreach( $result as $info ){
346
- echo '<tr>';
347
- echo '<td>' . $info['Field'] . '</td>';
348
- echo '<td>' . $info['Type'] . '</td>';
349
- echo '<td>' . $info['Collation'] . '</td>';
350
- echo '<td>' . ( $info['Null'] == 'NO' ? '-' : 'NULL' ) . '</td>';
351
- echo '<td>' . $info['Key'] . '</td>';
352
- echo '<td>' . $info['Default'] . '</td>';
353
- echo '</tr>';
354
- }
355
- echo '</table>';
356
- echo '</td>';
357
- echo '<td>';
358
- $result = WPF()->db->get_results("SHOW INDEXES FROM $table", ARRAY_A);
 
 
359
 
360
- echo '<table class="wpf-table-data">';
361
- echo '<tr><td colspan="6" style="background:#BBBBBB; color: #ffffff;font-size:14px; line-height:26px"><b>Indexes</b></td></tr>';
362
- $indexes = array();
363
- foreach( $result as $info ){
364
- $indexes[ $info['Key_name'] ]['Key_name'] = $info['Key_name'];
365
- $indexes[ $info['Key_name'] ]['Column_name'][] = $info['Column_name'];
366
- $indexes[ $info['Key_name'] ]['Non_unique'] = $info['Non_unique'];
367
- $indexes[ $info['Key_name'] ]['Index_type'] = $info['Index_type'];
368
- }
369
- foreach( $indexes as $info ) {
370
- echo '<tr>';
371
- echo '<td>' . $info['Key_name'] . '</td>';
372
- echo '<td>' . implode( ', ', $info['Column_name'] ) . '</td>';
373
- echo '<td>' . ( $info['Non_unique'] ? '0' : 'Un' ) . '</td>';
374
- echo '<td>' . $info['Index_type'] . '</td>';
375
- echo '</tr>';
376
- }
377
- echo '</table>';
378
 
379
- echo '</td>';
380
- echo '</tr>';
381
- echo '</table>';
 
 
 
382
  }
383
 
384
  function wpforo_issues(){
336
  }
337
 
338
  function wpforo_table_info( $table ){
339
+ $_table_exists = WPF()->db->get_var("SHOW TABLES LIKE '" . esc_sql($table) ."'" );
340
+ if( $_table_exists ){
341
+ $result = WPF()->db->get_results("SHOW FULL COLUMNS FROM " . esc_sql($table), ARRAY_A);
342
+ $count = WPF()->db->get_var("SELECT COUNT(*) FROM " . esc_sql($table) );
343
+ $status = WPF()->db->get_row("CHECK TABLE " . esc_sql($table), ARRAY_A);
344
+ echo '<table class="wpf-main-table-data"><tr><td>';
345
+ echo '<table class="wpf-table-data wpf-tbl">';
346
+ echo '<tr><td colspan="6" style="background:#999999; color: #ffffff;font-size:14px; line-height:26px"><b>' . $table . '</b> &nbsp;|&nbsp; Rows: ' . $count . ' &nbsp;|&nbsp; Status: ' . $status['Msg_text'] . '</td></tr>';
347
+ foreach( $result as $info ){
348
+ echo '<tr>';
349
+ echo '<td>' . $info['Field'] . '</td>';
350
+ echo '<td>' . $info['Type'] . '</td>';
351
+ echo '<td>' . $info['Collation'] . '</td>';
352
+ echo '<td>' . ( $info['Null'] == 'NO' ? '-' : 'NULL' ) . '</td>';
353
+ echo '<td>' . $info['Key'] . '</td>';
354
+ echo '<td>' . $info['Default'] . '</td>';
355
+ echo '</tr>';
356
+ }
357
+ echo '</table>';
358
+ echo '</td>';
359
+ echo '<td>';
360
+ $result = WPF()->db->get_results("SHOW INDEXES FROM " . esc_sql($table), ARRAY_A);
361
 
362
+ echo '<table class="wpf-table-data">';
363
+ echo '<tr><td colspan="6" style="background:#BBBBBB; color: #ffffff;font-size:14px; line-height:26px"><b>Indexes</b></td></tr>';
364
+ $indexes = array();
365
+ foreach( $result as $info ){
366
+ $indexes[ $info['Key_name'] ]['Key_name'] = $info['Key_name'];
367
+ $indexes[ $info['Key_name'] ]['Column_name'][] = $info['Column_name'];
368
+ $indexes[ $info['Key_name'] ]['Non_unique'] = $info['Non_unique'];
369
+ $indexes[ $info['Key_name'] ]['Index_type'] = $info['Index_type'];
370
+ }
371
+ foreach( $indexes as $info ) {
372
+ echo '<tr>';
373
+ echo '<td>' . $info['Key_name'] . '</td>';
374
+ echo '<td>' . implode( ', ', $info['Column_name'] ) . '</td>';
375
+ echo '<td>' . ( $info['Non_unique'] ? '0' : 'Un' ) . '</td>';
376
+ echo '<td>' . $info['Index_type'] . '</td>';
377
+ echo '</tr>';
378
+ }
379
+ echo '</table>';
380
 
381
+ echo '</td>';
382
+ echo '</tr>';
383
+ echo '</table>';
384
+ }else{
385
+ echo '<h3>Table <span style="color: red;">' . $table . '</span> doesn\'t exist</h3>';
386
+ }
387
  }
388
 
389
  function wpforo_issues(){
wpf-assets/js/ajax.js CHANGED
@@ -919,8 +919,7 @@ jQuery(document).ready(function ($) {
919
  }
920
  }
921
 
922
- var event = new Event('wpforo_topic_portable_form');
923
- document.dispatchEvent(event);
924
  }
925
  })
926
  }
@@ -1245,13 +1244,7 @@ jQuery(document).ready(function ($) {
1245
  }
1246
 
1247
  wpforo_wrap.on('change input propertychange', 'form[data-textareaid] textarea', function () {
1248
- var event = new Event('wpforo_textarea_content_changed');
1249
- document.dispatchEvent(event);
1250
- });
1251
-
1252
- wpforo_wrap.on('keypress', 'form[data-textareaid] textarea', function () {
1253
- var event = new Event('wpforo_textarea_content_changed');
1254
- document.dispatchEvent(event);
1255
  });
1256
 
1257
  document.addEventListener('wpforo_tinymce_content_changed', wpforo_content_changed);
919
  }
920
  }
921
 
922
+ wpforo_trigger_custom_event(document, 'wpforo_topic_portable_form');
 
923
  }
924
  })
925
  }
1244
  }
1245
 
1246
  wpforo_wrap.on('change input propertychange', 'form[data-textareaid] textarea', function () {
1247
+ wpforo_trigger_custom_event(document,'wpforo_textarea_content_changed');
 
 
 
 
 
 
1248
  });
1249
 
1250
  document.addEventListener('wpforo_tinymce_content_changed', wpforo_content_changed);
wpf-assets/js/frontend.js CHANGED
@@ -39,6 +39,28 @@ jQuery.fn.extend({
39
  }
40
  });
41
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  function wpforo_tinymce_initializeIt(selector, do_not_focus) {
43
  tinyMCE.init({
44
  forced_root_block: "",
@@ -73,16 +95,14 @@ function wpforo_tinymce_setup(editor) {
73
  wpforo_editor.set_active(editor.id);
74
  });
75
  editor.on('Dirty ExecCommand KeyPress SetContent', function(e) {
76
- var event = new Event('wpforo_tinymce_content_changed');
77
- document.dispatchEvent(event);
78
  });
79
  editor.on('paste', function(e) {
80
  jQuery('form[data-textareaid="'+editor.id+'"]').trigger({type: 'paste', delegatedEvent: {originalEvent: {clipboardData: e.clipboardData}},originalEvent: {clipboardData: e.clipboardData}});
81
  });
82
  editor.shortcuts.add('ctrl+13', 'submit', function(){ jQuery('form[data-textareaid="'+editor.id+'"]').find('[type=submit]').click(); });
83
  editor.shortcuts.add('ctrl+s', 'Save Draft', function(){
84
- var event = new Event('wpforo_tinymce_ctrl_s');
85
- document.dispatchEvent(event);
86
  });
87
  }
88
 
@@ -382,8 +402,7 @@ jQuery(document).ready(function($){
382
  if (e.ctrlKey && e.keyCode === 13) {
383
  $('[type=submit]', $(this)).click();
384
  }else if( (e.ctrlKey && e.which === 83) || e.which === 19 ){
385
- var event = new Event('wpforo_textarea_ctrl_s');
386
- document.dispatchEvent(event);
387
  e.preventDefault();
388
  return false;
389
  }
39
  }
40
  });
41
 
42
+ /**
43
+ * Trigger an custom event.
44
+ *
45
+ * @param {Element|Document} target HTML element to dispatch the event on.
46
+ * @param {string} name Event name.
47
+ * @param [detail = null] Event addintional data information.
48
+ */
49
+ function wpforo_trigger_custom_event(target, name, detail) {
50
+ if( typeof detail === 'undefined') detail = null;
51
+
52
+ var event;
53
+ if (typeof CustomEvent === 'function') {
54
+ event = new CustomEvent(name, { bubbles: true, cancelable: true, detail: detail });
55
+ } else {
56
+ event = document.createEvent('Event');
57
+ event.initEvent(name, true, true);
58
+ event.detail = detail;
59
+ }
60
+
61
+ target.dispatchEvent( event );
62
+ }
63
+
64
  function wpforo_tinymce_initializeIt(selector, do_not_focus) {
65
  tinyMCE.init({
66
  forced_root_block: "",
95
  wpforo_editor.set_active(editor.id);
96
  });
97
  editor.on('Dirty ExecCommand KeyPress SetContent', function(e) {
98
+ wpforo_trigger_custom_event(document,'wpforo_tinymce_content_changed');
 
99
  });
100
  editor.on('paste', function(e) {
101
  jQuery('form[data-textareaid="'+editor.id+'"]').trigger({type: 'paste', delegatedEvent: {originalEvent: {clipboardData: e.clipboardData}},originalEvent: {clipboardData: e.clipboardData}});
102
  });
103
  editor.shortcuts.add('ctrl+13', 'submit', function(){ jQuery('form[data-textareaid="'+editor.id+'"]').find('[type=submit]').click(); });
104
  editor.shortcuts.add('ctrl+s', 'Save Draft', function(){
105
+ wpforo_trigger_custom_event(document,'wpforo_tinymce_ctrl_s');
 
106
  });
107
  }
108
 
402
  if (e.ctrlKey && e.keyCode === 13) {
403
  $('[type=submit]', $(this)).click();
404
  }else if( (e.ctrlKey && e.which === 83) || e.which === 19 ){
405
+ wpforo_trigger_custom_event(document, 'wpforo_textarea_ctrl_s');
 
406
  e.preventDefault();
407
  return false;
408
  }
wpf-includes/class-members.php CHANGED
@@ -64,10 +64,12 @@ class wpForoMember{
64
 
65
  private function init_hooks(){
66
  add_action('delete_user_form', array($this, 'show_delete_form'), 10, 2);
67
- //Problem with disabled "Email Confirmation" option
68
- //Not tested with other plugins registration forms
69
- //add_action('register_new_user', array($this, 'after_register_new_user'));
70
- //add_action('after_password_reset', array($this, 'after_password_reset'));
 
 
71
  }
72
 
73
  public function get_cache( $var ){
@@ -794,6 +796,10 @@ class wpForoMember{
794
  $profile_fields['status'] = $data['status'];
795
  $profile_fields_types[] = '%s';
796
  }
 
 
 
 
797
 
798
  if( !empty($profile_fields) ){
799
  $result_profile = WPF()->db->update(
@@ -1602,9 +1608,21 @@ class wpForoMember{
1602
  }
1603
  }
1604
 
1605
- public function get_count(){
1606
- return WPF()->db->get_var( "SELECT COUNT(p.`userid`) FROM `".WPF()->tables->profiles."` p
1607
- INNER JOIN `".WPF()->db->users."` u ON u.`ID` = p.`userid` WHERE p.`status` NOT LIKE 'trashed'" );
 
 
 
 
 
 
 
 
 
 
 
 
1608
  }
1609
 
1610
  public function is_online( $userid, $duration = NULL ){
@@ -1794,7 +1812,7 @@ class wpForoMember{
1794
  $user = $this->get_member( $current_user->ID );
1795
  $user_meta = get_user_meta( $current_user->ID );
1796
  $status = ( isset($user['status']) ? $user['status'] : '' );
1797
- if( $status == 'active' ){
1798
  $user['groupid'] = intval($user['groupid']);
1799
  WPF()->current_user = $user;
1800
  WPF()->current_usermeta = $user_meta;
@@ -2913,10 +2931,11 @@ class wpForoMember{
2913
  }
2914
 
2915
  public function after_register_new_user($userid){
2916
- $this->update_profile_fields( $userid, array('status' => 'inactive'), false );
 
2917
  }
2918
 
2919
  public function after_password_reset($user){
2920
- $this->update_profile_fields( $user->ID, array('status' => 'active'), false );
2921
  }
2922
  }
64
 
65
  private function init_hooks(){
66
  add_action('delete_user_form', array($this, 'show_delete_form'), 10, 2);
67
+ //Not complete | TO-DO:
68
+ //-- Button to Activate for inactive members in Dashboard > Forums > Members
69
+ //-- Some information on Inactive Member profile page, that he/she's inactive
70
+ //-- Test with Enabled Password Registration Form for UM,BP, etc...
71
+ add_action('register_new_user', array($this, 'after_register_new_user'));
72
+ add_action('after_password_reset', array($this, 'after_password_reset'));
73
  }
74
 
75
  public function get_cache( $var ){
796
  $profile_fields['status'] = $data['status'];
797
  $profile_fields_types[] = '%s';
798
  }
799
+ if( wpfkey($data, 'is_email_confirmed') ){
800
+ $profile_fields['is_email_confirmed'] = $data['is_email_confirmed'];
801
+ $profile_fields_types[] = '%d';
802
+ }
803
 
804
  if( !empty($profile_fields) ){
805
  $result_profile = WPF()->db->update(
1608
  }
1609
  }
1610
 
1611
+ public function get_count( $args = array() ){
1612
+ $sql = "SELECT SQL_NO_CACHE COUNT(*) FROM `".WPF()->tables->profiles."` p
1613
+ INNER JOIN `".WPF()->db->users."` u ON u.`ID` = p.`userid` WHERE p.`status` NOT LIKE 'trashed'";
1614
+ if( $args ){
1615
+ $wheres = array();
1616
+ foreach ($args as $key => $value){
1617
+ if( is_array($value) ){
1618
+ $wheres[] = "$key IN('" . implode("','", array_map('esc_sql', $value) ) . "')";
1619
+ }else{
1620
+ $wheres[] = "$key = '" . esc_sql($value) . "'";
1621
+ }
1622
+ }
1623
+ if($wheres) $sql .= " AND " . implode(' AND ', $wheres);
1624
+ }
1625
+ return (int) WPF()->db->get_var($sql);
1626
  }
1627
 
1628
  public function is_online( $userid, $duration = NULL ){
1812
  $user = $this->get_member( $current_user->ID );
1813
  $user_meta = get_user_meta( $current_user->ID );
1814
  $status = ( isset($user['status']) ? $user['status'] : '' );
1815
+ if( !in_array( $status, array('banned', 'trashed')) ){
1816
  $user['groupid'] = intval($user['groupid']);
1817
  WPF()->current_user = $user;
1818
  WPF()->current_usermeta = $user_meta;
2931
  }
2932
 
2933
  public function after_register_new_user($userid){
2934
+ $default_password_nag = (bool) (int) trim( get_user_meta($userid, 'default_password_nag', true) );
2935
+ if($default_password_nag) $this->update_profile_fields( $userid, array('status' => 'inactive'), false );
2936
  }
2937
 
2938
  public function after_password_reset($user){
2939
+ $this->update_profile_fields( $user->ID, array('status' => 'active', 'is_email_confirmed' => 1), false );
2940
  }
2941
  }
wpf-includes/class-notices.php CHANGED
@@ -131,7 +131,7 @@ class wpForoNotices{
131
  });
132
  </script>
133
  <?php else :
134
- echo $backend_inner;
135
  endif;
136
 
137
  $this->clear();
131
  });
132
  </script>
133
  <?php else :
134
+ echo '<div class="wpf-backend-notices-wrap">' . $backend_inner . '</div>';
135
  endif;
136
 
137
  $this->clear();
wpf-includes/class-phrases.php CHANGED
@@ -216,13 +216,19 @@ class wpForoPhrase{
216
  }
217
 
218
  $xmlfile = strtolower(sanitize_file_name($_FILES['add_lang']['name']['xml']));
219
- if( move_uploaded_file(sanitize_text_field($_FILES['add_lang']['tmp_name']['xml']), WPFORO_DIR . '/wpf-admin/xml/' . $xmlfile) ){
220
- if($langid = $this->xml_import($xmlfile) ){
221
- delete_transient( 'wpforo_get_phrases' );
222
- WPF()->notice->add('New language successfully added and changed wpforo language to new language', 'success');
223
- return $langid;
 
 
 
224
  }
225
- }
 
 
 
226
  }
227
 
228
  WPF()->notice->add('Can\'t add new language', 'error');
216
  }
217
 
218
  $xmlfile = strtolower(sanitize_file_name($_FILES['add_lang']['name']['xml']));
219
+ $ext = strtolower( pathinfo($xmlfile, PATHINFO_EXTENSION) );
220
+ if( $ext == 'xml' ){
221
+ if( move_uploaded_file(sanitize_text_field($_FILES['add_lang']['tmp_name']['xml']), WPFORO_DIR . '/wpf-admin/xml/' . $xmlfile) ){
222
+ if($langid = $this->xml_import($xmlfile) ){
223
+ delete_transient( 'wpforo_get_phrases' );
224
+ WPF()->notice->add('New language successfully added and changed wpforo language to new language', 'success');
225
+ return $langid;
226
+ }
227
  }
228
+ } else {
229
+ WPF()->notice->add('Incorrect file type', 'error');
230
+ return FALSE;
231
+ }
232
  }
233
 
234
  WPF()->notice->add('Can\'t add new language', 'error');
wpf-includes/class-revisions.php CHANGED
@@ -23,7 +23,7 @@ class wpForoRevision {
23
  private function init_defaults() {
24
  $this->default = new stdClass();
25
  $this->default->options = array(
26
- 'auto_draft_interval' => 30000,
27
  'max_drafts_per_page' => 3,
28
  'is_preview_on' => 1,
29
  'is_draft_on' => 1
@@ -98,6 +98,21 @@ class wpForoRevision {
98
 
99
  private function get_current_url_query_vars_str(){
100
  $url_query_vars_str = wpforo_get_url_query_vars_str();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  if( !$url_query_vars_str ) $url_query_vars_str = 'wpforo_home_url';
102
  return $url_query_vars_str;
103
  }
23
  private function init_defaults() {
24
  $this->default = new stdClass();
25
  $this->default->options = array(
26
+ 'auto_draft_interval' => 60000,
27
  'max_drafts_per_page' => 3,
28
  'is_preview_on' => 1,
29
  'is_draft_on' => 1
98
 
99
  private function get_current_url_query_vars_str(){
100
  $url_query_vars_str = wpforo_get_url_query_vars_str();
101
+ $url_query_vars_str = preg_replace( '#^/?'.preg_quote(WPF()->permastruct).'#isu', '' , $url_query_vars_str, 1 );
102
+ $url_query_vars_str = preg_replace('#/?\?.*$#isu', '', $url_query_vars_str);
103
+
104
+ $wpf_url_parse = array_filter( explode('/', trim($url_query_vars_str, '/')) );
105
+ $wpf_url_parse = array_reverse($wpf_url_parse);
106
+ if(in_array(WPF()->tpl->slugs['paged'], $wpf_url_parse)){
107
+ foreach($wpf_url_parse as $key => $value){
108
+ unset($wpf_url_parse[$key]);
109
+ if( $value === WPF()->tpl->slugs['paged']) break;
110
+ }
111
+ $wpf_url_parse = array_values($wpf_url_parse);
112
+ $wpf_url_parse = array_reverse($wpf_url_parse);
113
+ $url_query_vars_str = implode('/', $wpf_url_parse);
114
+ }
115
+
116
  if( !$url_query_vars_str ) $url_query_vars_str = 'wpforo_home_url';
117
  return $url_query_vars_str;
118
  }
wpf-includes/functions-installation.php CHANGED
@@ -552,10 +552,6 @@ function wpforo_activation(){
552
  }
553
  }
554
 
555
- #################################################################
556
- // Only this version (revert inactive users back)
557
- @WPF()->db->query( "UPDATE `" . WPF()->tables->profiles . "` SET `status` = 'active' WHERE `status` = 'inactive'" );
558
-
559
  #################################################################
560
  // CHECK Addon Notice /////////////////////////////////////////
561
  $lastHash = get_option('wpforo-addon-note-dismissed');
552
  }
553
  }
554
 
 
 
 
 
555
  #################################################################
556
  // CHECK Addon Notice /////////////////////////////////////////
557
  $lastHash = get_option('wpforo-addon-note-dismissed');
wpf-includes/functions.php CHANGED
@@ -318,8 +318,8 @@ function wpforo_create_form_table($varname, $primary_key, $fields = array(), $se
318
  }
319
 
320
  $items_count = 0;
321
- if( $varname == 'member' && !isset($_GET['member_status']) ){
322
- $args['status'] = array('active');
323
  }
324
 
325
  if($varname == 'ad') {
@@ -397,13 +397,16 @@ function wpforo_create_form_table($varname, $primary_key, $fields = array(), $se
397
  </ul>
398
  <?php elseif($varname == 'member' && (!isset($_GET['groupid']) || (isset($_GET['groupid']) && !$_GET['groupid'])) ): ?>
399
  <?php
400
- $total = WPF()->member->get_count();
401
- $up_total = (!isset($_GET['member_status']) || (isset($_GET['member_status']) && $_GET['member_status'] == 'active' )) ? $items_count : ($total - $items_count);
402
- $ap_total = ((isset($_GET['member_status']) && $_GET['member_status'] == 'banned' )) ? $items_count : ($total - $items_count);
 
403
  ?>
404
  <ul class="subsubsub" style="margin:-25px 0px 5px 0px;">
405
- <li><a href="<?php echo admin_url( 'admin.php' ) ?>?page=wpforo-members&member_status=active" <?php if( !isset($_GET['member_status']) || (isset($_GET['member_status']) && $_GET['member_status'] == 'active' ) ) echo 'class="current"' ?>><?php _e('Active', 'wpforo'); ?> <span class="count">(<?php echo intval($up_total); ?>)</span></a> |</li>
406
- <li><a href="<?php echo admin_url( 'admin.php' ) ?>?page=wpforo-members&member_status=banned" <?php if( (isset($_GET['member_status']) && $_GET['member_status'] == 'banned' ) ) echo 'class="current"' ?>><?php _e('Banned', 'wpforo'); ?> <span class="count">(<?php echo intval($ap_total); ?>)</span></a></li>
 
 
407
  </ul>
408
  <?php endif; ?>
409
 
@@ -639,7 +642,7 @@ function wpforo_create_form_table($varname, $primary_key, $fields = array(), $se
639
  <?php if( $act_key != ( count($actions) - 1 ) ) echo "&nbsp;|&nbsp;"; ?>
640
  <?php break;
641
  case 'ban': if($item['userid'] == WPF()->current_userid) break; ?>
642
- <?php $ban_url = wp_nonce_url( admin_url( 'admin.php?page=wpforo-' . esc_attr(sanitize_text_field($varname)) . 's&id=' . intval($item[$primary_key]) . '&action=' . ($item['status'] == 'banned' ? 'unban' : 'ban') ), 'wpforo_admin_table_action_ban' ); ?>
643
  <span class="trash"><a class="submitban" title="<?php echo ($item['status'] == 'banned' ? __('unban user', 'wpforo') : __('ban user', 'wpforo') ) ?>" onclick="return confirm('<?php echo ($item['status'] == 'banned' ? __('Are you sure, you want to unban this user?', 'wpforo') : __('Are you sure, you want to ban this user?', 'wpforo') ) ?>');" href="<?php echo esc_url($ban_url); ?>"><?php echo ($item['status'] == 'banned' ? __('unban user', 'wpforo') : __('ban user', 'wpforo') ) ?></a></span>
644
  <?php if( $act_key != ( count($actions) - 1 ) ) echo "&nbsp;|&nbsp;"; ?>
645
  <?php break;
318
  }
319
 
320
  $items_count = 0;
321
+ if( $varname === 'member' && !wpfval($_GET, 'member_status') ){
322
+ $args['status'] = array();
323
  }
324
 
325
  if($varname == 'ad') {
397
  </ul>
398
  <?php elseif($varname == 'member' && (!isset($_GET['groupid']) || (isset($_GET['groupid']) && !$_GET['groupid'])) ): ?>
399
  <?php
400
+ $all_count = WPF()->member->get_count();
401
+ $active_count = WPF()->member->get_count( array('p.status' => 'active') );
402
+ $inactive_count = WPF()->member->get_count( array('p.status' => 'inactive') );
403
+ $banned_count = WPF()->member->get_count( array('p.status' => 'banned') );
404
  ?>
405
  <ul class="subsubsub" style="margin:-25px 0px 5px 0px;">
406
+ <li><a href="<?php echo admin_url( 'admin.php' ) ?>?page=wpforo-members" <?php if( !wpfval($_GET, 'member_status') ) echo 'class="current"' ?>><?php _e('All', 'wpforo'); ?> <span class="count">(<?php echo $all_count ?>)</span></a> |</li>
407
+ <li><a href="<?php echo admin_url( 'admin.php' ) ?>?page=wpforo-members&member_status=active" <?php if( wpfval($_GET, 'member_status') === 'active' ) echo 'class="current"' ?>><?php _e('Active', 'wpforo'); ?> <span class="count">(<?php echo $active_count ?>)</span></a> |</li>
408
+ <li><a href="<?php echo admin_url( 'admin.php' ) ?>?page=wpforo-members&member_status=inactive" <?php if( wpfval($_GET, 'member_status') === 'inactive' ) echo 'class="current"' ?>><?php _e('Inactive', 'wpforo'); ?> <span class="count">(<?php echo $inactive_count ?>)</span></a> |</li>
409
+ <li><a href="<?php echo admin_url( 'admin.php' ) ?>?page=wpforo-members&member_status=banned" <?php if( wpfval($_GET, 'member_status') === 'banned' ) echo 'class="current"' ?>><?php _e('Banned', 'wpforo'); ?> <span class="count">(<?php echo $banned_count ?>)</span></a></li>
410
  </ul>
411
  <?php endif; ?>
412
 
642
  <?php if( $act_key != ( count($actions) - 1 ) ) echo "&nbsp;|&nbsp;"; ?>
643
  <?php break;
644
  case 'ban': if($item['userid'] == WPF()->current_userid) break; ?>
645
+ <?php $member_status = wpfval($_GET, 'member_status'); $ban_url = wp_nonce_url( admin_url( 'admin.php?page=wpforo-' . esc_attr(sanitize_text_field($varname)) . 's'. ($member_status ? '&member_status=' . $member_status : '') .'&id=' . intval($item[$primary_key]) . '&action=' . ($item['status'] == 'banned' ? 'unban' : 'ban') ), 'wpforo_admin_table_action_ban' ); ?>
646
  <span class="trash"><a class="submitban" title="<?php echo ($item['status'] == 'banned' ? __('unban user', 'wpforo') : __('ban user', 'wpforo') ) ?>" onclick="return confirm('<?php echo ($item['status'] == 'banned' ? __('Are you sure, you want to unban this user?', 'wpforo') : __('Are you sure, you want to ban this user?', 'wpforo') ) ?>');" href="<?php echo esc_url($ban_url); ?>"><?php echo ($item['status'] == 'banned' ? __('unban user', 'wpforo') : __('ban user', 'wpforo') ) ?></a></span>
647
  <?php if( $act_key != ( count($actions) - 1 ) ) echo "&nbsp;|&nbsp;"; ?>
648
  <?php break;
wpf-includes/wpf-actions.php CHANGED
@@ -439,8 +439,8 @@ function wpforo_actions(){
439
  }
440
 
441
  $general_options = array(
442
- 'title' => sanitize_text_field( $_POST['wpforo_general_options']['title'] ),
443
- 'description' => sanitize_text_field( $_POST['wpforo_general_options']['description'] ),
444
  'menu_position' => intval( $_POST['wpforo_general_options']['menu_position'] ),
445
  'lang' => intval( $_POST['wpforo_general_options']['lang'] )
446
  );
@@ -861,19 +861,19 @@ function wpforo_actions(){
861
 
862
  if( $u_action && !empty($uids) ){
863
 
864
- if($u_action == 'del'){
865
  $url = self_admin_url( 'users.php?action=delete&users[]=' . implode( '&users[]=', $uids ) );
866
  $url = str_replace( '&amp;', '&', wp_nonce_url( $url, 'bulk-users' ) );
867
  wp_redirect( $url );
868
  exit();
869
- }elseif($u_action == 'ban'){
870
  if( $bulk ){
871
  !check_admin_referer( 'bulk_action_member' );
872
  }else{
873
  !check_admin_referer( 'wpforo_admin_table_action_ban' );
874
  }
875
  foreach($uids as $uid) WPF()->member->ban($uid);
876
- }elseif($u_action == 'unban'){
877
  if( $bulk ){
878
  !check_admin_referer( 'bulk_action_member' );
879
  }else{
@@ -882,7 +882,9 @@ function wpforo_actions(){
882
  foreach($uids as $uid) WPF()->member->unban($uid);
883
  }
884
  wpforo_clean_cache('user');
885
- wp_redirect( admin_url( 'admin.php?page=wpforo-members' ) );
 
 
886
  exit();
887
  }
888
  }
439
  }
440
 
441
  $general_options = array(
442
+ 'title' => sanitize_text_field( stripslashes($_POST['wpforo_general_options']['title']) ),
443
+ 'description' => sanitize_text_field( stripslashes($_POST['wpforo_general_options']['description']) ),
444
  'menu_position' => intval( $_POST['wpforo_general_options']['menu_position'] ),
445
  'lang' => intval( $_POST['wpforo_general_options']['lang'] )
446
  );
861
 
862
  if( $u_action && !empty($uids) ){
863
 
864
+ if($u_action === 'del'){
865
  $url = self_admin_url( 'users.php?action=delete&users[]=' . implode( '&users[]=', $uids ) );
866
  $url = str_replace( '&amp;', '&', wp_nonce_url( $url, 'bulk-users' ) );
867
  wp_redirect( $url );
868
  exit();
869
+ }elseif($u_action === 'ban'){
870
  if( $bulk ){
871
  !check_admin_referer( 'bulk_action_member' );
872
  }else{
873
  !check_admin_referer( 'wpforo_admin_table_action_ban' );
874
  }
875
  foreach($uids as $uid) WPF()->member->ban($uid);
876
+ }elseif($u_action === 'unban'){
877
  if( $bulk ){
878
  !check_admin_referer( 'bulk_action_member' );
879
  }else{
882
  foreach($uids as $uid) WPF()->member->unban($uid);
883
  }
884
  wpforo_clean_cache('user');
885
+ $member_status = wpfval($_GET, 'member_status');
886
+ $redirect_url = admin_url( 'admin.php?page=wpforo-members' . ($member_status ? '&member_status=' . $member_status : '') );
887
+ wp_redirect( $redirect_url );
888
  exit();
889
  }
890
  }
wpf-includes/wpf-hooks.php CHANGED
@@ -1500,36 +1500,38 @@ function wpforo_userform_to_wpuser_html_form($wp_user){
1500
  </select>
1501
  </td>
1502
  </tr>
1503
- <tr class="form-field">
1504
- <th scope="row" style="padding: 10px 20px 10px 20px;">
1505
- <label><?php _e('User Reputation', 'wpforo'); ?></label>
1506
- <p class="description" style="font-weight: normal;"><?php _e('By default all members get rating badges and titles based on number of posts. However, using this option you can grant lower or higher rating to certain user (this user). The default member reputation badges, titles and points can be managed in Forums > Settings > Members Tab.', 'wpforo') ?></p>
1507
- </th>
1508
- <td style="padding: 15px 20px 10px 20px; vertical-align: top;">
1509
- <div style="padding-bottom: 10px; margin-bottom: 10px; border-bottom: 1px dashed #cccccc;">
1510
- <label><input type="radio" id="wpf-user-rating-default" name="wpforo_customrank" value="0" <?php if( !wpfval($user, 'stat', 'rank') ) echo ' checked="checked"' ?> /> <?php _e('Default Rating', 'wpforo') ?></label> &nbsp;&nbsp;
1511
- <label><input type="radio" id="wpf-user-rating-custom" name="wpforo_customrank" value="1" <?php if( wpfval($user, 'stat', 'rank') ) echo ' checked="checked"' ?> /> <?php _e('Custom Rating', 'wpforo') ?></label>
1512
- </div>
1513
-
1514
- <table id="wpf-rating-table" cellspacing="0" cellpadding="0" border="0" style="display: block; width: 100%; height: 150px; overflow-y: scroll; hidden; border: 1px solid #ccc; border-top: none; border-bottom: none; <?php if( !wpfval($user, 'stat', 'rank') ) echo 'opacity:0.5;' ?>">
1515
- <tr>
1516
- <th style="text-align: center; width: 5%;">#</th>
1517
- <th style="width: 30%"><?php _e('Rating Level', 'wpforo'); ?></th>
1518
- <th style="width: 35%"><?php _e('Rating Title', 'wpforo'); ?></th>
1519
- <th style="width: 30%;text-align:center;"><?php _e('Rating Badge', 'wpforo'); ?></th>
1520
- </tr>
1521
- <?php $levels = WPF()->member->levels(); ?>
1522
- <?php foreach( $levels as $level ): $points = WPF()->member->rating($level, 'points'); $bgx = ( $level == wpfval($user, 'stat', 'rating') ) ? 'background-color: #feff88' : ''; ?>
1523
  <tr>
1524
- <td style="text-align: center;<?php echo $bgx ?>"><input type="radio" name="wpforo_userrank" id="wpf-user-rating-<?php echo intval($points) ?>" value="<?php echo $points ?>" <?php if( $level == wpfval($user, 'stat', 'rating') ) echo 'checked="checked"' ?>></td>
1525
- <td style="<?php echo $bgx ?>"><h4><label for="wpf-user-rating-<?php echo intval($points) ?>"><?php _e('Level', 'wpforo'); ?> <?php echo esc_html($level) ?></label></h4></td>
1526
- <td style="<?php echo $bgx ?>"><?php echo WPF()->member->rating($level, 'title') ?></td>
1527
- <td style="text-align:center;<?php echo $bgx ?>"><div class="wpf-badge-full wpf-badge-level-<?php echo esc_attr($level) ?>" style="color:<?php echo WPF()->member->rating($level, 'color') ?>;"><?php echo WPF()->member->rating_badge($level, 'full'); ?></div></td>
1528
  </tr>
1529
- <?php endforeach; ?>
1530
- </table>
1531
- </td>
1532
- </tr>
 
 
 
 
 
 
 
 
 
1533
  <tr>
1534
  <td colspan="2" style="padding: 5px;"></td>
1535
  </tr>
@@ -1786,6 +1788,8 @@ add_action( 'wpforo_after_add_topic', 'wpforo_topic_auto_subscribe' );
1786
  add_action( 'wpforo_after_add_post', 'wpforo_topic_auto_subscribe' );
1787
 
1788
  function wpforo_forum_subscribers_mail_sender( $topic ){
 
 
1789
 
1790
  if( defined('IS_GO2WPFORO') && IS_GO2WPFORO ) return;
1791
 
1500
  </select>
1501
  </td>
1502
  </tr>
1503
+ <?php if( !empty( $user ) ) : ?>
1504
+ <tr class="form-field">
1505
+ <th scope="row" style="padding: 10px 20px 10px 20px;">
1506
+ <label><?php _e('User Reputation', 'wpforo'); ?></label>
1507
+ <p class="description" style="font-weight: normal;"><?php _e('By default all members get rating badges and titles based on number of posts. However, using this option you can grant lower or higher rating to certain user (this user). The default member reputation badges, titles and points can be managed in Forums > Settings > Members Tab.', 'wpforo') ?></p>
1508
+ </th>
1509
+ <td style="padding: 15px 20px 10px 20px; vertical-align: top;">
1510
+ <div style="padding-bottom: 10px; margin-bottom: 10px; border-bottom: 1px dashed #cccccc;">
1511
+ <label><input type="radio" id="wpf-user-rating-default" name="wpforo_customrank" value="0" <?php if( !wpfval($user, 'stat', 'rank') ) echo ' checked="checked"' ?> /> <?php _e('Default Rating', 'wpforo') ?></label> &nbsp;&nbsp;
1512
+ <label><input type="radio" id="wpf-user-rating-custom" name="wpforo_customrank" value="1" <?php if( wpfval($user, 'stat', 'rank') ) echo ' checked="checked"' ?> /> <?php _e('Custom Rating', 'wpforo') ?></label>
1513
+ </div>
1514
+
1515
+ <table id="wpf-rating-table" cellspacing="0" cellpadding="0" border="0" style="display: block; width: 100%; height: 150px; overflow-y: scroll; hidden; border: 1px solid #ccc; border-top: none; border-bottom: none; <?php if( !wpfval($user, 'stat', 'rank') ) echo 'opacity:0.5;' ?>">
 
 
 
 
 
 
 
1516
  <tr>
1517
+ <th style="text-align: center; width: 5%;">#</th>
1518
+ <th style="width: 30%"><?php _e('Rating Level', 'wpforo'); ?></th>
1519
+ <th style="width: 35%"><?php _e('Rating Title', 'wpforo'); ?></th>
1520
+ <th style="width: 30%;text-align:center;"><?php _e('Rating Badge', 'wpforo'); ?></th>
1521
  </tr>
1522
+ <?php $levels = WPF()->member->levels(); ?>
1523
+ <?php foreach( $levels as $level ): $points = WPF()->member->rating($level, 'points'); $bgx = ( $level == wpfval($user, 'stat', 'rating') ) ? 'background-color: #feff88' : ''; ?>
1524
+ <tr>
1525
+ <td style="text-align: center;<?php echo $bgx ?>"><input type="radio" name="wpforo_userrank" id="wpf-user-rating-<?php echo intval($points) ?>" value="<?php echo $points ?>" <?php if( $level == wpfval($user, 'stat', 'rating') ) echo 'checked="checked"' ?>></td>
1526
+ <td style="<?php echo $bgx ?>"><h4><label for="wpf-user-rating-<?php echo intval($points) ?>"><?php _e('Level', 'wpforo'); ?> <?php echo esc_html($level) ?></label></h4></td>
1527
+ <td style="<?php echo $bgx ?>"><?php echo WPF()->member->rating($level, 'title') ?></td>
1528
+ <td style="text-align:center;<?php echo $bgx ?>"><div class="wpf-badge-full wpf-badge-level-<?php echo esc_attr($level) ?>" style="color:<?php echo WPF()->member->rating($level, 'color') ?>;"><?php echo WPF()->member->rating_badge($level, 'full'); ?></div></td>
1529
+ </tr>
1530
+ <?php endforeach; ?>
1531
+ </table>
1532
+ </td>
1533
+ </tr>
1534
+ <?php endif; ?>
1535
  <tr>
1536
  <td colspan="2" style="padding: 5px;"></td>
1537
  </tr>
1788
  add_action( 'wpforo_after_add_post', 'wpforo_topic_auto_subscribe' );
1789
 
1790
  function wpforo_forum_subscribers_mail_sender( $topic ){
1791
+ if( !wpfval($topic, 'topicurl') ) $topic['topicurl'] = wpforo_topic($topic['topicid'], 'url');
1792
+ if( !wpfkey($topic, 'body') ) $topic['body'] = wpforo_post($topic['first_postid'], 'body');
1793
 
1794
  if( defined('IS_GO2WPFORO') && IS_GO2WPFORO ) return;
1795
 
wpf-themes/classic/layouts/4/forum-sub.php CHANGED
@@ -31,7 +31,7 @@ $load_more = $items_count >= WPF()->forum->options['layout_threaded_intro_topics
31
  <div class="wpf-cat-forum-list">
32
  <?php if(!empty($child_forums)): ?>
33
  <?php foreach($child_forums as $child_forumid): ?>
34
- <?php if($child_forumid == $cat['forumid']) continue; $forum = wpforo_forum( $child_forumid ); ?>
35
  <div class="wpf-forum-item <?php wpforo_unread($child_forumid, 'forum'); ?>">
36
  <span class="wpf-circle wpf-s" style="border: 1px dashed <?php echo $forum['color'] ?>; color: <?php echo $forum['color'] ?>; display: inline-flex; margin-right: 8px;">
37
  <i class="<?php echo $forum['icon'] ?>"></i>
31
  <div class="wpf-cat-forum-list">
32
  <?php if(!empty($child_forums)): ?>
33
  <?php foreach($child_forums as $child_forumid): ?>
34
+ <?php if($child_forumid == $cat['forumid'] || !WPF()->perm->forum_can('vf', $child_forumid) ) continue; $forum = wpforo_forum( $child_forumid ); ?>
35
  <div class="wpf-forum-item <?php wpforo_unread($child_forumid, 'forum'); ?>">
36
  <span class="wpf-circle wpf-s" style="border: 1px dashed <?php echo $forum['color'] ?>; color: <?php echo $forum['color'] ?>; display: inline-flex; margin-right: 8px;">
37
  <i class="<?php echo $forum['icon'] ?>"></i>
wpf-themes/classic/layouts/4/forum.php CHANGED
@@ -46,7 +46,7 @@ $load_more = $items_count >= WPF()->forum->options['layout_threaded_intro_topics
46
  <div class="wpf-cat-forum-list">
47
  <?php if(!empty($child_forums)): ?>
48
  <?php foreach($child_forums as $child_forumid): ?>
49
- <?php if($child_forumid == $cat['forumid']) continue; $forum = wpforo_forum( $child_forumid ); ?>
50
  <div class="wpf-forum-item <?php wpforo_unread($child_forumid, 'forum'); ?>">
51
  <span class="wpf-circle wpf-s" style="border: 1px dashed <?php echo $forum['color'] ?>; color: <?php echo $forum['color'] ?>; display: inline-flex;">
52
  <i class="<?php echo $forum['icon'] ?>"></i>
46
  <div class="wpf-cat-forum-list">
47
  <?php if(!empty($child_forums)): ?>
48
  <?php foreach($child_forums as $child_forumid): ?>
49
+ <?php if( $child_forumid == $cat['forumid'] || !WPF()->perm->forum_can('vf', $child_forumid) ) continue; $forum = wpforo_forum( $child_forumid ); ?>
50
  <div class="wpf-forum-item <?php wpforo_unread($child_forumid, 'forum'); ?>">
51
  <span class="wpf-circle wpf-s" style="border: 1px dashed <?php echo $forum['color'] ?>; color: <?php echo $forum['color'] ?>; display: inline-flex;">
52
  <i class="<?php echo $forum['icon'] ?>"></i>
wpforo.php CHANGED
@@ -5,14 +5,14 @@
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 (A. Chakhoyan, R. Hovhannisyan)
7
  * Author URI: https://gvectors.com/
8
- * Version: 1.6.4
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.6.4');
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' );
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 (A. Chakhoyan, R. Hovhannisyan)
7
  * Author URI: https://gvectors.com/
8
+ * Version: 1.6.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.6.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' );