+ //TODO: add feature for alerts (-30min/-1h) ?
+ //TODO: [Direct link to calendar ?][Direct link to calendar settings ?][Alerts][Remove]
+
+ //Create the CalendarType form and give the proper parameters
+ $form = $this->factory->createNamed('calendar_'.$googleShortMail, 'Rapsys\AirBundle\Form\CalendarType', $formData, [
+ //Set action to register route name and context
+ 'action' => $this->generateUrl($this->config['route']['edit']['name'], ['mail' => $smail, 'hash' => $hash]+$this->config['route']['edit']['context']),
+ //Set calendar choices
+ //XXX: unique calendar summary required by choice widget is guaranteed by appending ' (x)' to secondary calendars earlier
+ 'calendar_choices' => array_flip($calendars),
+ //Set method
+ 'method' => 'POST'
+ ]);
+
+ //With post method
+ if ($request->isMethod('POST')) {
+ //Refill the fields in case the form is not valid.
+ $form->handleRequest($request);
+
+ //With reset submitted and valid
+ if ($form->isSubmitted() && $form->isValid()) {
+ //Set data
+ $data = $form->getData();
+
+ //Refresh button
+ if (($clicked = $form->getClickedButton()->getName()) == 'refresh') {
+ //Remove calendar key
+ $this->cache->delete($calendarKey);
+
+ //Add notice
+ $this->addFlash('notice', $this->translator->trans('Account %mail% calendars updated', ['%mail%' => $googleMail]));
+ //Add button
+ } elseif ($clicked == 'add') {
+ //Get google calendar service
+ $service = new \Google\Service\Calendar($this->google);
+
+ //Add calendar
+ try {
+ //Instantiate calendar
+ $calendar = new \Google\Service\Calendar\Calendar(
+ [
+ 'summary' => $this->translator->trans($this->config['context']['site']['title']),
+ 'timeZone' => date_default_timezone_get()
+ ]
+ );
+
+ //Insert calendar
+ $service->calendars->insert($calendar);
+ //Catch exception
+ } catch(\Google\Service\Exception $e) {
+ //Throw error
+ throw new \LogicException('Calendar insert failed', 0, $e);
+ }
+
+ //Remove calendar key
+ $this->cache->delete($calendarKey);
+
+ //Add notice
+ $this->addFlash('notice', $this->translator->trans('Account %mail% calendar added', ['%mail%' => $googleMail]));
+ //Delete button
+ } elseif ($clicked == 'delete') {
+ //Get google calendar service
+ $service = new \Google\Service\Calendar($this->google);
+
+ //Remove calendar
+ try {
+ //Set site title
+ $siteTitle = $this->translator->trans($this->config['context']['site']['title']);
+
+ //Iterate on calendars
+ foreach($calendars as $calendarId => $calendarSummary) {
+ //With calendar matching site title
+ if (substr($calendarSummary, 0, strlen($siteTitle)) == $siteTitle) {
+ //Delete the calendar
+ $service->calendars->delete($calendarId);
+ }
+ }
+ //Catch exception
+ } catch(\Google\Service\Exception $e) {
+ //Throw error
+ throw new \LogicException('Calendar delete failed', 0, $e);
+ }
+
+ //Remove calendar key
+ $this->cache->delete($calendarKey);
+
+ //Add notice
+ $this->addFlash('notice', $this->translator->trans('Account %mail% calendars deleted', ['%mail%' => $googleMail]));
+ //Unlink button
+ } elseif ($clicked == 'unlink') {
+ //Iterate on each google calendars
+ foreach($googleCalendars as $googleCalendar) {
+ //Remove google calendar from database
+ $this->manager->remove($googleCalendar);
+ }
+
+ //Remove google token from database
+ $this->manager->remove($googleToken);
+
+ //Flush to persist
+ $this->manager->flush();
+
+ //Revoke access token
+ $this->google->revokeToken($googleToken->getAccess());
+
+ //With refresh token
+ if ($refresh = $googleToken->getRefresh()) {
+ //Revoke refresh token
+ $this->google->revokeToken($googleToken->getRefresh());
+ }
+
+ //Remove calendar key
+ $this->cache->delete($calendarKey);
+
+ //Add notice
+ $this->addFlash('notice', $this->translator->trans('Account %mail% calendars unlinked', ['%mail%' => $googleMail]));
+ //Submit button
+ } else {
+ //Flipped calendar data
+ $dataCalendarFlip = array_flip($data['calendar']);
+
+ //Iterate on each google calendars
+ foreach($googleCalendars as $googleCalendar) {
+ //Without calendar in flipped data
+ if (!isset($dataCalendarFlip[$googleCalendarMail = $googleCalendar->getMail()])) {
+ //Remove google calendar from database
+ $this->manager->remove($googleCalendar);
+ //With calendar in flipped data
+ } else {
+ //Remove google calendar from calendar data
+ unset($data['calendar'][$dataCalendarFlip[$googleCalendarMail]]);
+ }
+ }
+
+ //Iterate on remaining calendar data
+ foreach($data['calendar'] as $googleCalendarMail) {
+ //Create new google calendar
+ //XXX: remove trailing ' (x)' from summary
+ $googleCalendar = new GoogleCalendar($googleToken, $googleCalendarMail, preg_replace('/ \([0-9]\)$/', '', $calendars[$googleCalendarMail]));
+
+ //Queue google calendar save
+ $this->manager->persist($googleCalendar);
+ }
+
+ //Flush to persist ids
+ $this->manager->flush();
+
+ //Add notice
+ $this->addFlash('notice', $this->translator->trans('Account %mail% calendars updated', ['%mail%' => $googleMail]));
+ }
+
+ //Redirect to cleanup the form
+ return $this->redirectToRoute($this->config['route']['edit']['name'], ['mail' => $smail, 'hash' => $hash]+$this->config['route']['edit']['context']);
+ }