3 namespace Rapsys\AirBundle\Controller
;
5 use Google\Service\Calendar
;
6 use Symfony\Component\HttpFoundation\Request
;
7 use Symfony\Component\HttpFoundation\Response
;
8 use Symfony\Component\Routing\Generator\UrlGeneratorInterface
;
9 use Symfony\Component\Cache\Adapter\FilesystemAdapter
;
11 #use Rapsys\AirBundle\Entity\Slot;
12 #use Rapsys\AirBundle\Entity\Session;
13 #use Rapsys\AirBundle\Entity\Location;
14 #use Rapsys\AirBundle\Entity\User;
15 #use Rapsys\AirBundle\Entity\Snippet;
17 class CalendarController
extends DefaultController
{
19 * Calendar authorization
21 * @desc Initiate calendar oauth process
23 * @param Request $request The request instance
25 * @return Response The rendered view
27 public function index(Request
$request): Response
{
28 //Prevent non-admin to access here
29 $this->denyAccessUnlessGranted('ROLE_ADMIN', null, $this->translator
->trans('Unable to access this page without role %role%!', ['%role%' => $this->translator
->trans('Admin')]));
32 #$doctrine = $this->getDoctrine();
35 $section = $this->translator
->trans('Calendar oauth form');
38 $this->context
['description'] = $this->translator
->trans('Initiate calendar oauth process');
41 $title = $this->translator
->trans($this->config
['site']['title']).' - '.$section;
43 //Create the form according to the FormType created previously.
44 //And give the proper parameters
45 $form = $this->createForm('Rapsys\AirBundle\Form\CalendarType', ['calendar' => $this->config
['calendar']['calendar'], 'prefix' => $this->config
['calendar']['prefix']], [
46 'action' => $this->generateUrl('rapsys_air_calendar'),
50 if ($request->isMethod('POST')) {
51 // Refill the fields in case the form is not valid.
52 $form->handleRequest($request);
54 if ($form->isValid()) {
56 $data = $form->getData();
58 //When empty use config project
59 $data['project'] = $data['project']?:$this->config
['calendar']['project'];
61 //When empty use config client
62 $data['client'] = $data['client']?:$this->config
['calendar']['client'];
64 //When empty use config secret
65 $data['secret'] = $data['secret']?:$this->config
['calendar']['secret'];
68 $googleClient = new \Google\
Client(
70 'application_name' => $data['project'],
71 'client_id' => $data['client'],
72 'client_secret' => $data['secret'],
73 'redirect_uri' => $redirect = $this->generateUrl('rapsys_air_calendar_callback', [], UrlGeneratorInterface
::ABSOLUTE_URL
),
74 'scopes' => [Calendar
::CALENDAR
, Calendar
::CALENDAR_EVENTS
],
75 'access_type' => 'offline',
76 'approval_prompt' => 'force'
80 # //Set application name
81 # $googleClient->setApplicationName($data['project']);
84 # $googleClient->setClientId($data['client']);
87 # $googleClient->setClientSecret($data['secret']);
89 # //Add calendar scope
90 # //XXX: required to create the airlibre calendar ?
91 # $googleClient->addScope(Calendar::CALENDAR);
92 # //Add calendar events scope
93 # $googleClient->addScope(Calendar::CALENDAR_EVENTS);
96 # $googleClient->setRedirectUri($redirect = $this->generateUrl('rapsys_air_calendar_callback', [], UrlGeneratorInterface::ABSOLUTE_URL));
98 # //Set offline access
99 # $googleClient->setAccessType('offline');
101 # //Set included scopes
102 # //TODO: remove that useless of check scopes in callback
103 # $googleClient->setIncludeGrantedScopes(true);
106 #$googleClient->setLoginHint('rapsys.eu@gmail.com');
109 //TODO: force refresh token creation with approval prompt
110 #$googleClient->setApprovalPrompt('consent');
113 $authUrl = $googleClient->createAuthUrl();
116 $session = $request->getSession();
118 //Store calendar, prefix, project, client and secret in session
119 $session->set('calendar.calendar', $data['calendar']);
120 $session->set('calendar.prefix', $data['prefix']);
121 $session->set('calendar.project', $data['project']);
122 $session->set('calendar.client', $data['client']);
123 $session->set('calendar.secret', $data['secret']);
124 $session->set('calendar.redirect', $redirect);
126 //Redirect externally
127 return $this->redirect($authUrl);
132 return $this->render('@RapsysAir/calendar/index.html.twig', ['title' => $title, 'section' => $section, 'form' => $form->createView()]+
$this->context
);
136 * List all sessions for the organizer
138 * Display all sessions for the user with an application or login form
140 * @todo Fetch all google calendar and let user select one
141 * @todo Then save the calendar fucking id in database ??? with token infos !!!
143 * @param Request $request The request instance
145 * @return Response The rendered view
147 public function callback(Request
$request) {
149 $section = $this->translator
->trans('Calendar callback');
152 $this->context
['description'] = $this->translator
->trans('Finish calendar oauth process');
155 $title = $this->translator
->trans($this->config
['site']['title']).' - '.$section;
158 if (!empty($code = $request->get('code'))) {
160 $session = $request->getSession();
163 $calendar = $session->get('calendar.calendar');
166 $prefix = $session->get('calendar.prefix');
169 $project = $session->get('calendar.project');
172 $client = $session->get('calendar.client');
175 $secret = $session->get('calendar.secret');
178 $redirect = $session->get('calendar.redirect');
181 #$googleClient = new \Google\Client(['application_name' => $project, 'client_id' => $client, 'client_secret' => $secret, 'redirect_uri' => $redirect]);
182 $googleClient = new \Google\
Client(
184 'application_name' => $project,
185 'client_id' => $client,
186 'client_secret' => $secret,
187 'redirect_uri' => $redirect,
188 'scopes' => [Calendar
::CALENDAR
, Calendar
::CALENDAR_EVENTS
],
189 'access_type' => 'offline',
190 'approval_prompt' => 'force'
194 //Authenticate with code
195 if (!empty($token = $googleClient->authenticate($code))) {
197 if (!empty($token['error'])) {
198 $this->context
['error'] = $this->translator
->trans(ucfirst(str_replace('_', ' ', $token['error'])));
199 //Without refresh token
200 } elseif (empty($token['refresh_token'])) {
201 $this->context
['error'] = $this->translator
->trans('Missing refresh token');
204 //Retrieve cache object
205 $cache = new FilesystemAdapter($this->config
['cache']['namespace'], $this->config
['cache']['lifetime'], $this->config
['path']['cache']);
208 $cacheCalendars = $cache->getItem('calendars');
214 if ($cacheCalendars->isHit()) {
216 $calendars = $cacheCalendars->get();
220 if (empty($calendars[$client])) {
222 $calendars[$client] = [
223 'project' => $project,
225 'redirect' => $redirect,
231 $calendars[$client]['tokens'][$token['access_token']] = [
232 'calendar' => $calendar,
234 'refresh' => $token['refresh_token'],
235 'expire' => $token['expires_in'],
236 'scope' => $token['scope'],
237 'type' => $token['token_type'],
238 'created' => $token['created']
242 $cacheCalendars->set($calendars);
245 $cache->save($cacheCalendars);
248 $this->context
['message'] = $this->translator
->trans('Token stored for project '.$project);
250 //With failed authenticate
252 $this->context
['error'] = $this->translator
->trans('Client authenticate failed');
255 } elseif (!empty($error = $request->get('error'))) {
256 $this->context
['error'] = $this->translator
->trans(ucfirst(str_replace('_', ' ', $error)));
260 return $this->render('@RapsysAir/calendar/callback.html.twig', ['title' => $title, 'section' => $section]+
$this->context
);