Facebook stuf
[rock.divinelegy.git] / Controllers / UserAuthController.php
1 <?php
2
3 namespace Controllers;
4
5 use Domain\Util;
6 use Services\Http\IHttpResponse;
7 use Services\Http\IHttpRequest;
8 use Services\IFacebookSessionFactory;
9 use Domain\Entities\IUserStepByStepBuilder;
10 use DataAccess\IUserRepository;
11 use Facebook\FacebookSession;
12 use Facebook\FacebookRequest;
13 use Facebook\GraphUser;
14 use Facebook\GraphLocation;
15
16 class UserAuthController implements IDivineController
17 {
18 private $_response;
19 private $_request;
20 private $_facebookSessionFactory;
21 private $_facebookSession;
22 private $_facebookRequest;
23 private $_userRepository;
24
25 /* @var $_userStepByStepBuilder Domain\Entities\UserStepByStepBuilder */
26 private $_userStepByStepBuilder;
27
28 //override
29 public function __construct(
30 IHttpRequest $request,
31 IHttpResponse $response,
32 IFacebookSessionFactory $facebookSessionFactory,
33 IUserRepository $userRepository,
34 IUserStepByStepBuilder $userStepByStepBuilder
35 ) {
36 $this->_request = $request;
37 $this->_response = $response;
38 $this->_facebookSessionFactory = $facebookSessionFactory;
39 $this->_userRepository = $userRepository;
40 $this->_userStepByStepBuilder = $userStepByStepBuilder;
41 }
42
43 public function indexAction() {
44 $token = $this->validateAuthRequest();
45 $facebookSession = $this->_facebookSessionFactory->createInstance($token);
46
47 //If it fails to validate the exception will deal with it.
48 $facebookSession->validate();
49
50 $this->_facebookSession = $this->isSessionLongLived($facebookSession) ? $facebookSession->getLongLivedSession() : $facebookSession;
51 $this->_facebookRequest = (new FacebookRequest($this->_facebookSession, 'GET', '/me?fields=hometown,first_name,last_name'))->execute();
52
53 $id = $this->_facebookRequest->getGraphObject(GraphUser::className())->getId();
54
55 // If the user is not in the DB, create them.
56 $user = $this->_userRepository->findByFacebookId($id) ?: $this->registerUser();
57
58 $this->_response->setHeader('Content-Type', 'application/json')
59 ->setBody(json_encode(array('token' => $this->_facebookSession->getToken(), 'expires' => $this->getSessionExpiryTimestamp($this->_facebookSession), 'displayName' => $user->getDisplayName())))
60 ->sendResponse();
61 }
62
63 private function validateAuthRequest()
64 {
65 $request = $this->_request->get();
66 $response = $this->_response->setHeader('Content-Type', 'application/json');
67
68 if(!isset($request['token']))
69 {
70 //TODO: Perhaps I should be using the status reporter class here (and above).
71 //Will require changes to front end though, but at least it would be more consistent.
72 $response->setBody(json_encode(array('result' => 'error', 'message' => 'missing auth token')))
73 ->sendResponse();
74 die();
75 }
76
77 return $request['token'];
78 }
79
80 private function registerUser()
81 {
82 $userProfile = $this->_facebookRequest->getGraphObject(GraphUser::className());
83
84 $homeTown = $userProfile->getProperty('hometown');
85
86 if($homeTown)
87 {
88 $homeTownPageId = $homeTown ? $homeTown->getProperty('id') : null;
89
90 $pageRequest = (new FacebookRequest($this->_facebookSession, 'GET', '/' . $homeTownPageId ))->execute();
91 $pageLocation = $pageRequest->getGraphObject(GraphLocation::className())->getProperty('location')->cast(GraphLocation::className());
92
93 $country = Util::countryNameFromLatLong($pageLocation->getLatitude(), $pageLocation->getLongitude());
94 }
95
96 $firstName = $userProfile->getFirstName();
97 $lastName = $userProfile->getLastName();
98 $facebookId = $userProfile->getId();
99
100 //TODO: Is insantiating the VO classes here a good idea?
101 $newUser = $this->_userStepByStepBuilder->With_DisplayName($firstName)
102 ->With_Name(new \Domain\VOs\Name($firstName, $lastName))
103 ->With_Tags(array())
104 ->With_FacebookId($facebookId)
105 ->With_Quota(100000000) //XXX: quota is in bytes
106 //XXX: Is this confusing? Maybe better to do a conditional and only call with_country when we have a country
107 ->With_Country(isset($country) ? new \Domain\VOs\Country($country) : null)
108 ->build();
109
110 $this->_userRepository->save($newUser);
111
112 return $newUser;
113 }
114
115 private function isSessionLongLived(FacebookSession $session)
116 {
117 return $this->getSessionExpiryTimestamp($session) - time() >= 60;
118 }
119
120 private function getSessionExpiryTimestamp(FacebookSession $session)
121 {
122 return $session->getSessionInfo()->getExpiresAt()->format('U');
123 }
124 }