PageRenderTime 42ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/google/index.php

https://github.com/whale2/users
PHP | 480 lines | 398 code | 62 blank | 20 comment | 33 complexity | 646e8b22a9e185ab1d778d37f0a27ce1 MD5 | raw file
  1. <?php
  2. class GoogleAuthenticationModule extends AuthenticationModule
  3. {
  4. private $siteid;
  5. private $regHeadersLoaded = false;
  6. private $adminHeaderShown = false;
  7. private $remember;
  8. public function __construct($siteid, $remember = true)
  9. {
  10. parent::__construct();
  11. $this->siteid = $siteid;
  12. // TODO Replace it with immediate GFC call:
  13. // http://code.google.com/p/userbase/issues/detail?id=16
  14. $this->remember = $remember;
  15. }
  16. public function getID()
  17. {
  18. return "google";
  19. }
  20. public function getLegendColor()
  21. {
  22. return "FF9900";
  23. }
  24. public function getTitle()
  25. {
  26. return "Other accounts using Google Friend Connect";
  27. }
  28. public function getUserCredentials($user)
  29. {
  30. $db = UserConfig::getDB();
  31. $userid = $user->getID();
  32. if ($stmt = $db->prepare('SELECT google_id FROM '.UserConfig::$mysql_prefix.'googlefriendconnect WHERE user_id = ?'))
  33. {
  34. if (!$stmt->bind_param('i', $userid))
  35. {
  36. throw new Exception("Can't bind parameter".$stmt->error);
  37. }
  38. if (!$stmt->execute())
  39. {
  40. throw new Exception("Can't execute statement: ".$stmt->error);
  41. }
  42. if (!$stmt->bind_result($google_id))
  43. {
  44. throw new Exception("Can't bind result: ".$stmt->error);
  45. }
  46. $google_ids = array();
  47. while ($stmt->fetch() === TRUE) {
  48. $google_ids[] = $google_id;
  49. }
  50. $stmt->close();
  51. if (count($google_ids) > 0)
  52. {
  53. return new GoogleFriendConnectUserCredentials($this, $google_ids);
  54. }
  55. }
  56. else
  57. {
  58. throw new Exception("Can't prepare statement: ".$db->error);
  59. }
  60. return null;
  61. }
  62. public function getTotalConnectedUsers()
  63. {
  64. $db = UserConfig::getDB();
  65. $conns = 0;
  66. if ($stmt = $db->prepare('SELECT COUNT(DISTINCT user_id) AS connst FROM '.UserConfig::$mysql_prefix.'googlefriendconnect'))
  67. {
  68. if (!$stmt->execute())
  69. {
  70. throw new Exception("Can't execute statement: ".$stmt->error);
  71. }
  72. if (!$stmt->bind_result($regs))
  73. {
  74. throw new Exception("Can't bind result: ".$stmt->error);
  75. }
  76. $stmt->fetch();
  77. $stmt->close();
  78. }
  79. else
  80. {
  81. throw new Exception("Can't prepare statement: ".$db->error);
  82. }
  83. return $conns;
  84. }
  85. /*
  86. * retrieves aggregated registrations numbers
  87. */
  88. public function getDailyRegistrations()
  89. {
  90. $db = UserConfig::getDB();
  91. $dailyregs = array();
  92. if ($stmt = $db->prepare('SELECT regdate, count(*) AS reqs FROM (SELECT CAST(regtime AS DATE) AS regdate, id AS regs FROM '.UserConfig::$mysql_prefix.'users u LEFT JOIN '.UserConfig::$mysql_prefix.'googlefriendconnect g ON u.id = g.user_id WHERE g.google_id IS NOT NULL GROUP BY id) agg group by agg.regdate'))
  93. {
  94. if (!$stmt->execute())
  95. {
  96. throw new Exception("Can't execute statement: ".$stmt->error);
  97. }
  98. if (!$stmt->bind_result($regdate, $regs))
  99. {
  100. throw new Exception("Can't bind result: ".$stmt->error);
  101. }
  102. while($stmt->fetch() === TRUE)
  103. {
  104. $dailyregs[] = array('regdate' => $regdate, 'regs' => $regs);
  105. }
  106. $stmt->close();
  107. }
  108. else
  109. {
  110. throw new Exception("Can't prepare statement: ".$db->error);
  111. }
  112. return $dailyregs;
  113. }
  114. public function renderLoginForm($action)
  115. {
  116. ?>
  117. <script src="http://www.google.com/jsapi"></script>
  118. <script src="http://www.google.com/friendconnect/script/friendconnect.js?key=notsupplied&v=0.8"></script>
  119. <script>
  120. google.setOnLoadCallback(function() {
  121. google.friendconnect.container.loadOpenSocialApi({
  122. site: '<?php echo $this->siteid?>',
  123. onload: function(securityToken) {
  124. if (!window.timesloaded) {
  125. window.timesloaded = 1;
  126. } else {
  127. window.timesloaded++;
  128. }
  129. if (window.timesloaded > 1) {
  130. document.googleloginform.submit();
  131. }
  132. }
  133. });
  134. });
  135. </script>
  136. <p>Sign in using your <b>OpenID</b> or an existing account with <b>Google</b>, <b>Twitter</b>, <b>Yahoo!</b> and more.</p>
  137. <a href="#" onclick="google.friendconnect.requestSignIn(function() {document.googleloginform.submit()}); return false;"><span style="background-image: url(<?php echo UserConfig::$USERSROOTURL ?>/modules/google/google-sprite.png); background-position: 0px 0px; width: 152px; height: 21px; display: block; cursor: hand;" title="Log in using existing account via Gogle Friend Connect"></span></a>
  138. <form action="<?php echo $action?>" method="POST" name="googleloginform">
  139. <input type="hidden" name="login" value="Login &gt;&gt;&gt;"/>
  140. </form>
  141. <?php
  142. }
  143. public function renderRegistrationForm($full = false, $action = null, $errors = null , $data = null)
  144. {
  145. if (is_null($action))
  146. {
  147. $action = UserConfig::$USERSROOTURL.'/register.php?module='.$this->getID();
  148. }
  149. if (!$this->regHeadersLoaded)
  150. {
  151. ?>
  152. <script src="http://www.google.com/jsapi"></script>
  153. <script src="http://www.google.com/friendconnect/script/friendconnect.js?key=notsupplied&v=0.8"></script>
  154. <script>
  155. google.setOnLoadCallback(function() {
  156. google.friendconnect.container.loadOpenSocialApi({
  157. site: '<?php echo $this->siteid?>',
  158. onload: function(securityToken) {
  159. if (!window.timesloaded) {
  160. window.timesloaded = 1;
  161. } else {
  162. window.timesloaded++;
  163. }
  164. if (window.timesloaded > 1) {
  165. document.googleregform.submit();
  166. }
  167. }
  168. });
  169. });
  170. </script>
  171. <form action="<?php echo $action?>" method="POST" name="googleregform">
  172. <input type="hidden" name="register" value="Register &gt;&gt;&gt;"/>
  173. </form>
  174. <?php
  175. $this->regHeadersLoaded = true;
  176. }
  177. if ($full)
  178. {
  179. ?>
  180. <p>Sign un using your <b>OpenID</b> or an existing account with <b>Google</b>, <b>Twitter</b>, <b>Yahoo!</b> and more.</p>
  181. <?php
  182. }
  183. ?>
  184. <a href="#" onclick="google.friendconnect.requestSignIn(); return false;"><span style="background-image: url(<?php echo UserConfig::$USERSROOTURL ?>/modules/google/google-sprite.png); background-position: 0px -42px; width: 200px; height: 21px; display: block; cursor: hand;" title="Quick Sign up using existing account via Google Friend Connect"></span></a>
  185. <?php
  186. }
  187. /*
  188. * Renders user editing form
  189. *
  190. * Parameters:
  191. * $action - form action to post back to
  192. * $errors - error messages to display
  193. * $user - user object for current user that is being edited
  194. * $data - data submitted to the form
  195. */
  196. public function renderEditUserForm($action, $errors, $user, $data)
  197. {
  198. $associations = $user->getGoogleFriendsConnectAssociations();
  199. ?>
  200. <form action="<?php echo $action?>" method="POST">
  201. <input type="hidden" name="save" value="save"/>
  202. <?php
  203. foreach ($associations as $association)
  204. {
  205. ?><div style="float: left; margin-right: 1em">
  206. <img src="<?php echo $association['userpic']?>"/><br/>
  207. <input type="submit" name="remove[<?php echo $association['google_id']?>]" value="remove" style="font-size: xx-small"/>
  208. </div><?php
  209. }
  210. UserTools::renderCSRFNonce();
  211. ?>
  212. </form>
  213. <div style="clear: both"></div>
  214. <script src="http://www.google.com/jsapi"></script>
  215. <script src="http://www.google.com/friendconnect/script/friendconnect.js?key=notsupplied&v=0.8"></script>
  216. <script>
  217. google.setOnLoadCallback(function() {
  218. google.friendconnect.container.loadOpenSocialApi({
  219. site: '<?php echo $this->siteid?>',
  220. onload: function(securityToken) {
  221. if (!window.timesloaded) {
  222. window.timesloaded = 1;
  223. } else {
  224. window.timesloaded++;
  225. }
  226. if (window.timesloaded > 1) {
  227. document.googleeditform.submit();
  228. }
  229. }
  230. });
  231. });
  232. </script>
  233. <p>Connect to your <b>OpenID</b> or existing account with <b>Google</b>, <b>Twitter</b>, <b>Yahoo!</b> and more.</p>
  234. <a href="#" onclick="google.friendconnect.requestSignIn(function() {document.googleeditform.submit()}); return false;"><span style="background-image: url(<?php echo UserConfig::$USERSROOTURL ?>/modules/google/google-sprite.png); background-position: 0px -21px; width: 218px; height: 21px; display: block; cursor: hand;" title="Connect to another account via Google Friend Connect"></span></a>
  235. <form action="<?php echo $action?>" method="POST" name="googleeditform">
  236. <input type="hidden" name="save" value="Save &gt;&gt;&gt;"/>
  237. <?php UserTools::renderCSRFNonce(); ?>
  238. </form>
  239. <?php
  240. }
  241. public function processLogin($data, &$remember)
  242. {
  243. $remember = $this->remember;
  244. $fcauth = $_COOKIE['fcauth'.$this->siteid];
  245. $ch = curl_init();
  246. curl_setopt($ch, CURLOPT_URL, 'http://www.google.com/friendconnect/api/people/@viewer/@self?fcauth='.urlencode($fcauth));
  247. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  248. $data = json_decode(curl_exec($ch), true);
  249. curl_close($ch);
  250. if (!is_null($data) &&
  251. array_key_exists('entry', $data) &&
  252. array_key_exists('id', $data['entry']))
  253. {
  254. $user = User::getUserByGoogleFriendConnectID($data['entry']['id']);
  255. if (!is_null($user)) {
  256. $user->recordActivity(USERBASE_ACTIVITY_LOGIN_GFC);
  257. return $user;
  258. } else {
  259. return $this->processRegistration($data, $remember);
  260. }
  261. } else {
  262. return false;
  263. }
  264. }
  265. public function processRegistration($data, &$remember)
  266. {
  267. $remember = $this->remember;
  268. $fcauth = $_COOKIE['fcauth'.$this->siteid];
  269. $ch = curl_init();
  270. curl_setopt($ch, CURLOPT_URL, 'http://www.google.com/friendconnect/api/people/@viewer/@self?fcauth='.urlencode($fcauth));
  271. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  272. $data = json_decode(curl_exec($ch), true);
  273. curl_close($ch);
  274. $googleid = null;
  275. $displayName = null;
  276. $thumbnailUrl = null;
  277. if (!is_null($data) &&
  278. array_key_exists('entry', $data) &&
  279. array_key_exists('id', $data['entry']))
  280. {
  281. $googleid = $data['entry']['id'];
  282. $displayName = $data['entry']['displayName'];
  283. $thumbnailUrl = $data['entry']['thumbnailUrl'];
  284. }
  285. $errors = array();
  286. if (is_null($googleid))
  287. {
  288. $errors['googleid'][] = 'No Google Friend Connect user id is passed';
  289. throw new InputValidationException('No Google Friend Connect user id', 0, $errors);
  290. }
  291. $existing_user = User::getUserByGoogleFriendConnectID($googleid);
  292. if (!is_null($existing_user))
  293. {
  294. $existing_user->recordActivity(USERBASE_ACTIVITY_LOGIN_GFC);
  295. return $existing_user;
  296. }
  297. if (is_null($displayName))
  298. {
  299. $errors['username'][] = "User doesn't have display name";
  300. }
  301. if (count($errors) > 0)
  302. {
  303. throw new ExistingUserException('User already exists', 0, $errors);
  304. }
  305. // ok, let's create a user
  306. $user = User::createNewGoogleFriendConnectUser($displayName, $googleid, $thumbnailUrl);
  307. $user->recordActivity(USERBASE_ACTIVITY_REGISTER_GFC);
  308. return $user;
  309. }
  310. /*
  311. * Updates user information
  312. *
  313. * returns true if successful and false if unsuccessful
  314. *
  315. * throws InputValidationException if there are problems with input data
  316. */
  317. public function processEditUser($user, $data)
  318. {
  319. // if remove, then save stores id to remove
  320. if (array_key_exists('remove', $data))
  321. {
  322. $keys = array_keys($data['remove']);
  323. if (count($keys) > 0) {
  324. $user->removeGoogleFriendConnectAssociation($keys[0]);
  325. }
  326. }
  327. else
  328. {
  329. $fcauth = $_COOKIE['fcauth'.$this->siteid];
  330. $ch = curl_init();
  331. curl_setopt($ch, CURLOPT_URL, 'http://www.google.com/friendconnect/api/people/@viewer/@self?fcauth='.urlencode($fcauth));
  332. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  333. $data = json_decode(curl_exec($ch), true);
  334. curl_close($ch);
  335. $googleid = null;
  336. $displayName = null;
  337. $thumbnailUrl = null;
  338. if (!is_null($data) &&
  339. array_key_exists('entry', $data) &&
  340. array_key_exists('id', $data['entry']))
  341. {
  342. $googleid = $data['entry']['id'];
  343. $displayName = $data['entry']['displayName'];
  344. $thumbnailUrl = $data['entry']['thumbnailUrl'];
  345. }
  346. if (is_null($googleid))
  347. {
  348. $errors['googleid'][] = 'No Google Friend Connect user id is passed';
  349. throw new InputValidationException('No Google Friend Connect user id', 0, $errors);
  350. }
  351. $user->addGoogleFriendConnectAssociation($googleid, $thumbnailUrl);
  352. }
  353. return true;
  354. }
  355. public function getAdminHeaderHTML() {
  356. $html = '';
  357. if (!$this->adminHeaderShown) {
  358. $html .= '
  359. <script src="http://www.google.com/jsapi"></script>
  360. <script src="http://www.google.com/friendconnect/script/friendconnect.js?key=notsupplied&v=0.8"></script>
  361. <script>
  362. google.setOnLoadCallback(function() {
  363. google.friendconnect.container.loadOpenSocialApi({
  364. site: \''.$this->siteid.'\',
  365. onload: function(securityToken) {
  366. if (!window.timesloaded) {
  367. window.timesloaded = 1;
  368. } else {
  369. window.timesloaded++;
  370. }
  371. if (window.timesloaded > 1) {
  372. document.googleloginform.submit();
  373. }
  374. }
  375. });
  376. });
  377. </script>';
  378. $this->adminHeaderShown = true;
  379. }
  380. return $html;
  381. }
  382. }
  383. class GoogleFriendConnectUserCredentials extends UserCredentials {
  384. // A list of Google Friend Connect IDs
  385. private $google_ids;
  386. private $module;
  387. public function __construct($module, $google_ids) {
  388. $this->module = $module;
  389. $this->google_ids = $google_ids;
  390. }
  391. public function getUserIDs() {
  392. return $this->google_ids;
  393. }
  394. public function getHTML() {
  395. $html = $this->module->getAdminHeaderHTML();
  396. $first = true;
  397. foreach ($this->google_ids as $google_id) {
  398. if ($first) {
  399. $first = false;
  400. } else {
  401. $html .= ', ';
  402. }
  403. $html .= "<a href=\"#\" onclick=\"google.friendconnect.showMemberProfile('$google_id'); return false;\">$google_id</a>";
  404. }
  405. return $html;
  406. }
  407. }