Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
31 / 31
100.00% covered (success)
100.00%
8 / 8
CRAP
100.00% covered (success)
100.00%
1 / 1
Shortcode
100.00% covered (success)
100.00%
31 / 31
100.00% covered (success)
100.00%
8 / 8
17
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 name
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 init
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 callback
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
2
 scan_shortcode
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
5
 redirect_url
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 state_redirect
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 should_display
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
4
1<?php
2/**
3 * Shortcode Class.
4 *
5 * @package RtCamp\GoogleLogin
6 * @since 1.0.0
7 */
8
9declare(strict_types=1);
10
11namespace RtCamp\GoogleLogin\Modules;
12
13use RtCamp\GoogleLogin\Interfaces\Module as ModuleInterface;
14use RtCamp\GoogleLogin\Utils\Helper;
15use RtCamp\GoogleLogin\Utils\GoogleClient;
16use function RtCamp\GoogleLogin\plugin;
17
18/**
19 * Class Shortcode
20 *
21 * @package RtCamp\GoogleLogin
22 */
23class Shortcode implements ModuleInterface {
24
25    /**
26     * Shortcode tag.
27     *
28     * @var string
29     */
30    const TAG = 'google_login';
31
32    /**
33     * Redirect URL.
34     *
35     * @var string
36     */
37    public $redirect_uri;
38
39    /**
40     * Google client instance.
41     *
42     * @var GoogleClient
43     */
44    private $gh_client;
45
46    /**
47     * Assets object.
48     *
49     * @var Assets
50     */
51    private $assets;
52
53    /**
54     * Shortcode constructor.
55     *
56     * @param GoogleClient $client GH Client object.
57     * @param Assets       $assets Assets object.
58     */
59    public function __construct( GoogleClient $client, Assets $assets ) {
60        $this->gh_client = $client;
61        $this->assets    = $assets;
62    }
63
64    /**
65     * Module name.
66     *
67     * @return string
68     */
69    public function name(): string {
70        return 'shortcode';
71    }
72
73    /**
74     * Initialization actions.
75     */
76    public function init(): void {
77        add_shortcode( self::TAG, [ $this, 'callback' ] );
78        add_filter( 'do_shortcode_tag', [ $this, 'scan_shortcode' ], 10, 3 );
79    }
80
81    /**
82     * Callback function for shortcode rendering.
83     *
84     * @param array $attrs Shortcode attributes.
85     *
86     * @return string
87     */
88    public function callback( $attrs = [] ): string {
89        $attrs = shortcode_atts(
90            [
91                'button_text'   => __( 'Login with google', 'login-with-google' ),
92                'force_display' => 'no',
93                'redirect_to'   => get_permalink(),
94            ],
95            $attrs,
96            self::TAG
97        );
98
99        if ( ! $this->should_display( $attrs ) ) {
100            return '';
101        }
102
103        $this->redirect_uri = $attrs['redirect_to'];
104
105        add_filter( 'rtcamp.google_redirect_url', [ $this, 'redirect_url' ] );
106        add_filter( 'rtcamp.google_login_state', [ $this, 'state_redirect' ] );
107
108        $attrs['login_url'] = $this->gh_client->authorization_url();
109
110        remove_filter( 'rtcamp.google_login_state', [ $this, 'state_redirect' ] );
111        remove_filter( 'rtcamp.google_redirect_url', [ $this, 'redirect_url' ] );
112        $template = trailingslashit( plugin()->template_dir ) . 'google-login-button.php';
113
114        return Helper::render_template( $template, $attrs, false );
115    }
116
117    /**
118     * Check if the current single post or page contains
119     * shortcode. If it does, enqueue the relevant style.
120     *
121     * @param string       $output Shortcode output.
122     * @param string       $tag Shortcode tag being processed.
123     * @param array|string $attrs Shortcode attributes.
124     *
125     * @return string
126     */
127    public function scan_shortcode( string $output, string $tag, $attrs ): string {
128        if ( ( ! is_single() && ! is_page() ) || self::TAG !== $tag || ! $this->should_display( (array) $attrs ) ) {
129            return $output;
130        }
131
132        $this->assets->enqueue_login_styles();
133
134        return $output;
135    }
136
137
138    /**
139     * Filter redirect URL as per shortcode param.
140     *
141     * @param string $url Login URL.
142     *
143     * @return string
144     */
145    public function redirect_url( string $url ): string {
146
147        return remove_query_arg( 'redirect_to', $url );
148    }
149
150    /**
151     * Add redirect_to location in state.
152     *
153     * @param array $state State data.
154     *
155     * @return array
156     */
157    public function state_redirect( array $state ): array {
158        if ( is_null( $this->redirect_uri ) ) {
159            return $state;
160        }
161
162        $state['redirect_to'] = $this->redirect_uri;
163
164        return $state;
165    }
166
167    /**
168     * Determines whether to process the shortcode.
169     *
170     * @param array $attrs Shortcode attributes.
171     *
172     * @return bool
173     */
174    private function should_display( array $attrs ): bool {
175        if ( ! is_user_logged_in() || ( ! empty( $attrs['force_display'] ) && 'yes' === (string) $attrs['force_display'] ) ) {
176            return true;
177        }
178
179        return false;
180    }
181}