+ //Without result
+ if ($result === null) {
+ //Return result
+ return $result;
+ }
+
+ //Set route
+ $route = 'rapsysair_session_view';
+
+ //Set route params
+ $routeParams = ['id' => $id, 'location' => $this->slugger->slug($this->translator->trans($result['l_title']))];
+
+ //Set session
+ $session = [
+ 'id' => $id,
+ 'date' => $result['date'],
+ 'begin' => $result['begin'],
+ 'start' => $result['start'],
+ 'length' => $result['length'],
+ 'stop' => $result['stop'],
+ 'rainfall' => $result['rainfall'] !== null ? $result['rainfall'].' mm' : $result['rainfall'],
+ 'rainrisk' => $result['rainrisk'] !== null ? ($result['rainrisk']*100).' %' : $result['rainrisk'],
+ 'realfeel' => $result['realfeel'] !== null ? $result['realfeel'].' °C' : $result['realfeel'],
+ 'realfeelmin' => $result['realfeelmin'] !== null ? $result['realfeelmin'].' °C' : $result['realfeelmin'],
+ 'realfeelmax' => $result['realfeelmax'] !== null ? $result['realfeelmax'].' °C' : $result['realfeelmax'],
+ 'temperature' => $result['temperature'] !== null ? $result['temperature'].' °C' : $result['temperature'],
+ 'temperaturemin' => $result['temperaturemin'] !== null ? $result['temperaturemin'].' °C' : $result['temperaturemin'],
+ 'temperaturemax' => $result['temperaturemax'] !== null ? $result['temperaturemax'].' °C' : $result['temperaturemax'],
+ 'locked' => $result['locked'],
+ 'created' => $result['created'],
+ 'updated' => $result['updated'],
+ 'title' => $this->translator->trans('Session %id%', ['%id%' => $id]),
+ 'modified' => $result['modified'],
+ 'application' => null,
+ 'location' => [
+ 'id' => $result['l_id'],
+ 'at' => $this->translator->trans('at '.$result['l_title']),
+ 'title' => $locationTitle = $this->translator->trans($result['l_title']),
+ 'description' => $this->translator->trans($result['l_description']??'None'),
+ 'address' => $result['l_address'],
+ 'zipcode' => $result['l_zipcode'],
+ 'city' => $result['l_city'],
+ 'in' => $this->translator->trans('in '.$result['l_city']),
+ 'map' => $this->translator->trans($result['l_title'].' access map'),
+ 'multimap' => $this->translator->trans($result['l_title'].' sector map'),
+ 'latitude' => $result['l_latitude'],
+ 'longitude' => $result['l_longitude'],
+ 'indoor' => $result['l_indoor'],
+ 'slug' => $routeParams['location'],
+ 'link' => $this->router->generate('rapsysair_location_view', ['id' => $result['l_id'], 'location' => $routeParams['location']])
+ ],
+ 'slot' => [
+ 'id' => $result['t_id'],
+ 'the' => $this->translator->trans('the '.lcfirst($result['t_title'])),
+ 'title' => $this->translator->trans($result['t_title'])
+ ],
+ 'snippet' => null,
+ 'applications' => null
+ ];
+
+ //With application
+ if (!empty($result['a_id'])) {
+ $session['application'] = [
+ 'dance' => [
+ 'id' => $result['ad_id'],
+ 'title' => $this->translator->trans($result['ad_name'].' '.lcfirst($result['ad_type'])),
+ 'name' => $this->translator->trans($result['ad_name']),
+ 'type' => $this->translator->trans($result['ad_type']),
+ 'slug' => $routeParams['dance'] = $this->slugger->slug($this->translator->trans($result['ad_name'].' '.lcfirst($result['ad_type']))),
+ 'link' => $this->router->generate('rapsysair_dance_view', ['id' => $result['ad_id'], 'name' => $this->slugger->slug($this->translator->trans($result['ad_name'])), 'type' => $this->slugger->slug($this->translator->trans($result['ad_type']))])
+ ],
+ 'user' => [
+ 'id' => $result['au_id'],
+ 'by' => $this->translator->trans('by %pseudonym%', [ '%pseudonym%' => $result['au_pseudonym'] ]),
+ 'title' => $result['au_pseudonym'],
+ 'slug' => $routeParams['user'] = $this->slugger->slug($result['au_pseudonym']),
+ 'link' => $result['au_id'] == 1 && $routeParams['user'] == 'milonga-raphael' ? $this->router->generate('rapsysair_user_milongaraphael') : $this->router->generate('rapsysair_user_view', ['id' => $result['au_id'], 'user' => $routeParams['user']]),
+ 'contact' => $this->router->generate('rapsysair_contact', ['id' => $result['au_id'], 'user' => $routeParams['user']])
+ ],
+ 'id' => $result['a_id'],
+ 'canceled' => $result['a_canceled']
+ ];
+ }
+
+ //With snippet
+ if (!empty($result['p_id'])) {
+ $session['snippet'] = [
+ 'id' => $result['p_id'],
+ 'description' => $result['p_description'],
+ 'class' => $result['p_class'],
+ 'contact' => $result['p_contact'],
+ 'donate' => $result['p_donate'],
+ 'link' => $result['p_link'],
+ 'profile' => $result['p_profile'],
+ 'rate' => $result['p_rate'],
+ 'hat' => $result['p_hat']
+ ];
+ }
+
+ //With applications
+ if (!empty($result['sa_id'])) {
+ //Extract applications id
+ $result['sa_id'] = explode("\n", $result['sa_id']);
+ //Extract applications score
+ //XXX: score may be null before grant or for bad behaviour, replace NULL with 'NULL' to avoid silent drop in mysql
+ $result['sa_score'] = array_map(function($v){return $v==='NULL'?null:$v;}, explode("\n", $result['sa_score']));
+ //Extract applications created
+ $result['sa_created'] = array_map(function($v){return new \DateTime($v);}, explode("\n", $result['sa_created']));
+ //Extract applications updated
+ $result['sa_updated'] = array_map(function($v){return new \DateTime($v);}, explode("\n", $result['sa_updated']));
+ //Extract applications canceled
+ //XXX: canceled is null before cancelation, replace NULL with 'NULL' to avoid silent drop in mysql
+ $result['sa_canceled'] = array_map(function($v){return $v==='NULL'?null:new \DateTime($v);}, explode("\n", $result['sa_canceled']));
+
+ //Extract applications user id
+ $result['sau_id'] = explode("\n", $result['sau_id']);
+ //Extract applications user pseudonym
+ $result['sau_pseudonym'] = explode("\n", $result['sau_pseudonym']);
+
+ //Init applications
+ $session['applications'] = [];
+
+ //Iterate on each applications id
+ foreach($result['sa_id'] as $i => $sa_id) {
+ $session['applications'][$sa_id] = [
+ 'user' => null,
+ 'score' => $result['sa_score'][$i],
+ 'created' => $result['sa_created'][$i],
+ 'updated' => $result['sa_updated'][$i],
+ 'canceled' => $result['sa_canceled'][$i]
+ ];
+ if (!empty($result['sau_id'][$i])) {
+ $session['applications'][$sa_id]['user'] = [
+ 'id' => $result['sau_id'][$i],
+ 'title' => $result['sau_pseudonym'][$i],
+ 'slug' => $this->slugger->slug($result['sau_pseudonym'][$i])
+ ];
+ }
+ }
+ }
+
+ //Set link
+ $session['link'] = $this->router->generate($route, $routeParams);
+
+ //Set canonical
+ $session['canonical'] = $this->router->generate($route, $routeParams, UrlGeneratorInterface::ABSOLUTE_URL);
+
+ //Set alternates
+ $session['alternates'] = [];
+
+ //Iterate on each locales
+ foreach($this->translator->getFallbackLocales() as $fallback) {
+ //Set titles
+ $titles = [];
+
+ //Set route params location
+ $routeParams['location'] = $this->slugger->slug($this->translator->trans($result['l_title'], [], null, $fallback));
+
+ //With route params dance
+ if (!empty($routeParams['dance'])) {
+ $routeParams['dance'] = $this->slugger->slug($this->translator->trans($result['ad_name'].' '.lcfirst($result['ad_type']), [], null, $fallback));
+ }
+
+ //With route params user
+ if (!empty($routeParams['user'])) {
+ $routeParams['user'] = $this->slugger->slug($result['au_pseudonym']);
+ }
+
+ //With current locale
+ if ($fallback === $this->locale) {
+ //Set current locale title
+ $titles[$this->locale] = $this->translator->trans($this->languages[$this->locale]);
+ //Without current locale
+ } else {
+ //Iterate on other locales
+ foreach(array_diff($this->translator->getFallbackLocales(), [$fallback]) as $other) {
+ //Set other locale title
+ $titles[$other] = $this->translator->trans($this->languages[$fallback], [], null, $other);
+ }
+
+ //Add alternates locale
+ $session['alternates'][str_replace('_', '-', $fallback)] = [
+ 'absolute' => $this->router->generate($route, ['_locale' => $fallback]+$routeParams, UrlGeneratorInterface::ABSOLUTE_URL),
+ 'relative' => $this->router->generate($route, ['_locale' => $fallback]+$routeParams),
+ 'title' => implode('/', $titles),
+ 'translated' => $this->translator->trans($this->languages[$fallback], [], null, $fallback)
+ ];
+ }
+
+ //Add alternates shorter locale
+ if (empty($parameters['alternates'][$shortFallback = substr($fallback, 0, 2)])) {
+ //Set locale locales context
+ $session['alternates'][$shortFallback] = [
+ 'absolute' => $this->router->generate($route, ['_locale' => $fallback]+$routeParams, UrlGeneratorInterface::ABSOLUTE_URL),
+ 'relative' => $this->router->generate($route, ['_locale' => $fallback]+$routeParams),
+ 'title' => implode('/', $titles),
+ 'translated' => $this->translator->trans($this->languages[$fallback], [], null, $fallback)
+ ];
+ }
+ }
+
+ //Return session
+ return $session;