PluginProbe
wpForo Forum / 2.1.0
wpForo Forum v2.1.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 / classes / API.php

API.php in wpForo Forum 2.1.0, at classes/API.php

975 lines 40.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace wpforo\classes;
4
5 use WP_Error;
6
7 // Exit if accessed directly
8 if( ! defined( 'ABSPATH' ) ) exit;
9
10 class API {
11 const FB_SDK_VERSION = 'v14.0';
12 public $locale = 'en_US';
13 public $locale_iso = 'en';
14 public $fb_local = [
15 'af_ZA',
16 'ar_AR',
17 'az_AZ',
18 'be_BY',
19 'bg_BG',
20 'bn_IN',
21 'bs_BA',
22 'ca_ES',
23 'cs_CZ',
24 'cy_GB',
25 'da_DK',
26 'de_DE',
27 'el_GR',
28 'en_US',
29 'en_GB',
30 'eo_EO',
31 'es_ES',
32 'es_LA',
33 'et_EE',
34 'eu_ES',
35 'fa_IR',
36 'fb_LT',
37 'fi_FI',
38 'fo_FO',
39 'fr_FR',
40 'fr_CA',
41 'fy_NL',
42 'ga_IE',
43 'gl_ES',
44 'he_IL',
45 'hi_IN',
46 'hr_HR',
47 'hu_HU',
48 'hy_AM',
49 'id_ID',
50 'is_IS',
51 'it_IT',
52 'ja_JP',
53 'ka_GE',
54 'km_KH',
55 'ko_KR',
56 'ku_TR',
57 'la_VA',
58 'lt_LT',
59 'lv_LV',
60 'mk_MK',
61 'ml_IN',
62 'ms_MY',
63 'nb_NO',
64 'ne_NP',
65 'nl_NL',
66 'nn_NO',
67 'pa_IN',
68 'pl_PL',
69 'ps_AF',
70 'pt_PT',
71 'pt_BR',
72 'ro_RO',
73 'ru_RU',
74 'sk_SK',
75 'sl_SI',
76 'sq_AL',
77 'sr_RS',
78 'sv_SE',
79 'sw_KE',
80 'ta_IN',
81 'te_IN',
82 'th_TH',
83 'tl_PH',
84 'tr_TR',
85 'uk_UA',
86 'vi_VN',
87 'zh_CN',
88 'zh_HK',
89 'zh_TW',
90 ];
91 public $tw_local = [
92 'en',
93 'ar',
94 'bn',
95 'cs',
96 'da',
97 'de',
98 'el',
99 'es',
100 'fa',
101 'fi',
102 'fil',
103 'fr',
104 'he',
105 'hi',
106 'hu',
107 'id',
108 'it',
109 'ja',
110 'ko',
111 'msa',
112 'nl',
113 'no',
114 'pl',
115 'pt',
116 'ro',
117 'ru',
118 'sv',
119 'th',
120 'tr',
121 'uk',
122 'ur',
123 'vi',
124 'zh-cn',
125 'zh-tw',
126 ];
127 public $ok_local = [ "ru", "en", "uk", "hy", "mo", "ro", "kk", "uz", "az", "tr" ];
128
129 public function __construct() {
130 add_action( 'wpforo_after_init', function() {
131 if( ! is_admin() ) {
132 $this->init_wp_recaptcha();
133 $this->hooks();
134 }
135 } );
136 }
137
138 private function hooks() {
139 $template = WPF()->current_object['template'];
140
141 ###############################################################################
142 ############### Facebook & Twitter API ########################################
143 ###############################################################################
144
145 if( ! is_user_logged_in() ) {
146 if( wpforo_setting( 'authorization', 'fb_login' ) ) {
147 if( in_array( $template, ['login','register'], true ) ) {
148 add_action( 'wp_enqueue_scripts', [ $this, 'fb_enqueue' ] );
149 add_action( 'wpforo_bottom_hook', [ $this, 'fb_login_sdk' ], 9 );
150 }
151 if( wpforo_setting( 'authorization', 'fb_api_id' ) && wpforo_setting( 'authorization', 'fb_api_secret' ) ) {
152 if( wpforo_setting( 'authorization', 'fb_lb_on_lp' ) ) {
153 add_action( 'wpforo_login_form_end', [ $this, 'fb_login_button' ] );
154 }
155 if( wpforo_setting( 'authorization', 'fb_lb_on_rp' ) ) {
156 add_action( 'wpforo_register_form_end', [ $this, 'fb_login_button' ] );
157 }
158 }
159 add_action( 'wp_ajax_wpforo_facebook_auth', [ $this, 'fb_auth' ] );
160 add_action( 'wp_ajax_nopriv_wpforo_facebook_auth', [ $this, 'fb_auth' ] );
161 }
162 }
163
164 if( is_wpforo_page() ) {
165 if( apply_filters( 'wpforo_api_fb_load_sdk', true ) && wpforo_setting( 'social', 'sb', 'fb' ) ) {
166 add_action( 'wpforo_bottom_hook', [ $this, 'fb_sdk' ], 10 );
167 }
168 if( apply_filters( 'wpforo_api_tw_load_wjs', true ) && wpforo_setting( 'social', 'sb', 'tw' ) ) {
169 add_action( 'wpforo_top_hook', [ $this, 'tw_wjs' ], 11 );
170 }
171 if( apply_filters( 'wpforo_api_vk_load_js', true ) && wpforo_setting( 'social', 'sb', 'vk' ) ) {
172 add_action( 'wpforo_top_hook', [ $this, 'vk_js' ], 13 );
173 }
174 }
175
176 ###############################################################################
177 ############### reCAPTCHA API #################################################
178 ###############################################################################
179
180 $site_key = wpforo_setting( 'recaptcha', 'site_key' );
181 $secret_key = wpforo_setting( 'recaptcha', 'secret_key' );
182
183 if( ! is_user_logged_in() && $site_key && $secret_key ) {
184
185 $wpf_reg_form = wpforo_setting( 'recaptcha', 'wpf_reg_form' );
186 $wpf_login_form = wpforo_setting( 'recaptcha', 'wpf_login_form' );
187 $wpf_lostpass_form = wpforo_setting( 'recaptcha', 'wpf_lostpass_form' );
188
189 add_filter( 'script_loader_tag', [ &$this, 'rc_enqueue_async' ], 10, 3 );
190
191 //Verification Hooks: Login / Register / Reset Pass
192 if( $wpf_login_form ) add_filter( 'wp_authenticate_user', [ $this, 'rc_verify_wp_login' ], 15, 2 );
193 if( $wpf_reg_form ) add_filter( 'registration_errors', [ $this, 'rc_verify_wp_register' ], 10, 3 );
194 if( $wpf_lostpass_form ) add_action( 'lostpassword_post', [ $this, 'rc_verify_wp_lostpassword' ], 10 );
195
196 //Load reCAPTCHA API on wpForo pages: Login / Register / Reset Pass
197 if( in_array( $template, [ 'login', 'register', 'lostpassword' ], true ) ) {
198 if( $wpf_reg_form || $wpf_login_form || $wpf_lostpass_form ) {
199 add_action( 'wp_enqueue_scripts', [ $this, 'rc_enqueue' ] );
200 }
201 }
202
203 //Load reCAPTCHA Widget wpForo forms: Login / Register / Reset Pass
204 if( $wpf_login_form && $template === 'login' ) add_action( 'login_form', [ $this, 'rc_widget' ] );
205 if( $wpf_reg_form && $template === 'register' ) add_action( 'register_form', [ $this, 'rc_widget' ] );
206 if( $wpf_lostpass_form && $template === 'lostpassword' ) {
207 add_action( 'lostpassword_form', [ $this, 'rc_widget' ] );
208 }
209
210 //Load reCAPTCHA API and Widget for Topic and Post Editor
211 if( $template === 'forum' || $template === 'topic' || $template === 'post' ) {
212 add_action( 'wp_enqueue_scripts', [ $this, 'rc_enqueue' ] );
213 add_action( 'wpforo_verify_form_end', [ $this, 'rc_verify' ] );
214 if( wpforo_setting( 'recaptcha', 'topic_editor' ) ) {
215 add_action( 'wpforo_topic_form_extra_fields_after', [ $this, 'rc_widget' ] );
216 }
217 if( wpforo_setting( 'recaptcha', 'post_editor' ) ) {
218 add_action( 'wpforo_reply_form_extra_fields_after', [ $this, 'rc_widget' ] );
219 add_action( 'wpforo_portable_form_extra_fields_after', [ $this, 'rc_widget' ] );
220 }
221 }
222 }
223
224 ###############################################################################
225 }
226
227 private function init_wp_recaptcha() {
228 $template = WPF()->current_object['template'];
229 $site_key = wpforo_setting( 'recaptcha', 'site_key' );
230 $secret_key = wpforo_setting( 'recaptcha', 'secret_key' );
231
232 if( ! is_user_logged_in() && $site_key && $secret_key ) {
233 $reg_form = wpforo_setting( 'recaptcha', 'reg_form' );
234 $login_form = wpforo_setting( 'recaptcha', 'login_form' );
235 $lostpass_form = wpforo_setting( 'recaptcha', 'lostpass_form' );
236
237 //Verification Hooks: Login / Register / Reset Pass
238 if( $login_form ) add_filter( 'wp_authenticate_user', [ $this, 'rc_verify_wp_login' ], 15, 2 );
239 if( $reg_form ) add_filter( 'registration_errors', [ $this, 'rc_verify_wp_register' ], 10, 3 );
240 if( $lostpass_form ) add_action( 'lostpassword_post', [ $this, 'rc_verify_wp_lostpassword' ], 10 );
241
242 //Load reCAPTCHA API and Widget on wp-login.php
243 if( $reg_form || $login_form || $lostpass_form ) {
244 add_action( 'login_enqueue_scripts', [ $this, 'rc_enqueue' ] );
245 add_action( 'login_enqueue_scripts', [ $this, 'rc_enqueue_css' ] );
246 if( $login_form && $template !== 'login' ) add_action( 'login_form', [ $this, 'rc_widget' ] );
247 if( $reg_form && $template !== 'register' ) add_action( 'register_form', [ $this, 'rc_widget' ] );
248 if( $lostpass_form && $template !== 'lostpassword' ) {
249 add_action( 'lostpassword_form', [ $this, 'rc_widget' ] );
250 }
251 }
252 }
253 }
254
255 public function local( $api ) {
256 $wplocal = get_locale();
257 $wplocal_iso = substr( $wplocal, 0, 2 );
258
259 if( $api === 'fb' ) {
260 if( in_array( $wplocal, $this->fb_local ) ) {
261 return $wplocal;
262 } else {
263 return $this->locale;
264 }
265 } elseif( $api === 'tw' ) {
266 if( in_array( $wplocal_iso, $this->tw_local ) ) {
267 return $wplocal_iso;
268 } else {
269 return $this->locale_iso;
270 }
271 } elseif( $api === 'vk' ) {
272 return $wplocal_iso;
273 } elseif( $api === 'ok' ) {
274 if( in_array( $wplocal_iso, $this->ok_local ) ) {
275 return $wplocal_iso;
276 } else {
277 return $this->locale_iso;
278 }
279 }
280
281 return $wplocal;
282 }
283
284 public function fb_enqueue() {
285 $app_id = wpforo_setting( 'authorization', 'fb_api_id' );
286 wp_register_script( 'wpforo-snfb', WPFORO_URL . '/assets/js/snfb.js', [ 'jquery' ], WPFORO_VERSION, false );
287 wp_enqueue_script( 'wpforo-snfb' );
288 wp_localize_script( 'wpforo-snfb', 'wpforo_fb', [
289 'ajaxurl' => admin_url( 'admin-ajax.php' ),
290 'site_url' => home_url(),
291 'scopes' => 'email,public_profile',
292 'appId' => $app_id,
293 'l18n' => [
294 'chrome_ios_alert' => __(
295 'Please login into Facebook and then click connect button again',
296 'wpforo'
297 ),
298 ],
299 ] );
300 }
301
302 public function fb_auth() {
303
304 $app_version = 'v2.10';
305 $app_secret = wpforo_setting( 'authorization', 'fb_api_secret' );
306 check_ajax_referer( 'wpforo-fb-nonce', 'security' );
307 $fb_token = isset( $_POST['fb_response']['authResponse']['accessToken'] ) ? $_POST['fb_response']['authResponse']['accessToken'] : '';
308 $fb_url = add_query_arg(
309 [ 'fields' => 'id,first_name,last_name,email,link,about,locale,birthday', 'access_token' => $fb_token ],
310 'https://graph.facebook.com/' . $app_version . '/' . $_POST['fb_response']['authResponse']['userID']
311 );
312
313 ###################################################################################################################
314 // Verifying Graph API Calls with appsecret_proof
315 // Graph API calls can be made from clients or from your server on behalf of clients.
316 // Calls from a server can be better secured by adding a parameter called appsecret_proof.
317 // https://developers.facebook.com/docs/graph-api/securing-requests/
318 if( $app_secret ) {
319 $appsecret_proof = hash_hmac( 'sha256', $fb_token, trim( $app_secret ) );
320 $fb_url = add_query_arg( [ 'appsecret_proof' => $appsecret_proof ], $fb_url );
321 }
322 ###################################################################################################################
323
324 $fb_response = wp_remote_get( esc_url_raw( $fb_url ), [ 'timeout' => 30 ] );
325 if( is_wp_error( $fb_response ) ) wpforo_ajax_response( [ 'error' => $fb_response->get_error_message() ] );
326 $fb_user = json_decode( wp_remote_retrieve_body( $fb_response ), true );
327 if( isset( $fb_user['error'] ) ) {
328 wpforo_ajax_response( [ 'error' => 'Error code: ' . $fb_user['error']['code'] . ' - ' . $fb_user['error']['message'] ] );
329 }
330 if( empty( $fb_user['email'] ) ) {
331 wpforo_ajax_response( [
332 'error' => __(
333 'Your email is required to be able authorize you here. Please try loging again. ',
334 'wpforo'
335 ),
336 'fb' => $fb_user,
337 ] );
338 }
339 $fb_user['link'] = ( isset( $fb_user['link'] ) ) ? $fb_user['link'] : '';
340 $fb_user['about'] = ( isset( $fb_user['about'] ) ) ? $fb_user['about'] : '';
341 $fb_user['locale'] = ( isset( $fb_user['locale'] ) ) ? $fb_user['locale'] : '';
342 $user = [
343 'fb_user_id' => $fb_user['id'],
344 'first_name' => $fb_user['first_name'],
345 'last_name' => $fb_user['last_name'],
346 'user_email' => $fb_user['email'],
347 'user_url' => $fb_user['link'],
348 'user_pass' => wp_generate_password(),
349 'description' => $fb_user['about'],
350 'locale' => $fb_user['locale'],
351 'rich_editing' => 'true',
352 ];
353 $message = [ 'error' => __( 'Invalid User', 'wpforo' ) ];
354 if( empty( $user['fb_user_id'] ) ) wpforo_ajax_response( $message );
355 $member = wpforo_get_fb_user( $user );
356 $meta_updated = false;
357
358 if( $member ) {
359 $user_id = $member->ID;
360 $message = [ 'success' => $user_id, 'method' => 'login' ];
361 if( empty( $member->user_email ) ) {
362 wp_update_user( [ 'ID' => $user_id, 'user_email' => $user['user_email'] ] );
363 }
364 } else {
365 if( ! wpforo_setting( 'authorization', 'user_register' ) ) {
366 wpforo_ajax_response( [ 'error' => __( 'User registration is disabled', 'wpforo' ) ] );
367 }
368 $username = wpforo_unique_username( $user['user_email'] );
369 $user['user_login'] = str_replace( '.', '', $username );
370 $user['user_nicename'] = sanitize_title( $username );
371 $user['display_name'] = ( $user['first_name'] || $user['last_name'] ) ? trim(
372 $user['first_name'] . ' ' . $user['last_name']
373 ) : ucfirst( str_replace( '-', ' ', $user['user_nicename'] ) );
374 $user_id = wp_insert_user( $user );
375 if( ! is_wp_error( $user_id ) ) {
376 wp_new_user_notification( $user_id, null, 'admin' );
377 wp_new_user_notification( $user_id, '', 'user' );
378 update_user_meta( $user_id, '_fb_user_id', $user['fb_user_id'] );
379 if( isset( $fb_user['birthday'] ) && $fb_user['birthday'] ) {
380 update_user_meta( $user_id, '_fb_user_birthday', $fb_user['birthday'] );
381 }
382 $meta_updated = true;
383 $message = [ 'success' => $user_id, 'method' => 'registration' ];
384 }
385 }
386 if( is_numeric( $user_id ) ) {
387 wp_set_auth_cookie( $user_id, true );
388 if( ! $meta_updated ) update_user_meta( $user_id, '_fb_user_id', $user['fb_user_id'] );
389 }
390 wpforo_ajax_response( $message );
391 }
392
393 public function fb_redirect() {
394 if( wpforo_setting( 'authorization', 'fb_redirect' ) === 'custom' && wpforo_setting( 'authorization', 'fb_redirect_url' ) != '' ) {
395 return esc_url( wpforo_setting( 'authorization', 'fb_redirect_url' ) );
396 } elseif( wpforo_setting( 'authorization', 'fb_redirect' ) === 'profile' ) {
397 return wpforo_home_url( "account/" );
398 } else {
399 return wpforo_home_url();
400 }
401 }
402
403 public function fb_sdk() {
404 // @todo
405 // FB SDK is disabled temporarily.
406 return false;
407 if( wpforo_setting( 'authorization', 'fb_api_id' ) ){
408 ?>
409 <script>
410 window.fbAsyncInit = function() {
411 FB.init({
412 appId : '<?php echo wpforo_setting( 'authorization', 'fb_api_id' ) ?>',
413 autoLogAppEvents : true,
414 xfbml : true,
415 version : '<?php echo self::FB_SDK_VERSION ?>'
416 });
417 };
418 </script>
419 <?php
420 if( !wpforo_setting( 'authorization', 'fb_login' ) ){
421 ?><div id="fb-root"></div><script async defer crossorigin="anonymous" src="https://connect.facebook.net/<?php echo $this->local('fb') ?>/sdk.js"></script><?php
422 }
423 }
424 }
425
426 public function fb_login_sdk() {
427 ?>
428 <script type='text/javascript'>
429 function statusChangeCallback(response) {
430 if (response.status === 'connected') {
431 //testAPI();
432 } else {
433 //document.getElementById('status').innerHTML = 'Please log ' + 'into this webpage.';
434 }
435 }
436 function checkLoginState () { FB.getLoginStatus(function (response) { statusChangeCallback(response) })}
437 window.fbAsyncInit = function() {
438 FB.init({
439 appId : '<?php echo trim( wpforo_setting( 'authorization', 'fb_api_id' ) ) ?>',
440 cookie : <?php echo wpforo_setting( 'legal', 'cookies' ) ? 'true' : 'false'; ?>, // Enable cookies to allow the server to access the session.
441 xfbml : true,
442 version: '<?php echo self::FB_SDK_VERSION ?>'
443 });
444 FB.getLoginStatus(function(response) { statusChangeCallback(response) });
445 };
446 </script>
447 <div id="fb-root"></div>
448 <script async defer crossorigin="anonymous" src="https://connect.facebook.net/<?php echo $this->local('fb') ?>/sdk.js#xfbml=1&version=<?php echo self::FB_SDK_VERSION ?>"></script>
449 <?php
450 }
451
452 public function fb_login_button() {
453 $checkbox = wpforo_setting( 'legal', 'checkbox_fb_login' );
454 $public_profile = '<a href="https://developers.facebook.com/docs/facebook-login/permissions#reference-public_profile" target="_blank" rel="nofollow" title="' . wpforo_phrase(
455 'Read more about Facebook public_profile properties.',
456 false
457 ) . '">public_profile</a>';
458 ?>
459 <?php if( $checkbox ): ?>
460 <div class="wpforo-fb-info">
461 <span class="wpforo-fb-info-title">
462 <i class="fas fa-info-circle wpfcl-5" aria-hidden="true" style="font-size:16px;"></i> &nbsp;<?php wpforo_phrase( 'Facebook Login Information' ); ?>
463 </span>
464 <span class="wpforo-fb-info-text">
465 <?php echo apply_filters(
466 'wpforo_fb_login_privacy_info',
467 sprintf(
468 wpforo_phrase(
469 'When you login first time using Facebook Login button, we collect your account %s information shared by Facebook, based on your privacy settings. We also get your email address to automatically create a forum account for you. Once your account is created, you\'ll be logged-in to this account and you\'ll receive a confirmation email.',
470 false
471 ),
472 $public_profile
473 )
474 ); ?>
475 </span>
476 <label class="wpforo-legal-checkbox wpflegal-fblogin">
477 <input id="wpflegal_fblogin" name="legal[agree-fb-login]" value="1" type="checkbox"> &nbsp;
478 <span><?php wpforo_phrase( 'I allow to create an account and send confirmation email.' ); ?></span>
479 </label>
480 </div>
481 <?php endif; ?>
482 <div class="wpforo_fb-button wpforo-fb-login-wrap" data-redirect="<?php echo $this->fb_redirect() ?>"
483 data-fb_nonce="<?php echo wp_create_nonce(
484 'wpforo-fb-nonce'
485 ) ?>" <?php if( $checkbox ) echo 'style="pointer-events: none; opacity:0.6;"'; ?>>
486 <div class="fb-login-button"
487 data-max-rows="1"
488 onlogin="wpforo_fb_check_auth"
489 data-width=""
490 data-size="medium"
491 data-button-type="login_with"
492 data-layout="rounded"
493 data-show-faces="false"
494 data-auth-type="rerequest"
495 data-auto-logout-link="false"
496 data-use-continue-as="true"
497 data-scope="email,public_profile"></div>
498 <img data-no-lazy="1" src="<?php echo WPFORO_URL . '/assets/images/loading.gif'; ?>" class="wpforo_fb-spinner" style="display:none" alt="loading...">
499 </div>
500 <?php
501 }
502
503 public function fb_share_button( $url = '', $type = 'custom' ) {
504 if( ! wpforo_setting( 'social', 'sb', 'fb' ) || ! wpforo_setting( 'authorization', 'fb_api_id' ) ) return;
505 $url = $url ?: WPF()->current_url;
506 if( $type === 'custom' ) { ?>
507 <span class="wpforo-share-button wpf-fb" data-wpfurl="<?php echo $url ?>"
508 title="<?php wpforo_phrase( 'Share to Facebook' ); ?>">
509 <?php if( wpforo_setting( 'social', 'sb_icon' ) === 'figure' ): ?>
510 <i class="fab fa-facebook-f" aria-hidden="true"></i>
511 <?php elseif( wpforo_setting( 'social', 'sb_icon' ) === 'square' ): ?>
512 <i class="fab fa-facebook-square" aria-hidden="true"></i>
513 <?php else: ?>
514 <i class="fab fa-facebook" aria-hidden="true"></i>
515 <?php endif; ?>
516 </span>
517 <?php
518 } else {
519 ?>
520 <div class="wpf-sbw wpf-sbw-fb">
521 <?php if( wpforo_setting( 'social', 'sb_type' ) === 'button_count' ): ?>
522 <a target="_blank" href="https://www.facebook.com/share.php?u=<?php echo urlencode( $url ) ?>"
523 class="fb-xfbml-parse-ignore"><?php wpforo_phrase( 'Share' ); ?></a>
524 <?php elseif( wpforo_setting( 'social', 'sb_type' ) === 'button' ): ?>
525 <a class="wpf-sb-button wpf-fb" href="https://www.facebook.com/share.php?u=<?php echo urlencode($url) ?>" target="_blank">
526 <i class="fab fa-facebook-f" aria-hidden="true"></i> <span><?php echo wpforo_phrase('Share') ?></span>
527 </a>
528 <?php else: ?>
529 <a class="wpf-sb-button wpf-sb-icon wpf-fb" href="https://www.facebook.com/share.php?u=<?php echo urlencode($url) ?>" target="_blank">
530 <i class="fab fa-facebook-f" aria-hidden="true"></i>
531 </a>
532 <?php endif; ?>
533 </div>
534 <?php
535 }
536 }
537
538 public function tw_wjs() {
539 ?>
540 <script type="text/javascript">window.twttr = (function (d, s, id) {
541 var js, fjs = d.getElementsByTagName(s)[0], t = window.twttr || {}
542 if (d.getElementById(id)) return t
543 js = d.createElement(s)
544 js.id = id
545 js.src = 'https://platform.twitter.com/widgets.js'
546 fjs.parentNode.insertBefore(js, fjs)
547 t._e = []
548 t.ready = function (f) { t._e.push(f) }
549 return t
550 }(document, 'script', 'twitter-wjs'))</script>
551 <?php
552 }
553
554 public function tw_share_button( $url = '', $type = 'custom', $text = '' ) {
555 if( ! wpforo_setting( 'social', 'sb', 'tw' ) ) return;
556 $url = $url ?: WPF()->current_url;
557 $n_url = strlen( $url );
558 $n_text = 280 - $n_url;
559 $text = $text ?: wpfval( WPF()->current_object, 'og_text' );
560 $text = urlencode( wpforo_text( strip_shortcodes( strip_tags( $text ) ), $n_text, false ) );
561 if( $type == 'custom' ) { ?>
562 <a class="wpforo-share-button wpf-tw"
563 href="https://twitter.com/intent/tweet?text=<?php echo $text ?>&url=<?php echo urlencode( $url ) ?>"
564 title="<?php wpforo_phrase( 'Tweet this post' ); ?>">
565 <?php if( wpforo_setting( 'social', 'sb_icon' ) === 'figure' ): ?>
566 <i class="fab fa-twitter" aria-hidden="true"></i>
567 <?php elseif( wpforo_setting( 'social', 'sb_icon' ) === 'square' ): ?>
568 <i class="fab fa-twitter-square" aria-hidden="true"></i>
569 <?php else: ?>
570 <i class="fab fa-twitter" aria-hidden="true"></i>
571 <?php endif; ?>
572 </a>
573 <?php
574 } else { ?>
575 <div class="wpf-sbw wpf-sbw-tw">
576 <?php if( wpforo_setting( 'social', 'sb_type' ) === 'button_count' ): ?>
577 <a href="https://twitter.com/share?ref_src=twsrc%5Etfw" class="twitter-share-button"
578 data-lang="<?php $this->local( 'tw' ) ?>" data-show-count="true"><?php wpforo_phrase(
579 'Tweet'
580 ); ?></a>
581 <?php elseif( wpforo_setting( 'social', 'sb_type' ) === 'button' ): ?>
582 <a class="wpf-sb-button wpf-tw"
583 href="https://twitter.com/intent/tweet?text=<?php echo $text ?>&url=<?php echo urlencode(
584 $url
585 ) ?>">
586 <i class="fab fa-twitter" aria-hidden="true"></i> <span><?php echo wpforo_phrase(
587 'Tweet'
588 ) ?></span>
589 </a>
590 <?php else: ?>
591 <a class="wpf-sb-button wpf-sb-icon wpf-tw"
592 href="https://twitter.com/intent/tweet?text=<?php echo $text ?>&url=<?php echo urlencode(
593 $url
594 ) ?>">
595 <i class="fab fa-twitter" aria-hidden="true"></i>
596 </a>
597 <?php endif; ?>
598 </div>
599 <?php
600 }
601 }
602
603 public function vk_js() {
604 ?>
605 <script type="text/javascript" src="https://vk.com/js/api/share.js?95" charset="windows-1251"></script>
606 <?php
607 }
608
609 public function wapp_share_button( $url = '', $type = 'custom', $text = '' ) {
610 if( ! wpforo_setting( 'social', 'sb', 'wapp' ) ) return;
611 $url = $url ?: WPF()->current_url;
612 $domain = wp_is_mobile() ? 'https://api.whatsapp.com' : 'https://web.whatsapp.com';
613 $text = $text ?: ( wpfval( WPF()->current_object, 'og_text' ) ? WPF()->current_object['og_text'] : WPF()->board->get_current( 'settings' )['title'] );
614 $text = urlencode( wpforo_text( strip_shortcodes( strip_tags( $text ) ), 100, false ) ) . ' URL: ' . urlencode( $url );
615 if( $type === 'custom' ) { ?>
616 <a class="wpforo-share-button wpf-wapp" href="<?php echo $domain ?>/send?text=<?php echo $text ?>"
617 title="<?php wpforo_phrase( 'Share to WhatsApp' ); ?>" target="_blank"
618 data-action="share/whatsapp/share">
619 <i class="fab fa-whatsapp" aria-hidden="true"></i>
620 </a>
621 <?php
622 } else { ?>
623 <div class="wpf-sbw wpf-sbw-wapp">
624 <?php if( wpforo_setting( 'social', 'sb_type' ) === 'button_count' ): ?>
625 <!-- WhatsApp is not available -->
626 <?php elseif( wpforo_setting( 'social', 'sb_type' ) === 'button' ): ?>
627 <a class="wpf-sb-button wpf-wapp" href="<?php echo $domain ?>/send?text=<?php echo $text ?>"
628 target="_blank" data-action="share/whatsapp/share">
629 <i class="fab fa-whatsapp" aria-hidden="true"></i> <span><?php echo wpforo_phrase( 'Share' ) ?></span>
630 </a>
631 <?php else: ?>
632 <a class="wpf-sb-button wpf-sb-icon wpf-wapp"
633 href="<?php echo $domain ?>/send?text=<?php echo $text ?>" target="_blank"
634 data-action="share/whatsapp/share">
635 <i class="fab fa-whatsapp" aria-hidden="true"></i>
636 </a>
637 <?php endif; ?>
638 </div>
639 <?php
640 }
641 }
642
643 public function lin_share_button( $url = '', $type = 'custom', $text = '' ) {
644 if( ! wpforo_setting( 'social', 'sb', 'lin' ) ) return;
645 $url = $url ?: WPF()->current_url;
646 $title = wpfval( WPF()->current_object, 'topic', 'title' );
647 $text = $text ?: ( wpfval( WPF()->current_object, 'og_text' ) ? WPF()->current_object['og_text'] : WPF()->board->get_current(
648 'settings'
649 )['title'] );
650 $text = urlencode( wpforo_text( strip_shortcodes( strip_tags( $text ) ), 500, false ) );
651 if( $type == 'custom' ) { ?>
652 <a class="wpforo-share-button wpf-lin"
653 href="https://www.linkedin.com/shareArticle?mini=true&url=<?php echo urlencode(
654 $url
655 ) ?>&title=<?php echo urlencode( $title ) ?>&summary=<?php echo $text ?>"
656 title="<?php wpforo_phrase( 'Share to LinkedIn' ); ?>" target="_blank">
657 <i class="fab fa-linkedin-in" aria-hidden="true"></i>
658 </a>
659 <?php
660 } else { ?>
661 <div class="wpf-sbw wpf-sbw-lin">
662 <?php if( wpforo_setting( 'social', 'sb_type' ) === 'button_count' ): ?>
663 <!-- LinkedIn is not available -->
664 <?php elseif( wpforo_setting( 'social', 'sb_type' ) === 'button' ): ?>
665 <a class="wpf-sb-button wpf-lin"
666 href="https://www.linkedin.com/shareArticle?mini=true&url=<?php echo urlencode(
667 $url
668 ) ?>&title=<?php echo urlencode( $title ) ?>&summary=<?php echo $text ?>" target="_blank">
669 <i class="fab fa-linkedin-in" aria-hidden="true"></i> <span><?php echo wpforo_phrase(
670 'Share'
671 ) ?></span>
672 </a>
673 <?php else: ?>
674 <a class="wpf-sb-button wpf-sb-icon wpf-lin"
675 href="https://www.linkedin.com/shareArticle?mini=true&url=<?php echo urlencode(
676 $url
677 ) ?>&title=<?php echo urlencode( $title ) ?>&summary=<?php echo $text ?>" target="_blank">
678 <i class="fab fa-linkedin-in" aria-hidden="true"></i>
679 </a>
680 <?php endif; ?>
681 </div>
682 <?php
683 }
684 }
685
686 public function vk_share_button( $url = '', $type = 'custom', $text = '' ) {
687 if( ! wpforo_setting( 'social', 'sb', 'vk' ) ) return;
688 $url = $url ?: WPF()->current_url;
689 $text = $text ?: wpfval( WPF()->current_object, 'og_text' );
690 $text = urlencode( wpforo_text( strip_shortcodes( strip_tags( $text ) ), 500, false ) );
691 if( $type === 'custom' ) { ?>
692 <a class="wpforo-share-button wpf-vk" onclick="return VK.Share.click(0, this);"
693 href="https://vk.com/share.php?url=<?php echo urlencode( $url ) ?>&description=<?php echo $text ?>"
694 title="<?php wpforo_phrase( 'Share to VK' ); ?>" target="_blank">
695 <i class="fab fa-vk" aria-hidden="true"></i>
696 </a>
697 <?php
698 } else { ?>
699 <div class="wpf-sbw wpf-sbw-vk">
700 <?php if( wpforo_setting( 'social', 'sb_type' ) === 'button_count' ): ?>
701 <script type="text/javascript">document.write(VK.Share.button(false, {
702 type: 'round',
703 text: "<?php wpforo_phrase( 'Share' ); ?>"
704 }))</script>
705 <?php elseif( wpforo_setting( 'social', 'sb_type' ) === 'button' ): ?>
706 <a class="wpf-sb-button wpf-vk" onclick="return VK.Share.click(0, this);"
707 href="https://vk.com/share.php?url=<?php echo urlencode(
708 $url
709 ) ?>&description=<?php echo $text ?>" target="_blank">
710 <i class="fab fa-vk" aria-hidden="true"></i> <span><?php echo wpforo_phrase( 'Share' ) ?></span>
711 </a>
712 <?php else: ?>
713 <a class="wpf-sb-button wpf-sb-icon wpf-vk" onclick="return VK.Share.click(0, this);"
714 href="https://vk.com/share.php?url=<?php echo urlencode(
715 $url
716 ) ?>&description=<?php echo $text ?>" target="_blank">
717 <i class="fab fa-vk" aria-hidden="true"></i>
718 </a>
719 <?php endif; ?>
720 </div>
721 <?php
722 }
723 }
724
725 public function ok_share_button( $url = '', $type = 'custom', $text = '' ) {
726 if( ! wpforo_setting( 'social', 'sb', 'ok' ) ) return;
727 $url = $url ?: WPF()->current_url;
728 if( preg_match( '|\#post-(\d+)|s', $url, $a ) ) {
729 $pid = ( isset( $a[1] ) ) ? intval( $a[1] ) : mt_rand( 100000, 999999 );
730 } else {
731 $pid = mt_rand( 100000, 999999 );
732 }
733 $text = $text ?: wpfval( WPF()->current_object, 'og_text' );
734 $text = wpforo_text( strip_shortcodes( strip_tags( $text ) ), 500, false );
735 if( $type == 'custom' ) { ?>
736 <a class="wpforo-share-button wpf-ok"
737 href="https://connect.ok.ru/offer?url=<?php echo urlencode( $url ) ?>&description=<?php echo urlencode(
738 $text
739 ) ?>" title="<?php wpforo_phrase( 'Share to OK' ); ?>" target="_blank">
740 <?php if( wpforo_setting( 'social', 'sb_icon' ) === 'figure' ): ?>
741 <i class="fab fa-odnoklassniki" aria-hidden="true"></i>
742 <?php elseif( wpforo_setting( 'social', 'sb_icon' ) === 'square' ): ?>
743 <i class="fab fa-odnoklassniki-square" aria-hidden="true"></i>
744 <?php else: ?>
745 <i class="fab fa-odnoklassniki-square" aria-hidden="true"></i>
746 <?php endif; ?>
747 </a>
748 <?php
749 } else { ?>
750 <div class="wpf-sbw wpf-sbw-ok">
751 <?php if( wpforo_setting( 'social', 'sb_type' ) === 'button_count' ): ?>
752 <div id="<?php echo 'wpfokb_' . $pid ?>"></div>
753 <script>
754 !function (d, id, did, st, title, description, image) {
755 var js = d.createElement('script')
756 js.src = 'https://connect.ok.ru/connect.js'
757 js.onload = js.onreadystatechange = function () {
758 if (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') {
759 if (!this.executed) {
760 this.executed = true
761 setTimeout(function () { OK.CONNECT.insertShareWidget(id, did, st, title, description, image) }, 0)
762 }
763 }
764 }
765 d.documentElement.appendChild(js)
766 }(document, "<?php echo 'wpfokb_' . $pid ?>", "<?php echo esc_attr(
767 $url
768 ) ?>", '{"sz":20,"st":"straight","ck":2,"lang":"<?php echo $this->local(
769 'ok'
770 ) ?>"}', '', '', '')
771 </script>
772 <?php elseif( wpforo_setting( 'social', 'sb_type' ) === 'button' ): ?>
773 <a class="wpf-sb-button wpf-ok" href="https://connect.ok.ru/offer?url=<?php echo urlencode(
774 $url
775 ) ?>&description=<?php echo urlencode( $text ) ?>" title="<?php wpforo_phrase( 'Share to OK' ); ?>"
776 target="_blank">
777 <i class="fab fa-odnoklassniki" aria-hidden="true"></i> <span><?php echo wpforo_phrase(
778 'Share'
779 ) ?></span>
780 </a>
781 <?php else: ?>
782 <a class="wpf-sb-button wpf-sb-icon wpf-ok"
783 href="https://connect.ok.ru/offer?url=<?php echo urlencode(
784 $url
785 ) ?>&description=<?php echo urlencode( $text ) ?>"
786 title="<?php wpforo_phrase( 'Share to OK' ); ?>" target="_blank">
787 <i class="fab fa-odnoklassniki" aria-hidden="true"></i>
788 </a>
789 <?php endif; ?>
790 </div>
791 <?php
792 }
793 }
794
795 public function share_toggle( $url = '', $text = '', $type = 'custom' ) {
796 WPF()->api->fb_share_button( $url, $type );
797 WPF()->api->tw_share_button( $url, $type, $text );
798 WPF()->api->wapp_share_button( $url, $type, $text );
799 WPF()->api->lin_share_button( $url, $type, $text );
800 WPF()->api->vk_share_button( $url, $type, $text );
801 WPF()->api->ok_share_button( $url, $type, $text );
802 }
803
804 public function share_buttons( $url = '', $type = 'default', $text = '' ) {
805 $template = wpfval( WPF()->current_object, 'template' );
806 $exclude = [ 'lostpassword', 'resetpassword' ];
807 if( $template && ! in_array( $template, $exclude ) ) {
808 WPF()->api->fb_share_button( $url, $type );
809 WPF()->api->tw_share_button( $url, $type, $text );
810 WPF()->api->wapp_share_button( $url, $type, $text );
811 WPF()->api->lin_share_button( $url, $type, $text );
812 WPF()->api->vk_share_button( $url, $type, $text );
813 WPF()->api->ok_share_button( $url, $type, $text );
814 }
815 }
816
817 public function rc_enqueue() {
818 $theme = wpforo_setting( 'recaptcha', 'theme' );
819 $site_key = wpforo_setting( 'recaptcha', 'site_key' );
820 wp_register_script(
821 'wpforo_recaptcha',
822 'https://www.google.com/recaptcha/api.js?onload=wpForoReCallback&render=explicit'
823 );
824 wp_add_inline_script(
825 'wpforo_recaptcha',
826 "var wpForoReCallback = function(){
827 setTimeout(function () {
828 if( typeof grecaptcha !== 'undefined' && typeof grecaptcha.render === 'function' ){
829 var rc_widgets = document.getElementsByClassName('wpforo_recaptcha_widget');
830 if( rc_widgets.length ){
831 var i;
832 for (i = 0; i < rc_widgets.length; i++) {
833 if( rc_widgets[i].firstElementChild === null ){
834 rc_widgets[i].innerHtml = '';
835 grecaptcha.render(
836 rc_widgets[i], { 'sitekey': '" . $site_key . "', 'theme': '" . $theme . "' }
837 );
838 }
839 }
840 }
841 }
842 }, 800);
843 }"
844 );
845 wp_enqueue_script( 'wpforo_recaptcha' );
846 }
847
848 public function rc_enqueue_async( $tag, $handle ) {
849 if( $handle === 'wpforo_recaptcha' ) return str_replace( '<script', '<script async defer', $tag );
850
851 return $tag;
852 }
853
854 public function rc_enqueue_css() {
855 wp_register_style( 'wpforo-rc-style', false );
856 wp_enqueue_style( 'wpforo-rc-style' );
857 $custom_css = ".wpforo_recaptcha_widget{ -webkit-transform:scale(0.9); transform:scale(0.9); -webkit-transform-origin:left 0; transform-origin:left 0; }";
858 wp_add_inline_style( 'wpforo-rc-style', $custom_css );
859 }
860
861 public function rc_widget() {
862 $site_key = wpforo_setting( 'recaptcha', 'site_key' );
863 if( $site_key ) {
864 echo '<div class="wpforo_recaptcha_widget"></div><div class="wpf-cl"></div>';
865 echo "\r\n<script>wpForoReCallback();</script>";
866 }
867 }
868
869 public function rc_check() {
870 if( isset( $_POST['g-recaptcha-response'] ) ) {
871 $secret_key = wpforo_setting( 'recaptcha', 'secret_key' );
872 $url = 'https://www.google.com/recaptcha/api/siteverify?secret=' . $secret_key . '&response=' . $_POST['g-recaptcha-response'];
873 $response = wp_remote_get( $url );
874 if( is_wp_error( $response ) || empty( $response['body'] ) ) {
875 $error = wpforo_phrase( "ERROR: Can't connect to Google reCAPTCHA API", false );
876 if( WP_DEBUG === true ) $error .= ' ( ' . $response->get_error_message() . ' )';
877
878 return $error;
879 }
880 $response = json_decode( $response['body'], true );
881 if( $response['success'] == true ) {
882 return 'success';
883 } else {
884 return wpforo_phrase( 'Google reCAPTCHA verification failed', false );
885 }
886 } else {
887 return wpforo_phrase( 'Google reCAPTCHA data are not submitted', false );
888 }
889 }
890
891 public function rc_verify() {
892 if( ! wpforo_setting( 'recaptcha', 'post_editor' ) || ! wpforo_setting( 'recaptcha', 'topic_editor' ) ) {
893 if( ! wpforo_setting( 'recaptcha', 'post_editor' ) && in_array(
894 wpfval( $_POST, 'wpfaction' ),
895 [ 'post_add', 'post_edit' ],
896 true
897 ) ) {
898 return true;
899 } elseif( ! wpforo_setting( 'recaptcha', 'topic_editor' ) && in_array(
900 wpfval( $_POST, 'wpfaction' ),
901 [ 'topic_add', 'topic_edit' ],
902 true
903 ) ) {
904 return true;
905 }
906 }
907 $result = $this->rc_check();
908 if( $result === 'success' ) {
909 return true;
910 } else {
911 WPF()->notice->add( $result, 'error' );
912 wp_safe_redirect( wpforo_get_request_uri() );
913 exit();
914 }
915 }
916
917 public function rc_verify_wp_login( $user ) {
918 if( ! isset( $_POST['log'] ) && ! isset( $_POST['pwd'] ) ) return $user;
919 if( ! wpforo_setting( 'recaptcha', 'login_form' ) || ! wpforo_setting( 'recaptcha', 'wpf_login_form' ) ) {
920 if( ! wpfval( $_POST, 'wpforologin' ) && ! wpforo_setting( 'recaptcha', 'login_form' ) ) {
921 return $user;
922 } elseif( wpfval( $_POST, 'wpforologin' ) && ! wpforo_setting( 'recaptcha', 'wpf_login_form' ) ) {
923 return $user;
924 }
925 }
926 $errors = is_wp_error( $user ) ? $user : new WP_Error();
927 $result = $this->rc_check();
928 if( $result != 'success' ) {
929 $errors->add( 'wpforo-recaptcha-error', $result );
930 $user = is_wp_error( $user ) ? $user : $errors;
931 remove_filter( 'authenticate', 'wp_authenticate_username_password' );
932 remove_filter( 'authenticate', 'wp_authenticate_cookie' );
933 }
934
935 return $user;
936 }
937
938 public function rc_verify_wp_register( $errors = '' ) {
939 if( ! is_wp_error( $errors ) ) $errors = new WP_Error();
940 if( ! wpforo_setting( 'recaptcha', 'reg_form' ) || ! wpforo_setting( 'recaptcha', 'wpf_reg_form' ) ) {
941 if( ! wpfval( $_POST, 'wpfreg' ) && ! wpforo_setting( 'recaptcha', 'reg_form' ) ) {
942 return $errors;
943 } elseif( wpfval( $_POST, 'wpfreg' ) && ! wpforo_setting( 'recaptcha', 'wpf_reg_form' ) ) {
944 return $errors;
945 }
946 }
947 $result = $this->rc_check();
948 if( $result != 'success' ) {
949 $errors->add( 'wpforo-recaptcha-error', $result );
950 }
951
952 return $errors;
953 }
954
955 public function rc_verify_wp_lostpassword( $errors = '' ) {
956 if( ! is_wp_error( $errors ) ) $errors = new WP_Error();
957 if( ! wpforo_setting( 'recaptcha', 'lostpass_form' ) || ! wpforo_setting( 'recaptcha', 'wpf_lostpass_form' ) ) {
958 if( ! wpfval( $_POST, 'wpfororp' ) && ! wpforo_setting( 'recaptcha', 'lostpass_form' ) ) {
959 return;
960 } elseif( wpfval( $_POST, 'wpfororp' ) && ! wpforo_setting( 'recaptcha', 'wpf_lostpass_form' ) ) {
961 return;
962 }
963 }
964 $result = $this->rc_check();
965 if( $result !== 'success' ) {
966 if( isset( $_POST['wc_reset_password'] ) && isset( $_POST['_wp_http_referer'] ) ) {
967 //$errors->add('wpforo-recaptcha-error', $result);
968 //return $errors;
969 } else {
970 wp_die( $result, 'reCAPTCHA ERROR', [ 'back_link' => true ] );
971 }
972 }
973 }
974 }
975