From f110b8ba20232e0ceeb67390f8e672431868d32d Mon Sep 17 00:00:00 2001 From: =?utf8?q?Rapha=C3=ABl=20Gertz?= <git@rapsys.eu> Date: Fri, 25 Oct 2019 16:33:24 +0200 Subject: [PATCH 1/1] Initial import --- Controller/DefaultController.php | 305 +++++++++++ DataFixtures/AirFixtures.php | 246 +++++++++ DependencyInjection/RapsysAirExtension.php | 46 ++ Entity/Application.php | 187 +++++++ Entity/Group.php | 6 + Entity/Location.php | 304 +++++++++++ Entity/Session.php | 281 +++++++++++ Entity/Slot.php | 191 +++++++ Entity/Title.php | 7 + Entity/User.php | 85 ++++ Entity/Vote.php | 141 ++++++ Form/ApplicationType.php | 39 ++ Form/ContactType.php | 40 ++ RapsysAirBundle.php | 9 + Repository/ApplicationRepository.php | 26 + Repository/SessionRepository.php | 45 ++ Resources/config/doctrine/Application.orm.yml | 27 + Resources/config/doctrine/Group.orm.yml | 8 + Resources/config/doctrine/Location.orm.yml | 69 +++ Resources/config/doctrine/Session.orm.yml | 41 ++ Resources/config/doctrine/Slot.orm.yml | 24 + Resources/config/doctrine/Title.orm.yml | 8 + Resources/config/doctrine/User.orm.yml | 27 + Resources/config/doctrine/Vote.orm.yml | 23 + Resources/config/routing.yml | 17 + Resources/config/services.yml | 15 + Resources/public/css/reset.css | 45 ++ Resources/public/css/screen.css | 473 ++++++++++++++++++ Resources/public/ico/favicon.ico | Bin 0 -> 90022 bytes Resources/public/png/apple.png | Bin 0 -> 14257 bytes Resources/public/png/favicon.png | Bin 0 -> 15277 bytes Resources/public/png/logo.png | Bin 0 -> 4297 bytes Resources/public/svg/favicon.svg | 95 ++++ Resources/public/svg/logo.svg | 228 +++++++++ Resources/public/xcf/openair.xcf | Bin 0 -> 30224 bytes Resources/translations/messages.fr.yml | 60 +++ Resources/translations/validators.fr.yml | 11 + Resources/views/admin/index.html.twig | 57 +++ Resources/views/admin/index.html.twig.toto | 1 + Resources/views/admin/session.html.twig | 31 ++ Resources/views/base.html.twig | 78 +++ Resources/views/form/contact.html.twig | 34 ++ .../views/form/form_div_layout.html.twig | 417 +++++++++++++++ Resources/views/form/login.html.twig | 32 ++ Resources/views/form/recover.html.twig | 28 ++ Resources/views/form/recover_mail.html.twig | 30 ++ Resources/views/form/register.html.twig | 42 ++ Resources/views/mail/contact.html.twig | 43 ++ Resources/views/mail/generic.html.twig | 49 ++ Resources/views/mail/register.html.twig | 43 ++ Resources/views/page/index.html.twig | 7 + Tests/Controller/DefaultControllerTest.php | 17 + Twig/Base64Extension.php | 12 + Twig/Bb2htmlExtension.php | 64 +++ Twig/FileGetContentsExtension.php | 11 + 55 files changed, 4125 insertions(+) create mode 100644 Controller/DefaultController.php create mode 100644 DataFixtures/AirFixtures.php create mode 100644 DependencyInjection/RapsysAirExtension.php create mode 100644 Entity/Application.php create mode 100644 Entity/Group.php create mode 100644 Entity/Location.php create mode 100644 Entity/Session.php create mode 100644 Entity/Slot.php create mode 100644 Entity/Title.php create mode 100644 Entity/User.php create mode 100644 Entity/Vote.php create mode 100644 Form/ApplicationType.php create mode 100644 Form/ContactType.php create mode 100644 RapsysAirBundle.php create mode 100644 Repository/ApplicationRepository.php create mode 100644 Repository/SessionRepository.php create mode 100644 Resources/config/doctrine/Application.orm.yml create mode 100644 Resources/config/doctrine/Group.orm.yml create mode 100644 Resources/config/doctrine/Location.orm.yml create mode 100644 Resources/config/doctrine/Session.orm.yml create mode 100644 Resources/config/doctrine/Slot.orm.yml create mode 100644 Resources/config/doctrine/Title.orm.yml create mode 100644 Resources/config/doctrine/User.orm.yml create mode 100644 Resources/config/doctrine/Vote.orm.yml create mode 100644 Resources/config/routing.yml create mode 100644 Resources/config/services.yml create mode 100644 Resources/public/css/reset.css create mode 100644 Resources/public/css/screen.css create mode 100644 Resources/public/ico/favicon.ico create mode 100644 Resources/public/png/apple.png create mode 100644 Resources/public/png/favicon.png create mode 100644 Resources/public/png/logo.png create mode 100644 Resources/public/svg/favicon.svg create mode 100644 Resources/public/svg/logo.svg create mode 100644 Resources/public/xcf/openair.xcf create mode 100644 Resources/translations/messages.fr.yml create mode 100644 Resources/translations/validators.fr.yml create mode 100644 Resources/views/admin/index.html.twig create mode 100644 Resources/views/admin/index.html.twig.toto create mode 100644 Resources/views/admin/session.html.twig create mode 100644 Resources/views/base.html.twig create mode 100644 Resources/views/form/contact.html.twig create mode 100644 Resources/views/form/form_div_layout.html.twig create mode 100644 Resources/views/form/login.html.twig create mode 100644 Resources/views/form/recover.html.twig create mode 100644 Resources/views/form/recover_mail.html.twig create mode 100644 Resources/views/form/register.html.twig create mode 100644 Resources/views/mail/contact.html.twig create mode 100644 Resources/views/mail/generic.html.twig create mode 100644 Resources/views/mail/register.html.twig create mode 100644 Resources/views/page/index.html.twig create mode 100644 Tests/Controller/DefaultControllerTest.php create mode 100644 Twig/Base64Extension.php create mode 100644 Twig/Bb2htmlExtension.php create mode 100644 Twig/FileGetContentsExtension.php diff --git a/Controller/DefaultController.php b/Controller/DefaultController.php new file mode 100644 index 0000000..31d4b89 --- /dev/null +++ b/Controller/DefaultController.php @@ -0,0 +1,305 @@ +<?php + +namespace Rapsys\AirBundle\Controller; + +use Symfony\Bundle\FrameworkBundle\Controller\Controller; +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; +use Symfony\Component\HttpFoundation\Request; +use Rapsys\AirBundle\Entity\Session; +use Rapsys\AirBundle\Entity\Application; +use Symfony\Component\Form\FormError; + +class DefaultController extends Controller { + public function contactAction(Request $request) { + //Get translator + $trans = $this->get('translator'); + + //Set section + $section = $trans->trans('Contact'); + + //Set title + $title = $section.' - '.$trans->trans($this->getParameter('rapsys_air.title')); + + //Create the form according to the FormType created previously. + //And give the proper parameters + $form = $this->createForm('Rapsys\AirBundle\Form\ContactType', null, [ + // To set the action use $this->generateUrl('route_identifier') + 'action' => $this->generateUrl('rapsys_air_contact'), + 'method' => 'POST' + ]); + + if ($request->isMethod('POST')) { + // Refill the fields in case the form is not valid. + $form->handleRequest($request); + + if ($form->isValid()) { + //Get data + $data = $form->getData(); + + //Get contact name + $contactName = $this->getParameter('rapsys_air.contact_name'); + + //Get contact mail + $contactMail = $this->getParameter('rapsys_air.contact_mail'); + + //Get logo + $logo = $this->getParameter('rapsys_air.logo'); + + //Get title + $title = $trans->trans($this->getParameter('rapsys_air.title')); + + //Get subtitle + $subtitle = $trans->trans('Hi,').' '.$contactName; + + $message = \Swift_Message::newInstance() + ->setSubject($data['subject']) + ->setFrom([$data['mail'] => $data['name']]) + ->setTo([$contactMail => $contactName]) + ->setBody($data['message']) + ->addPart( + $this->renderView( + '@RapsysAir/mail/generic.html.twig', + [ + 'logo' => $logo, + 'title' => $title, + 'subtitle' => $subtitle, + 'home' => $this->get('router')->generate('rapsys_air_homepage', [], UrlGeneratorInterface::ABSOLUTE_URL), + 'subject' => $data['subject'], + 'contact_name' => $contactName, + 'message' => strip_tags($data['message']) + ] + ), + 'text/html' + ); + //Send message + if ($this->get('mailer')->send($message)) { + //Redirect to cleanup the form + return $this->redirectToRoute('rapsys_air_contact', ['sent' => 1]); + } + } + } + + //Render template + return $this->render('@RapsysAir/form/contact.html.twig', ['title' => $title, 'section' => $section, 'form' => $form->createView(), 'sent' => $request->query->get('sent', 0)]); + } + + public function indexAction() { + //Get translator + $trans = $this->get('translator'); + + //Set section + $section = $trans->trans('Index'); + + //Set title + $title = $section.' - '.$trans->trans($this->getParameter('rapsys_air.title')); + + return $this->render('@RapsysAir/page/index.html.twig', ['title' => $title, 'section' => $section]); + } + + public function adminAction(Request $request) { + $this->denyAccessUnlessGranted('ROLE_ADMIN', null, 'Unable to access this page!'); + + //Get translator + $trans = $this->get('translator'); + + //Set section + $section = $trans->trans('Admin'); + + //Set title + $title = $section.' - '.$trans->trans($this->getParameter('rapsys_air.title')); + + //Create the form according to the FormType created previously. + //And give the proper parameters + $form = $this->createForm('Rapsys\AirBundle\Form\ApplicationType', null, [ + // To set the action use $this->generateUrl('route_identifier') + 'action' => $this->generateUrl('rapsys_air_admin'), + 'method' => 'POST', + 'attr' => [ 'class' => 'form_col' ] + ]); + + //Get doctrine + $doctrine = $this->getDoctrine(); + + //Handle request + if ($request->isMethod('POST')) { + // Refill the fields in case the form is not valid. + $form->handleRequest($request); + + if ($form->isValid()) { + //Get data + $data = $form->getData(); + + //Get manager + $manager = $doctrine->getManager(); + + //Protect session fetching + try { + $session = $doctrine->getRepository(Session::class)->findOneByLocationSlotDate($data['location'], $data['slot'], $data['date']); + //Catch no session case + } catch (\Doctrine\ORM\NoResultException $e) { + //Create the session + $session = new Session(); + $session->setLocation($data['location']); + $session->setSlot($data['slot']); + $session->setDate($data['date']); + $session->setCreated(new \DateTime('now')); + $session->setUpdated(new \DateTime('now')); + $manager->persist($session); + //Flush to get the ids + #$manager->flush(); + } + + //Init application + $application = false; + + //Protect application fetching + try { + //TODO: handle admin case where we provide a user in extra + $application = $doctrine->getRepository(Application::class)->findOneBySessionUser($session, $this->getUser()); + + //Add error message to mail field + $form->get('slot')->addError(new FormError($trans->trans('Application already exists'))); + //Catch no application cases + //XXX: combine these catch when php 7.1 is available + } catch (\Doctrine\ORM\NoResultException $e) { + //Catch invalid argument because session is not already persisted + } catch(\Doctrine\ORM\ORMInvalidArgumentException $e) { + } + + //Create new application if none found + if (!$application) { + //Create the application + $application = new Application(); + $application->setSession($session); + //TODO: handle admin case where we provide a user in extra + $application->setUser($this->getUser()); + $application->setCreated(new \DateTime('now')); + $application->setUpdated(new \DateTime('now')); + $manager->persist($application); + + //Flush to get the ids + $manager->flush(); + + //Add notice in flash message + $this->addFlash('notice', $trans->trans('Application request the %date% for %location% on the slot %slot% saved', ['%location%' => $data['location']->getTitle(), '%slot%' => $data['slot']->getTitle(), '%date%' => $data['date']->format('Y-m-d')])); + + //Redirect to cleanup the form + return $this->redirectToRoute('rapsys_air_admin'); + } + } + } + + //Compute period + $period = new \DatePeriod( + //Start from first monday of week + new \DateTime('Monday this week'), + //Iterate on each day + new \DateInterval('P1D'), + //End with next sunday and 4 weeks + new \DateTime('Monday this week + 5 week') + ); + + //Fetch sessions + $sessions = $doctrine->getRepository(Session::class)->findByDatePeriod($period); + + //Init calendar + $calendar = []; + + //Init month + $month = null; + + //Iterate on each day + foreach($period as $date) { + //Init day in calendar + $calendar[$Ymd = $date->format('Ymd')] = [ + 'title' => $date->format('d'), + 'class' => [], + 'sessions' => [] + ]; + //Append month for first day of month + if ($month != $date->format('m')) { + $month = $date->format('m'); + $calendar[$Ymd]['title'] .= '/'.$month; + } + //Deal with today + if ($date->format('U') == ($today = strtotime('today'))) { + $calendar[$Ymd]['title'] .= '/'.$month; + $calendar[$Ymd]['current'] = true; + $calendar[$Ymd]['class'][] = 'current'; + } + //Disable passed days + if ($date->format('U') < $today) { + $calendar[$Ymd]['disabled'] = true; + $calendar[$Ymd]['class'][] = 'disabled'; + } + //Set next month days + if ($date->format('m') > date('m')) { + $calendar[$Ymd]['next'] = true; + $calendar[$Ymd]['class'][] = 'next'; + } + //Iterate on each session to find the one of the day + foreach($sessions as $session) { + if (($sessionYmd = $session->getDate()->format('Ymd')) == $Ymd) { + //Count number of application + $count = count($session->getApplications()); + + //Compute classes + $class = []; + if ($session->getApplication()) { + $class[] = 'granted'; + } elseif ($count == 0) { + $class[] = 'orphaned'; + } elseif ($count > 1) { + $class[] = 'disputed'; + } else { + $class[] = 'pending'; + } + + //Add the session + $calendar[$Ymd]['sessions'][$session->getSlot()->getId().$session->getLocation()->getId()] = [ + 'id' => $session->getId(), + 'title' => ($count > 1?'['.$count.'] ':'').$session->getSlot()->getTitle().' '.$session->getLocation()->getTitle(), + 'class' => $class + ]; + } + } + + //Sort sessions + ksort($calendar[$Ymd]['sessions']); + } + + return $this->render('@RapsysAir/admin/index.html.twig', ['title' => $title, 'section' => $section, 'form' => $form->createView(), 'calendar' => $calendar]); + } + + public function sessionAction(Request $request, $id) { + /*header('Content-Type: text/plain'); + var_dump($calendar); + exit;*/ + + //Get translator + $trans = $this->get('translator'); + + //Set section + $section = $trans->trans('Session %id%', ['%id%' => $id]); + + //Set title + $title = $section.' - '.$trans->trans($this->getParameter('rapsys_air.title')); + + //Create the form according to the FormType created previously. + //And give the proper parameters + /*$form = $this->createForm('Rapsys\AirBundle\Form\ApplicationType', null, [ + // To set the action use $this->generateUrl('route_identifier') + 'action' => $this->generateUrl('rapsys_air_admin'), + 'method' => 'POST', + 'attr' => [ 'class' => 'form_col' ] + ]);*/ + + //Get doctrine + $doctrine = $this->getDoctrine(); + + //Fetch session + $session = $doctrine->getRepository(Session::class)->findOneById($id); + + return $this->render('@RapsysAir/admin/session.html.twig', ['title' => $title, 'section' => $section, /*'form' => $form->createView(),*/ 'session' => $session]); + } +} diff --git a/DataFixtures/AirFixtures.php b/DataFixtures/AirFixtures.php new file mode 100644 index 0000000..cfaaa62 --- /dev/null +++ b/DataFixtures/AirFixtures.php @@ -0,0 +1,246 @@ +<?php + +namespace Rapsys\AirBundle\DataFixtures; + +use Rapsys\AirBundle\Entity\Title; +use Rapsys\AirBundle\Entity\Group; +use Rapsys\AirBundle\Entity\User; +use Rapsys\AirBundle\Entity\Location; +use Rapsys\AirBundle\Entity\Slot; + +class AirFixtures extends \Doctrine\Bundle\FixturesBundle\Fixture implements \Symfony\Component\DependencyInjection\ContainerAwareInterface { + /** + * @var ContainerInterface + */ + private $container; + + public function setContainer(\Symfony\Component\DependencyInjection\ContainerInterface $container = null) + { + $this->container = $container; + } + + /** + * {@inheritDoc} + */ + public function load(\Doctrine\Common\Persistence\ObjectManager $manager) { + $encoder = $this->container->get('security.password_encoder'); + + //Title tree + $titleTree = array( + 'M.' => 'Monsieur', + 'Mlle' => 'Mademoiselle', + 'Mme' => 'Madame' + ); + + //Create titles + $titles = array(); + foreach($titleTree as $shortData => $titleData) { + $title = new Title(); + $title->setShort($shortData); + $title->setTitle($titleData); + $title->setCreated(new \DateTime('now')); + $title->setUpdated(new \DateTime('now')); + $manager->persist($title); + $titles[$shortData] = $title; + unset($title); + } + + //Group tree + $groupTree = array( + 'ROLE_USER', + 'ROLE_ADMIN', + 'ROLE_SUPER' + ); + + //Create groups + $groups = array(); + foreach($groupTree as $groupData) { + $group = new Group($groupData); + $group->setCreated(new \DateTime('now')); + $group->setUpdated(new \DateTime('now')); + $manager->persist($group); + $groups[$groupData] = $group; + unset($group); + } + + //Flush to get the ids + $manager->flush(); + + //User tree + $userTree = array( + array( + 'short' => 'M.', + 'group' => 'ROLE_SUPER', + 'mail' => 'airlibre@rapsys.eu', + 'pseudonym' => 'Rapsys', + 'forename' => 'Raphaël', + 'surname' => 'Gertz', + 'password' => 'test' + ), + array( + 'short' => 'M.', + 'group' => 'ROLE_ADMIN', + 'mail' => 'rannou402@orange.fr', + 'pseudonym' => 'Mitch', + 'forename' => 'Michel', + 'surname' => 'Rannou', + 'password' => 'test' + ), + array( + 'short' => 'Mlle', + 'group' => 'ROLE_ADMIN', + 'mail' => 'roxmaps@gmail.com', + 'pseudonym' => 'Roxana', + 'forename' => 'Roxana', + 'surname' => 'Prado', + 'password' => 'test' + ), + array( + 'short' => 'M.', + 'group' => 'ROLE_ADMIN', + 'mail' => 'majid.ghedjatti@gmail.com', + 'pseudonym' => 'El Guerrillero', + 'forename' => 'Majid', + 'surname' => 'Ghedjatti', + 'password' => 'test' + ), + array( + 'short' => 'M.', + 'group' => 'ROLE_ADMIN', + 'mail' => 'denis.courvoisier@wanadoo.fr', + 'pseudonym' => 'Sined', + 'forename' => 'Denis', + 'surname' => 'Courvoisier', + 'password' => 'test' + ), + array( + 'short' => 'M.', + 'group' => 'ROLE_ADMIN', + 'mail' => 'kastango13@gmail.com', + 'pseudonym' => 'Kastrat', + 'forename' => 'Kastrat', + 'surname' => 'Hasaj', + 'password' => 'test' + ), + ); + + //Create users + $users = array(); + foreach($userTree as $userData) { + $user = new User(); + $user->setMail($userData['mail']); + $user->setPseudonym($userData['pseudonym']); + $user->setForename($userData['forename']); + $user->setSurname($userData['surname']); + $user->setPassword($encoder->encodePassword($user, $userData['password'])); + $user->setActive(true); + $user->setTitle($titles[$userData['short']]); + $user->addGroup($groups[$userData['group']]); + $user->setCreated(new \DateTime('now')); + $user->setUpdated(new \DateTime('now')); + $manager->persist($user); + $users[] = $user; + unset($user); + } + + //Flush to get the ids + $manager->flush(); + + //Location tree + $locationTree = [ + [ + 'title' => 'Esplanade du Trocadéro', + 'address' => '1 Avenue Hussein 1er de Jordanie', + #75016 pour meteo-france, accuweather supporte 75116 + 'zipcode' => '75116', + 'city' => 'Paris', + 'latitude' => 48.8619, + 'longitude' => 2.2888 + ], + [ + 'title' => 'Opéra Garnier', + 'address' => 'Place de l\'Opéra', + 'zipcode' => '75009', + 'city' => 'Paris', + 'latitude' => 48.871365, + 'longitude' => 2.332026 + ], + [ + 'title' => 'Marché Saint Honoré', + 'address' => '1 Passage des Jacobins', + 'zipcode' => '75001', + 'city' => 'Paris', + 'latitude' => 48.8668, + 'longitude' => 2.331659 + ], + [ + 'title' => 'Jardin Tino-Rossi', + 'address' => '2 Quai Saint-Bernard', + 'zipcode' => '75005', + 'city' => 'Paris', + 'latitude' => 48.847736, + 'longitude' => 2.360953 + ], + [ + 'title' => 'Palais de Tokyo', + 'address' => '13 Avenue du Président Wilson', + 'zipcode' => '75116', + 'city' => 'Paris', + 'latitude' => 48.864567, + 'longitude' => 2.296892 + ] + ]; + + //Create locations + $locations = array(); + foreach($locationTree as $locationData) { + $location = new Location(); + $location->setTitle($locationData['title']); + $location->setAddress($locationData['address']); + $location->setZipcode($locationData['zipcode']); + $location->setCity($locationData['city']); + $location->setLatitude($locationData['latitude']); + $location->setLongitude($locationData['longitude']); + $location->setCreated(new \DateTime('now')); + $location->setUpdated(new \DateTime('now')); + $manager->persist($location); + $locations[$locationData['title']] = $location; + unset($location); + } + + //Flush to get the ids + $manager->flush(); + + //Slot tree + $slotTree = [ + [ + 'begin' => '14:00:00 UTC', + 'end' => '19:00:00 UTC' + ], + [ + 'begin' => '19:00:00 UTC', + 'end' => '23:00:00 UTC' + ], + [ + 'begin' => '23:00:00 UTC', + 'end' => '02:00:00 UTC' + ] + ]; + + //Create slots + $slots = array(); + foreach($slotTree as $slotData) { + $slot = new Slot(); + $slot->setBegin(new \DateTime($slotData['begin'])); + $slot->setEnd(new \DateTime($slotData['end'])); + $slot->setCreated(new \DateTime('now')); + $slot->setUpdated(new \DateTime('now')); + $manager->persist($slot); + $slots[$slot->getId()] = $slot; + unset($slot); + } + + //Flush to get the ids + $manager->flush(); + } +} diff --git a/DependencyInjection/RapsysAirExtension.php b/DependencyInjection/RapsysAirExtension.php new file mode 100644 index 0000000..5a2bdff --- /dev/null +++ b/DependencyInjection/RapsysAirExtension.php @@ -0,0 +1,46 @@ +<?php + +namespace Rapsys\AirBundle\DependencyInjection; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\HttpKernel\DependencyInjection\Extension; +use Symfony\Component\DependencyInjection\Loader; + +/** + * This is the class that loads and manages your bundle configuration. + * + * @link http://symfony.com/doc/current/cookbook/bundles/extension.html + */ +class RapsysAirExtension extends Extension { + /** + * {@inheritdoc} + */ + public function load(array $configs, ContainerBuilder $container) { + $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + $loader->load('services.yml'); + + $configuration = new Configuration(); + $config = $this->processConfiguration($configuration, $configs); + + //Set default config in parameter + if (!$container->hasParameter($alias = $this->getAlias())) { + $container->setParameter($alias, $config[$alias]); + } else { + $config[$alias] = $container->getParameter($alias); + } + + //Transform the one level tree in flat parameters + foreach($config[$alias] as $k => $v) { + //Set is as parameters + $container->setParameter($alias.'.'.$k, $v); + } + } + + /** + * {@inheritdoc} + */ + public function getAlias() { + return 'rapsys_air'; + } +} diff --git a/Entity/Application.php b/Entity/Application.php new file mode 100644 index 0000000..c157132 --- /dev/null +++ b/Entity/Application.php @@ -0,0 +1,187 @@ +<?php + +namespace Rapsys\AirBundle\Entity; + +/** + * Application + */ +class Application +{ + /** + * @var integer + */ + private $id; + + /** + * @var \DateTime + */ + private $created; + + /** + * @var \DateTime + */ + private $updated; + + /** + * @var \Doctrine\Common\Collections\Collection + */ + private $votes; + + /** + * @var \Rapsys\AirBundle\Entity\Session + */ + private $session; + + /** + * @var \Rapsys\AirBundle\Entity\User + */ + private $user; + + /** + * Constructor + */ + public function __construct() + { + $this->votes = new \Doctrine\Common\Collections\ArrayCollection(); + } + + /** + * Get id + * + * @return integer + */ + public function getId() + { + return $this->id; + } + + /** + * Set created + * + * @param \DateTime $created + * + * @return Application + */ + public function setCreated($created) + { + $this->created = $created; + + return $this; + } + + /** + * Get created + * + * @return \DateTime + */ + public function getCreated() + { + return $this->created; + } + + /** + * Set updated + * + * @param \DateTime $updated + * + * @return Application + */ + public function setUpdated($updated) + { + $this->updated = $updated; + + return $this; + } + + /** + * Get updated + * + * @return \DateTime + */ + public function getUpdated() + { + return $this->updated; + } + + /** + * Add vote + * + * @param \Rapsys\AirBundle\Entity\Vote $vote + * + * @return Application + */ + public function addVote(\Rapsys\AirBundle\Entity\Vote $vote) + { + $this->votes[] = $vote; + + return $this; + } + + /** + * Remove vote + * + * @param \Rapsys\AirBundle\Entity\Vote $vote + */ + public function removeVote(\Rapsys\AirBundle\Entity\Vote $vote) + { + $this->votes->removeElement($vote); + } + + /** + * Get votes + * + * @return \Doctrine\Common\Collections\Collection + */ + public function getVotes() + { + return $this->votes; + } + + /** + * Set session + * + * @param \Rapsys\AirBundle\Entity\Session $session + * + * @return Application + */ + public function setSession(\Rapsys\AirBundle\Entity\Session $session = null) + { + $this->session = $session; + + return $this; + } + + /** + * Get session + * + * @return \Rapsys\AirBundle\Entity\Session + */ + public function getSession() + { + return $this->session; + } + + /** + * Set user + * + * @param \Rapsys\AirBundle\Entity\User $user + * + * @return Application + */ + public function setUser(\Rapsys\AirBundle\Entity\User $user = null) + { + $this->user = $user; + + return $this; + } + + /** + * Get user + * + * @return \Rapsys\AirBundle\Entity\User + */ + public function getUser() + { + return $this->user; + } +} diff --git a/Entity/Group.php b/Entity/Group.php new file mode 100644 index 0000000..3ccf6ee --- /dev/null +++ b/Entity/Group.php @@ -0,0 +1,6 @@ +<?php + +// src/Rapsys/AirBundle/Entity/Group.php +namespace Rapsys\AirBundle\Entity; + +class Group extends \Rapsys\UserBundle\Entity\Group {} diff --git a/Entity/Location.php b/Entity/Location.php new file mode 100644 index 0000000..4e9ceaf --- /dev/null +++ b/Entity/Location.php @@ -0,0 +1,304 @@ +<?php + +namespace Rapsys\AirBundle\Entity; + +/** + * Location + */ +class Location +{ + /** + * @var integer + */ + private $id; + + /** + * @var string + */ + private $title; + + /** + * @var string + */ + private $address; + + /** + * @var string + */ + private $zipcode; + + /** + * @var string + */ + private $city; + + /** + * @var string + */ + private $latitude; + + /** + * @var string + */ + private $longitude; + + /** + * @var \DateTime + */ + private $created; + + /** + * @var \DateTime + */ + private $updated; + + /** + * @var \Doctrine\Common\Collections\Collection + */ + private $sessions; + + /** + * Constructor + */ + public function __construct() + { + $this->sessions = new \Doctrine\Common\Collections\ArrayCollection(); + } + + /** + * Get id + * + * @return integer + */ + public function getId() + { + return $this->id; + } + + /** + * Set title + * + * @param string $title + * + * @return Location + */ + public function setTitle($title) + { + $this->title = $title; + + return $this; + } + + /** + * Get title + * + * @return string + */ + public function getTitle() + { + return $this->title; + } + + /** + * Set address + * + * @param string $address + * + * @return Location + */ + public function setAddress($address) + { + $this->address = $address; + + return $this; + } + + /** + * Get address + * + * @return string + */ + public function getAddress() + { + return $this->address; + } + + /** + * Set zipcode + * + * @param string $zipcode + * + * @return Location + */ + public function setZipcode($zipcode) + { + $this->zipcode = $zipcode; + + return $this; + } + + /** + * Get zipcode + * + * @return string + */ + public function getZipcode() + { + return $this->zipcode; + } + + /** + * Set city + * + * @param string $city + * + * @return Location + */ + public function setCity($city) + { + $this->city = $city; + + return $this; + } + + /** + * Get city + * + * @return string + */ + public function getCity() + { + return $this->city; + } + + /** + * Set latitude + * + * @param string $latitude + * + * @return Location + */ + public function setLatitude($latitude) + { + $this->latitude = $latitude; + + return $this; + } + + /** + * Get latitude + * + * @return string + */ + public function getLatitude() + { + return $this->latitude; + } + + /** + * Set longitude + * + * @param string $longitude + * + * @return Location + */ + public function setLongitude($longitude) + { + $this->longitude = $longitude; + + return $this; + } + + /** + * Get longitude + * + * @return string + */ + public function getLongitude() + { + return $this->longitude; + } + + /** + * Set created + * + * @param \DateTime $created + * + * @return Location + */ + public function setCreated($created) + { + $this->created = $created; + + return $this; + } + + /** + * Get created + * + * @return \DateTime + */ + public function getCreated() + { + return $this->created; + } + + /** + * Set updated + * + * @param \DateTime $updated + * + * @return Location + */ + public function setUpdated($updated) + { + $this->updated = $updated; + + return $this; + } + + /** + * Get updated + * + * @return \DateTime + */ + public function getUpdated() + { + return $this->updated; + } + + /** + * Add session + * + * @param \Rapsys\AirBundle\Entity\Session $session + * + * @return Location + */ + public function addSession(\Rapsys\AirBundle\Entity\Session $session) + { + $this->sessions[] = $session; + + return $this; + } + + /** + * Remove session + * + * @param \Rapsys\AirBundle\Entity\Session $session + */ + public function removeSession(\Rapsys\AirBundle\Entity\Session $session) + { + $this->sessions->removeElement($session); + } + + /** + * Get sessions + * + * @return \Doctrine\Common\Collections\Collection + */ + public function getSessions() + { + return $this->sessions; + } +} + diff --git a/Entity/Session.php b/Entity/Session.php new file mode 100644 index 0000000..72d1f33 --- /dev/null +++ b/Entity/Session.php @@ -0,0 +1,281 @@ +<?php + +namespace Rapsys\AirBundle\Entity; + +/** + * Session + */ +class Session { + /** + * @var integer + */ + private $id; + + /** + * @var \DateTime + */ + private $date; + + /** + * @var \DateTime + */ + private $begin; + + /** + * @var \DateTime + */ + private $end; + + /** + * @var \DateTime + */ + private $created; + + /** + * @var \DateTime + */ + private $updated; + + /** + * @var \Doctrine\Common\Collections\Collection + */ + private $applications; + + /** + * @var \Rapsys\AirBundle\Entity\Location + */ + private $location; + + /** + * @var \Rapsys\AirBundle\Entity\Application + */ + private $application; + + /** + * Constructor + */ + public function __construct() { + $this->applications = new \Doctrine\Common\Collections\ArrayCollection(); + } + + /** + * Get id + * + * @return integer + */ + public function getId() { + return $this->id; + } + + /** + * Set date + * + * @param \DateTime $date + * + * @return Session + */ + public function setDate($date) { + $this->date = $date; + + return $this; + } + + /** + * Get date + * + * @return \DateTime + */ + public function getDate() { + return $this->date; + } + + /** + * Set begin + * + * @param \DateTime $begin + * + * @return Session + */ + public function setBegin($begin) { + $this->begin = $begin; + + return $this; + } + + /** + * Get begin + * + * @return \DateTime + */ + public function getBegin() { + return $this->begin; + } + + /** + * Set end + * + * @param \DateTime $end + * + * @return Session + */ + public function setEnd($end) { + $this->end = $end; + + return $this; + } + + /** + * Get end + * + * @return \DateTime + */ + public function getEnd() { + return $this->end; + } + + /** + * Set created + * + * @param \DateTime $created + * + * @return Session + */ + public function setCreated($created) { + $this->created = $created; + + return $this; + } + + /** + * Get created + * + * @return \DateTime + */ + public function getCreated() { + return $this->created; + } + + /** + * Set updated + * + * @param \DateTime $updated + * + * @return Session + */ + public function setUpdated($updated) { + $this->updated = $updated; + + return $this; + } + + /** + * Get updated + * + * @return \DateTime + */ + public function getUpdated() { + return $this->updated; + } + + /** + * Add application + * + * @param \Rapsys\AirBundle\Entity\Application $application + * + * @return Session + */ + public function addApplication(\Rapsys\AirBundle\Entity\Application $application) { + $this->applications[] = $application; + + return $this; + } + + /** + * Remove application + * + * @param \Rapsys\AirBundle\Entity\Application $application + */ + public function removeApplication(\Rapsys\AirBundle\Entity\Application $application) { + $this->applications->removeElement($application); + } + + /** + * Get applications + * + * @return \Doctrine\Common\Collections\Collection + */ + public function getApplications() { + return $this->applications; + } + + /** + * Set location + * + * @param \Rapsys\AirBundle\Entity\Location $location + * + * @return Session + */ + public function setLocation(\Rapsys\AirBundle\Entity\Location $location = null) { + $this->location = $location; + + return $this; + } + + /** + * Get location + * + * @return \Rapsys\AirBundle\Entity\Location + */ + public function getLocation() { + return $this->location; + } + /** + * @var \Rapsys\AirBundle\Entity\Slot + */ + private $slot; + + + /** + * Set slot + * + * @param \Rapsys\AirBundle\Entity\Slot $slot + * + * @return Session + */ + public function setSlot(\Rapsys\AirBundle\Entity\Slot $slot = null) { + $this->slot = $slot; + + return $this; + } + + /** + * Get slot + * + * @return \Rapsys\AirBundle\Entity\Slot + */ + public function getSlot() { + return $this->slot; + } + + /** + * Set application + * + * @param \Rapsys\AirBundle\Entity\Application $application + * + * @return Session + */ + public function setApplication(\Rapsys\AirBundle\Entity\Application $application = null) { + $this->application = $application; + + return $this; + } + + /** + * Get application + * + * @return \Rapsys\AirBundle\Entity\Application + */ + public function getApplication() { + return $this->application; + } +} diff --git a/Entity/Slot.php b/Entity/Slot.php new file mode 100644 index 0000000..03bfd3f --- /dev/null +++ b/Entity/Slot.php @@ -0,0 +1,191 @@ +<?php + +namespace Rapsys\AirBundle\Entity; + +/** + * Slot + */ +class Slot +{ + /** + * @var integer + */ + private $id; + + /** + * @var \DateTime + */ + private $begin; + + /** + * @var \DateTime + */ + private $end; + + /** + * @var \DateTime + */ + private $created; + + /** + * @var \DateTime + */ + private $updated; + + /** + * @var \Doctrine\Common\Collections\Collection + */ + private $sessions; + + /** + * Constructor + */ + public function __construct() + { + $this->sessions = new \Doctrine\Common\Collections\ArrayCollection(); + } + + /** + * Get id + * + * @return integer + */ + public function getId() + { + return $this->id; + } + + /** + * Set begin + * + * @param \DateTime $begin + * + * @return Slot + */ + public function setBegin($begin) + { + $this->begin = $begin; + + return $this; + } + + /** + * Get begin + * + * @return \DateTime + */ + public function getBegin() + { + return $this->begin; + } + + /** + * Set end + * + * @param \DateTime $end + * + * @return Slot + */ + public function setEnd($end) + { + $this->end = $end; + + return $this; + } + + /** + * Get end + * + * @return \DateTime + */ + public function getEnd() + { + return $this->end; + } + + /** + * Set created + * + * @param \DateTime $created + * + * @return Slot + */ + public function setCreated($created) + { + $this->created = $created; + + return $this; + } + + /** + * Get created + * + * @return \DateTime + */ + public function getCreated() + { + return $this->created; + } + + /** + * Set updated + * + * @param \DateTime $updated + * + * @return Slot + */ + public function setUpdated($updated) + { + $this->updated = $updated; + + return $this; + } + + /** + * Get updated + * + * @return \DateTime + */ + public function getUpdated() + { + return $this->updated; + } + + /** + * Add session + * + * @param \Rapsys\AirBundle\Entity\Session $session + * + * @return Slot + */ + public function addSession(\Rapsys\AirBundle\Entity\Session $session) + { + $this->sessions[] = $session; + + return $this; + } + + /** + * Remove session + * + * @param \Rapsys\AirBundle\Entity\Session $session + */ + public function removeSession(\Rapsys\AirBundle\Entity\Session $session) + { + $this->sessions->removeElement($session); + } + + /** + * Get sessions + * + * @return \Doctrine\Common\Collections\Collection + */ + public function getSessions() + { + return $this->sessions; + } + + public function getTitle() { + return $this->begin->format('H:i').'-'.$this->end->format('H:i'); + } +} diff --git a/Entity/Title.php b/Entity/Title.php new file mode 100644 index 0000000..54a6a60 --- /dev/null +++ b/Entity/Title.php @@ -0,0 +1,7 @@ +<?php + +// src/Rapsys/AirBundle/Entity/Title.php +namespace Rapsys\AirBundle\Entity; + +class Title extends \Rapsys\UserBundle\Entity\Title { +} diff --git a/Entity/User.php b/Entity/User.php new file mode 100644 index 0000000..473fd07 --- /dev/null +++ b/Entity/User.php @@ -0,0 +1,85 @@ +<?php + +// src/Rapsys/AirBundle/Entity/User.php +namespace Rapsys\AirBundle\Entity; + +class User extends \Rapsys\UserBundle\Entity\User { + /** + * @var \Doctrine\Common\Collections\Collection + */ + private $votes; + + /** + * @var \Doctrine\Common\Collections\Collection + */ + private $applications; + + /** + * Constructor + */ + public function __construct() { + parent::__construct(); + } + + /** + * Add vote + * + * @param \Rapsys\AirBundle\Entity\Vote $vote + * + * @return User + */ + public function addVote(\Rapsys\AirBundle\Entity\Vote $vote) { + $this->votes[] = $vote; + + return $this; + } + + /** + * Remove vote + * + * @param \Rapsys\AirBundle\Entity\Vote $vote + */ + public function removeVote(\Rapsys\AirBundle\Entity\Vote $vote) { + $this->votes->removeElement($vote); + } + + /** + * Get votes + * + * @return \Doctrine\Common\Collections\Collection + */ + public function getVotes() { + return $this->votes; + } + + /** + * Add application + * + * @param \Rapsys\AirBundle\Entity\Application $application + * + * @return User + */ + public function addApplication(\Rapsys\AirBundle\Entity\Application $application) { + $this->applications[] = $application; + + return $this; + } + + /** + * Remove application + * + * @param \Rapsys\AirBundle\Entity\Application $application + */ + public function removeApplication(\Rapsys\AirBundle\Entity\Application $application) { + $this->applications->removeElement($application); + } + + /** + * Get applications + * + * @return \Doctrine\Common\Collections\Collection + */ + public function getApplications() { + return $this->applications; + } +} diff --git a/Entity/Vote.php b/Entity/Vote.php new file mode 100644 index 0000000..7b2fb53 --- /dev/null +++ b/Entity/Vote.php @@ -0,0 +1,141 @@ +<?php + +namespace Rapsys\AirBundle\Entity; + +/** + * Vote + */ +class Vote +{ + /** + * @var integer + */ + private $id; + + /** + * @var \DateTime + */ + private $created; + + /** + * @var \DateTime + */ + private $updated; + + /** + * @var \Rapsys\AirBundle\Entity\Application + */ + private $application; + + /** + * @var \Rapsys\AirBundle\Entity\User + */ + private $user; + + + /** + * Get id + * + * @return integer + */ + public function getId() + { + return $this->id; + } + + /** + * Set created + * + * @param \DateTime $created + * + * @return Vote + */ + public function setCreated($created) + { + $this->created = $created; + + return $this; + } + + /** + * Get created + * + * @return \DateTime + */ + public function getCreated() + { + return $this->created; + } + + /** + * Set updated + * + * @param \DateTime $updated + * + * @return Vote + */ + public function setUpdated($updated) + { + $this->updated = $updated; + + return $this; + } + + /** + * Get updated + * + * @return \DateTime + */ + public function getUpdated() + { + return $this->updated; + } + + /** + * Set application + * + * @param \Rapsys\AirBundle\Entity\Application $application + * + * @return Vote + */ + public function setApplication(\Rapsys\AirBundle\Entity\Application $application = null) + { + $this->application = $application; + + return $this; + } + + /** + * Get application + * + * @return \Rapsys\AirBundle\Entity\Application + */ + public function getApplication() + { + return $this->application; + } + + /** + * Set user + * + * @param \Rapsys\AirBundle\Entity\User $user + * + * @return Vote + */ + public function setUser(\Rapsys\AirBundle\Entity\User $user = null) + { + $this->user = $user; + + return $this; + } + + /** + * Get user + * + * @return \Rapsys\AirBundle\Entity\User + */ + public function getUser() + { + return $this->user; + } +} diff --git a/Form/ApplicationType.php b/Form/ApplicationType.php new file mode 100644 index 0000000..8439d29 --- /dev/null +++ b/Form/ApplicationType.php @@ -0,0 +1,39 @@ +<?php + +namespace Rapsys\AirBundle\Form; + +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\OptionsResolver\OptionsResolver; +use Symfony\Bridge\Doctrine\Form\Type\EntityType; +use Symfony\Component\Form\Extension\Core\Type\DateType; +use Symfony\Component\Form\Extension\Core\Type\SubmitType; +use Symfony\Component\Validator\Constraints\Date; +use Symfony\Component\Validator\Constraints\NotBlank; + +class ApplicationType extends AbstractType { + /** + * {@inheritdoc} + */ + public function buildForm(FormBuilderInterface $builder, array $options) { + return $builder + ->add('location', EntityType::class, array('class' => 'RapsysAirBundle:Location', 'choice_label' => 'title', 'attr' => array('placeholder' => 'Your location'), 'constraints' => array(new NotBlank(array('message' => 'Please provide your location'))))) + ->add('date', DateType::class, array('attr' => [ 'placeholder' => 'Your date', 'class' => 'date' ], 'html5' => true, 'input' => 'datetime', 'data' => new \DateTime('+7 day'), 'constraints' => array(new NotBlank(array('message' => 'Please provide your date')), new Date(array('message' => 'Your date doesn\'t seems to be valid'))))) + ->add('slot', EntityType::class, array('class' => 'RapsysAirBundle:Slot', 'choice_label' => 'title', 'attr' => array('placeholder' => 'Your slot'), 'constraints' => array(new NotBlank(array('message' => 'Please provide your slot'))))) + ->add('submit', SubmitType::class, array('label' => 'Send', 'attr' => array('class' => 'submit'))); + } + + /** + * {@inheritdoc} + */ + public function configureOptions(OptionsResolver $resolver) { + $resolver->setDefaults(['error_bubbling' => true]); + } + + /** + * {@inheritdoc} + */ + public function getName() { + return 'rapsys_air_application'; + } +} diff --git a/Form/ContactType.php b/Form/ContactType.php new file mode 100644 index 0000000..e9a5ba1 --- /dev/null +++ b/Form/ContactType.php @@ -0,0 +1,40 @@ +<?php + +namespace Rapsys\AirBundle\Form; + +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\OptionsResolver\OptionsResolver; +use Symfony\Component\Form\Extension\Core\Type\TextType; +use Symfony\Component\Form\Extension\Core\Type\TextareaType; +use Symfony\Component\Form\Extension\Core\Type\EmailType; +use Symfony\Component\Form\Extension\Core\Type\SubmitType; +use Symfony\Component\Validator\Constraints\Email; +use Symfony\Component\Validator\Constraints\NotBlank; + +class ContactType extends AbstractType { + /** + * {@inheritdoc} + */ + public function buildForm(FormBuilderInterface $builder, array $options) { + return $builder->add('name', TextType::class, array('attr' => array('placeholder' => 'Your name'), 'constraints' => array(new NotBlank(array('message' => 'Please provide your name'))))) + ->add('subject', TextType::class, array('attr' => array('placeholder' => 'Subject'), 'constraints' => array(new NotBlank(array('message' => 'Please provide your subject'))))) + ->add('mail', EmailType::class, array('attr' => array('placeholder' => 'Your mail address'), 'constraints' => array(new NotBlank(array('message' => 'Please provide a valid mail')), new Email(array('message' => 'Your mail doesn\'t seems to be valid'))))) + ->add('message', TextareaType::class, array('attr' => array('placeholder' => 'Your message here', 'cols' => 50, 'rows' => 15), 'constraints' => array(new NotBlank(array('message' => 'Please provide your message'))))) + ->add('submit', SubmitType::class, array('label' => 'Send', 'attr' => array('class' => 'submit'))); + } + + /** + * {@inheritdoc} + */ + public function configureOptions(OptionsResolver $resolver) { + $resolver->setDefaults(['error_bubbling' => true]); + } + + /** + * {@inheritdoc} + */ + public function getName() { + return 'contact_form'; + } +} diff --git a/RapsysAirBundle.php b/RapsysAirBundle.php new file mode 100644 index 0000000..06f1b37 --- /dev/null +++ b/RapsysAirBundle.php @@ -0,0 +1,9 @@ +<?php + +namespace Rapsys\AirBundle; + +use Symfony\Component\HttpKernel\Bundle\Bundle; + +class RapsysAirBundle extends Bundle +{ +} diff --git a/Repository/ApplicationRepository.php b/Repository/ApplicationRepository.php new file mode 100644 index 0000000..3112d14 --- /dev/null +++ b/Repository/ApplicationRepository.php @@ -0,0 +1,26 @@ +<?php + +namespace Rapsys\AirBundle\Repository; + +/** + * ApplicationRepository + */ +class ApplicationRepository extends \Doctrine\ORM\EntityRepository { + /** + * Find session by session and user + * + * @param $session The session + * @param $user The user + */ + public function findOneBySessionUser($session, $user) { + //Fetch article + $ret = $this->getEntityManager() + ->createQuery('SELECT a FROM RapsysAirBundle:Application a WHERE (a.session = :session AND a.user = :user)') + ->setParameter('session', $session) + ->setParameter('user', $user) + ->getSingleResult(); + + //Send result + return $ret; + } +} diff --git a/Repository/SessionRepository.php b/Repository/SessionRepository.php new file mode 100644 index 0000000..e295bfd --- /dev/null +++ b/Repository/SessionRepository.php @@ -0,0 +1,45 @@ +<?php + +namespace Rapsys\AirBundle\Repository; + +/** + * SessionRepository + */ +class SessionRepository extends \Doctrine\ORM\EntityRepository { + /** + * Find session by location, slot and date + * + * @param $location The location + * @param $slot The slot + * @param $date The datetime + */ + public function findOneByLocationSlotDate($location, $slot, $date) { + //Fetch session + $ret = $this->getEntityManager() + ->createQuery('SELECT s FROM RapsysAirBundle:Session s WHERE (s.location = :location AND s.slot = :slot AND s.date = :date)') + ->setParameter('location', $location) + ->setParameter('slot', $slot) + ->setParameter('date', $date) + ->getSingleResult(); + + //Send result + return $ret; + } + + /** + * Find sessions by date period + * + * @param $period The date period + */ + public function findByDatePeriod($period) { + //Fetch sessions + $ret = $this->getEntityManager() + ->createQuery('SELECT s FROM RapsysAirBundle:Session s WHERE s.date BETWEEN :begin AND :end') + ->setParameter('begin', $period->getStartDate()) + ->setParameter('end', $period->getEndDate()) + ->getResult(); + + //Send result + return $ret; + } +} diff --git a/Resources/config/doctrine/Application.orm.yml b/Resources/config/doctrine/Application.orm.yml new file mode 100644 index 0000000..aaf461f --- /dev/null +++ b/Resources/config/doctrine/Application.orm.yml @@ -0,0 +1,27 @@ +Rapsys\AirBundle\Entity\Application: + type: entity + repositoryClass: Rapsys\AirBundle\Repository\ApplicationRepository + table: applications + id: + id: + type: integer + generator: + strategy: AUTO + options: + unsigned: true + fields: + created: + type: datetime + updated: + type: datetime + manyToOne: + session: + targetEntity: Rapsys\AirBundle\Entity\Session + inversedBy: applications + user: + targetEntity: Rapsys\AirBundle\Entity\User + inversedBy: applications + oneToMany: + votes: + targetEntity: Rapsys\AirBundle\Entity\Vote + mappedBy: application diff --git a/Resources/config/doctrine/Group.orm.yml b/Resources/config/doctrine/Group.orm.yml new file mode 100644 index 0000000..57f70a9 --- /dev/null +++ b/Resources/config/doctrine/Group.orm.yml @@ -0,0 +1,8 @@ +Rapsys\AirBundle\Entity\Group: + type: entity + #repositoryClass: Rapsys\AirBundle\Repository\GroupRepository + table: groups + manyToMany: + users: + targetEntity: Rapsys\AirBundle\Entity\User + mappedBy: groups diff --git a/Resources/config/doctrine/Location.orm.yml b/Resources/config/doctrine/Location.orm.yml new file mode 100644 index 0000000..86d86db --- /dev/null +++ b/Resources/config/doctrine/Location.orm.yml @@ -0,0 +1,69 @@ +Rapsys\AirBundle\Entity\Location: + type: entity + #repositoryClass: Rapsys\AirBundle\Repository\LocationRepository + table: locations + id: + id: + type: integer + generator: + strategy: AUTO + options: + unsigned: true + fields: + title: + type: string + length: 24 + address: + type: string + length: 32 + zipcode: + type: string + length: 5 + city: + type: string + length: 64 + latitude: + type: decimal + precision: 8 + scale: 6 + longitude: + type: decimal + precision: 9 + scale: 6 + created: + type: datetime + updated: + type: datetime + oneToMany: + sessions: + targetEntity: Rapsys\AirBundle\Entity\Session + mappedBy: location + +# manyToOne: +# title: +# targetEntity: Rapsys\UserBundle\Entity\Title +# inversedBy: users +# manyToMany: +# groups: +# targetEntity: Rapsys\UserBundle\Entity\Group +# inversedBy: users +# joinTable: +# name: groups_users +# +# manyToOne: +# site: +# targetEntity: Rapsys\BlogBundle\Entity\Site +# inversedBy: articles +# author: +# targetEntity: Rapsys\BlogBundle\Entity\Author +# inversedBy: articles +# manyToMany: +# keywords: +# targetEntity: Rapsys\BlogBundle\Entity\Keyword +# inversedBy: articles +# joinTable: +# name: articles_keywords +# oneToMany: +# article_translations: +# targetEntity: Rapsys\BlogBundle\Entity\ArticleTranslation +# mappedBy: article diff --git a/Resources/config/doctrine/Session.orm.yml b/Resources/config/doctrine/Session.orm.yml new file mode 100644 index 0000000..9c89adb --- /dev/null +++ b/Resources/config/doctrine/Session.orm.yml @@ -0,0 +1,41 @@ +Rapsys\AirBundle\Entity\Session: + type: entity + repositoryClass: Rapsys\AirBundle\Repository\SessionRepository + table: sessions + id: + id: + type: integer + generator: + strategy: AUTO + options: + unsigned: true + fields: + date: + type: date + begin: + type: time + nullable: true + end: + type: time + nullable: true + created: + type: datetime + updated: + type: datetime + oneToOne: + application: + targetEntity: Rapsys\AirBundle\Entity\Application + manyToOne: + location: + targetEntity: Rapsys\AirBundle\Entity\Location + inversedBy: sessions + slot: + targetEntity: Rapsys\AirBundle\Entity\Slot + inversedBy: sessions + oneToMany: + applications: + targetEntity: Rapsys\AirBundle\Entity\Application + mappedBy: session + uniqueConstraints: + date_location_slot: + columns: [ date, location_id, slot_id ] diff --git a/Resources/config/doctrine/Slot.orm.yml b/Resources/config/doctrine/Slot.orm.yml new file mode 100644 index 0000000..c4ff511 --- /dev/null +++ b/Resources/config/doctrine/Slot.orm.yml @@ -0,0 +1,24 @@ +Rapsys\AirBundle\Entity\Slot: + type: entity + #repositoryClass: Rapsys\AirBundle\Repository\SlotRepository + table: slots + id: + id: + type: integer + generator: + strategy: AUTO + options: + unsigned: true + fields: + begin: + type: time + end: + type: time + created: + type: datetime + updated: + type: datetime + oneToMany: + sessions: + targetEntity: Rapsys\AirBundle\Entity\Session + mappedBy: slot diff --git a/Resources/config/doctrine/Title.orm.yml b/Resources/config/doctrine/Title.orm.yml new file mode 100644 index 0000000..d68aa60 --- /dev/null +++ b/Resources/config/doctrine/Title.orm.yml @@ -0,0 +1,8 @@ +Rapsys\AirBundle\Entity\Title: + type: entity + #repositoryClass: Rapsys\AirBundle\Repository\TitleRepository + table: titles + oneToMany: + users: + targetEntity: User + mappedBy: title diff --git a/Resources/config/doctrine/User.orm.yml b/Resources/config/doctrine/User.orm.yml new file mode 100644 index 0000000..4df938e --- /dev/null +++ b/Resources/config/doctrine/User.orm.yml @@ -0,0 +1,27 @@ +Rapsys\AirBundle\Entity\User: + type: entity + #repositoryClass: Rapsys\AirBundle\Repository\UserRepository + table: users + oneToMany: + votes: + targetEntity: Rapsys\AirBundle\Entity\Vote + mappedBy: user + applications: + targetEntity: Rapsys\AirBundle\Entity\Application + mappedBy: user +# manyToMany: +# groups: +# targetEntity: Group +# inversedBy: users +# joinTable: +# name: groups_users + associationOverride: + groups: + joinTable: + name: groups_users + joinColumns: + id: + name: user_id + inverseJoinColumns: + id: + name: group_id diff --git a/Resources/config/doctrine/Vote.orm.yml b/Resources/config/doctrine/Vote.orm.yml new file mode 100644 index 0000000..ee8e2ea --- /dev/null +++ b/Resources/config/doctrine/Vote.orm.yml @@ -0,0 +1,23 @@ +Rapsys\AirBundle\Entity\Vote: + type: entity + #repositoryClass: Rapsys\AirBundle\Repository\VoteRepository + table: votes + id: + id: + type: integer + generator: + strategy: AUTO + options: + unsigned: true + fields: + created: + type: datetime + updated: + type: datetime + manyToOne: + application: + targetEntity: Rapsys\AirBundle\Entity\Application + inversedBy: votes + user: + targetEntity: Rapsys\AirBundle\Entity\User + inversedBy: votes diff --git a/Resources/config/routing.yml b/Resources/config/routing.yml new file mode 100644 index 0000000..dd63f57 --- /dev/null +++ b/Resources/config/routing.yml @@ -0,0 +1,17 @@ +rapsys_air_homepage: + path: / + defaults: { _controller: RapsysAirBundle:Default:index } + +rapsys_air_admin: + path: /admin + defaults: { _controller: RapsysAirBundle:Default:admin } + +rapsys_air_contact: + path: /contact + defaults: { _controller: RapsysAirBundle:Default:contact } + +rapsys_air_session: + path: /admin/session/{id} + defaults: { _controller: RapsysAirBundle:Default:session } + requirements: + id: '\d+' diff --git a/Resources/config/services.yml b/Resources/config/services.yml new file mode 100644 index 0000000..9f2f696 --- /dev/null +++ b/Resources/config/services.yml @@ -0,0 +1,15 @@ +services: + rapsys_air.twig.file_get_contents: + class: Rapsys\AirBundle\Twig\FileGetContentsExtension + tags: [ twig.extension ] + rapsys_air.twig.base64: + class: Rapsys\AirBundle\Twig\Base64Extension + tags: [ twig.extension ] + rapsys_air.twig.bb2html: + class: Rapsys\AirBundle\Twig\Bb2htmlExtension + tags: [ twig.extension ] + Rapsys\AirBundle\DataFixtures\AirFixtures: + tags: [ doctrine.fixture.orm ] +# rapsys_air.example: +# class: Rapsys\AirBundle\Example +# arguments: ["@service_id", "plain_value", "%parameter%"] diff --git a/Resources/public/css/reset.css b/Resources/public/css/reset.css new file mode 100644 index 0000000..c59ac50 --- /dev/null +++ b/Resources/public/css/reset.css @@ -0,0 +1,45 @@ +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, embed, +figure, figcaption, footer, header, hgroup, +menu, nav, output, ruby, section, summary, +time, mark, audio, video, input, textarea, button, select, option { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} + +article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { + display: block; +} + +body { + line-height: 1; +} + +ol, ul { + list-style: none; +} + +blockquote, q { + quotes: none; +} + +blockquote:before, blockquote:after, q:before, q:after { + content: ''; + content: none; +} + +table { + border-collapse: collapse; + border-spacing: 0; +} diff --git a/Resources/public/css/screen.css b/Resources/public/css/screen.css new file mode 100644 index 0000000..5477726 --- /dev/null +++ b/Resources/public/css/screen.css @@ -0,0 +1,473 @@ +/* Reset link */ +a { + text-decoration: none; + color: #066; +} + +a:hover { + text-decoration: underline solid #00c3f9; +} + +h1::first-letter, +h2::first-letter, +h3::first-letter, +h4::first-letter, +h5::first-letter, +h6::first-letter, +a::first-letter { + color: #00c3f9; +} + +/* Default styling */ +h1 { + font-size: 2rem; + margin: 1.34rem 0; +} + +h2 { + font-size: 1.5rem; + margin: 1.245rem 0; +} + +h3 { + font-size: 1.17rem; + margin: 1.17rem 0; +} + +h4 { + font-size: 1rem; + margin: 1.33rem 0; +} + +h5 { + font-size: .83rem; + margin: 1.386rem 0; +} + +h6 { + font-size: .67rem; + margin: 1.561rem 0; +} + +p { +} + +body { + display: flex; + flex-flow: column wrap; + color: #066; +} + +/* Header */ +#header { + border: .1rem solid #00c3f9; + border-top: 0; + border-radius: 0 0 .5rem .5rem; + margin: .5rem; + margin-top: 0; + padding: .5rem; + left: 0; + right: 0; + display: flex; + justify-content: space-between; + min-width: 180px; +} + +#header h1 { + order: 0; + padding: 0; + margin: 0; + vertical-align: middle; + white-space: nowrap; +} + +#header h1 a { + display: flex; +} + +/*#header h2 { + order: 1; + font-size: 1.5rem; + margin: 0; + white-space: nowrap; +} + +#header h2:before { + content: ">\00a0"; +}*/ + +#header nav { + order: 3; + margin-left: auto; + display: flex; + flex-direction: row; + flex-wrap: wrap; + align-items: center; + justify-content: flex-end; +} + +#header nav h2 { + display: none; +} + +#header nav a { + text-align: center; + border-radius: .25rem; + padding: .375rem .5rem .25rem .5rem; + margin: 0 0 .1rem .5rem; + border: .1rem solid #00c3f9; + font-weight: bold; + background-color: #cff; +} + +/* Message */ +div.error::before, +div.error::after { + content: "â "; + line-height: 100%; + margin: auto 0; +} + +div.error { + display: flex; + flex-direction: row; + justify-content: space-between; + border: .05rem solid #c33333; + background-color: #f9c3c3; + color: #c33333; + font-size: .9rem; + padding: .2rem; + border-radius: .2rem; + text-align: center; +} + +div.flash { + margin: 0 .5rem .5rem; +} + +/*ul#error::before, +ul#error::after, +ul.error::before, +ul.error::after, +ul#notice::before, +ul#notice::after { + content: "â "; + padding: .1rem .5rem 0 .5rem; + position: absolute; +} + +ul#error::before, +ul#error::after { + padding-top: .2rem; +} + +ul#notice::before, +ul#notice::after { + content: "â¹"; + padding-top: .3rem; +} + +ul#notice::after, +ul#error::after { + margin-left: 37.8rem; +} + +ul.error::after { + margin-left: 34rem; +} + +ul#notice, +ul#error, +ul.error { + display: flex; + flex-direction: column; + justify-content: center; + box-sizing: border-box; + text-align: center; + border: .05rem solid #c33333; + background-color: #f9c3c3; + color: #c33333; + font-size: .9rem; + padding: .2rem; + border-radius: .2rem; + width: 40rem; + margin: 0 auto .5rem auto; +} + +ul.error { + width: 36rem; + margin: .2rem 0 0 0; +} + +ul#notice { + border: .05rem solid #3333c3; + background-color: #c3c3f9; + color: #3333c3; +} + +ul.error { + margin-top: .2rem; +}*/ + +/* Content */ +#form, +#content, +#dashboard { + border: .1rem solid #00c3f9; + border-radius: .5rem; + margin: .5rem; + margin-top: 0; + overflow: hidden; + padding: .5rem; +} + +section h2 { + background-color: #cff; + border-bottom: .1rem solid #00c3f9; + margin: -.5rem -.5rem .5rem -.5rem; + padding: .5rem; + padding-bottom: .4rem; +} + +/* Form */ +form { + display: flex; + flex-direction: column; + border: .05rem solid #00c3f9; + border-radius: .2rem; + padding: .5rem; +} + +form section { + margin-bottom: 1rem; +} + +form section:only-child, +form section:last-child, +form section:last-of-type { + margin-bottom: .5rem; +} + +form section section, +form section section:only-child, +form section section:last-child, +form section section:last-of-type { + width: 50%; + margin-bottom: 0; +} + +form div { + display: flex; + flex-direction: row; + justify-content: space-around; + margin-bottom: .5rem; +} + +form div:only-child, +form div:last-child, +form div:last-of-type { + margin-bottom: 0; +} + +form section div.error { + margin: 0 1rem; +} + +form section section div.error { + margin: .25rem 0 0 0; +} + +label { + min-width: 5rem; + font-size: .9rem; + padding: .2rem 0; + text-align: right; + white-space: nowrap; +} + +button, +input, +select, +textarea { + box-sizing: border-box; + width: 100%; + padding: .1rem; + border: .05rem solid #00c3f9; + border-radius: .2rem; + font-size: .8rem; + color: #066; +} + +button.submit { + width: 25%; + min-width: 8rem; + margin: 0 auto; + padding: .2rem .1rem; +} + +/* Vertical form */ +.form_col { + margin-left: .5rem; + width: 10rem; +} + +.form_col div { + flex-direction: column; +} + +.form_col div.error { + flex-direction: row; +} + +.form_col label { + text-align: center; +} + +.form_col section section, +.form_col section section:only-child, +.form_col section section:last-child, +.form_col section section:last-of-type { + width: auto; +} + +.form_col div.date { + flex-direction: row; + justify-content: space-between; +} + +/* Dashboard */ +#dashboard .panel { + display: flex; + flex-direction: row; + flex-wrap: wrap; + place-content: space-between; +} + +#dashboard .grid { + display: table; + border: .05rem solid #00c3f9; + flex-grow: 1; + border-radius: .2rem; /* marche pas sur chrome */ + table-layout: fixed; + width: calc(100% - 12rem); + border-collapse: collapse; +} + +#dashboard .cell { + display: table-cell; + text-align: left; + border: .05rem solid #00c3f9; + font-size: initial; + height: 8rem; +} + +#dashboard dl.cell { + height: 3rem; +} + +#dashboard .cell h3 { + font-size: 1rem; + padding: .25rem; + margin: 0; +} + +#dashboard .cell dd { + text-align: center; +} + +#dashboard .seventh { + width: calc(100% / 7); +} + +#dashboard .disabled { + color: #acc; + background-color: #bee; +} + +#dashboard .current { + background-color: #cff; +} + +#dashboard .next { + background-color: #eff; +} + +#dashboard .session { + border-radius: .2rem; + border: .1rem solid #00c3f9; + font-size: .8rem; + padding: .2rem; + margin: 0 .1rem .1rem .1rem; + overflow-x: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} + +#dashboard .pending { + background-color: #ccc; +} + +#dashboard .granted { + background-color: #cff; + /*background-color: #33b679; + border-color: #33b679;*/ +} + +#dashboard .disputed { + background-color: #fcc; +} + +#dashboard .orphaned { + background-color: #fc9; +} + +/* Footer */ +#footer { + border: .1rem solid #00c3f9; + border-radius: .5rem; + margin: .5rem; + margin-top: 0; + padding: .5rem; + text-align: center; + font-size: .8rem; + display: flex; + justify-content: space-between; + background-color: #cff; +} + +#footer details { + font-weight: bold; +} + +#footer summary::after { + display: none; +} + +#footer summary::-webkit-details-marker { + display: none; +} + +/* viewport responsive hack */ +@media ( max-width: 650px ) { + #header { + flex-wrap: wrap; + } + + #dashboard .panel { + place-content: center; + flex-direction: column; + } + + #dashboard .grid { + width: 100%; + } + + #dashboard div.grid { + display: grid; + } + + .form_col { + margin: .5rem auto 0 auto; + } +} + diff --git a/Resources/public/ico/favicon.ico b/Resources/public/ico/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..fb6658823f2f2cf84fdbd5b3594550c51a3f8c41 GIT binary patch literal 90022 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 Soz%Dmg1#xu1kx&x^8SCWOGiuq literal 0 HcmV?d00001 diff --git a/Resources/public/png/apple.png b/Resources/public/png/apple.png new file mode 100644 index 0000000000000000000000000000000000000000..da559cf74091ba0162d8a8faafdf3ecb383837ca GIT binary patch literal 14257 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 Tot5K~00000NkvXXu0mjfDUB4Z literal 0 HcmV?d00001 diff --git a/Resources/public/png/favicon.png b/Resources/public/png/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..85f7b97a7b5e2c899a7bf33aab219cb892450930 GIT binary patch literal 15277 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 literal 0 HcmV?d00001 diff --git a/Resources/public/png/logo.png b/Resources/public/png/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..b57be8cffcaf2947823b272bc84927a963fb655c GIT binary patch literal 4297 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 literal 0 HcmV?d00001 diff --git a/Resources/public/svg/favicon.svg b/Resources/public/svg/favicon.svg new file mode 100644 index 0000000..1e196c6 --- /dev/null +++ b/Resources/public/svg/favicon.svg @@ -0,0 +1,95 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="210mm" + height="297mm" + viewBox="0 0 210 297" + version="1.1" + id="svg4570" + inkscape:version="0.92.3 (2405546, 2018-03-11)" + sodipodi:docname="openair.logo.svg"> + <title + id="title5131">Open Air Logo</title> + <defs + id="defs4564"> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient5174" + id="radialGradient5140" + cx="3.5708413" + cy="290.94611" + fx="3.5708413" + fy="290.94611" + r="3.5708413" + gradientTransform="matrix(0.96030384,0.85677319,-2.1146358,1.886651,616.04931,-259.20651)" + gradientUnits="userSpaceOnUse" /> + <linearGradient + inkscape:collect="always" + id="linearGradient5174"> + <stop + id="stop5166" + offset="0" + style="stop-color:#00c3f9;stop-opacity:0" /> + <stop + style="stop-color:#00c3f9;stop-opacity:0.33" + offset="0.40000001" + id="stop5168" /> + <stop + id="stop5172" + offset="1" + style="stop-color:#00c3f9;stop-opacity:1;" /> + </linearGradient> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="15.839192" + inkscape:cx="19.689661" + inkscape:cy="10.360728" + inkscape:document-units="mm" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:window-width="2560" + inkscape:window-height="1537" + inkscape:window-x="-4" + inkscape:window-y="-4" + inkscape:window-maximized="1" /> + <metadata + id="metadata4567"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title>Open Air Logo</dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Calque 1" + inkscape:groupmode="layer" + id="layer1"> + <path + inkscape:connector-curvature="0" + id="path5017" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.58333302px;line-height:1.25;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:url(#radialGradient5140);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.11197994;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill" + d="m 4.2394596,289.42973 c -0.7893188,-7.7e-4 -1.6132823,0.29881 -2.1442353,0.89641 -0.5268689,0.5976 -0.790304,1.41203 -0.790304,2.44326 0,1.02758 0.2634351,1.84019 0.790304,2.43778 0.530953,0.5976 1.2456986,0.89641 2.1442353,0.89641 0.8985367,0 1.6091981,-0.29881 2.1319828,-0.89641 0.5268689,-0.59759 0.790304,-1.4102 0.790304,-2.43778 0,-1.03123 -0.2634351,-1.84566 -0.790304,-2.44326 -0.5227847,-0.5976 -1.3463617,-0.89563 -2.1319828,-0.89641 z m 0,-0.8964 c 1.2824569,0 2.3076057,0.38444 3.0754463,1.1533 0.7678406,0.76523 1.1517608,1.7928 1.1517608,3.08277 0,1.2863 -0.3839202,2.3139 -1.1517608,3.08275 C 6.5470653,296.61738 5.5219165,297 4.2394596,297 2.9529184,297 1.9236856,296.61738 1.1517607,295.85215 0.38392027,295.08693 0,294.05936 0,292.7694 c 0,-1.28997 0.38392027,-2.31754 1.1517607,-3.08277 0.7719249,-0.76886 1.8011577,-1.1533 3.0876989,-1.1533 z" + sodipodi:nodetypes="acscscscascscscscs" + inkscape:export-xdpi="100.34" + inkscape:export-ydpi="100.34" /> + </g> +</svg> diff --git a/Resources/public/svg/logo.svg b/Resources/public/svg/logo.svg new file mode 100644 index 0000000..159107f --- /dev/null +++ b/Resources/public/svg/logo.svg @@ -0,0 +1,228 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="210mm" + height="297mm" + viewBox="0 0 210 297" + version="1.1" + id="svg8" + sodipodi:docname="logo.svg" + inkscape:version="0.92.3 (2405546, 2018-03-11)"> + <defs + id="defs2"> + <linearGradient + inkscape:collect="always" + id="linearGradient5174"> + <stop + id="stop5166" + offset="0" + style="stop-color:#00c3f9;stop-opacity:0" /> + <stop + style="stop-color:#00c3f9;stop-opacity:0.33" + offset="0.40000001" + id="stop5168" /> + <stop + id="stop5172" + offset="1" + style="stop-color:#00c3f9;stop-opacity:1;" /> + </linearGradient> + <clipPath + clipPathUnits="userSpaceOnUse" + id="clipPath18"> + <path + d="M 3044.85,0 C 1363.23,0 0,203.461 0,454.441 0,705.41 1363.23,908.859 3044.85,908.859 4726.47,908.859 6089.69,705.41 6089.69,454.441 6089.69,203.461 4726.47,0 3044.85,0" + id="path20" /> + </clipPath> + <clipPath + clipPathUnits="userSpaceOnUse" + id="clipPath30"> + <path + d="M 0,3832 0,0 l 6089.69,0 0,3832 L 0,3832 Z" + id="path32" /> + </clipPath> + <clipPath + clipPathUnits="userSpaceOnUse" + id="clipPath80"> + <path + d="m 2788.36,2246.6 -256.48,0 c -3.06,0.66 -19.07,4.34 -19.07,4.34 -17.41,4.1 -33.17,8.18 -48.17,12.44 l -6.49,1.93 c -15.5,4.52 -30.45,9.28 -44.44,14.09 l -4.55,1.52 c -13.92,4.85 -28.16,10.26 -43.53,16.52 l -8.06,3.3 c -14.03,5.88 -27.59,11.99 -40.31,18.1 l -6.54,3.26 c -14.56,7.15 -27.3,13.83 -39.59,20.71 -11.57,6.57 -23.65,13.86 -36.94,22.42 l -5.91,3.79 c -11.33,7.43 -22.51,15.21 -33.21,23.16 l -5.56,4.17 c -11.98,9.07 -22.38,17.36 -31.8,25.43 l -1.19,1.03 c -9.72,8.35 -19.3,17.09 -29.29,26.74 l -3.52,3.35 c -8.91,8.76 -17.92,18.14 -26.74,27.89 l -4.06,4.54 c -9.19,10.33 -17.29,19.98 -24.77,29.48 l -1.68,2.18 c -8.07,10.36 -15.78,20.86 -22.89,31.21 l -1.03,1.46 c -6.93,10.11 -13.69,20.71 -21.23,33.28 l -1.86,3.11 c -6.58,11.16 -12.75,22.33 -18.31,33.13 l -1.27,2.53 c -11.68,22.94 -22.2,46.97 -31.59,72.27 l -0.64,1.7 c -4.41,12.01 -8.53,24.3 -12.26,36.52 l -0.6,1.99 c -11.33,37.51 -19.82,76.79 -25.31,117.56 -0.35,2.6 -0.55,5.25 -0.88,7.85 30.2,9.7 62.33,15.04 95.71,15.04 9.99,0 20.46,-0.6 32,-1.82 l 15.43,-1.64 1.44,15.45 c 15.75,169.23 79.48,321.07 167.3,405.86 -19.6,-51.67 -34.76,-105.27 -45.24,-160 -18.26,-95.59 -21.4,-190.06 -9.27,-280.74 5.48,-40.77 13.97,-80.05 25.31,-117.56 l 0.59,-1.99 c 3.73,-12.22 7.86,-24.51 12.27,-36.52 l 0.63,-1.7 c 9.39,-25.3 19.91,-49.33 31.6,-72.27 l 1.26,-2.53 c 5.56,-10.8 11.74,-21.97 18.31,-33.13 l 1.87,-3.11 c 7.53,-12.57 14.3,-23.17 21.22,-33.28 l 1.04,-1.46 c 7.11,-10.35 14.82,-20.85 22.89,-31.21 l 1.67,-2.18 c 7.49,-9.5 15.58,-19.15 24.77,-29.48 l 4.06,-4.54 c 8.82,-9.75 17.83,-19.13 26.75,-27.89 l 3.51,-3.35 c 9.99,-9.65 19.58,-18.39 29.29,-26.74 l 1.19,-1.03 c 9.42,-8.07 19.83,-16.36 31.8,-25.43 l 5.56,-4.17 c 10.71,-7.95 21.89,-15.73 33.21,-23.16 l 5.91,-3.79 c 13.29,-8.56 25.37,-15.85 36.95,-22.42 12.28,-6.88 25.03,-13.56 39.59,-20.71 l 6.53,-3.26 c 12.72,-6.11 26.28,-12.22 40.31,-18.1 l 8.06,-3.3 c 15.38,-6.26 29.61,-11.67 43.53,-16.52 l 4.55,-1.52 c 13.99,-4.81 28.95,-9.57 44.45,-14.09 l 6.47,-1.93 c 15.01,-4.26 30.77,-8.34 48.18,-12.44 0,0 16.02,-3.68 19.07,-4.34" + id="path82" /> + </clipPath> + <clipPath + clipPathUnits="userSpaceOnUse" + id="clipPath92"> + <path + d="m 4078.74,2296.83 c -70.64,7.85 -137.5,18.24 -200.68,31.03 150.52,95.28 244.88,262.64 244.88,443.38 0,245.43 -173.93,461.07 -413.56,512.75 l -7.73,1.66 -3.11,7.27 c -86.59,201.73 -254.36,351.23 -455.56,417.29 11.47,19.88 20.58,32.95 25.61,37.54 299.13,-1.39 568.3,-179.6 686.42,-454.83 l 3.12,-7.27 7.73,-1.66 c 239.62,-51.68 413.56,-267.32 413.56,-512.75 0,-202.21 -117.9,-387.97 -300.68,-474.41" + id="path94" /> + </clipPath> + <clipPath + clipPathUnits="userSpaceOnUse" + id="clipPath104"> + <path + d="m 3549.34,2246.6 -62.19,0 c -87.81,0 -171.3,4.24 -250.34,12.59 -23.74,5.79 -47.08,12.04 -69.74,19.01 -13.3,4.1 -26.3,8.41 -39.2,12.89 l -1.92,0.68 c -12.67,4.47 -25.13,9.11 -37.23,13.88 l -1.87,0.74 c -12.34,4.9 -24.42,9.97 -36.99,15.52 -116.98,51.84 -215.06,122.74 -292.07,211.34 -7.01,8.09 -13.8,16.3 -20.4,24.61 l -1.27,1.6 c -6.44,8.15 -12.67,16.4 -18.71,24.74 l -1.44,1.99 c -5.99,8.35 -11.81,16.78 -17.36,25.22 l -1.17,1.8 c -5.69,8.69 -11.2,17.48 -16.94,27.12 -47.66,80.21 -80.73,170.1 -98.31,267.17 l -0.3,1.63 c -1.73,9.67 -3.29,19.39 -4.89,30.48 l -0.24,1.59 c -1.34,9.5 -2.52,19 -3.58,28.53 l -0.38,3.54 c -1,9.47 -1.86,18.96 -2.58,28.51 l -0.25,3.42 c -0.68,9.61 -1.23,19.25 -1.63,28.84 l -0.08,2.66 c -0.4,9.98 -0.65,19.98 -0.73,30.57 -0.65,93.21 11.69,187.94 36.97,282.57 2.61,9.73 5.36,19.4 8.22,29.04 l 0.48,1.61 c 2.86,9.55 5.84,19.05 8.94,28.51 l 0.51,1.54 c 0.69,2.07 1.41,4.17 2.11,6.24 131.82,235.2 366.62,359.44 498.49,391.61 -19.1,-17.91 -37.78,-37.4 -55.88,-58.3 -74,-85.49 -135.6,-192.8 -178.13,-310.32 -3.67,-10.2 -6.95,-19.7 -10.11,-29.23 l -0.5,-1.54 c -3.11,-9.46 -6.09,-18.96 -8.95,-28.51 l -0.48,-1.61 c -2.87,-9.64 -5.61,-19.31 -8.22,-29.04 -25.28,-94.63 -37.62,-189.36 -36.96,-282.57 0.08,-10.59 0.32,-20.59 0.72,-30.57 l 0.09,-2.66 c 0.39,-9.59 0.95,-19.23 1.62,-28.84 l 0.25,-3.42 c 0.72,-9.55 1.59,-19.04 2.59,-28.51 l 0.38,-3.54 c 1.05,-9.53 2.23,-19.03 3.57,-28.53 l 0.24,-1.59 c 1.61,-11.09 3.16,-20.81 4.89,-30.48 l 0.31,-1.63 c 17.56,-97.07 50.65,-186.96 98.31,-267.17 5.74,-9.64 11.25,-18.43 16.93,-27.12 l 1.17,-1.8 c 5.56,-8.44 11.37,-16.87 17.37,-25.22 l 1.43,-1.99 c 6.05,-8.34 12.28,-16.59 18.72,-24.74 l 1.27,-1.6 c 6.59,-8.31 13.39,-16.52 20.4,-24.61 76.99,-88.6 175.08,-159.5 292.06,-211.34 12.56,-5.55 24.66,-10.62 36.99,-15.52 l 1.87,-0.74 c 12.11,-4.77 24.55,-9.41 37.25,-13.88 l 1.91,-0.68 c 12.89,-4.48 25.91,-8.79 39.21,-12.89 40.2,-12.38 82.15,-22.92 125.77,-31.6" + id="path106" /> + </clipPath> + <clipPath + clipPathUnits="userSpaceOnUse" + id="clipPath18-8"> + <path + d="M 3044.85,0 C 1363.23,0 0,203.461 0,454.441 0,705.41 1363.23,908.859 3044.85,908.859 4726.47,908.859 6089.69,705.41 6089.69,454.441 6089.69,203.461 4726.47,0 3044.85,0" + id="path20-1" /> + </clipPath> + <clipPath + clipPathUnits="userSpaceOnUse" + id="clipPath30-2"> + <path + d="M 0,3832 0,0 l 6089.69,0 0,3832 L 0,3832 Z" + id="path32-0" /> + </clipPath> + <clipPath + clipPathUnits="userSpaceOnUse" + id="clipPath80-2"> + <path + d="m 2788.36,2246.6 -256.48,0 c -3.06,0.66 -19.07,4.34 -19.07,4.34 -17.41,4.1 -33.17,8.18 -48.17,12.44 l -6.49,1.93 c -15.5,4.52 -30.45,9.28 -44.44,14.09 l -4.55,1.52 c -13.92,4.85 -28.16,10.26 -43.53,16.52 l -8.06,3.3 c -14.03,5.88 -27.59,11.99 -40.31,18.1 l -6.54,3.26 c -14.56,7.15 -27.3,13.83 -39.59,20.71 -11.57,6.57 -23.65,13.86 -36.94,22.42 l -5.91,3.79 c -11.33,7.43 -22.51,15.21 -33.21,23.16 l -5.56,4.17 c -11.98,9.07 -22.38,17.36 -31.8,25.43 l -1.19,1.03 c -9.72,8.35 -19.3,17.09 -29.29,26.74 l -3.52,3.35 c -8.91,8.76 -17.92,18.14 -26.74,27.89 l -4.06,4.54 c -9.19,10.33 -17.29,19.98 -24.77,29.48 l -1.68,2.18 c -8.07,10.36 -15.78,20.86 -22.89,31.21 l -1.03,1.46 c -6.93,10.11 -13.69,20.71 -21.23,33.28 l -1.86,3.11 c -6.58,11.16 -12.75,22.33 -18.31,33.13 l -1.27,2.53 c -11.68,22.94 -22.2,46.97 -31.59,72.27 l -0.64,1.7 c -4.41,12.01 -8.53,24.3 -12.26,36.52 l -0.6,1.99 c -11.33,37.51 -19.82,76.79 -25.31,117.56 -0.35,2.6 -0.55,5.25 -0.88,7.85 30.2,9.7 62.33,15.04 95.71,15.04 9.99,0 20.46,-0.6 32,-1.82 l 15.43,-1.64 1.44,15.45 c 15.75,169.23 79.48,321.07 167.3,405.86 -19.6,-51.67 -34.76,-105.27 -45.24,-160 -18.26,-95.59 -21.4,-190.06 -9.27,-280.74 5.48,-40.77 13.97,-80.05 25.31,-117.56 l 0.59,-1.99 c 3.73,-12.22 7.86,-24.51 12.27,-36.52 l 0.63,-1.7 c 9.39,-25.3 19.91,-49.33 31.6,-72.27 l 1.26,-2.53 c 5.56,-10.8 11.74,-21.97 18.31,-33.13 l 1.87,-3.11 c 7.53,-12.57 14.3,-23.17 21.22,-33.28 l 1.04,-1.46 c 7.11,-10.35 14.82,-20.85 22.89,-31.21 l 1.67,-2.18 c 7.49,-9.5 15.58,-19.15 24.77,-29.48 l 4.06,-4.54 c 8.82,-9.75 17.83,-19.13 26.75,-27.89 l 3.51,-3.35 c 9.99,-9.65 19.58,-18.39 29.29,-26.74 l 1.19,-1.03 c 9.42,-8.07 19.83,-16.36 31.8,-25.43 l 5.56,-4.17 c 10.71,-7.95 21.89,-15.73 33.21,-23.16 l 5.91,-3.79 c 13.29,-8.56 25.37,-15.85 36.95,-22.42 12.28,-6.88 25.03,-13.56 39.59,-20.71 l 6.53,-3.26 c 12.72,-6.11 26.28,-12.22 40.31,-18.1 l 8.06,-3.3 c 15.38,-6.26 29.61,-11.67 43.53,-16.52 l 4.55,-1.52 c 13.99,-4.81 28.95,-9.57 44.45,-14.09 l 6.47,-1.93 c 15.01,-4.26 30.77,-8.34 48.18,-12.44 0,0 16.02,-3.68 19.07,-4.34" + id="path82-9" /> + </clipPath> + <clipPath + clipPathUnits="userSpaceOnUse" + id="clipPath92-4"> + <path + d="m 4078.74,2296.83 c -70.64,7.85 -137.5,18.24 -200.68,31.03 150.52,95.28 244.88,262.64 244.88,443.38 0,245.43 -173.93,461.07 -413.56,512.75 l -7.73,1.66 -3.11,7.27 c -86.59,201.73 -254.36,351.23 -455.56,417.29 11.47,19.88 20.58,32.95 25.61,37.54 299.13,-1.39 568.3,-179.6 686.42,-454.83 l 3.12,-7.27 7.73,-1.66 c 239.62,-51.68 413.56,-267.32 413.56,-512.75 0,-202.21 -117.9,-387.97 -300.68,-474.41" + id="path94-6" /> + </clipPath> + <clipPath + clipPathUnits="userSpaceOnUse" + id="clipPath104-6"> + <path + d="m 3549.34,2246.6 -62.19,0 c -87.81,0 -171.3,4.24 -250.34,12.59 -23.74,5.79 -47.08,12.04 -69.74,19.01 -13.3,4.1 -26.3,8.41 -39.2,12.89 l -1.92,0.68 c -12.67,4.47 -25.13,9.11 -37.23,13.88 l -1.87,0.74 c -12.34,4.9 -24.42,9.97 -36.99,15.52 -116.98,51.84 -215.06,122.74 -292.07,211.34 -7.01,8.09 -13.8,16.3 -20.4,24.61 l -1.27,1.6 c -6.44,8.15 -12.67,16.4 -18.71,24.74 l -1.44,1.99 c -5.99,8.35 -11.81,16.78 -17.36,25.22 l -1.17,1.8 c -5.69,8.69 -11.2,17.48 -16.94,27.12 -47.66,80.21 -80.73,170.1 -98.31,267.17 l -0.3,1.63 c -1.73,9.67 -3.29,19.39 -4.89,30.48 l -0.24,1.59 c -1.34,9.5 -2.52,19 -3.58,28.53 l -0.38,3.54 c -1,9.47 -1.86,18.96 -2.58,28.51 l -0.25,3.42 c -0.68,9.61 -1.23,19.25 -1.63,28.84 l -0.08,2.66 c -0.4,9.98 -0.65,19.98 -0.73,30.57 -0.65,93.21 11.69,187.94 36.97,282.57 2.61,9.73 5.36,19.4 8.22,29.04 l 0.48,1.61 c 2.86,9.55 5.84,19.05 8.94,28.51 l 0.51,1.54 c 0.69,2.07 1.41,4.17 2.11,6.24 131.82,235.2 366.62,359.44 498.49,391.61 -19.1,-17.91 -37.78,-37.4 -55.88,-58.3 -74,-85.49 -135.6,-192.8 -178.13,-310.32 -3.67,-10.2 -6.95,-19.7 -10.11,-29.23 l -0.5,-1.54 c -3.11,-9.46 -6.09,-18.96 -8.95,-28.51 l -0.48,-1.61 c -2.87,-9.64 -5.61,-19.31 -8.22,-29.04 -25.28,-94.63 -37.62,-189.36 -36.96,-282.57 0.08,-10.59 0.32,-20.59 0.72,-30.57 l 0.09,-2.66 c 0.39,-9.59 0.95,-19.23 1.62,-28.84 l 0.25,-3.42 c 0.72,-9.55 1.59,-19.04 2.59,-28.51 l 0.38,-3.54 c 1.05,-9.53 2.23,-19.03 3.57,-28.53 l 0.24,-1.59 c 1.61,-11.09 3.16,-20.81 4.89,-30.48 l 0.31,-1.63 c 17.56,-97.07 50.65,-186.96 98.31,-267.17 5.74,-9.64 11.25,-18.43 16.93,-27.12 l 1.17,-1.8 c 5.56,-8.44 11.37,-16.87 17.37,-25.22 l 1.43,-1.99 c 6.05,-8.34 12.28,-16.59 18.72,-24.74 l 1.27,-1.6 c 6.59,-8.31 13.39,-16.52 20.4,-24.61 76.99,-88.6 175.08,-159.5 292.06,-211.34 12.56,-5.55 24.66,-10.62 36.99,-15.52 l 1.87,-0.74 c 12.11,-4.77 24.55,-9.41 37.25,-13.88 l 1.91,-0.68 c 12.89,-4.48 25.91,-8.79 39.21,-12.89 40.2,-12.38 82.15,-22.92 125.77,-31.6" + id="path106-1" /> + </clipPath> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient5174" + id="linearGradient5075" + x1="1.018965" + y1="285.02298" + x2="7.7508168" + y2="285.02298" + gradientUnits="userSpaceOnUse" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient5174" + id="radialGradient5140" + cx="3.5708413" + cy="290.94611" + fx="3.5708413" + fy="290.94611" + r="3.5708413" + gradientTransform="matrix(0.81002191,0.81002303,-1.7837077,1.7837053,519.6412,-230.90846)" + gradientUnits="userSpaceOnUse" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient5174" + id="radialGradient5202" + cx="34.65731" + cy="290.9346" + fx="34.65731" + fy="290.9346" + r="3.534668" + gradientTransform="matrix(1,0,0,1.0913743,0,-26.583936)" + gradientUnits="userSpaceOnUse" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="2.8" + inkscape:cx="33.962344" + inkscape:cy="136.63132" + inkscape:document-units="mm" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:window-width="1666" + inkscape:window-height="1294" + inkscape:window-x="436" + inkscape:window-y="107" + inkscape:window-maximized="0" /> + <metadata + id="metadata5"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Calque 1" + inkscape:groupmode="layer" + id="layer1"> + <text + xml:space="preserve" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.58333302px;line-height:1.25;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#006666;fill-opacity:1;stroke:none;stroke-width:0.26458332;" + x="7.7265034" + y="294.79858" + id="text4105" + inkscape:export-xdpi="99.20594" + inkscape:export-ydpi="99.20594"><tspan + sodipodi:role="line" + id="tspan4103" + x="7.7265034" + y="294.79858" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.58333302px;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332;fill:#006666;fill-opacity:1;">pen</tspan></text> + <path + inkscape:connector-curvature="0" + id="path5017" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.58333302px;line-height:1.25;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:url(#radialGradient5140);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:markers stroke fill" + d="m 3.576009,287.79126 c -0.6657944,-7.3e-4 -1.3608126,0.2825 -1.808675,0.84749 -0.4444173,0.565 -0.666626,1.33498 -0.666626,2.30994 0,0.97152 0.2222087,1.73978 0.666626,2.30477 0.4478624,0.56499 1.0507541,0.84749 1.808675,0.84749 0.757921,0 1.3573676,-0.2825 1.7983398,-0.84749 0.4444173,-0.56499 0.666626,-1.33325 0.666626,-2.30477 0,-0.97496 -0.2222087,-1.74494 -0.666626,-2.30994 -0.4409722,-0.56499 -1.1356634,-0.84676 -1.7983398,-0.84749 z m 0,-0.84749 c 1.08176,0 1.946479,0.36346 2.5941569,1.09037 0.6476779,0.72347 0.9715169,1.69498 0.9715169,2.91455 0,1.21612 -0.323839,2.18764 -0.9715169,2.91455 -0.6476779,0.72347 -1.5123969,1.08521 -2.5941569,1.08521 -1.085205,0 -1.953369,-0.36174 -2.60449208,-1.08521 C 0.32383899,293.13977 2.1886081e-8,292.16826 2.1886081e-8,290.94869 2.1886081e-8,289.72912 0.32383899,288.75761 0.97151692,288.03414 1.62264,287.30723 2.490804,286.94377 3.576009,286.94377 Z" + sodipodi:nodetypes="acscscscascscscscs" + inkscape:export-xdpi="99.20594" + inkscape:export-ydpi="99.20594" /> + <rect + style="fill:url(#linearGradient5075);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:0, 1.09999998;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers stroke fill" + id="rect5067" + width="6.7318516" + height="1.3363476" + x="1.018965" + y="284.3548" /> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:url(#radialGradient5202);fill-opacity:1.0;stroke:none;stroke-width:0.26458332" + x="31.039961" + y="294.79224" + id="text5152" + inkscape:export-xdpi="99.20594" + inkscape:export-ydpi="99.20594"><tspan + sodipodi:role="line" + id="tspan5150" + x="31.039961" + y="294.79224" + style="fill:url(#radialGradient5202);fill-opacity:1.0;stroke-width:0.26458332">A</tspan></text> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#006666;fill-opacity:1;stroke:none;stroke-width:0.26458332;" + x="38.277328" + y="294.79953" + id="text5156" + inkscape:export-xdpi="99.20594" + inkscape:export-ydpi="99.20594"><tspan + sodipodi:role="line" + id="tspan5154" + x="38.277328" + y="294.79953" + style="fill:#006666;fill-opacity:1;stroke-width:0.26458332;">ir</tspan></text> + </g> +</svg> diff --git a/Resources/public/xcf/openair.xcf b/Resources/public/xcf/openair.xcf new file mode 100644 index 0000000000000000000000000000000000000000..ebe102bf9656fddd8014a91f4693c3bf68e00a61 GIT binary patch literal 30224 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 N7A$^kYV#1({|BtTOI!c| literal 0 HcmV?d00001 diff --git a/Resources/translations/messages.fr.yml b/Resources/translations/messages.fr.yml new file mode 100644 index 0000000..40c37fe --- /dev/null +++ b/Resources/translations/messages.fr.yml @@ -0,0 +1,60 @@ +'Outdoor space reservation system': 'Système de réservation d''espace en plein air' +'Open Air': 'Air libre' +Navigation: Navigation +About: 'à propos' +Index: Accueil +Admin: Administration +Contact: Contact +'Raphaël Gertz all rights reserved': 'Raphaël Gertz tous droits réservés' +'Copyright 2018': 'Droit d''auteur 2018' +Send: Envoyer +Subject: Sujet +'Your name': 'Votre nom' +'Your mail address': 'Votre courriel' +'Your message has been sent': 'Votre message a bien été envoyé' +'Your message here': 'Votre message ici' +'Your password': 'Votre mot de passe' +Logout: Déconnection +Register: Enregistrement +Login: Identification +Recover: Récupération +Dashboard: Tableau de bord +'Hi, %name%': 'Salut, %name%' +'Subject:': 'Sujet :' +'Name': 'Nom' +'Message': 'Message' +'Title': 'Civilité' +'Your title': 'Votre civilité' +'Forename': 'Prénom' +'Your forename': 'Votre prénom' +'Surname': 'Nom' +'Your surname': 'Votre nom' +'Pseudonym': 'Pseudonyme' +'Your pseudonym': 'Votre pseudonyme' +'Mail': 'Courriel' +'Password': 'Mot de passe' +'Confirm password': 'Confirmation' +'Your password confirmation': 'Votre confirmation de mot de passe' +'Welcome to %title%': 'Bienvenue sur %title%' +'Thanks so much for joining us, from now on, you can reserve your %title% spaces.': 'Merci de nous avoir rejoint, à partir de maintenant, vous pouvez réserver vos espaces à l''%title%.' +'Your account has been created': 'Votre compte a bien été créé' +'Invalid credentials.': 'Identifiants invalides' +'Thanks so much for joining us, to recover your account you can follow this link: <a href="%url%">%url%</a>': 'Merci de nous avoir rejoint, pour récupérer votre compte vous pouvez suivre ce lien : <a href="%url%">%url%</a>' +'Your password is updated and an account recover message has been sent': 'Votre mot de passe est modifié et un message de récupération de compte a été envoyé' +'Unable to find account': 'Impossible de trouver le compte' +'Account already exists: %mail%': 'Le compte existe déjà : %mail%' +'Your recover account message has been sent': 'Votre message de récupération de compte a été envoyé' +'To recover your account click here': 'Pour récupérer votre compte cliquez ici' +'Recover account on %title%': 'Récupération de compte sur %title%' +'Account recovered on %title%': 'Compte récupéré sur %title%' +'Your account password has been changed, to recover your account you can follow this link: <a href="%url%">%url%</a>': 'Votre mot de passe a été changé, pour récupérer votre compte vous pouvez suivre ce lien : <a href="%url%">%url%</a>' +'Authentication request could not be processed due to a system problem.': 'Authentification impossible suite à un problème système' +Location: Emplacement +Your location: Votre emplacement +Date: Date +Your date: Votre date +Slot: Créneau +Your slot: Votre créneau +'Application request the %date% for %location% on the slot %slot% saved': 'Réservation le %date% pour %location% sur le créneau %slot% enregistrée' +#'Application request the %date% for %location% on the slot %slot% already exists': 'Réservation le %date% pour %location% sur le créneau %slot% déjà existante' +'Application already exists': 'Réservation déjà existante' diff --git a/Resources/translations/validators.fr.yml b/Resources/translations/validators.fr.yml new file mode 100644 index 0000000..e945217 --- /dev/null +++ b/Resources/translations/validators.fr.yml @@ -0,0 +1,11 @@ +'Please provide your name': 'Veuillez fournir votre nom' +'Please provide your mail': 'Veuillez fournir votre courriel' +'Please provide a valid mail': 'Veuillez fournir un courriel valide' +'Please provide your pseudonym': 'Veuillez fournir votre pseudonyme' +'Please provide your forename': 'Veuillez fournir votre prénom' +'Please provide your surname': 'Veuillez fournir votre nom' +'Please provide your password': 'Veuillez fournir votre mot de passe' +'Please provide your subject': 'Veuillez fournir votre sujet' +'Please provide your message': 'Veuillez fournir votre message' +'The password and confirmation must match': 'Le mot de passe doit correspondre à la confirmation' +'Your mail doesn''t seems to be valid': 'Votre courriel ne semble pas valable' diff --git a/Resources/views/admin/index.html.twig b/Resources/views/admin/index.html.twig new file mode 100644 index 0000000..687e217 --- /dev/null +++ b/Resources/views/admin/index.html.twig @@ -0,0 +1,57 @@ +{% extends '@RapsysAir/base.html.twig' %} +{% block content %} +<section id="dashboard"> + <h2>{% trans %}Dashboard{% endtrans %}</h2> + <div class="panel"> + {% if calendar is defined and calendar %} + <table class="grid"> + <tbody> + <tr> + {% for date, day in calendar %} + <td class="{{ ['cell', 'seventh']|merge(day.class)|join(' ') }}"> + <h3>{{ day.title }}</h3> + {% if day.sessions is not empty %} + <ul> + {% for session in day.sessions %} + <li class="{{ ['session']|merge(session.class)|join(' ') }}"> + <a href="{{ path('rapsys_air_session', {'id': session.id}) }}" title="{{ session.title }}">{{ session.title }}</a> + </li> + {% endfor %} + </ul> + {% endif %} + </td> + {% if loop.index % 7 == 0 and not loop.last %} + </tr> + <tr> + {% endif %} + {% endfor %} + </tr> + </tbody> + </table> + {% endif %} + <div> + {{ form_start(form) }} + + <header>{{ form_errors(form) }}</header> + + <section> + {{ form_row(form.location) }} + + {{ form_row(form.date) }} + + {{ form_row(form.slot) }} + </section> + + {{ form_row(form.submit) }} + + {# Render CSRF token etc .#} + <footer style="display:none"> + {{ form_rest(form) }} + </footer> + + {{ form_end(form) }} + </div> + </div> + {# dump(calendar) #} +</section> +{% endblock %} diff --git a/Resources/views/admin/index.html.twig.toto b/Resources/views/admin/index.html.twig.toto new file mode 100644 index 0000000..d529910 --- /dev/null +++ b/Resources/views/admin/index.html.twig.toto @@ -0,0 +1 @@ +|length > 21 ? session.title|slice(0, 21) ~ '...' : session.title diff --git a/Resources/views/admin/session.html.twig b/Resources/views/admin/session.html.twig new file mode 100644 index 0000000..ef61643 --- /dev/null +++ b/Resources/views/admin/session.html.twig @@ -0,0 +1,31 @@ +{% extends '@RapsysAir/base.html.twig' %} +{% block content %} +<section id="dashboard"> + <h2>{{ section }}</h2> + <div class="panel"> + <div class="grid"> + <dl class="cell"> + <dt><h3>{% trans %}Location{% endtrans %}</h3></dt> + <dd>{{ session.location.getTitle() }}</dd> + </dl> + <dl class="cell"> + <dt><h3>{% trans %}Date{% endtrans %}</h3></dt> + <dd>{{ session.date.format('Y-m-d') }}</dd> + </dl> + <dl class="cell"> + <dt><h3>{% trans %}Slot{% endtrans %}</h3></dt> + <dd>{{ session.slot.getTitle() }}</dd> + </dl> + <dl class="cell"> + <dt><h3>{% trans %}Application{% endtrans %}</h3></dt> + {% if session.application is null %} + <dd>{% trans %}None{% endtrans %}</dd> + {% else %} + <dd>{{ session.application.getTitle() }}</dd> + {% endif %} + </dl> + </div> + </div> + {{ dump(session) }} +</section> +{% endblock %} diff --git a/Resources/views/base.html.twig b/Resources/views/base.html.twig new file mode 100644 index 0000000..a95e21a --- /dev/null +++ b/Resources/views/base.html.twig @@ -0,0 +1,78 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="UTF-8" /> + <title>{% block title %}{{ title }}{% endblock %}</title> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + {% block stylesheet %} + {% stylesheet '//fonts.googleapis.com/css?family=Irish+Grover' '//fonts.googleapis.com/css?family=La+Belle+Aurore' '@RapsysAirBundle/Resources/public/css/{reset,screen}.css' %} + <link href="{{ asset_url }}" type="text/css" rel="stylesheet" /> + {% endstylesheet %} + {% endblock %} + <!--{% block javascript %} + {% javascript '@RapsysAirBundle/Resources/public/js/*.js' %} + <script src="{{ asset_url }}"></script> + {% endjavascript %} + {% endblock %}--> + <link rel="icon" type="image/png" href="{{ asset('bundles/rapsysair/png/favicon.png') }}" sizes="192x192" /> + <link rel="shortcut icon" type="image/x-icon" href="{{ asset('bundles/rapsysair/ico/favicon.ico') }}" /> + </head> + {% block body %} + <body> + {% block header %} + <header id="header"> + {% block header_title %} + {% block blog_title %}<h1><a href="{{ path('rapsys_air_homepage') }}"><img src="{{ asset('bundles/rapsysair/png/logo.png') }}" alt="{% trans %}Open Air{% endtrans %}" /></a></h1>{% endblock %} + {% block header_nav %} + <nav> + <h2>{% trans %}Navigation{% endtrans %}</h2> + <a href="{{ path('rapsys_air_admin') }}">{% trans %}Admin{% endtrans %}</a> + <a href="{{ path('rapsys_air_contact') }}">{% trans %}Contact{% endtrans %}</a> + {% if is_granted('IS_AUTHENTICATED_REMEMBERED') %} + <a href="{{ path('rapsys_user_logout') }}">{% trans %}Logout{% endtrans %}</a> + {% else %} + <a href="{{ path('rapsys_user_register') }}">{% trans %}Register{% endtrans %}</a> + {% endif %} + </nav> + {% endblock %} + {% block blog_subtitle %}{% endblock %} + {% block blog_tagline %} + {% if tags is defined and tags %} + <ul> + {% for id, tag in tags %} + <li><h2><a href="#">Tag</a></h2></li> + {% endfor %} + </ul> + {% endif %} + {% endblock %} + {% endblock %} + </header> + {% endblock %} + + {# pass an array argument to get the messages of those types (['warning', 'error']) #} + {% for label, messages in app.flashes %} + {% if messages %} + <div class="flash {{label}}"> + <ul> + {% for message in messages %} + <li>{{ message }}</li> + {% endfor %} + </ul> + </div> + {% endif %} + {% endfor %} + + {% block sidebar %}<aside id="sidebar"></aside>{% endblock %} + + {% block content %}<section id="content"></section>{% endblock %} + + {% block footer %} + <footer id="footer"> + <span> </span> + <details><summary>{% trans %}Raphaël Gertz all rights reserved{% endtrans %}</summary><span>{% trans %}Copyright 2018{% endtrans %}.</span></details> + <span> </span> + </footer> + {% endblock %} + </body> + {% endblock %} +</html> diff --git a/Resources/views/form/contact.html.twig b/Resources/views/form/contact.html.twig new file mode 100644 index 0000000..b75b91b --- /dev/null +++ b/Resources/views/form/contact.html.twig @@ -0,0 +1,34 @@ +{% extends '@RapsysAir/base.html.twig' %} +{% block content %} + <section id="form"> + <h2><a href="{{ path('rapsys_air_contact') }}">{{ section }}</a></h2> + {% if sent %} + <p>{% trans %}Your message has been sent{% endtrans %}</p> + {% else %} + <div> + {{ form_start(form) }} + + <header>{{ form_errors(form) }}</header> + + <section> + {{ form_row(form.subject) }} + + {{ form_row(form.name) }} + + {{ form_row(form.mail) }} + + {{ form_row(form.message) }} + </section> + + {{ form_row(form.submit) }} + + {# Render CSRF token etc .#} + <footer style="display:none"> + {{ form_rest(form) }} + </footer> + + {{ form_end(form) }} + </div> + {% endif %} + </section> +{% endblock %} diff --git a/Resources/views/form/form_div_layout.html.twig b/Resources/views/form/form_div_layout.html.twig new file mode 100644 index 0000000..7f73c51 --- /dev/null +++ b/Resources/views/form/form_div_layout.html.twig @@ -0,0 +1,417 @@ +{# Widgets #} + +{%- block form_widget -%} + {% if compound %} + {{- block('form_widget_compound') -}} + {% else %} + {{- block('form_widget_simple') -}} + {% endif %} +{%- endblock form_widget -%} + +{%- block form_widget_simple -%} + {%- set type = type|default('text') -%} + <input type="{{ type }}" {{ block('widget_attributes') }} {% if value is not empty %}value="{{ value }}" {% endif %}/> +{%- endblock form_widget_simple -%} + +{%- block form_widget_compound -%} + <div {{ block('widget_container_attributes') }}> + {%- if form is rootform -%} + {{ form_errors(form) }} + {%- endif -%} + {{- block('form_rows') -}} + {{- form_rest(form) -}} + </div> +{%- endblock form_widget_compound -%} + +{%- block collection_widget -%} + {% if prototype is defined %} + {%- set attr = attr|merge({'data-prototype': form_row(prototype) }) -%} + {% endif %} + {{- block('form_widget') -}} +{%- endblock collection_widget -%} + +{%- block textarea_widget -%} + <textarea {{ block('widget_attributes') }}>{{ value }}</textarea> +{%- endblock textarea_widget -%} + +{%- block choice_widget -%} + {% if expanded %} + {{- block('choice_widget_expanded') -}} + {% else %} + {{- block('choice_widget_collapsed') -}} + {% endif %} +{%- endblock choice_widget -%} + +{%- block choice_widget_expanded -%} + <div {{ block('widget_container_attributes') }}> + {%- for child in form %} + {{- form_widget(child) -}} + {{- form_label(child, null, {translation_domain: choice_translation_domain}) -}} + {% endfor -%} + </div> +{%- endblock choice_widget_expanded -%} + +{%- block choice_widget_collapsed -%} + {%- if required and placeholder is none and not placeholder_in_choices and not multiple and (attr.size is not defined or attr.size <= 1) -%} + {% set required = false %} + {%- endif -%} + <select {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}> + {%- if placeholder is not none -%} + <option value=""{% if required and value is empty %} selected="selected"{% endif %}>{{ placeholder != '' ? (translation_domain is same as(false) ? placeholder : placeholder|trans({}, translation_domain)) }}</option> + {%- endif -%} + {%- if preferred_choices|length > 0 -%} + {% set options = preferred_choices %} + {{- block('choice_widget_options') -}} + {%- if choices|length > 0 and separator is not none -%} + <option disabled="disabled">{{ separator }}</option> + {%- endif -%} + {%- endif -%} + {%- set options = choices -%} + {{- block('choice_widget_options') -}} + </select> +{%- endblock choice_widget_collapsed -%} + +{%- block choice_widget_options -%} + {% for group_label, choice in options %} + {%- if choice is iterable -%} + <optgroup label="{{ choice_translation_domain is same as(false) ? group_label : group_label|trans({}, choice_translation_domain) }}"> + {% set options = choice %} + {{- block('choice_widget_options') -}} + </optgroup> + {%- else -%} + <option value="{{ choice.value }}"{% if choice.attr %}{% with { attr: choice.attr } %}{{ block('attributes') }}{% endwith %}{% endif %}{% if choice is selectedchoice(value) %} selected="selected"{% endif %}>{{ choice_translation_domain is same as(false) ? choice.label : choice.label|trans({}, choice_translation_domain) }}</option> + {%- endif -%} + {% endfor %} +{%- endblock choice_widget_options -%} + +{%- block checkbox_widget -%} + <input type="checkbox" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} /> +{%- endblock checkbox_widget -%} + +{%- block radio_widget -%} + <input type="radio" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} /> +{%- endblock radio_widget -%} + +{%- block datetime_widget -%} + {% if widget == 'single_text' %} + {{- block('form_widget_simple') -}} + {%- else -%} + <div {{ block('widget_container_attributes') }}> + {{- form_errors(form.date) -}} + {{- form_errors(form.time) -}} + {{- form_widget(form.date) -}} + {{- form_widget(form.time) -}} + </div> + {%- endif -%} +{%- endblock datetime_widget -%} + +{%- block date_widget -%} + {%- if widget == 'single_text' -%} + {{ block('form_widget_simple') }} + {%- else -%} + <div {{ block('widget_container_attributes') }}> + {{- date_pattern|replace({ + '{{ year }}': form_widget(form.year), + '{{ month }}': form_widget(form.month), + '{{ day }}': form_widget(form.day), + })|raw -}} + </div> + {%- endif -%} +{%- endblock date_widget -%} + +{%- block time_widget -%} + {%- if widget == 'single_text' -%} + {{ block('form_widget_simple') }} + {%- else -%} + {%- set vars = widget == 'text' ? { 'attr': { 'size': 1 }} : {} -%} + <div {{ block('widget_container_attributes') }}> + {{ form_widget(form.hour, vars) }}{% if with_minutes %}:{{ form_widget(form.minute, vars) }}{% endif %}{% if with_seconds %}:{{ form_widget(form.second, vars) }}{% endif %} + </div> + {%- endif -%} +{%- endblock time_widget -%} + +{%- block dateinterval_widget -%} + {%- if widget == 'single_text' -%} + {{- block('form_widget_simple') -}} + {%- else -%} + <div {{ block('widget_container_attributes') }}> + {{- form_errors(form) -}} + <table class="{{ table_class|default('') }}" role="presentation"> + <thead> + <tr> + {%- if with_years %}<th>{{ form_label(form.years) }}</th>{% endif -%} + {%- if with_months %}<th>{{ form_label(form.months) }}</th>{% endif -%} + {%- if with_weeks %}<th>{{ form_label(form.weeks) }}</th>{% endif -%} + {%- if with_days %}<th>{{ form_label(form.days) }}</th>{% endif -%} + {%- if with_hours %}<th>{{ form_label(form.hours) }}</th>{% endif -%} + {%- if with_minutes %}<th>{{ form_label(form.minutes) }}</th>{% endif -%} + {%- if with_seconds %}<th>{{ form_label(form.seconds) }}</th>{% endif -%} + </tr> + </thead> + <tbody> + <tr> + {%- if with_years %}<td>{{ form_widget(form.years) }}</td>{% endif -%} + {%- if with_months %}<td>{{ form_widget(form.months) }}</td>{% endif -%} + {%- if with_weeks %}<td>{{ form_widget(form.weeks) }}</td>{% endif -%} + {%- if with_days %}<td>{{ form_widget(form.days) }}</td>{% endif -%} + {%- if with_hours %}<td>{{ form_widget(form.hours) }}</td>{% endif -%} + {%- if with_minutes %}<td>{{ form_widget(form.minutes) }}</td>{% endif -%} + {%- if with_seconds %}<td>{{ form_widget(form.seconds) }}</td>{% endif -%} + </tr> + </tbody> + </table> + {%- if with_invert %}{{ form_widget(form.invert) }}{% endif -%} + </div> + {%- endif -%} +{%- endblock dateinterval_widget -%} + +{%- block number_widget -%} + {# type="number" doesn't work with floats #} + {%- set type = type|default('text') -%} + {{ block('form_widget_simple') }} +{%- endblock number_widget -%} + +{%- block integer_widget -%} + {%- set type = type|default('number') -%} + {{ block('form_widget_simple') }} +{%- endblock integer_widget -%} + +{%- block money_widget -%} + {{ money_pattern|replace({ '{{ widget }}': block('form_widget_simple') })|raw }} +{%- endblock money_widget -%} + +{%- block url_widget -%} + {%- set type = type|default('url') -%} + {{ block('form_widget_simple') }} +{%- endblock url_widget -%} + +{%- block search_widget -%} + {%- set type = type|default('search') -%} + {{ block('form_widget_simple') }} +{%- endblock search_widget -%} + +{%- block percent_widget -%} + {%- set type = type|default('text') -%} + {{ block('form_widget_simple') }} % +{%- endblock percent_widget -%} + +{%- block password_widget -%} + {%- set type = type|default('password') -%} + {{ block('form_widget_simple') }} +{%- endblock password_widget -%} + +{%- block hidden_widget -%} + {%- set type = type|default('hidden') -%} + {{ block('form_widget_simple') }} +{%- endblock hidden_widget -%} + +{%- block email_widget -%} + {%- set type = type|default('email') -%} + {{ block('form_widget_simple') }} +{%- endblock email_widget -%} + +{%- block range_widget -%} + {% set type = type|default('range') %} + {{- block('form_widget_simple') -}} +{%- endblock range_widget %} + +{%- block button_widget -%} + {%- if label is empty -%} + {%- if label_format is not empty -%} + {% set label = label_format|replace({ + '%name%': name, + '%id%': id, + }) %} + {%- elseif label is same as(false) -%} + {% set translation_domain = false %} + {%- else -%} + {% set label = name|humanize %} + {%- endif -%} + {%- endif -%} + <button type="{{ type|default('button') }}" {{ block('button_attributes') }}>{{ translation_domain is same as(false) ? label : label|trans({}, translation_domain) }}</button> +{%- endblock button_widget -%} + +{%- block submit_widget -%} + {%- set type = type|default('submit') -%} + {{ block('button_widget') }} +{%- endblock submit_widget -%} + +{%- block reset_widget -%} + {%- set type = type|default('reset') -%} + {{ block('button_widget') }} +{%- endblock reset_widget -%} + +{%- block tel_widget -%} + {%- set type = type|default('tel') -%} + {{ block('form_widget_simple') }} +{%- endblock tel_widget -%} + +{%- block color_widget -%} + {%- set type = type|default('color') -%} + {{ block('form_widget_simple') }} +{%- endblock color_widget -%} + +{# Labels #} + +{%- block form_label -%} + {% if label is not same as(false) -%} + {% if not compound -%} + {% set label_attr = label_attr|merge({'for': id}) %} + {%- endif -%} + {% if required -%} + {% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' required')|trim}) %} + {%- endif -%} + {% if label is empty -%} + {%- if label_format is not empty -%} + {% set label = label_format|replace({ + '%name%': name, + '%id%': id, + }) %} + {%- else -%} + {% set label = name|humanize %} + {%- endif -%} + {%- endif -%} + <{{ element|default('label') }}{% if label_attr %}{% with { attr: label_attr } %}{{ block('attributes') }}{% endwith %}{% endif %}> + {%- if translation_domain is same as(false) -%} + {{- label -}} + {%- else -%} + {{- label|trans({}, translation_domain) -}} + {%- endif -%} + </{{ element|default('label') }}> + {%- endif -%} +{%- endblock form_label -%} + +{%- block button_label -%}{%- endblock -%} + +{# Rows #} + +{%- block repeated_row -%} + {# + No need to render the errors here, as all errors are mapped + to the first child (see RepeatedTypeValidatorExtension). + #} + {{- block('form_rows') -}} +{%- endblock repeated_row -%} + +{%- block form_row -%} + <div> + {{- form_label(form) -}} + <section> + {{- form_widget(form) -}} + {%- if errors|length > 0 -%} + <div class="error"> + {{- form_errors(form) -}} + </div> + {%- endif -%} + </section> + </div> +{%- endblock form_row -%} + +{%- block button_row -%} + <div> + {{- form_widget(form) -}} + </div> +{%- endblock button_row -%} + +{%- block hidden_row -%} + {{ form_widget(form) }} +{%- endblock hidden_row -%} + +{# Misc #} + +{%- block form -%} + {{ form_start(form) }} + {{- form_widget(form) -}} + {{ form_end(form) }} +{%- endblock form -%} + +{%- block form_start -%} + {%- do form.setMethodRendered() -%} + {% set method = method|upper %} + {%- if method in ["GET", "POST"] -%} + {% set form_method = method %} + {%- else -%} + {% set form_method = "POST" %} + {%- endif -%} + <form name="{{ name }}" method="{{ form_method|lower }}"{% if action != '' %} action="{{ action }}"{% endif %}{% for attrname, attrvalue in attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}{% if multipart %} enctype="multipart/form-data"{% endif %}> + {%- if form_method != method -%} + <input type="hidden" name="_method" value="{{ method }}" /> + {%- endif -%} +{%- endblock form_start -%} + +{%- block form_end -%} + {%- if not render_rest is defined or render_rest -%} + {{ form_rest(form) }} + {%- endif -%} + </form> +{%- endblock form_end -%} + +{%- block form_errors -%} + {%- if errors|length > 0 -%} + <ul> + {%- for error in errors -%} + <li>{{ error.message }}</li> + {%- endfor -%} + </ul> + {%- endif -%} +{%- endblock form_errors -%} + +{%- block form_rest -%} + {% for child in form -%} + {% if not child.rendered %} + {{- form_row(child) -}} + {% endif %} + {%- endfor -%} + + {% if not form.methodRendered and form is rootform %} + {%- do form.setMethodRendered() -%} + {% set method = method|upper %} + {%- if method in ["GET", "POST"] -%} + {% set form_method = method %} + {%- else -%} + {% set form_method = "POST" %} + {%- endif -%} + + {%- if form_method != method -%} + <input type="hidden" name="_method" value="{{ method }}" /> + {%- endif -%} + {% endif -%} +{% endblock form_rest %} + +{# Support #} + +{%- block form_rows -%} + {% for child in form %} + {{- form_row(child) -}} + {% endfor %} +{%- endblock form_rows -%} + +{%- block widget_attributes -%} + id="{{ id }}" name="{{ full_name }}" + {%- if disabled %} disabled="disabled"{% endif -%} + {%- if required %} required="required"{% endif -%} + {{ block('attributes') }} +{%- endblock widget_attributes -%} + +{%- block widget_container_attributes -%} + {%- if id is not empty %}id="{{ id }}"{% endif -%} + {{ block('attributes') }} +{%- endblock widget_container_attributes -%} + +{%- block button_attributes -%} + id="{{ id }}" name="{{ full_name }}"{% if disabled %} disabled="disabled"{% endif -%} + {{ block('attributes') }} +{%- endblock button_attributes -%} + +{% block attributes -%} + {%- for attrname, attrvalue in attr -%} + {{- " " -}} + {%- if attrname in ['placeholder', 'title'] -%} + {{- attrname }}="{{ translation_domain is same as(false) ? attrvalue : attrvalue|trans({}, translation_domain) }}" + {%- elseif attrvalue is same as(true) -%} + {{- attrname }}="{{ attrname }}" + {%- elseif attrvalue is not same as(false) -%} + {{- attrname }}="{{ attrvalue }}" + {%- endif -%} + {%- endfor -%} +{%- endblock attributes -%} diff --git a/Resources/views/form/login.html.twig b/Resources/views/form/login.html.twig new file mode 100644 index 0000000..d680b2d --- /dev/null +++ b/Resources/views/form/login.html.twig @@ -0,0 +1,32 @@ +{% extends '@RapsysAir/base.html.twig' %} +{% block content %} + <section id="form"> + <h2><a href="{{ path('rapsys_user_login') }}">{% trans %}Login{% endtrans %}</a></h2> + <div> + {{ form_start(form) }} + + <header>{{ form_errors(form) }}</header> + + <section> + {{ form_row(form.mail) }} + + {{ form_row(form.password) }} + + {% if error %} + <div class="error"> + <ul><li><a href="{{ path('rapsys_user_recover') }}">{% trans %}To recover your account click here{% endtrans %}</a></li></ul> + </div> + {% endif %} + </section> + + {{ form_row(form.submit) }} + + {# Render CSRF token etc .#} + <footer style="display:none"> + {{ form_rest(form) }} + </footer> + + {{ form_end(form) }} + </div> + </section> +{% endblock %} diff --git a/Resources/views/form/recover.html.twig b/Resources/views/form/recover.html.twig new file mode 100644 index 0000000..63f948d --- /dev/null +++ b/Resources/views/form/recover.html.twig @@ -0,0 +1,28 @@ +{% extends '@RapsysAir/base.html.twig' %} +{% block content %} + <section id="form"> + <h2><a href="{{ path('rapsys_user_recover') }}">{% trans %}Recover{% endtrans %}</a></h2> + {% if sent %} + <p>{% trans %}Your recover account message has been sent{% endtrans %}</p> + {% else %} + <div> + {{ form_start(form) }} + + <header>{{ form_errors(form) }}</header> + + <section> + {{ form_row(form.mail) }} + </section> + + {{ form_row(form.submit) }} + + {# Render CSRF token etc .#} + <footer style="display:none"> + {{ form_rest(form) }} + </footer> + + {{ form_end(form) }} + </div> + {% endif %} + </section> +{% endblock %} diff --git a/Resources/views/form/recover_mail.html.twig b/Resources/views/form/recover_mail.html.twig new file mode 100644 index 0000000..74b2dd7 --- /dev/null +++ b/Resources/views/form/recover_mail.html.twig @@ -0,0 +1,30 @@ +{% extends '@RapsysAir/base.html.twig' %} +{% block content %} + <section id="form"> + <h2><a href="{{ path('rapsys_user_recover') }}">{% trans %}Recover{% endtrans %}</a></h2> + {% if sent %} + <p>{% trans %}Your password is updated and an account recover message has been sent{% endtrans %}</p> + {% elseif notfound %} + <p>{% trans %}Unable to find account{% endtrans %}</p> + {% else %} + <div> + {{ form_start(form) }} + + <header>{{ form_errors(form) }}</header> + + <section> + {{ form_row(form.password) }} + </section> + + {{ form_row(form.submit) }} + + {# Render CSRF token etc .#} + <footer style="display:none"> + {{ form_rest(form) }} + </footer> + + {{ form_end(form) }} + </div> + {% endif %} + </section> +{% endblock %} diff --git a/Resources/views/form/register.html.twig b/Resources/views/form/register.html.twig new file mode 100644 index 0000000..ca69b5e --- /dev/null +++ b/Resources/views/form/register.html.twig @@ -0,0 +1,42 @@ +{% extends '@RapsysAir/base.html.twig' %} +{% block content %} + <section id="form"> + <h2>{{ title|trans }}</h2> + {% if sent %} + <p>{% trans %}Your account has been created{% endtrans %}</p> + {% else %} + <div> + {{ form_start(form) }} + + <header>{{ form_errors(form) }}</header> + + <section> + {{ form_row(form.mail) }} + + {{ form_row(form.password.first) }} + + {{ form_row(form.password.second) }} + </section> + + <section> + {{ form_row(form.title) }} + + {{ form_row(form.forename) }} + + {{ form_row(form.surname) }} + + {{ form_row(form.pseudonym) }} + </section> + + {{ form_row(form.submit) }} + + {# Render CSRF token etc .#} + <footer style="display:none"> + {{ form_rest(form) }} + </footer> + + {{ form_end(form) }} + </div> + {% endif %} + </section> +{% endblock %} diff --git a/Resources/views/mail/contact.html.twig b/Resources/views/mail/contact.html.twig new file mode 100644 index 0000000..7fe13ff --- /dev/null +++ b/Resources/views/mail/contact.html.twig @@ -0,0 +1,43 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <meta name="viewport" content="width=device-width" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <title>{{ subject }}</title> + <style> + body {background:white;color:#066} + a {text-decoration:none;color:#066} + a:hover {text-decoration:underline} + table {width: 100%;border-radius: .5rem} + table.head {border:.1rem solid #00c3f9;text-align:center} + table.body {background:white;border:.1rem solid #00c3f9;margin:.5rem 0} + table.footer {border:.1rem solid #00c3f9;text-align:center;font-weight:bold} + table.footer summary:after {display:none} + table.footer summary::-webkit-details-marker {display:none} + </style> +</head> +<body> + <table class="head"> + <tr> + <td><a href="{{ url }}"><img src="data:image/png;base64, {{ logo|file_get_contents|base64_encode }}" alt="{{ title|trans }}" /></a></td> + <td><h1><a href="{{ url }}">{{ title|trans }}</a></h1></td> + </tr> + </table> + <table class="body"> + <tr> + <td> </td> + <td> + <h2>{% trans %}Hi,{% endtrans %} {{ contact_name }}</h2> + <h3>{% trans %}Subject:{% endtrans %} {{ subject }}</h3> + <p>{{ message|nl2br }}</p> + </td> + <td> </td> + </tr> + </table> + <table class="footer"> + <tr> + <td>{% trans %}Raphaël Gertz all rights reserved{% endtrans %} - {% trans %}Copyright 2018{% endtrans %}.</td> + </tr> + </table> +</body> +</html> diff --git a/Resources/views/mail/generic.html.twig b/Resources/views/mail/generic.html.twig new file mode 100644 index 0000000..5e6da39 --- /dev/null +++ b/Resources/views/mail/generic.html.twig @@ -0,0 +1,49 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <meta name="viewport" content="width=device-width" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <title>{{ title }}</title> + <style> + body {background:white;color:#066} + a {text-decoration:none;color:#066} + a:hover {text-decoration:underline} + table {width: 100%;border-radius: .5rem} + table.head {border:.1rem solid #00c3f9;text-align:center} + table.body {background:white;border:.1rem solid #00c3f9;margin:.5rem 0} + table.footer {border:.1rem solid #00c3f9;text-align:center;font-weight:bold} + table.footer summary:after {display:none} + table.footer summary::-webkit-details-marker {display:none} + </style> +</head> +<body> + <table class="head"> + <tr> + <td><a href="{{ home }}"><img src="data:image/png;base64, {{ logo|file_get_contents|base64_encode }}" alt="{{ title }}" /></a></td> + <td><h1><a href="{{ home }}">{{ title }}</a></h1></td> + </tr> + </table> + <table class="body"> + <tr> + <td> </td> + <td> + <h2>{{ subtitle }}</h2> + {% if subject %} + <h3>{% trans %}Subject:{% endtrans %} {{ subject }}</h3> + {% endif %} + {% if raw is defined %} + <p>{{ raw|raw }}</p> + {% else %} + <p>{{ message|nl2br }}</p> + {% endif %} + </td> + <td> </td> + </tr> + </table> + <table class="footer"> + <tr> + <td>{% trans %}Raphaël Gertz all rights reserved{% endtrans %} - {% trans %}Copyright 2018{% endtrans %}.</td> + </tr> + </table> +</body> +</html> diff --git a/Resources/views/mail/register.html.twig b/Resources/views/mail/register.html.twig new file mode 100644 index 0000000..8a6c0d3 --- /dev/null +++ b/Resources/views/mail/register.html.twig @@ -0,0 +1,43 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <meta name="viewport" content="width=device-width" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <title>{{ 'Welcome to %title%'|trans({'%title%': title}) }}</title> + <style> + body {background:white;color:#066} + a {text-decoration:none;color:#066} + a:hover {text-decoration:underline} + table {width: 100%;border-radius: .5rem} + table.head {border:.1rem solid #00c3f9;text-align:center} + table.body {background:white;border:.1rem solid #00c3f9;margin:.5rem 0} + table.footer {border:.1rem solid #00c3f9;text-align:center;font-weight:bold} + table.footer summary:after {display:none} + table.footer summary::-webkit-details-marker {display:none} + </style> +</head> +<body> + <table class="head"> + <tr> + <td><a href="{{ url }}"><img src="data:image/png;base64, {{ logo|file_get_contents|base64_encode }}" alt="{{ title|trans }}" /></a></td> + <td><h1><a href="{{ url }}">{{ title|trans }}</a></h1></td> + </tr> + </table> + <table class="body"> + <tr> + <td> </td> + <td> + <h2>{% trans %}Hi,{% endtrans %} {{ contact_name }}</h2> + <h3>{% trans %}Subject:{% endtrans %} {{ 'Welcome to %title%'|trans({'%title%': title|trans}) }}</h3> + <p>{{ 'Thanks so much for joining us, from now you can reserver your %title% spaces.'|trans({'%title%': title|trans}) }}</p> + </td> + <td> </td> + </tr> + </table> + <table class="footer"> + <tr> + <td>{% trans %}Raphaël Gertz all rights reserved{% endtrans %} - {% trans %}Copyright 2018{% endtrans %}.</td> + </tr> + </table> +</body> +</html> diff --git a/Resources/views/page/index.html.twig b/Resources/views/page/index.html.twig new file mode 100644 index 0000000..f0997a7 --- /dev/null +++ b/Resources/views/page/index.html.twig @@ -0,0 +1,7 @@ +{% extends '@RapsysAir/base.html.twig' %} +{% block content %} +<section id="content"> + <h2><a href="{{ path('rapsys_air_homepage') }}">{{ section }}</a></h2> + <p>{% trans %}Outdoor space reservation system{% endtrans %}</p> +</section> +{% endblock %} diff --git a/Tests/Controller/DefaultControllerTest.php b/Tests/Controller/DefaultControllerTest.php new file mode 100644 index 0000000..fed9e42 --- /dev/null +++ b/Tests/Controller/DefaultControllerTest.php @@ -0,0 +1,17 @@ +<?php + +namespace Rapsys\AirBundle\Tests\Controller; + +use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; + +class DefaultControllerTest extends WebTestCase +{ + public function testIndex() + { + $client = static::createClient(); + + $crawler = $client->request('GET', '/'); + + $this->assertContains('Hello World', $client->getResponse()->getContent()); + } +} diff --git a/Twig/Base64Extension.php b/Twig/Base64Extension.php new file mode 100644 index 0000000..8272989 --- /dev/null +++ b/Twig/Base64Extension.php @@ -0,0 +1,12 @@ +<?php +// src/Rapsys/AirBundle/Twig/Base64Extension.php +namespace Rapsys\AirBundle\Twig; + +class Base64Extension extends \Twig_Extension { + public function getFilters() { + return array( + new \Twig_SimpleFilter('base64_encode', 'base64_encode'), + new \Twig_SimpleFilter('base64_decode', 'base64_decode') + ); + } +} diff --git a/Twig/Bb2htmlExtension.php b/Twig/Bb2htmlExtension.php new file mode 100644 index 0000000..a9b3c8e --- /dev/null +++ b/Twig/Bb2htmlExtension.php @@ -0,0 +1,64 @@ +<?php +// src/Rapsys/AirBundle/Twig/Bb2htmlExtension.php +namespace Rapsys\AirBundle\Twig; + +class Bb2htmlExtension extends \Twig_Extension { + public function getFilters() { + return array( + new \Twig\TwigFilter( + 'bb2html', + function($text) { + $ctx = bbcode_create( + array( + '' => array('type' => BBCODE_TYPE_ROOT), + 'code' => array( + 'type' => BBCODE_TYPE_OPTARG, + 'open_tag' => '<pre class="{PARAM}">', + 'close_tag' => '</pre>', + 'default_arg' => '{CONTENT}' + ), + 'ul' => array( + 'type' => BBCODE_TYPE_NOARG, + 'open_tag' => '<ul>', + 'close_tag' => '</ul>', + 'childs' => 'li' + ), + 'li' => array( + 'type' => BBCODE_TYPE_NOARG, + 'open_tag' => '<li>', + 'close_tag' => '</li>', + 'parent' => 'ul', + 'childs' => 'url' + ), + 'url' => array( + 'type' => BBCODE_TYPE_OPTARG, + 'open_tag' => '<a href="{PARAM}">', + 'close_tag' => '</a>', + 'default_arg' => '{CONTENT}', + 'parent' => 'p,li' + ) + ) + ); + $text = nl2br(bbcode_parse($ctx, htmlspecialchars($text))); + if (preg_match_all('#\<pre[^>]*\>(.*?)\</pre\>#s', $text, $matches) && !empty($matches[1])) { + foreach($matches[1] as $string) { + $text = str_replace($string, str_replace('<br />', '', $string), $text); + } + } + if (preg_match_all('#\<ul[^>]*\>(.*?)\</ul\>#s', $text, $matches) && !empty($matches[1])) { + foreach($matches[1] as $string) { + $text = str_replace($string, str_replace('<br />', '', $string), $text); + } + } + $text = preg_replace( + array('#(<br />(\r?\n?))*<pre#s', '#</pre>(<br />(\r?\n?))*#', '#(<br />(\r?\n?))*<ul#s', '#</ul>(<br />(\r?\n?))*#', '#(<br />(\r?\n?)){2,}#'), + array('</p>\2<pre', '</pre>\2<p>', '</p>\2<ul', '</ul>\2<p>', '</p>\2<p>'), + $text + ); + return $text; + }, + array('is_safe' => array('html')) + ) + ); + } +} diff --git a/Twig/FileGetContentsExtension.php b/Twig/FileGetContentsExtension.php new file mode 100644 index 0000000..ac4ab2a --- /dev/null +++ b/Twig/FileGetContentsExtension.php @@ -0,0 +1,11 @@ +<?php +// src/Rapsys/AirBundle/Twig/FileGetContentsExtension.php +namespace Rapsys\AirBundle\Twig; + +class FileGetContentsExtension extends \Twig_Extension { + public function getFilters() { + return array( + new \Twig_SimpleFilter('file_get_contents', 'file_get_contents', array(false, null)) + ); + } +} -- 2.41.3