PluginProbe
wpForo Forum / 2.0.8
wpForo Forum v2.0.8
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.0.8, at classes/API.php

978 lines 40.1 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 if( wpforo_setting( 'authorization', 'fb_api_id' ) ){
405 ?>
406 <script>
407 window.fbAsyncInit = function() {
408 FB.init({
409 appId : '<?php echo wpforo_setting( 'authorization', 'fb_api_id' ) ?>',
410 autoLogAppEvents : true,
411 xfbml : true,
412 version : '<?php echo self::FB_SDK_VERSION ?>'
413 });
414 };
415 </script>
416 <?php
417 if( !wpforo_setting( 'authorization', 'fb_login' ) ){
418 ?><div id="fb-root"></div><script async defer crossorigin="anonymous" src="https://connect.facebook.net/<?php echo $this->local('fb') ?>/sdk.js"></script><?php
419 }
420 }
421 }
422
423 public function fb_login_sdk() {
424 ?>
425 <script type='text/javascript'>
426 function statusChangeCallback(response) {
427 if (response.status === 'connected') {
428 //testAPI();
429 } else {
430 //document.getElementById('status').innerHTML = 'Please log ' + 'into this webpage.';
431 }
432 }
433 function checkLoginState () { FB.getLoginStatus(function (response) { statusChangeCallback(response) })}
434 window.fbAsyncInit = function() {
435 FB.init({
436 appId : '<?php echo trim( wpforo_setting( 'authorization', 'fb_api_id' ) ) ?>',
437 cookie : <?php echo wpforo_setting( 'legal', 'cookies' ) ? 'true' : 'false'; ?>, // Enable cookies to allow the server to access the session.
438 xfbml : true,
439 version: '<?php echo self::FB_SDK_VERSION ?>'
440 });
441 FB.getLoginStatus(function(response) { statusChangeCallback(response) });
442 };
443 </script>
444 <div id="fb-root"></div>
445 <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>
446 <?php
447 }
448
449 public function fb_login_button() {
450 $checkbox = wpforo_setting( 'legal', 'checkbox_fb_login' );
451 $public_profile = '<a href="https://developers.facebook.com/docs/facebook-login/permissions#reference-public_profile" target="_blank" rel="nofollow" title="' . wpforo_phrase(
452 'Read more about Facebook public_profile properties.',
453 false
454 ) . '">public_profile</a>';
455 ?>
456 <?php if( $checkbox ): ?>
457 <div class="wpforo-fb-info">
458 <span class="wpforo-fb-info-title">
459 <i class="fas fa-info-circle wpfcl-5" aria-hidden="true" style="font-size:16px;"></i> &nbsp;<?php wpforo_phrase( 'Facebook Login Information' ); ?>
460 </span>
461 <span class="wpforo-fb-info-text">
462 <?php echo apply_filters(
463 'wpforo_fb_login_privacy_info',
464 sprintf(
465 wpforo_phrase(
466 '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.',
467 false
468 ),
469 $public_profile
470 )
471 ); ?>
472 </span>
473 <label class="wpforo-legal-checkbox wpflegal-fblogin">
474 <input id="wpflegal_fblogin" name="legal[agree-fb-login]" value="1" type="checkbox"> &nbsp;
475 <span><?php wpforo_phrase( 'I allow to create an account and send confirmation email.' ); ?></span>
476 </label>
477 </div>
478 <?php endif; ?>
479 <div class="wpforo_fb-button wpforo-fb-login-wrap" data-redirect="<?php echo $this->fb_redirect() ?>"
480 data-fb_nonce="<?php echo wp_create_nonce(
481 'wpforo-fb-nonce'
482 ) ?>" <?php if( $checkbox ) echo 'style="pointer-events: none; opacity:0.6;"'; ?>>
483 <div class="fb-login-button"
484 data-max-rows="1"
485 onlogin="wpforo_fb_check_auth"
486 data-width=""
487 data-size="medium"
488 data-button-type="login_with"
489 data-layout="rounded"
490 data-show-faces="false"
491 data-auth-type="rerequest"
492 data-auto-logout-link="false"
493 data-use-continue-as="true"
494 data-scope="email,public_profile"></div>
495 <img data-no-lazy="1" src="<?php echo WPFORO_URL . '/assets/images/loading.gif'; ?>" class="wpforo_fb-spinner" style="display:none" alt="loading...">
496 </div>
497 <?php
498 }
499
500 public function fb_share_button( $url = '', $type = 'custom' ) {
501 if( ! wpforo_setting( 'social', 'sb', 'fb' ) || ! wpforo_setting( 'authorization', 'fb_api_id' ) ) return;
502 $url = $url ?: WPF()->current_url;
503 if( $type === 'custom' ) { ?>
504 <span class="wpforo-share-button wpf-fb" data-wpfurl="<?php echo $url ?>"
505 title="<?php wpforo_phrase( 'Share to Facebook' ); ?>">
506 <?php if( wpforo_setting( 'social', 'sb_icon' ) === 'figure' ): ?>
507 <i class="fab fa-facebook-f" aria-hidden="true"></i>
508 <?php elseif( wpforo_setting( 'social', 'sb_icon' ) === 'square' ): ?>
509 <i class="fab fa-facebook-square" aria-hidden="true"></i>
510 <?php else: ?>
511 <i class="fab fa-facebook" aria-hidden="true"></i>
512 <?php endif; ?>
513 </span>
514 <?php
515 } else {
516 ?>
517 <div class="wpf-sbw wpf-sbw-fb">
518 <?php if( wpforo_setting( 'social', 'sb_type' ) === 'button_count' ): ?>
519 <div class="fb-share-button" data-href="<?php echo esc_url( $url ) ?>" data-layout="button_count"
520 data-size="small" data-mobile-iframe="true">
521 <a target="_blank"
522 href="https://www.facebook.com/sharer/sharer.php?u=<?php echo urlencode( $url ) ?>"
523 class="fb-xfbml-parse-ignore"><?php wpforo_phrase( 'Share' ); ?></a>
524 </div>
525 <?php elseif( wpforo_setting( 'social', 'sb_type' ) === 'button' ): ?>
526 <span class="wpf-sb-button wpf-fb" data-wpfurl="<?php echo esc_url( $url ) ?>">
527 <i class="fab fa-facebook-f" aria-hidden="true"></i> <span><?php echo wpforo_phrase(
528 'Share'
529 ) ?></span>
530 </span>
531 <?php else: ?>
532 <span class="wpf-sb-button wpf-sb-icon wpf-fb" data-wpfurl="<?php echo esc_url( $url ) ?>">
533 <i class="fab fa-facebook-f" aria-hidden="true"></i>
534 </span>
535 <?php endif; ?>
536 </div>
537 <?php
538 }
539 }
540
541 public function tw_wjs() {
542 ?>
543 <script type="text/javascript">window.twttr = (function (d, s, id) {
544 var js, fjs = d.getElementsByTagName(s)[0], t = window.twttr || {}
545 if (d.getElementById(id)) return t
546 js = d.createElement(s)
547 js.id = id
548 js.src = 'https://platform.twitter.com/widgets.js'
549 fjs.parentNode.insertBefore(js, fjs)
550 t._e = []
551 t.ready = function (f) { t._e.push(f) }
552 return t
553 }(document, 'script', 'twitter-wjs'))</script>
554 <?php
555 }
556
557 public function tw_share_button( $url = '', $type = 'custom', $text = '' ) {
558 if( ! wpforo_setting( 'social', 'sb', 'tw' ) ) return;
559 $url = $url ?: WPF()->current_url;
560 $n_url = strlen( $url );
561 $n_text = 280 - $n_url;
562 $text = $text ?: wpfval( WPF()->current_object, 'og_text' );
563 $text = urlencode( wpforo_text( strip_shortcodes( strip_tags( $text ) ), $n_text, false ) );
564 if( $type == 'custom' ) { ?>
565 <a class="wpforo-share-button wpf-tw"
566 href="https://twitter.com/intent/tweet?text=<?php echo $text ?>&url=<?php echo urlencode( $url ) ?>"
567 title="<?php wpforo_phrase( 'Tweet this post' ); ?>">
568 <?php if( wpforo_setting( 'social', 'sb_icon' ) === 'figure' ): ?>
569 <i class="fab fa-twitter" aria-hidden="true"></i>
570 <?php elseif( wpforo_setting( 'social', 'sb_icon' ) === 'square' ): ?>
571 <i class="fab fa-twitter-square" aria-hidden="true"></i>
572 <?php else: ?>
573 <i class="fab fa-twitter" aria-hidden="true"></i>
574 <?php endif; ?>
575 </a>
576 <?php
577 } else { ?>
578 <div class="wpf-sbw wpf-sbw-tw">
579 <?php if( wpforo_setting( 'social', 'sb_type' ) === 'button_count' ): ?>
580 <a href="https://twitter.com/share?ref_src=twsrc%5Etfw" class="twitter-share-button"
581 data-lang="<?php $this->local( 'tw' ) ?>" data-show-count="true"><?php wpforo_phrase(
582 'Tweet'
583 ); ?></a>
584 <?php elseif( wpforo_setting( 'social', 'sb_type' ) === 'button' ): ?>
585 <a class="wpf-sb-button wpf-tw"
586 href="https://twitter.com/intent/tweet?text=<?php echo $text ?>&url=<?php echo urlencode(
587 $url
588 ) ?>">
589 <i class="fab fa-twitter" aria-hidden="true"></i> <span><?php echo wpforo_phrase(
590 'Tweet'
591 ) ?></span>
592 </a>
593 <?php else: ?>
594 <a class="wpf-sb-button wpf-sb-icon wpf-tw"
595 href="https://twitter.com/intent/tweet?text=<?php echo $text ?>&url=<?php echo urlencode(
596 $url
597 ) ?>">
598 <i class="fab fa-twitter" aria-hidden="true"></i>
599 </a>
600 <?php endif; ?>
601 </div>
602 <?php
603 }
604 }
605
606 public function vk_js() {
607 ?>
608 <script type="text/javascript" src="https://vk.com/js/api/share.js?95" charset="windows-1251"></script>
609 <?php
610 }
611
612 public function wapp_share_button( $url = '', $type = 'custom', $text = '' ) {
613 if( ! wpforo_setting( 'social', 'sb', 'wapp' ) ) return;
614 $url = $url ?: WPF()->current_url;
615 $domain = wp_is_mobile() ? 'https://api.whatsapp.com' : 'https://web.whatsapp.com';
616 $text = $text ?: ( wpfval( WPF()->current_object, 'og_text' ) ? WPF()->current_object['og_text'] : WPF()->board->get_current( 'settings' )['title'] );
617 $text = urlencode( wpforo_text( strip_shortcodes( strip_tags( $text ) ), 100, false ) ) . ' URL: ' . urlencode( $url );
618 if( $type === 'custom' ) { ?>
619 <a class="wpforo-share-button wpf-wapp" href="<?php echo $domain ?>/send?text=<?php echo $text ?>"
620 title="<?php wpforo_phrase( 'Share to WhatsApp' ); ?>" target="_blank"
621 data-action="share/whatsapp/share">
622 <i class="fab fa-whatsapp" aria-hidden="true"></i>
623 </a>
624 <?php
625 } else { ?>
626 <div class="wpf-sbw wpf-sbw-wapp">
627 <?php if( wpforo_setting( 'social', 'sb_type' ) === 'button_count' ): ?>
628 <!-- WhatsApp is not available -->
629 <?php elseif( wpforo_setting( 'social', 'sb_type' ) === 'button' ): ?>
630 <a class="wpf-sb-button wpf-wapp" href="<?php echo $domain ?>/send?text=<?php echo $text ?>"
631 target="_blank" data-action="share/whatsapp/share">
632 <i class="fab fa-whatsapp" aria-hidden="true"></i> <span><?php echo wpforo_phrase( 'Share' ) ?></span>
633 </a>
634 <?php else: ?>
635 <a class="wpf-sb-button wpf-sb-icon wpf-wapp"
636 href="<?php echo $domain ?>/send?text=<?php echo $text ?>" target="_blank"
637 data-action="share/whatsapp/share">
638 <i class="fab fa-whatsapp" aria-hidden="true"></i>
639 </a>
640 <?php endif; ?>
641 </div>
642 <?php
643 }
644 }
645
646 public function lin_share_button( $url = '', $type = 'custom', $text = '' ) {
647 if( ! wpforo_setting( 'social', 'sb', 'lin' ) ) return;
648 $url = $url ?: WPF()->current_url;
649 $title = wpfval( WPF()->current_object, 'topic', 'title' );
650 $text = $text ?: ( wpfval( WPF()->current_object, 'og_text' ) ? WPF()->current_object['og_text'] : WPF()->board->get_current(
651 'settings'
652 )['title'] );
653 $text = urlencode( wpforo_text( strip_shortcodes( strip_tags( $text ) ), 500, false ) );
654 if( $type == 'custom' ) { ?>
655 <a class="wpforo-share-button wpf-lin"
656 href="https://www.linkedin.com/shareArticle?mini=true&url=<?php echo urlencode(
657 $url
658 ) ?>&title=<?php echo urlencode( $title ) ?>&summary=<?php echo $text ?>"
659 title="<?php wpforo_phrase( 'Share to LinkedIn' ); ?>" target="_blank">
660 <i class="fab fa-linkedin-in" aria-hidden="true"></i>
661 </a>
662 <?php
663 } else { ?>
664 <div class="wpf-sbw wpf-sbw-lin">
665 <?php if( wpforo_setting( 'social', 'sb_type' ) === 'button_count' ): ?>
666 <!-- LinkedIn is not available -->
667 <?php elseif( wpforo_setting( 'social', 'sb_type' ) === 'button' ): ?>
668 <a class="wpf-sb-button wpf-lin"
669 href="https://www.linkedin.com/shareArticle?mini=true&url=<?php echo urlencode(
670 $url
671 ) ?>&title=<?php echo urlencode( $title ) ?>&summary=<?php echo $text ?>" target="_blank">
672 <i class="fab fa-linkedin-in" aria-hidden="true"></i> <span><?php echo wpforo_phrase(
673 'Share'
674 ) ?></span>
675 </a>
676 <?php else: ?>
677 <a class="wpf-sb-button wpf-sb-icon wpf-lin"
678 href="https://www.linkedin.com/shareArticle?mini=true&url=<?php echo urlencode(
679 $url
680 ) ?>&title=<?php echo urlencode( $title ) ?>&summary=<?php echo $text ?>" target="_blank">
681 <i class="fab fa-linkedin-in" aria-hidden="true"></i>
682 </a>
683 <?php endif; ?>
684 </div>
685 <?php
686 }
687 }
688
689 public function vk_share_button( $url = '', $type = 'custom', $text = '' ) {
690 if( ! wpforo_setting( 'social', 'sb', 'vk' ) ) return;
691 $url = $url ?: WPF()->current_url;
692 $text = $text ?: wpfval( WPF()->current_object, 'og_text' );
693 $text = urlencode( wpforo_text( strip_shortcodes( strip_tags( $text ) ), 500, false ) );
694 if( $type === 'custom' ) { ?>
695 <a class="wpforo-share-button wpf-vk" onclick="return VK.Share.click(0, this);"
696 href="https://vk.com/share.php?url=<?php echo urlencode( $url ) ?>&description=<?php echo $text ?>"
697 title="<?php wpforo_phrase( 'Share to VK' ); ?>" target="_blank">
698 <i class="fab fa-vk" aria-hidden="true"></i>
699 </a>
700 <?php
701 } else { ?>
702 <div class="wpf-sbw wpf-sbw-vk">
703 <?php if( wpforo_setting( 'social', 'sb_type' ) === 'button_count' ): ?>
704 <script type="text/javascript">document.write(VK.Share.button(false, {
705 type: 'round',
706 text: "<?php wpforo_phrase( 'Share' ); ?>"
707 }))</script>
708 <?php elseif( wpforo_setting( 'social', 'sb_type' ) === 'button' ): ?>
709 <a class="wpf-sb-button wpf-vk" onclick="return VK.Share.click(0, this);"
710 href="https://vk.com/share.php?url=<?php echo urlencode(
711 $url
712 ) ?>&description=<?php echo $text ?>" target="_blank">
713 <i class="fab fa-vk" aria-hidden="true"></i> <span><?php echo wpforo_phrase( 'Share' ) ?></span>
714 </a>
715 <?php else: ?>
716 <a class="wpf-sb-button wpf-sb-icon wpf-vk" onclick="return VK.Share.click(0, this);"
717 href="https://vk.com/share.php?url=<?php echo urlencode(
718 $url
719 ) ?>&description=<?php echo $text ?>" target="_blank">
720 <i class="fab fa-vk" aria-hidden="true"></i>
721 </a>
722 <?php endif; ?>
723 </div>
724 <?php
725 }
726 }
727
728 public function ok_share_button( $url = '', $type = 'custom', $text = '' ) {
729 if( ! wpforo_setting( 'social', 'sb', 'ok' ) ) return;
730 $url = $url ?: WPF()->current_url;
731 if( preg_match( '|\#post-(\d+)|s', $url, $a ) ) {
732 $pid = ( isset( $a[1] ) ) ? intval( $a[1] ) : mt_rand( 100000, 999999 );
733 } else {
734 $pid = mt_rand( 100000, 999999 );
735 }
736 $text = $text ?: wpfval( WPF()->current_object, 'og_text' );
737 $text = wpforo_text( strip_shortcodes( strip_tags( $text ) ), 500, false );
738 if( $type == 'custom' ) { ?>
739 <a class="wpforo-share-button wpf-ok"
740 href="https://connect.ok.ru/offer?url=<?php echo urlencode( $url ) ?>&description=<?php echo urlencode(
741 $text
742 ) ?>" title="<?php wpforo_phrase( 'Share to OK' ); ?>" target="_blank">
743 <?php if( wpforo_setting( 'social', 'sb_icon' ) === 'figure' ): ?>
744 <i class="fab fa-odnoklassniki" aria-hidden="true"></i>
745 <?php elseif( wpforo_setting( 'social', 'sb_icon' ) === 'square' ): ?>
746 <i class="fab fa-odnoklassniki-square" aria-hidden="true"></i>
747 <?php else: ?>
748 <i class="fab fa-odnoklassniki-square" aria-hidden="true"></i>
749 <?php endif; ?>
750 </a>
751 <?php
752 } else { ?>
753 <div class="wpf-sbw wpf-sbw-ok">
754 <?php if( wpforo_setting( 'social', 'sb_type' ) === 'button_count' ): ?>
755 <div id="<?php echo 'wpfokb_' . $pid ?>"></div>
756 <script>
757 !function (d, id, did, st, title, description, image) {
758 var js = d.createElement('script')
759 js.src = 'https://connect.ok.ru/connect.js'
760 js.onload = js.onreadystatechange = function () {
761 if (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') {
762 if (!this.executed) {
763 this.executed = true
764 setTimeout(function () { OK.CONNECT.insertShareWidget(id, did, st, title, description, image) }, 0)
765 }
766 }
767 }
768 d.documentElement.appendChild(js)
769 }(document, "<?php echo 'wpfokb_' . $pid ?>", "<?php echo esc_attr(
770 $url
771 ) ?>", '{"sz":20,"st":"straight","ck":2,"lang":"<?php echo $this->local(
772 'ok'
773 ) ?>"}', '', '', '')
774 </script>
775 <?php elseif( wpforo_setting( 'social', 'sb_type' ) === 'button' ): ?>
776 <a class="wpf-sb-button wpf-ok" href="https://connect.ok.ru/offer?url=<?php echo urlencode(
777 $url
778 ) ?>&description=<?php echo urlencode( $text ) ?>" title="<?php wpforo_phrase( 'Share to OK' ); ?>"
779 target="_blank">
780 <i class="fab fa-odnoklassniki" aria-hidden="true"></i> <span><?php echo wpforo_phrase(
781 'Share'
782 ) ?></span>
783 </a>
784 <?php else: ?>
785 <a class="wpf-sb-button wpf-sb-icon wpf-ok"
786 href="https://connect.ok.ru/offer?url=<?php echo urlencode(
787 $url
788 ) ?>&description=<?php echo urlencode( $text ) ?>"
789 title="<?php wpforo_phrase( 'Share to OK' ); ?>" target="_blank">
790 <i class="fab fa-odnoklassniki" aria-hidden="true"></i>
791 </a>
792 <?php endif; ?>
793 </div>
794 <?php
795 }
796 }
797
798 public function share_toggle( $url = '', $text = '', $type = 'custom' ) {
799 WPF()->api->fb_share_button( $url, $type );
800 WPF()->api->tw_share_button( $url, $type, $text );
801 WPF()->api->wapp_share_button( $url, $type, $text );
802 WPF()->api->lin_share_button( $url, $type, $text );
803 WPF()->api->vk_share_button( $url, $type, $text );
804 WPF()->api->ok_share_button( $url, $type, $text );
805 }
806
807 public function share_buttons( $url = '', $type = 'default', $text = '' ) {
808 $template = wpfval( WPF()->current_object, 'template' );
809 $exclude = [ 'lostpassword', 'resetpassword' ];
810 if( $template && ! in_array( $template, $exclude ) ) {
811 WPF()->api->fb_share_button( $url, $type );
812 WPF()->api->tw_share_button( $url, $type, $text );
813 WPF()->api->wapp_share_button( $url, $type, $text );
814 WPF()->api->lin_share_button( $url, $type, $text );
815 WPF()->api->vk_share_button( $url, $type, $text );
816 WPF()->api->ok_share_button( $url, $type, $text );
817 }
818 }
819
820 public function rc_enqueue() {
821 $theme = wpforo_setting( 'recaptcha', 'theme' );
822 $site_key = wpforo_setting( 'recaptcha', 'site_key' );
823 wp_register_script(
824 'wpforo_recaptcha',
825 'https://www.google.com/recaptcha/api.js?onload=wpForoReCallback&render=explicit'
826 );
827 wp_add_inline_script(
828 'wpforo_recaptcha',
829 "var wpForoReCallback = function(){
830 setTimeout(function () {
831 if( typeof grecaptcha !== 'undefined' && typeof grecaptcha.render === 'function' ){
832 var rc_widgets = document.getElementsByClassName('wpforo_recaptcha_widget');
833 if( rc_widgets.length ){
834 var i;
835 for (i = 0; i < rc_widgets.length; i++) {
836 if( rc_widgets[i].firstElementChild === null ){
837 rc_widgets[i].innerHtml = '';
838 grecaptcha.render(
839 rc_widgets[i], { 'sitekey': '" . $site_key . "', 'theme': '" . $theme . "' }
840 );
841 }
842 }
843 }
844 }
845 }, 800);
846 }"
847 );
848 wp_enqueue_script( 'wpforo_recaptcha' );
849 }
850
851 public function rc_enqueue_async( $tag, $handle ) {
852 if( $handle === 'wpforo_recaptcha' ) return str_replace( '<script', '<script async defer', $tag );
853
854 return $tag;
855 }
856
857 public function rc_enqueue_css() {
858 wp_register_style( 'wpforo-rc-style', false );
859 wp_enqueue_style( 'wpforo-rc-style' );
860 $custom_css = ".wpforo_recaptcha_widget{ -webkit-transform:scale(0.9); transform:scale(0.9); -webkit-transform-origin:left 0; transform-origin:left 0; }";
861 wp_add_inline_style( 'wpforo-rc-style', $custom_css );
862 }
863
864 public function rc_widget() {
865 $site_key = wpforo_setting( 'recaptcha', 'site_key' );
866 if( $site_key ) {
867 echo '<div class="wpforo_recaptcha_widget"></div><div class="wpf-cl"></div>';
868 echo "\r\n<script>wpForoReCallback();</script>";
869 }
870 }
871
872 public function rc_check() {
873 if( isset( $_POST['g-recaptcha-response'] ) ) {
874 $secret_key = wpforo_setting( 'recaptcha', 'secret_key' );
875 $url = 'https://www.google.com/recaptcha/api/siteverify?secret=' . $secret_key . '&response=' . $_POST['g-recaptcha-response'];
876 $response = wp_remote_get( $url );
877 if( is_wp_error( $response ) || empty( $response['body'] ) ) {
878 $error = wpforo_phrase( "ERROR: Can't connect to Google reCAPTCHA API", false );
879 if( WP_DEBUG === true ) $error .= ' ( ' . $response->get_error_message() . ' )';
880
881 return $error;
882 }
883 $response = json_decode( $response['body'], true );
884 if( $response['success'] == true ) {
885 return 'success';
886 } else {
887 return wpforo_phrase( 'Google reCAPTCHA verification failed', false );
888 }
889 } else {
890 return wpforo_phrase( 'Google reCAPTCHA data are not submitted', false );
891 }
892 }
893
894 public function rc_verify() {
895 if( ! wpforo_setting( 'recaptcha', 'post_editor' ) || ! wpforo_setting( 'recaptcha', 'topic_editor' ) ) {
896 if( ! wpforo_setting( 'recaptcha', 'post_editor' ) && in_array(
897 wpfval( $_POST, 'wpfaction' ),
898 [ 'post_add', 'post_edit' ],
899 true
900 ) ) {
901 return true;
902 } elseif( ! wpforo_setting( 'recaptcha', 'topic_editor' ) && in_array(
903 wpfval( $_POST, 'wpfaction' ),
904 [ 'topic_add', 'topic_edit' ],
905 true
906 ) ) {
907 return true;
908 }
909 }
910 $result = $this->rc_check();
911 if( $result === 'success' ) {
912 return true;
913 } else {
914 WPF()->notice->add( $result, 'error' );
915 wp_safe_redirect( wpforo_get_request_uri() );
916 exit();
917 }
918 }
919
920 public function rc_verify_wp_login( $user ) {
921 if( ! isset( $_POST['log'] ) && ! isset( $_POST['pwd'] ) ) return $user;
922 if( ! wpforo_setting( 'recaptcha', 'login_form' ) || ! wpforo_setting( 'recaptcha', 'wpf_login_form' ) ) {
923 if( ! wpfval( $_POST, 'wpforologin' ) && ! wpforo_setting( 'recaptcha', 'login_form' ) ) {
924 return $user;
925 } elseif( wpfval( $_POST, 'wpforologin' ) && ! wpforo_setting( 'recaptcha', 'wpf_login_form' ) ) {
926 return $user;
927 }
928 }
929 $errors = is_wp_error( $user ) ? $user : new WP_Error();
930 $result = $this->rc_check();
931 if( $result != 'success' ) {
932 $errors->add( 'wpforo-recaptcha-error', $result );
933 $user = is_wp_error( $user ) ? $user : $errors;
934 remove_filter( 'authenticate', 'wp_authenticate_username_password' );
935 remove_filter( 'authenticate', 'wp_authenticate_cookie' );
936 }
937
938 return $user;
939 }
940
941 public function rc_verify_wp_register( $errors = '' ) {
942 if( ! is_wp_error( $errors ) ) $errors = new WP_Error();
943 if( ! wpforo_setting( 'recaptcha', 'reg_form' ) || ! wpforo_setting( 'recaptcha', 'wpf_reg_form' ) ) {
944 if( ! wpfval( $_POST, 'wpfreg' ) && ! wpforo_setting( 'recaptcha', 'reg_form' ) ) {
945 return $errors;
946 } elseif( wpfval( $_POST, 'wpfreg' ) && ! wpforo_setting( 'recaptcha', 'wpf_reg_form' ) ) {
947 return $errors;
948 }
949 }
950 $result = $this->rc_check();
951 if( $result != 'success' ) {
952 $errors->add( 'wpforo-recaptcha-error', $result );
953 }
954
955 return $errors;
956 }
957
958 public function rc_verify_wp_lostpassword( $errors = '' ) {
959 if( ! is_wp_error( $errors ) ) $errors = new WP_Error();
960 if( ! wpforo_setting( 'recaptcha', 'lostpass_form' ) || ! wpforo_setting( 'recaptcha', 'wpf_lostpass_form' ) ) {
961 if( ! wpfval( $_POST, 'wpfororp' ) && ! wpforo_setting( 'recaptcha', 'lostpass_form' ) ) {
962 return;
963 } elseif( wpfval( $_POST, 'wpfororp' ) && ! wpforo_setting( 'recaptcha', 'wpf_lostpass_form' ) ) {
964 return;
965 }
966 }
967 $result = $this->rc_check();
968 if( $result !== 'success' ) {
969 if( isset( $_POST['wc_reset_password'] ) && isset( $_POST['_wp_http_referer'] ) ) {
970 //$errors->add('wpforo-recaptcha-error', $result);
971 //return $errors;
972 } else {
973 wp_die( $result, 'reCAPTCHA ERROR', [ 'back_link' => true ] );
974 }
975 }
976 }
977 }
978