PluginProbe
Gianism / trunk
Gianism vtrunk
4.3.0 4.3.1 4.3.2 4.3.3 4.3.4 4.4.0 5.0.0 5.0.1 5.0.2 5.1.0 5.2.1 5.2.2 5.3.0 6.0.0 6.0.1 trunk 1.0 1.1 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 All 65 releases
gianism / app / Gianism / Service / AbstractService.php

AbstractService.php in Gianism trunk, at app/Gianism/Service/AbstractService.php

1,078 lines 28.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Gianism\Service;
4
5 use Gianism\Helper\Option;
6 use Gianism\Pattern\AppBase;
7 use Gianism\Pattern\Application;
8 use Gianism\Pattern\Singleton;
9 use Gianism\Controller\Login;
10
11 /**
12 * Common Utility for Social Service
13 *
14 * @package Gianism
15 * @since 2.0.0
16 * @author Takahashi Fumiki
17 * @property-read string $service_name
18 * @property-read bool $enabled
19 */
20 #[\AllowDynamicProperties]
21 abstract class AbstractService extends Application {
22
23 /**
24 * URL prefix
25 *
26 * If this property is empty,
27 * service name will be used.
28 * e.g. http://example.jp/facebook/
29 *
30 * @var string
31 */
32 public $url_prefix = '';
33
34 /**
35 * Option key to retrieve
36 *
37 * @var array
38 */
39 protected $option_keys = [];
40
41 /**
42 * Verbose service name
43 *
44 * If not set, $this->service_name will be used;
45 *
46 * @var string
47 */
48 public $verbose_service_name = '';
49
50 /**
51 * Constructor
52 *
53 * If you override constructor, call inside that
54 *
55 * <code>
56 * parent::construct();
57 * </code>
58 *
59 * @param array $argument
60 */
61 protected function __construct( array $argument = array() ) {
62 parent::__construct( $argument );
63 // Setup name
64 if ( empty( $this->verbose_service_name ) ) {
65 $this->verbose_service_name = $this->service_name;
66 }
67 if ( empty( $this->url_prefix ) ) {
68 $this->url_prefix = $this->service_name;
69 }
70 // Sync options
71 $this->fill_default_option();
72 $this->set_option();
73 add_action( Option::UPDATED_ACTION, array( $this, 'set_option' ) );
74 // Register actions if enabled.
75 if ( $this->enabled ) {
76 // Initialize
77 $this->init_action();
78 // Show profile page
79 $connect_priority = apply_filters( 'gianism_service_priority', 10, $this->service_name, 'connect' );
80 add_action( 'gianism_user_profile', array( $this, 'profile_connect' ), $connect_priority );
81 // Add Hook on Login Form page
82 $login_priority = apply_filters( 'gianism_service_priority', 10, $this->service_name, 'login' );
83 add_action( 'gianism_login_form', array( $this, 'login_form' ), $login_priority, 3 );
84 if ( method_exists( $this, 'print_script' ) ) {
85 //Add Hook On footer
86 add_action( 'admin_print_footer_scripts', array( $this, 'print_script' ) );
87 add_action( 'wp_footer', array( $this, 'print_script' ) );
88 add_action( 'login_footer', array( $this, 'print_script' ) );
89 }
90 }
91 }
92
93 /**
94 * Initialize
95 *
96 * If some stuff is required, override this.
97 *
98 * @return void
99 */
100 protected function init_action() {
101 // Do stuff.
102 }
103
104 /**
105 * Fill default option
106 */
107 final public function fill_default_option() {
108 foreach ( $this->option_keys as $key => $default ) {
109 $this->option->set_default( $key, $default );
110 }
111 }
112
113 /**
114 * Setup default option
115 *
116 * @return void
117 */
118 final public function set_option() {
119 foreach ( $this->option_keys as $key => $default ) {
120 if ( isset( $this->option->values[ $key ] ) ) {
121 $this->{$key} = $this->option->values[ $key ];
122 }
123 }
124 }
125
126 /**
127 * Return default option keys
128 *
129 * @return array
130 */
131 final public function get_keys() {
132 return $this->option_keys;
133 }
134
135 /**
136 * Get setting path
137 *
138 * If this class is external, override this function.
139 *
140 * @param string $template_dir setting, setup
141 * @return string
142 */
143 public function get_admin_template( $template_dir ) {
144 $dir = trailingslashit( $this->dir . 'templates/' . basename( $template_dir ) );
145 if ( is_dir( $dir ) ) {
146 return sprintf( '%s%s.php', $dir, $this->service_name );
147 } else {
148 return false;
149 }
150 }
151
152 /**
153 * Detect if user is connected to this service
154 *
155 * @param int $user_id
156 *
157 * @return bool
158 */
159 abstract public function is_connected( $user_id );
160
161 /**
162 * Disconnect user from this service
163 *
164 * @param int $user_id
165 *
166 * @return mixed
167 */
168 abstract public function disconnect( $user_id );
169
170 /**
171 * This controller return always false
172 *
173 * @param string $mail
174 *
175 * @return bool
176 */
177 public function is_pseudo_mail( $mail ) {
178 return false;
179 }
180
181 /**
182 * Called on redirect endpoint
183 *
184 * @param string $action
185 * @param \WP_Query $wp_query
186 *
187 * @return void
188 */
189 public function parse_request( $action, \WP_Query &$wp_query ) {
190 nocache_headers();
191 $method = 'handle_' . strtolower( str_replace( '-', '_', $action ) );
192 if ( ! $this->enabled ) {
193 // Not enabled.
194 $wp_query->set_404();
195 return;
196 }
197 if ( 'default' !== $action && ! $this->input->verify_nonce( $this->input->nonce_action( "{$this->service_name}_{$action}" ) ) ) {
198 // If not default, nonce required.
199 $this->input->wp_die( __( 'This request seems to be a wrong access. Please try again.', 'wp-gianism' ), 403 );
200 }
201 if ( 'default' !== $action && method_exists( get_called_class(), $method ) ) {
202 // Method found, just call
203 $this->{$method}( $wp_query );
204 } else {
205 // Else, call default.
206 $specified_action = $this->session->get( 'action' );
207 if ( $specified_action ) {
208 // If session is set, override with it.
209 $action = $specified_action;
210 }
211 $this->handle_default( $action );
212 }
213 }
214
215 /**
216 * Handle callback request
217 *
218 * This function must exit at last.
219 *
220 * @param string $action
221 *
222 * @return void
223 */
224 abstract protected function handle_default( $action );
225
226 /**
227 * Handle connect
228 *
229 * @param \WP_Query $wp_query
230 */
231 protected function handle_connect( \WP_Query $wp_query ) {
232 try {
233 // Is user logged in?
234 if ( ! is_user_logged_in() ) {
235 throw new \Exception( __( 'You must be logged in.', 'wp-gianism' ) );
236 }
237 // Is user connected already?
238 if ( $this->is_connected( get_current_user_id() ) ) {
239 // translators: %s is service name.
240 throw new \Exception( sprintf( __( 'You are already connected with %s', 'wp-gianism' ), $this->verbose_service_name ) );
241 }
242 // Set redirect URL
243 $url = $this->get_api_url( 'connect' );
244 if ( ! $url ) {
245 throw new \Exception( __( 'Sorry, but failed to connect with API.', 'wp-gianism' ) );
246 }
247 // Write session
248 $this->session->write(
249 [
250 'redirect_to' => $this->input->get( 'redirect_to' ),
251 'action' => 'connect',
252 ]
253 );
254 // OK, let's redirect.
255 wp_redirect( $url );
256 exit;
257 } catch ( \Exception $e ) {
258 $this->input->wp_die( $e->getMessage() );
259 }
260 }
261
262 /**
263 * Handle disconnect
264 *
265 * @param \WP_Query $wp_query
266 */
267 protected function handle_disconnect( \WP_Query $wp_query ) {
268 try {
269 $redirect_url = $this->input->get( 'redirect_to' ) ?: admin_url( 'profile.php' );
270 /**
271 * Filter redirect URL
272 */
273 $redirect_url = apply_filters( '', $redirect_url, $this->service_name, $wp_query );
274 // Is user logged in?
275 if ( ! is_user_logged_in() ) {
276 throw new \Exception( __( 'You must be logged in.', 'wp-gianism' ) );
277 }
278 // Has connection?
279 if ( ! $this->is_connected( get_current_user_id() ) ) {
280 // translators: %s is service name.
281 throw new \Exception( sprintf( __( 'Your account is not connected with %s', 'wp-gianism' ), $this->verbose_service_name ) );
282 }
283 // O.K.
284 $this->disconnect( get_current_user_id() );
285 // translators: %s is service name.
286 $this->add_message( sprintf( __( 'Your account is now unlinked from %s.', 'wp-gianism' ), $this->verbose_service_name ) );
287 // Redirect
288 wp_redirect( $this->filter_redirect( $redirect_url, 'disconnect' ) );
289 exit;
290 } catch ( \Exception $e ) {
291 $this->input->wp_die( $e->getMessage() );
292 }
293 }
294
295 /**
296 * Make user login
297 *
298 * @param \WP_Query $wp_query
299 */
300 public function handle_login( \WP_Query $wp_query ) {
301 try {
302 // Is user logged in?
303 if ( is_user_logged_in() ) {
304 throw new \Exception( __( 'You are already logged in.', 'wp-gianism' ), 403 );
305 }
306 // Create URL
307 $url = $this->get_api_url( 'login' );
308 if ( ! $url ) {
309 throw new \Exception( __( 'Sorry, but failed to connect with API.', 'wp-gianism' ) );
310 }
311 // Write session
312 $session = [
313 'redirect_to' => $this->input->get( 'redirect_to' ),
314 'action' => 'login',
315 ];
316 $blog_id = $this->input->get( 'blog_id' );
317 if ( $blog_id ) {
318 // Store blog id if blog id is specified.
319 $session['blog_id'] = (int) $blog_id;
320 }
321 $this->session->write( $session );
322 // O.K. let's redirect
323 wp_redirect( $url );
324 exit;
325 } catch ( \Exception $e ) {
326 $this->input->wp_die( $e->getMessage() );
327 }
328 }
329
330 /**
331 * Show connect button on profile page
332 *
333 * @param \WP_User $user
334 *
335 * @return void
336 */
337 public function profile_connect( \WP_User $user ) {
338 $html = <<<EOS
339 <tr>
340 <th>{$this->verbose_service_name}</th>
341 <td class="wpg-connector {$this->service_name}">
342 <p class="description desc-%s"><i class="lsf lsf-%s"></i> %s</p>
343 <p class="button-wrap">%s</p>
344 </td><!-- .wpg-connector -->
345 </tr>
346 EOS;
347 $is_connected = $this->is_connected( $user->ID );
348 if ( $is_connected ) {
349 $class_name = 'connected';
350 $icon_class = 'check';
351 $message = $this->connection_message( 'connected' );
352 $button = $this->is_pseudo_mail( $user->user_email ) ? '' : $this->disconnect_button();
353 } else {
354 $class_name = 'disconnected';
355 $icon_class = 'login';
356 $message = $this->connection_message( 'disconnected' );
357 $button = $this->connect_button();
358 }
359 /**
360 * Filtering message on connection table
361 *
362 * @filter gianism_connect_message
363 * @param string $message
364 * @param string $service
365 * @param bool $is_connected
366 *
367 * @return string
368 */
369 $message = apply_filters( 'gianism_connect_message', $message, $this->service_name, $is_connected );
370 printf( $html, $class_name, $icon_class, $message, $button );
371 }
372
373 /**
374 * Connection message
375 *
376 * Overriding this function, you can
377 * customize connection message
378 *
379 * @param string $context
380 *
381 * @return string
382 */
383 public function connection_message( $context = 'connected' ) {
384 switch ( $context ) {
385 case 'connected':
386 // translators: %s is service name.
387 return sprintf( __( 'Your account is already connected with %s account.', 'wp-gianism' ), $this->verbose_service_name );
388 break;
389 default: // Disconnected
390 // translators: %1$s is service name, %2$s is site name.
391 return sprintf( __( 'Connecting with %1$s, you can login with %2$s via %1$s without password or email address.', 'wp-gianism' ), $this->verbose_service_name, get_bloginfo( 'name' ) );
392 break;
393 }
394 }
395
396 /**
397 * Display login buttons
398 *
399 * @param boolean $is_register
400 * @param string $redirect_to
401 * @param string $context
402 *
403 * @return void
404 */
405 public function login_form( $is_register = false, $redirect_to = '', $context = '' ) {
406 echo $this->login_button( $redirect_to, $is_register, $context );
407 }
408
409 /**
410 * Returns redirect to url if set.
411 *
412 * @param string $default_url
413 * @param array $args
414 *
415 * @return string
416 */
417 protected function get_redirect_to( $default_url, $args = array() ) {
418 $redirect_to = $default_url;
419 if ( isset( $_REQUEST['redirect_to'] ) ) {
420 $domain = $_SERVER['SERVER_NAME'];
421 if ( preg_match( "/^(https?:\/\/{$domain}|\/)/", $_REQUEST['redirect_to'] ) ) {
422 $redirect_to = $_REQUEST['redirect_to'];
423 if ( ! empty( $args ) ) {
424 $redirect_to = add_query_arg( $args, $redirect_to );
425 }
426 }
427 }
428 return $this->filter_redirect( $redirect_to, 'default' );
429 }
430
431 /**
432 * Returns current action name.
433 *
434 * @return string
435 */
436 protected function get_action() {
437 return $this->input->request( 'wpg' );
438 }
439
440 /**
441 * Return api URL to authenticate
442 *
443 * If you need additional information (ex. token),
444 * use $this->session->write inside.
445 *
446 * <code>
447 * $this->session->write('token', $token);
448 * return $url;
449 * </code>
450 *
451 * @param string $action 'connect', 'login'
452 *
453 * @return string|false URL to redirect
454 * @throws \Exception
455 */
456 abstract protected function get_api_url( $action );
457
458 /**
459 * Returns link to filter
460 *
461 * @param string $markup
462 * @param string $href
463 * @param string $text
464 * @param bool $is_register
465 *
466 * @return string
467 */
468 public function filter_link( $markup, $href, $text, $is_register = false, $context = '' ) {
469 /**
470 * gianism_link_html
471 *
472 * @package Gianism
473 * @since 3.0.4 Add context parameter.
474 * @param string $markup Final markup.
475 * @param string $href Link's attribute.
476 * @param string $text Link text.
477 * @param bool $is_register Is register form.
478 * @param string $service Service name. facebook, twitter, etc.
479 * @param string $context Context. Default empty.
480 */
481 $link = apply_filters( 'gianism_link_html', $markup, $href, $text, $is_register, $this->service_name, $context );
482 return $link;
483 }
484
485 /**
486 * Filter redirect URL
487 *
488 * @param string $url
489 * @param string $context login, connect, disconnect
490 *
491 * @return string
492 */
493 protected function filter_redirect( $url, $context ) {
494 /**
495 * Filter hook to override redirect url
496 *
497 * @filter gianism_redirect_to
498 * @param string $url The URL user will be redirect to.
499 * @param string $service 'facebook', 'twitter', and so on.
500 * @param string $context The context of this redirect.
501 */
502 return apply_filters( 'gianism_redirect_to', $url, $this->service_name, $context );
503 }
504
505 /**
506 * Get URL for immediate endpoint.
507 *
508 * @param string $action 'connect', 'disconnect', 'login' or else.
509 * @param string $nonce_key If empty, nonce won't be set.
510 * @param array $args
511 *
512 * @return string
513 */
514 public function get_redirect_endpoint( $action = '', $nonce_key = '', $args = array() ) {
515 $prefix = empty( $this->url_prefix ) ? $this->service_name : $this->url_prefix;
516 $pre_prefix = $this->option->get_formatted_prefix();
517 if ( $pre_prefix ) {
518 $prefix = $pre_prefix . '/' . $prefix;
519 }
520 $scheme = $this->option->is_ssl_required() ? 'https' : 'http';
521 $base_url = $this->option->is_network_activated() ? get_site_url( $this->option->get_parent_blog_id(), '', $scheme ) : home_url( '', $scheme );
522 $url = trailingslashit( untrailingslashit( $base_url ) . '/' . ltrim( $prefix, '/' ) );
523 if ( ! empty( $action ) ) {
524 $url .= $action . '/';
525 }
526 if ( ! empty( $args ) ) {
527 $url .= '?' . http_build_query( $args );
528 }
529 if ( ! empty( $nonce_key ) ) {
530 $url = wp_nonce_url( $url, $this->input->nonce_action( $nonce_key ) );
531 }
532 return $url;
533 }
534
535 /**
536 * Detect if current client is smart phone.
537 *
538 * @deprecated 3.0.0
539 * @return boolean
540 */
541 protected function is_smartphone() {
542 return (bool) preg_match( '/(iPhone|iPad|Android|MSIEMobile)/', $this->input->server( 'HTTP_USER_AGENT' ) );
543 }
544
545 /**
546 * Create common button
547 *
548 * @param string $text Text to display.
549 * @param string $href Link's href.
550 * @param bool $icon_name Icon name of LSF.
551 * @param array $class_names Class name for this button.
552 * @param array $attributes Attributes for link.
553 * @param string $context Display context. Default empty.
554 *
555 * @return string
556 */
557 public function button( $text, $href, $icon_name = true, array $class_names = [ 'wpg-button' ], array $attributes = [], $context = '' ) {
558 // Create icon
559 if ( true === $icon_name ) {
560 $icon = "<i class=\"lsf lsf-{$this->service_name}\"></i> ";
561 } elseif ( is_string( $icon_name ) ) {
562 $icon = "<i class=\"lsf lsf-{$icon_name}\"></i> ";
563 } else {
564 $icon = '';
565 }
566 // If SVG exists, use it for guideline button style.
567 if ( in_array( 'wpg-guideline-button', $class_names, true ) ) {
568 $file = $this->svg_path();
569 if ( $file ) {
570 $icon = $this->url . '/assets/img/brands/' . $file;
571 $icon = sprintf( '<img src="%s" alt="" class="wpg-icon" />', esc_url( $icon ) );
572 }
573 }
574 $class_attr = implode(
575 ' ',
576 array_map(
577 function ( $attr ) {
578 return esc_attr( $attr );
579 },
580 $class_names
581 )
582 );
583 $atts = [];
584 foreach ( $attributes as $key => $value ) {
585 switch ( $key ) {
586 case 'onclick':
587 // Do nothing
588 break;
589 default:
590 $key = 'data-' . $key;
591 break;
592 }
593 $value = esc_attr( $value );
594 $atts[] = "{$key}=\"{$value}\"";
595 }
596 $atts = ' ' . implode( ' ', $atts );
597
598 switch ( $context ) {
599 case 'woo-checkout':
600 return __( 'Log in', 'wp-gianism' );
601 break;
602 default:
603 return sprintf(
604 '<a href="%2$s" rel="nofollow" class="%4$s"%5$s>%3$s%1$s</a>',
605 $text,
606 esc_url( $href ),
607 $icon,
608 $class_attr,
609 $atts
610 );
611 break;
612 }
613 }
614
615 /**
616 * Login label
617 *
618 * @param bool $register
619 * @param string $context
620 *
621 * @return string
622 */
623 protected function login_label( $register = false, $context = '' ) {
624 // translators: %s is service name.
625 return sprintf( __( 'Log in with %s', 'wp-gianism' ), $this->verbose_service_name );
626 }
627
628 /**
629 * Show login button
630 *
631 * @param string $redirect
632 * @param bool $register
633 * @param string $context
634 *
635 * @return string
636 */
637 public function login_button( $redirect = '', $register = false, $context = '' ) {
638 if ( ! $redirect ) {
639 $redirect = admin_url( 'profile.php' );
640 /**
641 * gianism_default_redirect_link
642 *
643 * @package Gianism
644 * @since 3.0.4
645 * @param string $redirect Redirect URL.
646 * @param string $service Service name. e.g. twitter.
647 * @param bool $register Detect if this is register context.
648 * @param string $context Context of this button. Default empty string.
649 */
650 $redirect = apply_filters( 'gianism_default_redirect_link', $redirect, $this->service_name, $register, $context );
651 }
652 $url_args = [
653 'redirect_to' => $redirect,
654 ];
655 if ( $this->network->is_child_site() ) {
656 $url_args['blog_id'] = get_current_blog_id();
657 }
658 $url = $this->get_redirect_endpoint( 'login', $this->service_name . '_login', $url_args );
659 $text = apply_filters( 'gianism_login_button_label', $this->login_label(), $register, $context );
660
661 $args = [
662 'gianism-ga-category' => "gianism/{$this->service_name}",
663 'gianism-ga-action' => 'login',
664 'gianism-ga-label' => sprintf( $this->_( 'Login with %s' ), $this->verbose_service_name ),
665 ];
666 if ( $this->need_confirmation( $context ) ) {
667 $args['gianism-confirmation'] = $this->confirmation_message( $context );
668 /**
669 * gianism_user_credentails
670 *
671 * @param array $credentials An array of credentail names. Default, [ 'User ID', 'Email' ]
672 * @param string $service
673 * @return array
674 */
675 $credentials = apply_filters( 'gianism_user_credentials', $this->target_credentials( $context ), $this->service_name );
676 $args['gianism-target'] = implode( ',', $credentials );
677 }
678 // Build class - always use guideline button style.
679 $class_names = [ 'wpg-guideline-button' ];
680 $class_names[] = $this->service_name;
681 $button = $this->button( $text, $url, $this->service_name, $class_names, $args, $context );
682
683 return $this->filter_link( $button, $url, $text, $register, $context );
684 }
685
686
687 /**
688 * Get connect button
689 *
690 * @param string $redirect_to If not set, profile page's URL
691 *
692 * @return string
693 */
694 public function connect_button( $redirect_to = '' ) {
695 if ( empty( $redirect_to ) ) {
696 $redirect_to = apply_filters( 'gianism_default_redirect_link', admin_url( 'profile.php' ), $this->service_name, false, 'connect' );
697 }
698 $url = $this->get_redirect_endpoint(
699 'connect',
700 $this->service_name . '_connect',
701 array(
702 'redirect_to' => $redirect_to,
703 )
704 );
705 $args = array(
706 'gianism-ga-category' => "gianism/{$this->service_name}",
707 'gianism-ga-action' => 'connect',
708 // translators: %s is service name.
709 'gianism-ga-label' => sprintf( __( 'Connect %s', 'wp-gianism' ), $this->verbose_service_name ),
710 );
711
712 return $this->button( __( 'Connect', 'wp-gianism' ), $url, 'link', array( 'wpg-button', 'connect' ), $args );
713 }
714
715 /**
716 * Get disconnect button
717 *
718 * @param string $redirect_to If not set, profile page's URL
719 *
720 * @return string
721 */
722 public function disconnect_button( $redirect_to = '' ) {
723 if ( empty( $redirect_to ) ) {
724 $redirect_to = apply_filters( 'gianism_default_redirect_link', admin_url( 'profile.php' ), $this->service_name, false, 'disconnect' );
725 }
726 $url = $this->get_redirect_endpoint(
727 'disconnect',
728 $this->service_name . '_disconnect',
729 array(
730 'redirect_to' => $redirect_to,
731 )
732 );
733 $args = array(
734 'gianism-ga-category' => "gianism/{$this->service_name}",
735 'gianism-ga-action' => 'disconnect',
736 // translators: %s is service name.
737 'gianism-ga-label' => sprintf( __( 'Disconnect %s', 'wp-gianism' ), $this->verbose_service_name ),
738 // translators: %s is service name.
739 'gianism-confirm' => sprintf( __( 'You really disconnect from %s? If so, please be sure about your credential(email, password), or else you might not be able to login again.', 'wp-gianism' ), $this->verbose_service_name ),
740 );
741
742 return $this->button( __( 'Disconnect', 'wp-gianism' ), $url, 'logout', array( 'wpg-button', 'disconnect' ), $args );
743 }
744
745 /**
746 * Set login cookie.
747 *
748 * @param int $user_id
749 */
750 protected function set_auth_cookie( $user_id ) {
751 /**
752 * Fires just before setting login cookie.
753 *
754 * @param int $user_id
755 * @param string $service_name
756 */
757 do_action( 'gianism_before_set_login_cookie', $user_id, $this->service_name );
758 // Should remember?
759 $remember = apply_filters( 'gianism_should_remember_cookie', true, $user_id, $this->service_name );
760 wp_set_auth_cookie( $user_id, $remember );
761 /**
762 * Fires just after setting login cookie.
763 *
764 * @param int $user_id
765 * @param string $service_name
766 */
767 do_action( 'gianism_after_set_login_cookie', $user_id, $this->service_name );
768 }
769
770 /**
771 * Fires connect hook
772 *
773 * @param int $user_id
774 * @param mixed $data
775 * @param bool $on_creation
776 */
777 protected function hook_connect( $user_id, $data, $on_creation = false ) {
778 /**
779 * Fires when user account is connected from SNS account.
780 *
781 * @action wpg_connect
782 *
783 * @param int $user_id
784 * @param mixed $data
785 * @param string $service_name
786 * @param bool $on_creation
787 */
788 do_action( 'wpg_connect', $user_id, $data, $this->service_name, (bool) $on_creation );
789 }
790
791 /**
792 * Fires disconnect hook
793 *
794 * @param $user_id
795 */
796 protected function hook_disconnect( $user_id ) {
797 /**
798 * Fires when user account is disconnected from SNS account.
799 *
800 * @action wpg_disconnect
801 *
802 * @param int $user_id
803 * @param string $service_name
804 */
805 do_action( 'wpg_disconnect', $user_id, $this->service_name );
806 }
807
808 /**
809 * Use's password is automatically generated
810 *
811 * @param int $user_id
812 */
813 protected function user_password_unknown( $user_id ) {
814 update_user_meta( $user_id, '_wpg_unknown_password', true );
815 }
816
817 /**
818 * Create valid username from email address
819 *
820 * @param string $email
821 *
822 * @return string
823 * @throws \Exception
824 */
825 protected function valid_username_from_mail( $email ) {
826 $emails = explode( '@', $email );
827 $suffix = array_shift( $emails );
828 if ( ! username_exists( $suffix ) ) {
829 return $suffix;
830 }
831 $service_domain = $suffix . '@' . $this->service_name;
832 if ( ! username_exists( $service_domain ) ) {
833 return $service_domain;
834 }
835 $original_domain = $suffix . '@' . $_SERVER['SERVER_NAME'];
836 if ( ! username_exists( $original_domain ) ) {
837 return $original_domain;
838 }
839 throw new \Exception( __( 'Cannot create valid user name.', 'wp-gianism' ) );
840 }
841
842 /**
843 * Returns API error string
844 *
845 * @return string
846 */
847 protected function api_error_string() {
848 // translators: %s is service name.
849 return sprintf( __( '%s API returns error.', 'wp-gianism' ), $this->verbose_service_name );
850 }
851
852 /**
853 * Message account duplication
854 *
855 * @return string
856 */
857 protected function duplicate_account_string() {
858 // translators: %s is service name.
859 return sprintf( __( 'This %s account is already connected with others.', 'wp-gianism' ), $this->verbose_service_name );
860 }
861
862 /**
863 * Add welcome message
864 *
865 * @param string $who
866 */
867 protected function welcome( $who ) {
868 // translators: %s is user name.
869 $this->add_message( sprintf( __( 'Welcome, %s!', 'wp-gianism' ), $who ) );
870 }
871
872 /**
873 * Add error message
874 *
875 * @param string $message
876 */
877 protected function auth_fail( $message ) {
878 $this->add_message( __( 'Sorry, but failed to Authenticate. Please try again.', 'wp-gianism' ) . ' ' . $message, true );
879 }
880
881 /**
882 * Add error message
883 *
884 * @return string
885 */
886 protected function mail_fail_string() {
887 return __( 'Cannot retrieve email address.', 'wp-gianism' );
888 }
889
890 /**
891 * Registration error string
892 *
893 * @return string
894 */
895 protected function registration_error_string() {
896 return __( 'Cannot register. Please try again later.', 'wp-gianism' );
897 }
898
899 /**
900 * Kill wrong access
901 */
902 protected function kill_wrong_access() {
903 // translators: %1$s URL, %2$s Blog name.
904 $this->input->wp_die( sprintf( __( 'Sorry, but wrong access. Please go back to <a href="%1$s">%2$s</a>.', 'wp-gianism' ), home_url( '/' ), get_bloginfo( 'name' ) ), 500, false );
905 }
906
907 /**
908 * Test if can register.
909 *
910 * @return bool
911 * @throws \Exception
912 */
913 protected function test_user_can_register() {
914 if ( ! $this->user_can_register() ) {
915 // translators: %s is service name.
916 throw new \Exception( sprintf( __( 'Registration via %s is not allowed.', 'wp-gianism' ), $this->verbose_service_name ) );
917 }
918
919 return true;
920 }
921
922 /**
923 * Detect if user can register or not
924 *
925 * @return bool
926 */
927 public function user_can_register() {
928 /**
929 * Whether if user can register for service
930 *
931 * @filter gianism_user_can_register
932 * @param bool $can_register
933 * @param string $service
934 *
935 * @return bool
936 */
937 return (bool) apply_filters( 'gianism_user_can_register', $this->option->user_can_register(), $this->service_name );
938 }
939
940 /**
941 * Get Request
942 *
943 * @param string $endpoint
944 * @param string|array $request
945 * @param string $method If x-www-form-urlencoded required, pass array or else, pass query string.
946 * @param bool $json if this request is JSON
947 * @param array $additional_headers Additional headers.
948 *
949 * @return array|\stdClass|bool|null
950 */
951 protected function get_response( $endpoint, $request = '', $method = 'POST', $json = false, array $additional_headers = array() ) {
952 $method = strtoupper( $method );
953 $ch = curl_init();
954 curl_setopt( $ch, CURLOPT_TIMEOUT, 20 );
955 curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 20 );
956 curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
957 curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
958 if ( $json ) {
959 $additional_headers[] = 'Content-Type: application/json';
960 }
961 switch ( $method ) {
962 case 'PUT':
963 case 'PATCH':
964 curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, $method );
965 // Other, same as POST.
966 case 'POST':
967 curl_setopt( $ch, CURLOPT_POST, true );
968 if ( is_array( $request ) ) {
969 $additional_headers = array_merge( $additional_headers, array( 'Content-Type: application/x-www-form-urlencoded' ) );
970 curl_setopt( $ch, CURLOPT_POSTFIELDS, http_build_query( $request ) );
971 } else {
972 curl_setopt( $ch, CURLOPT_POSTFIELDS, $request );
973 }
974 break;
975 case 'DELETE':
976 curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, 'DELETE' );
977 // Other, same as GET.
978 case 'GET':
979 $args = array();
980 if ( is_array( $request ) ) {
981 $request = http_build_query( $request );
982 }
983 if ( ! empty( $request ) ) {
984 $endpoint .= '?' . $request;
985 }
986 break;
987 default:
988 return array();
989 }
990 curl_setopt( $ch, CURLOPT_URL, $endpoint );
991 if ( ! empty( $additional_headers ) ) {
992 curl_setopt( $ch, CURLOPT_HTTPHEADER, $additional_headers );
993 }
994 $response = curl_exec( $ch );
995 curl_close( $ch );
996
997 return json_decode( $response );
998 }
999
1000 /**
1001 * Does this service needs confirmation?
1002 *
1003 * @param string $context 'login' or 'register'
1004 * @return bool
1005 */
1006 public function need_confirmation( $context = 'login' ) {
1007 return false;
1008 }
1009
1010 /**
1011 * Get confirmation message
1012 *
1013 * @param string $context
1014 * @return string
1015 */
1016 public function confirmation_message( $context = 'login' ) {
1017 $message = sprintf(
1018 // translators: %1$s blog name, %2$s is service name.
1019 __( '%1$s gets your information below from %2$s. Please proceed with your agreement.', 'wp-gianism' ),
1020 get_bloginfo( 'name' ),
1021 $this->verbose_service_name
1022 );
1023 /**
1024 * gianism_confirmation_message
1025 *
1026 * @param string $message
1027 * @param string $service
1028 * @param string $context
1029 * @return string
1030 */
1031 return apply_filters( 'gianism_confirmation_message', $message, $this->service_name, $context );
1032 }
1033
1034 /**
1035 * Information to retrieve.
1036 *
1037 * @param string $context
1038 * @return array
1039 */
1040 public function target_credentials( $context = 'login' ) {
1041 return [
1042 // translators: %s is serfice name.
1043 'id' => sprintf( __( '%s User ID', 'wp-gianism' ), $this->verbose_service_name ),
1044 'profile' => __( 'Profile', 'wp-gianism' ),
1045 'email' => __( 'Email', 'wp-gianism' ),
1046 ];
1047 }
1048
1049 /**
1050 * Get SVG path
1051 *
1052 * @return string
1053 */
1054 protected function svg_path() {
1055 return '';
1056 }
1057
1058 /**
1059 * Getter
1060 *
1061 * @param string $name
1062 *
1063 * @return mixed
1064 */
1065 public function __get( $name ) {
1066 switch ( $name ) {
1067 case 'service_name':
1068 $segments = explode( '\\', get_called_class() );
1069
1070 return strtolower( $segments[ count( $segments ) - 1 ] );
1071 case 'enabled':
1072 return $this->option->is_enabled( $this->service_name );
1073 default:
1074 return parent::__get( $name );
1075 }
1076 }
1077 }
1078