6 use Services\Http\IHttpResponse
;
7 use Services\Http\IHttpRequest
;
8 use Services\IFacebookSessionFactory
;
9 use Domain\Entities\IUserStepByStepBuilder
;
10 use Domain\Entities\IUser
;
11 use DataAccess\IUserRepository
;
12 use Facebook\FacebookSession
;
13 use Facebook\FacebookRequest
;
14 use Facebook\GraphUser
;
15 use Facebook\GraphLocation
;
16 use Facebook\FacebookRequestException
;
18 class UserAuthController
implements IDivineController
22 private $_facebookSessionFactory;
23 private $_facebookSession;
24 private $_facebookRequest;
25 private $_userRepository;
27 /* @var $_userStepByStepBuilder Domain\Entities\UserStepByStepBuilder */
28 private $_userStepByStepBuilder;
31 public function __construct(
32 IHttpRequest
$request,
33 IHttpResponse
$response,
34 IFacebookSessionFactory
$facebookSessionFactory,
35 IUserRepository
$userRepository,
36 IUserStepByStepBuilder
$userStepByStepBuilder
38 $this->_request
= $request;
39 $this->_response
= $response;
40 $this->_facebookSessionFactory
= $facebookSessionFactory;
41 $this->_userRepository
= $userRepository;
42 $this->_userStepByStepBuilder
= $userStepByStepBuilder;
45 public function indexAction() {
46 $token = $this->validateAuthRequest();
47 $facebookSession = $this->_facebookSessionFactory
->createInstance($token);
49 $this->_facebookSession
= $this->isSessionLongLived($facebookSession) ?
$facebookSession->getLongLivedSession() : $facebookSession;
50 $this->_facebookRequest
= (new FacebookRequest($this->_facebookSession
, 'GET', '/me?fields=hometown,first_name,last_name'))->execute();
52 $id = $this->_facebookRequest
->getGraphObject(GraphUser
::className())->getId();
54 // If the user is not in the DB, create them.
55 $user = $this->_userRepository
->findByFacebookId($id) ?
: $this->registerUser();
57 $this->_response
->setHeader('Content-Type', 'application/json')
58 ->setBody(json_encode(array('token' => $this->_facebookSession
->getToken(), 'expires' => $this->getSessionExpiryTimestamp($this->_facebookSession
), 'displayName' => $user->getDisplayName())))
62 private function validateAuthRequest()
64 $request = $this->_request
->get();
65 $response = $this->_response
->setHeader('Content-Type', 'application/json');
67 if(!isset($request['token']))
69 $response->setBody(json_encode(array('result' => 'error', 'message' => 'missing auth token')))
74 return $request['token'];
77 private function registerUser()
79 $userProfile = $this->_facebookRequest
->getGraphObject(GraphUser
::className());
81 $homeTown = $userProfile->getProperty('hometown');
85 $homeTownPageId = $homeTown ?
$homeTown->getProperty('id') : null
;
87 $pageRequest = (new FacebookRequest($this->_facebookSession
, 'GET', '/' . $homeTownPageId ))->execute();
88 $pageLocation = $pageRequest->getGraphObject(GraphLocation
::className())->getProperty('location')->cast(GraphLocation
::className());
90 $country = Util
::countryNameFromLatLong($pageLocation->getLatitude(), $pageLocation->getLongitude());
93 $firstName = $userProfile->getFirstName();
94 $lastName = $userProfile->getLastName();
95 $facebookId = $userProfile->getId();
97 //TODO: Is insantiating the VO classes here a good idea?
98 $newUser = $this->_userStepByStepBuilder
->With_DisplayName($firstName)
99 ->With_Name(new \Domain\VOs\
Name($firstName, $lastName))
101 ->With_FacebookId($facebookId)
102 ->With_Quota(100000000) //XXX: quota is in bytes
103 //XXX: Is this confusing? Maybe better to do a conditional and only call with_country when we have a country
104 ->With_Country(isset($country) ?
new \Domain\VOs\
Country($country) : null
)
107 $this->_userRepository
->save($newUser);
112 private function isSessionLongLived(FacebookSession
$session)
114 return $this->getSessionExpiryTimestamp($session) - time() >= 60;
117 private function getSessionExpiryTimestamp(FacebookSession
$session)
119 return $session->getSessionInfo()->getExpiresAt()->format('U');