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
;
16 class UserAuthController
implements IDivineController
20 private $_facebookSessionFactory;
21 private $_facebookSession;
22 private $_facebookRequest;
23 private $_userRepository;
25 /* @var $_userStepByStepBuilder Domain\Entities\UserStepByStepBuilder */
26 private $_userStepByStepBuilder;
29 public function __construct(
30 IHttpRequest
$request,
31 IHttpResponse
$response,
32 IFacebookSessionFactory
$facebookSessionFactory,
33 IUserRepository
$userRepository,
34 IUserStepByStepBuilder
$userStepByStepBuilder
36 $this->_request
= $request;
37 $this->_response
= $response;
38 $this->_facebookSessionFactory
= $facebookSessionFactory;
39 $this->_userRepository
= $userRepository;
40 $this->_userStepByStepBuilder
= $userStepByStepBuilder;
43 public function indexAction() {
44 $token = $this->validateAuthRequest();
45 $facebookSession = $this->_facebookSessionFactory
->createInstance($token);
47 //If it fails to validate the exception will deal with it.
48 $facebookSession->validate();
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();
53 $id = $this->_facebookRequest
->getGraphObject(GraphUser
::className())->getId();
55 // If the user is not in the DB, create them.
56 $user = $this->_userRepository
->findByFacebookId($id) ?
: $this->registerUser();
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())))
63 private function validateAuthRequest()
65 $request = $this->_request
->get();
66 $response = $this->_response
->setHeader('Content-Type', 'application/json');
68 if(!isset($request['token']))
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')))
77 return $request['token'];
80 private function registerUser()
82 $userProfile = $this->_facebookRequest
->getGraphObject(GraphUser
::className());
84 $homeTown = $userProfile->getProperty('hometown');
88 $homeTownPageId = $homeTown ?
$homeTown->getProperty('id') : null
;
90 $pageRequest = (new FacebookRequest($this->_facebookSession
, 'GET', '/' . $homeTownPageId ))->execute();
91 $pageLocation = $pageRequest->getGraphObject(GraphLocation
::className())->getProperty('location')->cast(GraphLocation
::className());
93 $country = Util
::countryNameFromLatLong($pageLocation->getLatitude(), $pageLocation->getLongitude());
96 $firstName = $userProfile->getFirstName();
97 $lastName = $userProfile->getLastName();
98 $facebookId = $userProfile->getId();
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))
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
)
110 $this->_userRepository
->save($newUser);
115 private function isSessionLongLived(FacebookSession
$session)
117 return $this->getSessionExpiryTimestamp($session) - time() >= 60;
120 private function getSessionExpiryTimestamp(FacebookSession
$session)
122 return $session->getSessionInfo()->getExpiresAt()->format('U');