]> Raphaƫl G. Git Repositories - airbundle/blob - Controller/CalendarController.php
Version 0.5.0
[airbundle] / Controller / CalendarController.php
1 <?php
2
3 namespace Rapsys\AirBundle\Controller;
4
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;
10
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;
16
17 class CalendarController extends DefaultController {
18 /**
19 * Calendar authorization
20 *
21 * Initiate calendar oauth process
22 *
23 * @param Request $request The request instance
24 *
25 * @return Response The rendered view
26 */
27 public function index(Request $request): Response {
28 //Without admin role
29 if (!$this->checker->isGranted('ROLE_ADMIN')) {
30 //Throw 403
31 throw $this->createAccessDeniedException($this->translator->trans('Unable to access this page without role %role%!', ['%role%' => $this->translator->trans('Admin')]));
32 }
33
34 //Set description
35 $this->context['description'] = $this->translator->trans('Initiate calendar oauth process');
36
37 //Set title
38 $this->context['title']['page'] = $this->translator->trans('Oauth form');
39
40 //Set section
41 $this->context['title']['section'] = $this->translator->trans('Calendar');
42
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('rapsysair_calendar'),
47 'method' => 'POST'
48 ]);
49
50 if ($request->isMethod('POST')) {
51 // Refill the fields in case the form is not valid.
52 $form->handleRequest($request);
53
54 if ($form->isValid()) {
55 //Get data
56 $data = $form->getData();
57
58 //When empty use config project
59 $data['project'] = $data['project']?:$this->config['calendar']['project'];
60
61 //When empty use config client
62 $data['client'] = $data['client']?:$this->config['calendar']['client'];
63
64 //When empty use config secret
65 $data['secret'] = $data['secret']?:$this->config['calendar']['secret'];
66
67 //Get google client
68 $googleClient = new \Google\Client(
69 [
70 'application_name' => $data['project'],
71 'client_id' => $data['client'],
72 'client_secret' => $data['secret'],
73 'redirect_uri' => $redirect = $this->generateUrl('rapsysair_calendar_callback', [], UrlGeneratorInterface::ABSOLUTE_URL),
74 'scopes' => [Calendar::CALENDAR, Calendar::CALENDAR_EVENTS],
75 'access_type' => 'offline',
76 'approval_prompt' => 'force'
77 ]
78 );
79
80 # //Set application name
81 # $googleClient->setApplicationName($data['project']);
82 #
83 # //Set client
84 # $googleClient->setClientId($data['client']);
85 #
86 # //Set client secret
87 # $googleClient->setClientSecret($data['secret']);
88 #
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);
94 #
95 # //Set redirect uri
96 # $googleClient->setRedirectUri($redirect = $this->generateUrl('rapsysair_calendar_callback', [], UrlGeneratorInterface::ABSOLUTE_URL));
97 #
98 # //Set offline access
99 # $googleClient->setAccessType('offline');
100 #
101 # //Set included scopes
102 # //TODO: remove that useless of check scopes in callback
103 # $googleClient->setIncludeGrantedScopes(true);
104
105 //Set login hint
106 #$googleClient->setLoginHint('rapsys.eu@gmail.com');
107
108 //Set prompt
109 //TODO: force refresh token creation with approval prompt
110 #$googleClient->setApprovalPrompt('consent');
111
112 //Get auth url
113 $authUrl = $googleClient->createAuthUrl();
114
115 //Get session
116 $session = $request->getSession();
117
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);
125
126 //Redirect externally
127 return $this->redirect($authUrl);
128 }
129 }
130
131 //Render template
132 return $this->render('@RapsysAir/calendar/index.html.twig', ['form' => $form->createView()]+$this->context);
133 }
134
135 /**
136 * List all sessions for the organizer
137 *
138 * Display all sessions for the user with an application or login form
139 *
140 * @todo Fetch all google calendar and let user select one
141 * @todo Then save the calendar fucking id in database ??? with token infos !!!
142 *
143 * @param Request $request The request instance
144 *
145 * @return Response The rendered view
146 */
147 public function callback(Request $request) {
148 //Set section
149 $section = $this->translator->trans('Calendar callback');
150
151 //Set description
152 $this->context['description'] = $this->translator->trans('Finish calendar oauth process');
153
154 //Set title
155 $this->context['title']['page'] = $this->translator->trans('Oauth callback');
156
157 //Set section
158 $this->context['title']['section'] = $this->translator->trans('Calendar');
159
160 //With code
161 if (!empty($code = $request->get('code'))) {
162 //Get session
163 $session = $request->getSession();
164
165 //Retrieve calendar
166 $calendar = $session->get('calendar.calendar');
167
168 //Retrieve prefix
169 $prefix = $session->get('calendar.prefix');
170
171 //Retrieve project
172 $project = $session->get('calendar.project');
173
174 //Retrieve client id
175 $client = $session->get('calendar.client');
176
177 //Retrieve secret
178 $secret = $session->get('calendar.secret');
179
180 //Retrieve redirect
181 $redirect = $session->get('calendar.redirect');
182
183 //Get google client
184 #$googleClient = new \Google\Client(['application_name' => $project, 'client_id' => $client, 'client_secret' => $secret, 'redirect_uri' => $redirect]);
185 $googleClient = new \Google\Client(
186 [
187 'application_name' => $project,
188 'client_id' => $client,
189 'client_secret' => $secret,
190 'redirect_uri' => $redirect,
191 'scopes' => [Calendar::CALENDAR, Calendar::CALENDAR_EVENTS],
192 'access_type' => 'offline',
193 'approval_prompt' => 'force'
194 ]
195 );
196
197 //Authenticate with code
198 if (!empty($token = $googleClient->authenticate($code))) {
199 //With error
200 if (!empty($token['error'])) {
201 $this->context['error'] = $this->translator->trans(ucfirst(str_replace('_', ' ', $token['error'])));
202 //Without refresh token
203 } elseif (empty($token['refresh_token'])) {
204 $this->context['error'] = $this->translator->trans('Missing refresh token');
205 //With valid token
206 } else {
207 //Retrieve cache object
208 $cache = new FilesystemAdapter($this->config['cache']['namespace'], $this->config['cache']['lifetime'], $this->config['path']['cache']);
209
210 //Retrieve calendars
211 $cacheCalendars = $cache->getItem('calendars');
212
213 //Init calendar
214 $calendars = [];
215
216 //With calendars
217 if ($cacheCalendars->isHit()) {
218 //Retrieve calendar
219 $calendars = $cacheCalendars->get();
220 }
221
222 //With empty client
223 if (empty($calendars[$client])) {
224 //Store client
225 $calendars[$client] = [
226 'project' => $project,
227 'secret' => $secret,
228 'redirect' => $redirect,
229 'tokens' => []
230 ];
231 }
232
233 //Add token
234 $calendars[$client]['tokens'][$token['access_token']] = [
235 'calendar' => $calendar,
236 'prefix' => $prefix,
237 'refresh' => $token['refresh_token'],
238 'expire' => $token['expires_in'],
239 'scope' => $token['scope'],
240 'type' => $token['token_type'],
241 'created' => $token['created']
242 ];
243
244 //Store calendar
245 $cacheCalendars->set($calendars);
246
247 //Save calendar
248 $cache->save($cacheCalendars);
249
250 //Set message
251 $this->context['message'] = $this->translator->trans('Token stored for project '.$project);
252 }
253 //With failed authenticate
254 } else {
255 $this->context['error'] = $this->translator->trans('Client authenticate failed');
256 }
257 //With error
258 } elseif (!empty($error = $request->get('error'))) {
259 $this->context['error'] = $this->translator->trans(ucfirst(str_replace('_', ' ', $error)));
260 }
261
262 //Render template
263 return $this->render('@RapsysAir/calendar/callback.html.twig', $this->context);
264 }
265 }