説明なし

google.php 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. <?php
  2. use NSL\Notices;
  3. class NextendSocialProviderGoogle extends NextendSocialProvider {
  4. /** @var NextendSocialProviderGoogleClient */
  5. protected $client;
  6. protected $color = '#4285f4';
  7. protected $colorUniform = '#dc4e41';
  8. protected $svg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#4285F4" d="M20.64 12.2045c0-.6381-.0573-1.2518-.1636-1.8409H12v3.4814h4.8436c-.2086 1.125-.8427 2.0782-1.7959 2.7164v2.2581h2.9087c1.7018-1.5668 2.6836-3.874 2.6836-6.615z"></path><path fill="#34A853" d="M12 21c2.43 0 4.4673-.806 5.9564-2.1805l-2.9087-2.2581c-.8059.54-1.8368.859-3.0477.859-2.344 0-4.3282-1.5831-5.036-3.7104H3.9574v2.3318C5.4382 18.9832 8.4818 21 12 21z"></path><path fill="#FBBC05" d="M6.964 13.71c-.18-.54-.2822-1.1168-.2822-1.71s.1023-1.17.2823-1.71V7.9582H3.9573A8.9965 8.9965 0 0 0 3 12c0 1.4523.3477 2.8268.9573 4.0418L6.964 13.71z"></path><path fill="#EA4335" d="M12 6.5795c1.3214 0 2.5077.4541 3.4405 1.346l2.5813-2.5814C16.4632 3.8918 14.426 3 12 3 8.4818 3 5.4382 5.0168 3.9573 7.9582L6.964 10.29C7.6718 8.1627 9.6559 6.5795 12 6.5795z"></path></svg>';
  9. protected $svgUniform = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="#fff" fill-rule="evenodd" d="M11.988,14.28 L11.988,9.816 L23.22,9.816 C23.388,10.572 23.52,11.28 23.52,12.276 C23.52,19.128 18.924,24 12,24 C5.376,24 -9.47390314e-15,18.624 -9.47390314e-15,12 C-9.47390314e-15,5.376 5.376,0 12,0 C15.24,0 17.952,1.188 20.028,3.132 L16.62,6.444 C15.756,5.628 14.244,4.668 12,4.668 C8.028,4.668 4.788,7.968 4.788,12.012 C4.788,16.056 8.028,19.356 12,19.356 C16.596,19.356 18.288,16.176 18.6,14.292 L11.988,14.292 L11.988,14.28 Z"/></svg>';
  10. const requiredApi1 = 'Google People API';
  11. protected $sync_fields = array(
  12. 'locale' => array(
  13. 'label' => 'Locale',
  14. 'node' => 'me',
  15. ),
  16. 'genders' => array(
  17. 'label' => 'Genders',
  18. 'node' => 'people',
  19. 'description' => self::requiredApi1,
  20. ),
  21. 'biographies' => array(
  22. 'label' => 'Biographies',
  23. 'node' => 'people',
  24. 'description' => self::requiredApi1,
  25. ),
  26. 'birthdays' => array(
  27. 'label' => 'Birthdays',
  28. 'node' => 'people',
  29. 'scope' => 'https://www.googleapis.com/auth/user.birthday.read',
  30. 'description' => self::requiredApi1,
  31. ),
  32. 'occupations' => array(
  33. 'label' => 'Occupations',
  34. 'node' => 'people',
  35. 'description' => self::requiredApi1,
  36. ),
  37. 'organizations' => array(
  38. 'label' => 'Organizations',
  39. 'node' => 'people',
  40. 'description' => self::requiredApi1,
  41. ),
  42. 'locations' => array(
  43. 'label' => 'Locations',
  44. 'node' => 'people',
  45. 'description' => self::requiredApi1,
  46. ),
  47. 'ageRanges' => array(
  48. 'label' => 'Age ranges',
  49. 'node' => 'people',
  50. 'description' => self::requiredApi1,
  51. ),
  52. 'addresses' => array(
  53. 'label' => 'Addresses',
  54. 'node' => 'people',
  55. 'scope' => 'https://www.googleapis.com/auth/user.addresses.read',
  56. 'description' => self::requiredApi1,
  57. ),
  58. 'phoneNumbers' => array(
  59. 'label' => 'Phone Numbers',
  60. 'node' => 'people',
  61. 'scope' => 'https://www.googleapis.com/auth/user.phonenumbers.read',
  62. 'description' => self::requiredApi1,
  63. )
  64. );
  65. public function __construct() {
  66. $this->id = 'google';
  67. $this->label = 'Google';
  68. $this->path = dirname(__FILE__);
  69. $this->requiredFields = array(
  70. 'client_id' => 'Client ID',
  71. 'client_secret' => 'Client Secret'
  72. );
  73. parent::__construct(array(
  74. 'client_id' => '',
  75. 'client_secret' => '',
  76. 'select_account' => 1,
  77. 'skin' => 'light',
  78. 'login_label' => 'Continue with <b>Google</b>',
  79. 'register_label' => 'Sign up with <b>Google</b>',
  80. 'link_label' => 'Link account with <b>Google</b>',
  81. 'unlink_label' => 'Unlink account from <b>Google</b>'
  82. ));
  83. }
  84. protected function forTranslation() {
  85. __('Continue with <b>Google</b>', 'nextend-facebook-connect');
  86. __('Sign up with <b>Google</b>', 'nextend-facebook-connect');
  87. __('Link account with <b>Google</b>', 'nextend-facebook-connect');
  88. __('Unlink account from <b>Google</b>', 'nextend-facebook-connect');
  89. }
  90. public function getRawDefaultButton() {
  91. $skin = $this->settings->get('skin');
  92. switch ($skin) {
  93. case 'dark':
  94. $color = $this->color;
  95. $svg = $this->svg;
  96. break;
  97. case 'light':
  98. $color = '#fff';
  99. $svg = $this->svg;
  100. break;
  101. default:
  102. $color = $this->colorUniform;
  103. $svg = $this->svgUniform;
  104. }
  105. return '<div class="nsl-button nsl-button-default nsl-button-' . $this->id . '" data-skin="' . $skin . '" style="background-color:' . $color . ';"><div class="nsl-button-svg-container">' . $svg . '</div><div class="nsl-button-label-container">{{label}}</div></div>';
  106. }
  107. public function getRawIconButton() {
  108. $skin = $this->settings->get('skin');
  109. switch ($skin) {
  110. case 'dark':
  111. $color = $this->color;
  112. $svg = $this->svg;
  113. break;
  114. case 'light':
  115. $color = '#fff';
  116. $svg = $this->svg;
  117. break;
  118. default:
  119. $color = $this->colorUniform;
  120. $svg = $this->svgUniform;
  121. }
  122. return '<div class="nsl-button nsl-button-icon nsl-button-' . $this->id . '" data-skin="' . $skin . '" style="background-color:' . $color . ';"><div class="nsl-button-svg-container">' . $svg . '</div></div>';
  123. }
  124. public function validateSettings($newData, $postedData) {
  125. $newData = parent::validateSettings($newData, $postedData);
  126. foreach ($postedData AS $key => $value) {
  127. switch ($key) {
  128. case 'tested':
  129. if ($postedData[$key] == '1' && (!isset($newData['tested']) || $newData['tested'] != '0')) {
  130. $newData['tested'] = 1;
  131. } else {
  132. $newData['tested'] = 0;
  133. }
  134. break;
  135. case 'skin':
  136. $newData[$key] = trim(sanitize_text_field($value));
  137. break;
  138. case 'client_id':
  139. case 'client_secret':
  140. $newData[$key] = trim(sanitize_text_field($value));
  141. if ($this->settings->get($key) !== $newData[$key]) {
  142. $newData['tested'] = 0;
  143. }
  144. if (empty($newData[$key])) {
  145. Notices::addError(sprintf(__('The %1$s entered did not appear to be a valid. Please enter a valid %2$s.', 'nextend-facebook-connect'), $this->requiredFields[$key], $this->requiredFields[$key]));
  146. }
  147. break;
  148. case 'select_account':
  149. $newData[$key] = $value ? 1 : 0;
  150. break;
  151. }
  152. }
  153. return $newData;
  154. }
  155. public function getClient() {
  156. if ($this->client === null) {
  157. require_once dirname(__FILE__) . '/google-client.php';
  158. $this->client = new NextendSocialProviderGoogleClient($this->id);
  159. $this->client->setClientId($this->settings->get('client_id'));
  160. $this->client->setClientSecret($this->settings->get('client_secret'));
  161. $this->client->setRedirectUri($this->getRedirectUriForOAuthFlow());
  162. if (!$this->settings->get('select_account')) {
  163. $this->client->setPrompt('');
  164. }
  165. }
  166. return $this->client;
  167. }
  168. /**
  169. * @return array
  170. * @throws Exception
  171. */
  172. protected function getCurrentUserInfo() {
  173. $fields = array(
  174. 'id',
  175. 'name',
  176. 'email',
  177. 'family_name',
  178. 'given_name',
  179. 'picture',
  180. );
  181. $extra_me_fields = apply_filters('nsl_google_sync_node_fields', array(), 'me');
  182. return $this->getClient()
  183. ->get('userinfo?fields=' . implode(',', array_merge($fields, $extra_me_fields)));
  184. }
  185. public function getMe() {
  186. return $this->authUserData;
  187. }
  188. /**
  189. * @return array
  190. * @throws Exception
  191. */
  192. public function getMyPeople() {
  193. $extra_people_fields = apply_filters('nsl_google_sync_node_fields', array(), 'people');
  194. if (!empty($extra_people_fields)) {
  195. return $this->getClient()
  196. ->get('people/me?personFields=' . implode(',', $extra_people_fields), array(), 'https://people.googleapis.com/v1/');
  197. }
  198. return $extra_people_fields;
  199. }
  200. /**
  201. * @param $key
  202. *
  203. * @return string
  204. */
  205. public function getAuthUserData($key) {
  206. switch ($key) {
  207. case 'id':
  208. return $this->authUserData['id'];
  209. case 'email':
  210. return $this->authUserData['email'];
  211. case 'name':
  212. return !empty($this->authUserData['name']) ? $this->authUserData['name'] : '';
  213. case 'first_name':
  214. return !empty($this->authUserData['given_name']) ? $this->authUserData['given_name'] : '';
  215. case 'last_name':
  216. return !empty($this->authUserData['family_name']) ? $this->authUserData['family_name'] : '';
  217. case 'picture':
  218. return $this->authUserData['picture'];
  219. }
  220. return parent::getAuthUserData($key);
  221. }
  222. public function syncProfile($user_id, $provider, $access_token) {
  223. if ($this->needUpdateAvatar($user_id)) {
  224. $this->updateAvatar($user_id, $this->getAuthUserData('picture'));
  225. }
  226. $this->storeAccessToken($user_id, $access_token);
  227. }
  228. public function deleteLoginPersistentData() {
  229. parent::deleteLoginPersistentData();
  230. if ($this->client !== null) {
  231. $this->client->deleteLoginPersistentData();
  232. }
  233. }
  234. public function getAvatar($user_id) {
  235. if (!$this->isUserConnected($user_id)) {
  236. return false;
  237. }
  238. $picture = $this->getUserData($user_id, 'profile_picture');
  239. if (!$picture || $picture == '') {
  240. return false;
  241. }
  242. return $picture;
  243. }
  244. public function getSyncDataFieldDescription($fieldName) {
  245. if (isset($this->sync_fields[$fieldName]['description'])) {
  246. return sprintf(__('Required API: %1$s', 'nextend-facebook-connect'), $this->sync_fields[$fieldName]['description']);
  247. }
  248. return parent::getSyncDataFieldDescription($fieldName);
  249. }
  250. }
  251. NextendSocialLogin::addProvider(new NextendSocialProviderGoogle);