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

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