Completed
Push — master ( 783e10...2dcfb9 )
by Dimas
08:03
created

client::create_auth_url()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace GoogleExt;
4
5
use Filemanager\file;
6
//use Google_Client;
7
use Google\Client as Google_Client;
8
9
class client extends Google_Client
10
{
11
  /**
12
   * Google Client Instances.
13
   *
14
   * @var \Google_Client
15
   */
16
  private $Client;
0 ignored issues
show
introduced by
The private property $Client is not used, and could be removed.
Loading history...
17
  /**
18
   * Filemanager instance.
19
   *
20
   * @var \Filemanager\file
21
   */
22
  private $filemanager;
23
  private $token_folder;
24
  private $configuration;
25
  public $application_name = "Google Client Library";
26
27
  public function __construct(array $config = ['token' => ['folder' => __DIR__ . '/token']])
28
  {
29
    parent::__construct($config);
30
    $this->filemanager = new \Filemanager\file();
31
    if (isset($config['token']['folder'])) {
32
      $token_folder = $config['token']['folder'];
33
      $this->token_folder = $token_folder;
34
      file::folder($token_folder, null, null, true);
0 ignored issues
show
Unused Code introduced by
The call to Filemanager\file::folder() has too many arguments starting with null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

34
      file::/** @scrutinizer ignore-call */ 
35
            folder($token_folder, null, null, true);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
35
      file::file($token_folder . '/.htaccess', 'deny from all');
0 ignored issues
show
Bug introduced by
'deny from all' of type string is incompatible with the type boolean expected by parameter $create of Filemanager\file::file(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

35
      file::file($token_folder . '/.htaccess', /** @scrutinizer ignore-type */ 'deny from all');
Loading history...
36
      file::file($token_folder . '/.gitignore', "*\n!.gitignore\n!.htaccess");
37
    }
38
    $this->configuration = $config;
39
  }
40
41
  public static function get_profile()
42
  {
43
    if (isset($_SESSION['google']['login'])) {
44
      return $_SESSION['google']['login'];
45
    }
46
    return [];
47
  }
48
49
  public static function get_profile_picture()
50
  {
51
    if (!empty(self::get_profile())) {
52
      if (isset(self::get_profile()['picture'])) return self::get_profile()['picture'];
53
    }
54
    return 'https://upload.wikimedia.org/wikipedia/commons/thumb/a/ac/No_image_available.svg/480px-No_image_available.svg.png';
55
  }
56
57
  public static function get_profile_name()
58
  {
59
    if (!empty(self::get_profile())) {
60
      if (isset(self::get_profile()['name'])) return self::get_profile()['name'];
61
    }
62
    return 'Login Required';
63
  }
64
65
  /**
66
   * @param string $redirect /auth/google
67
   */
68
  public function create_auth_url($scope, $redirect)
69
  {
70
    $this->custom_client($scope, $redirect);
71
    return $this->createAuthUrl();
72
  }
73
74
  /**
75
   * @return \GoogleExt\Client
76
   */
77
  public function custom_client($scope, $redirect)
78
  {
79
    $this->setApplicationName($this->application_name);
80
    $this->setCredentials(
81
      CONFIG['google']['client'],
82
      CONFIG['google']['secret'],
83
      CONFIG['google']['key']
84
    );
85
    $scopes = [
86
      'https://www.googleapis.com/auth/userinfo.email',
87
      'https://www.googleapis.com/auth/userinfo.profile'
88
    ];
89
    if (is_string($scope)) {
90
      switch ($scope) {
91
        case 'blogger':
92
          $scopes[] = 'https://www.googleapis.com/auth/blogger';
93
          break;
94
      }
95
    }
96
    $this->set_scope(array_unique($scopes));
97
    $this->set_offline(true);
98
    $this->setRedirectUri($this->getOrigin($redirect));
99
    $this->auto_login($redirect);
100
    return $this;
101
  }
102
103
  /**
104
   * Check user google is login.
105
   *
106
   * @return bool
107
   */
108
  public function is_login()
109
  {
110
    return isset($_SESSION['google']['login']) && !empty($_SESSION['google']['login']) && isset($_SESSION['google']['login']['email']);
111
  }
112
113
  /**
114
   * Revoke token.
115
   *
116
   * @return $this
117
   */
118
  public function revoke()
119
  {
120
    $this->revokeToken();
121
122
    $this;
123
  }
124
125
  /**
126
   * Get current origin url.
127
   *
128
   * @return string
129
   */
130
  public function getOrigin(string $path = null)
131
  {
132
    return (isset($_SERVER['HTTPS']) && 'on' === $_SERVER['HTTPS'] ? 'https' : 'http') . "://$_SERVER[HTTP_HOST]$path";
133
  }
134
135
  public function get_token_folder()
136
  {
137
    return $this->token_folder;
138
  }
139
140
  public function set_token_folder(string $path)
141
  {
142
    if ($path = realpath($path)) {
143
      $this->token_folder = $path;
144
    }
145
146
    return $this;
147
  }
148
149
  public function set_scope($scopes)
150
  {
151
    if (is_string($scopes)) {
152
      if ($this->is_url($scopes)) {
153
        $this->addScope($scopes);
154
      } else {
155
        throw new \MVC\Exception('Scope is URL format', 1);
156
157
        return null;
0 ignored issues
show
Unused Code introduced by
return null is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
158
      }
159
    } elseif (is_array($scopes)) {
160
      $this->setScopes($scopes);
161
    }
162
163
    return $this;
164
  }
165
166
  /**
167
   * Set access token offline.
168
   *
169
   * @param bool $offline
170
   *
171
   * @return client
172
   */
173
  public function set_offline($offline = true)
174
  {
175
    if ($offline) {
176
      $this->setAccessType('offline');
177
      $this->setApprovalPrompt('force');
178
    } else {
179
      $this->setApprovalPrompt('auto');
180
    }
181
182
    return $this;
183
  }
184
185
  /**
186
   * Set default credentials.
187
   *
188
   * @return client
189
   */
190
  public function setCredentials(string $client, string $secret, string $key)
191
  {
192
    $this->setApplicationName('Login to ' . $_SERVER['HTTP_HOST']);
193
    $this->setDeveloperKey($key);
194
    $this->setClientId($client);
195
    $this->setClientSecret($secret);
196
    $this->addScope('https://www.googleapis.com/auth/userinfo.email');
197
    $this->addScope('https://www.googleapis.com/auth/userinfo.profile');
198
199
    return $this;
200
  }
201
202
  /**
203
   * Check if current instance is valid.
204
   *
205
   * @return bool
206
   */
207
  public function isValid()
208
  {
209
    return $this->getAccessToken() && !$this->isAccessTokenExpired();
210
  }
211
212
  public function is_url($string)
213
  {
214
    return filter_var($string, FILTER_VALIDATE_URL);
215
  }
216
217
  /**
218
   * Check user has subscribed to youtube channel.
219
   *
220
   * @param string $cid          channel id
221
   * @param bool   $only_get_url = return URL channel
222
   */
223
  public function check_subscriber(string $cid = 'UCGNaoefvJRfd15fo-LQ0zvg', bool $only_get_url = false)
224
  {
225
    if (!$only_get_url) {
226
      /**
227
       * @var \Google\Client
228
       */
229
      $client = $this;
230
      $service = new \Google_Service_YouTube($client);
0 ignored issues
show
Bug introduced by
$client of type GoogleExt\client is incompatible with the type Google_Client expected by parameter $client of Google_Service_YouTube::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

230
      $service = new \Google_Service_YouTube(/** @scrutinizer ignore-type */ $client);
Loading history...
231
      $response = $service->subscriptions->listSubscriptions(
232
        'snippet,contentDetails',
233
        array_filter(['forChannelId' => $cid, 'mine' => true])
234
      );
235
236
      $result = count($response['items']);
0 ignored issues
show
Bug introduced by
It seems like $response['items'] can also be of type null; however, parameter $value of count() does only seem to accept Countable|array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

236
      $result = count(/** @scrutinizer ignore-type */ $response['items']);
Loading history...
237
      $output = [];
238
      if ($result > 0) {
239
        $output['success'] = true;
240
        $output['data'] = $response['items'];
241
        $_SESSION['subscribed'] = 1;
242
      } else {
243
        $output['error'] = true;
244
        $output['data'] = 'Belum Subscribe';
245
        $output['msg'] = 'Belum Subscribe';
246
        $_SESSION['subscribed'] = 0;
247
      }
248
    } else {
249
      $output = 'https://www.youtube.com/channel/' . $cid;
250
    }
251
252
    return $output;
253
  }
254
255
  /**
256
   * Auto get token from $_GET['code']
257
   * And auto refresh token
258
   * * @param string $redirect /auth/google
259
   */
260
  public function auto_login($redirect)
261
  {
262
    $config = $this->configuration;
263
    $this->setCredentials(
264
      CONFIG['google']['client'],
265
      CONFIG['google']['secret'],
266
      CONFIG['google']['key']
267
    );
268
    $this->setRedirectUri($this->getOrigin($redirect));
269
    if (isset($_GET['code'])) {
270
      $token = $this->fetchAccessTokenWithAuthCode($_GET['code']);
271
      /*$this->authenticate($_GET['code']);
272
      $access_token = $this->getAccessToken();
273
      e($access_token, $token);*/
274
      if (!empty($token)) {
275
        if (isset($token['error'])) {
276
          e($token);
277
        }
278
        $this->setAccessToken($token);
279
      }
280
      if (isset($config['token']['folder']) && $this->getAccessToken()) {
281
        $user = $this->fetch_user();
282
        $_SESSION['google']['login'] = $user;
283
        file::file($config['token']['folder'] . '/' . $user['email'] . '.json', $token, true);
284
      }
285
    } else {
286
      if (isset($this->login_data()['email'])) {
287
        $email = $this->login_data()['email'];
288
        $tokenpath = $config['token']['folder'] . '/' . $email . '.json';
289
        if (file_exists($tokenpath)) {
290
          $token = json_decode(file_get_contents($tokenpath), true);
291
          $this->setAccessToken($token);
292
        }
293
      }
294
    }
295
296
    if (isset($_SESSION['google']['login'])) {
297
      $user = $_SESSION['google']['login'];
298
      // auto refresh token
299
      if ($this->isAccessTokenExpired() && isset($user['email']) && $this->getAccessToken()) {
300
        $this->fetchAccessTokenWithRefreshToken($this->getRefreshToken());
301
        file::file($config['token']['folder'] . '/' . $user['email'] . '.json', json_encode($this->getAccessToken()), true);
0 ignored issues
show
Bug introduced by
json_encode($this->getAccessToken()) of type string is incompatible with the type boolean expected by parameter $create of Filemanager\file::file(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

301
        file::file($config['token']['folder'] . '/' . $user['email'] . '.json', /** @scrutinizer ignore-type */ json_encode($this->getAccessToken()), true);
Loading history...
302
      }
303
    }
304
  }
305
306
  /**
307
   * Get current user login ($_SESSION['login']).
308
   *
309
   * @return array
310
   */
311
  public function login_data()
312
  {
313
    return isset($_SESSION['login']) ? \ArrayHelper\helper::unset($_SESSION['login'], ['password']) : [];
314
  }
315
316
  /**
317
   * Get current google user data.
318
   *
319
   * @return void
320
   */
321
  public function userdata()
322
  {
323
    return isset($_SESSION['google']['login']) ? \ArrayHelper\helper::unset($_SESSION['google']['login'], ['password']) : [];
0 ignored issues
show
Bug Best Practice introduced by
The expression return IssetNode ? Array...('password')) : array() also could return the type array which is incompatible with the documented return type void.
Loading history...
324
  }
325
326
  /**
327
   * Fetch user information from google.
328
   *
329
   * @return array
330
   */
331
  public function fetch_user()
332
  {
333
    /**
334
     * @var \Google\Client
335
     */
336
    $client = $this;
337
    $service = new \Google_Service_Oauth2($client);
0 ignored issues
show
Bug introduced by
$client of type GoogleExt\client is incompatible with the type Google_Client expected by parameter $client of Google_Service_Oauth2::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

337
    $service = new \Google_Service_Oauth2(/** @scrutinizer ignore-type */ $client);
Loading history...
338
    $this->addScope(\Google_Service_Oauth2::USERINFO_EMAIL);
339
    $this->addScope(\Google_Service_Oauth2::USERINFO_PROFILE);
340
    $this->authenticate($_GET['code']);
0 ignored issues
show
Deprecated Code introduced by
The function Google\Client::authenticate() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

340
    /** @scrutinizer ignore-deprecated */ $this->authenticate($_GET['code']);
Loading history...
341
342
    return (array) $service->userinfo->get();
343
  }
344
}
345