mirror of
https://gitlab.com/animath/si/plateforme-corres2math.git
synced 2024-12-11 23:26:52 +00:00
Restart the project in Django
This commit is contained in:
parent
f341764d0b
commit
c882d1ac7a
45
.gitignore
vendored
45
.gitignore
vendored
@ -1 +1,44 @@
|
|||||||
.idea/
|
# Byte-compiled / optimized / DLL files
|
||||||
|
dist
|
||||||
|
build
|
||||||
|
__pycache__
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
*.swp
|
||||||
|
*.egg-info
|
||||||
|
_build
|
||||||
|
.tox
|
||||||
|
.coverage
|
||||||
|
coverage
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Jupyter Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
.spyproject
|
||||||
|
|
||||||
|
# Rope project settings
|
||||||
|
.ropeproject
|
||||||
|
|
||||||
|
# PyCharm project settings
|
||||||
|
.idea
|
||||||
|
|
||||||
|
# VSCode project settings
|
||||||
|
.vscode
|
||||||
|
|
||||||
|
# Local data
|
||||||
|
secrets.py
|
||||||
|
*.log
|
||||||
|
media/
|
||||||
|
# Virtualenv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
db.sqlite3
|
||||||
|
|
||||||
|
# Don't git personal data
|
||||||
|
import_olddb/
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
Options +FollowSymlinks
|
|
||||||
Options -Indexes
|
|
||||||
RewriteEngine On
|
|
||||||
RewriteRule ^(.*)$ dispatcher.php?path=$1 [QSA,L]
|
|
52
Dockerfile
52
Dockerfile
@ -1,39 +1,31 @@
|
|||||||
FROM php:7.3-apache as plateforme-builder
|
FROM python:3-alpine
|
||||||
|
|
||||||
# Enabling apache rewrite mod
|
ENV PYTHONUNBUFFERED 1
|
||||||
RUN a2enmod rewrite
|
|
||||||
|
|
||||||
RUN apt clean && apt update && apt upgrade -y
|
# Install LaTeX requirements
|
||||||
|
RUN apk add --no-cache gettext texlive nginx gcc libc-dev libffi-dev postgresql-dev mariadb-connector-c-dev
|
||||||
|
|
||||||
# Install MySQL drivers
|
RUN apk add --no-cache bash
|
||||||
RUN docker-php-ext-install pdo_mysql \
|
|
||||||
&& docker-php-ext-enable pdo_mysql
|
|
||||||
|
|
||||||
# Install zip utilities
|
RUN mkdir /code
|
||||||
RUN apt install -y libzip-dev zip \
|
WORKDIR /code
|
||||||
&& docker-php-ext-configure zip --with-libzip \
|
COPY requirements.txt /code/requirements.txt
|
||||||
&& docker-php-ext-install zip \
|
RUN pip install -r requirements.txt --no-cache-dir
|
||||||
&& docker-php-ext-enable zip
|
|
||||||
|
|
||||||
# Setup locales
|
COPY . /code/
|
||||||
RUN apt install locales locales-all -y && locale-gen fr_FR.UTF-8
|
|
||||||
ENV LANG fr_FR.UTF-8
|
|
||||||
ENV LANGUAGE fr_FR:fr
|
|
||||||
ENV LC_ALL fr_FR.UTF-8
|
|
||||||
|
|
||||||
# Setup timezone
|
# Configure nginx
|
||||||
RUN echo Europe/Paris > /etc/timezone \
|
RUN mkdir /run/nginx
|
||||||
&& ln -sf /usr/share/zoneinfo/Europe/Paris /etc/localtime \
|
RUN ln -sf /dev/stdout /var/log/nginx/access.log && ln -sf /dev/stderr /var/log/nginx/error.log
|
||||||
&& dpkg-reconfigure -f noninteractive tzdata
|
RUN ln -sf /code/nginx_corres2math.conf /etc/nginx/conf.d/corres2math.conf
|
||||||
|
RUN rm /etc/nginx/conf.d/default.conf
|
||||||
|
|
||||||
# Setup mailing
|
RUN cp /code/corres2math.cron /etc/crontabs/corres2math
|
||||||
RUN apt install -yq msmtp ca-certificates
|
|
||||||
COPY setup/msmtprc /etc/msmtprc
|
|
||||||
RUN echo "sendmail_path=msmtp -t" >> /usr/local/etc/php/conf.d/php-sendmail.ini
|
|
||||||
|
|
||||||
# Setting environment
|
# With a bashrc, the shell is better
|
||||||
ENV CORRES2MATH_LOCAL_PATH /var/www/html
|
RUN ln -s /code/.bashrc /root/.bashrc
|
||||||
ENV CORRES2MATH_MAIL_DOMAIN correspondances-maths.fr
|
|
||||||
ENV CORRES2MATH_URL_BASE https://inscription.correspondances-maths.fr
|
|
||||||
|
|
||||||
RUN chmod 0777 /var/www/html
|
ENTRYPOINT ["/code/entrypoint.sh"]
|
||||||
|
EXPOSE 80
|
||||||
|
|
||||||
|
CMD ["./manage.py", "shell_plus", "--ptpython"]
|
||||||
|
64
README.md
Normal file
64
README.md
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
# Plateforme d'inscription des Correspondances des Jeunes Mathématicien·nes
|
||||||
|
|
||||||
|
La plateforme des Correspondances des Jeunes Mathématicien·nes est née pour la seconde édition en 2019 de l'action.
|
||||||
|
D'abord codée en PHP, elle a subi une refonte totale en Python, à l'aide du framework Web [Django](https://www.djangoproject.com/).
|
||||||
|
|
||||||
|
Cette plateforme permet aux participants et encadrants de s'inscrire et de déposer leurs autorisations nécessaires.
|
||||||
|
Ils pourront ensuite déposer leurs solutions et notes de synthèse pour le premier tour en temps voulu. La plateforme
|
||||||
|
offre également un accès pour les organisateurs et les jurys leur permettant de communiquer avec les équipes et de
|
||||||
|
récupérer les documents nécessaires.
|
||||||
|
|
||||||
|
Un wiki plus détaillé arrivera ultérieurement. L'interface organisateur et jury est vouée à être plus poussée.
|
||||||
|
|
||||||
|
L'instance de production est disponible à l'adresse [inscription.correspondances-maths.fr](https://inscription.correspondances-maths.fr).
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Le plus simple pour installer la plateforme est d'utiliser l'image Docker incluse, qui fait tourner un serveur Nginx
|
||||||
|
exposé sur le port 80 avec le serveur Django. Ci-dessous une configuration Docker-Compose, à adapter selon vos besoins :
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
inscription-corres2math:
|
||||||
|
build: ./inscription-corres2math
|
||||||
|
links:
|
||||||
|
- postgres
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
env_file:
|
||||||
|
- ./inscription-corres2math.env
|
||||||
|
volumes:
|
||||||
|
# - ./inscription-corres2math:/code
|
||||||
|
- ./inscription-corres2math/media:/code/media
|
||||||
|
```
|
||||||
|
|
||||||
|
Le volume `/code` n'est à ajouter uniquement en développement, et jamais en production.
|
||||||
|
|
||||||
|
Il faut remplir les variables d'environnement suivantes :
|
||||||
|
|
||||||
|
```env
|
||||||
|
CORRES2MATH_STAGE= # dev ou prod
|
||||||
|
DJANGO_DB_TYPE= # MySQL, PostgreSQL ou SQLite (par défaut)
|
||||||
|
DJANGO_DB_HOST= # Hôte de la base de données
|
||||||
|
DJANGO_DB_NAME= # Nom de la base de données
|
||||||
|
DJANGO_DB_USER= # Utilisateur de la base de données
|
||||||
|
DJANGO_DB_PASSWORD= # Mot de passe pour accéder à la base de données
|
||||||
|
SMTP_HOST= # Hôte SMTP pour l'envoi de mails
|
||||||
|
SMTP_PORT=465 # Port du serveur SMTP
|
||||||
|
SMTP_HOST_USER= # Utilisateur du compte SMTP
|
||||||
|
SMTP_HOST_PASSWORD= # Mot de passe du compte SMTP
|
||||||
|
FROM_EMAIL=contact@correspondances-maths.fr # Nom de l'expéditeur des mails
|
||||||
|
SERVER_EMAIL=contact@correspondances-maths.fr # Adresse e-mail expéditrice
|
||||||
|
```
|
||||||
|
|
||||||
|
Si le type de base de données sélectionné est SQLite, la variable `DJANGO_DB_HOST` sera utilisée en guise de chemin vers
|
||||||
|
le fichier de base de données (par défaut, `db.sqlite3`).
|
||||||
|
|
||||||
|
En développement, il est recommandé d'utiliser SQLite pour des raisons de simplicité. Les paramètres de mail ne seront
|
||||||
|
pas utilisés, et les mails qui doivent être envoyés seront envoyés dans la console.
|
||||||
|
|
||||||
|
En production, il est recommandé de ne pas utiliser SQLite pour des raisons de performances.
|
||||||
|
|
||||||
|
La dernière différence entre le développment et la production est qu'en développement, chaque modification d'un fichier
|
||||||
|
est détectée et le serveur se relance automatiquement dès lors.
|
||||||
|
|
||||||
|
Une fois le site lancé, le premier compte créé sera un compte administrateur.
|
1
apps/api/__init__.py
Normal file
1
apps/api/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
default_app_config = 'api.apps.APIConfig'
|
10
apps/api/apps.py
Normal file
10
apps/api/apps.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
from django.apps import AppConfig
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
|
class APIConfig(AppConfig):
|
||||||
|
"""
|
||||||
|
Manage the inscription through a JSON API.
|
||||||
|
"""
|
||||||
|
name = 'api'
|
||||||
|
verbose_name = _('API')
|
15
apps/api/serializers.py
Normal file
15
apps/api/serializers.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
from django.contrib.auth.models import User
|
||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
class UserSerializer(serializers.ModelSerializer):
|
||||||
|
"""
|
||||||
|
Serialize a User object into JSON.
|
||||||
|
"""
|
||||||
|
class Meta:
|
||||||
|
model = User
|
||||||
|
exclude = (
|
||||||
|
'username',
|
||||||
|
'password',
|
||||||
|
'groups',
|
||||||
|
'user_permissions',
|
||||||
|
)
|
18
apps/api/urls.py
Normal file
18
apps/api/urls.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
from django.conf.urls import url, include
|
||||||
|
from rest_framework import routers
|
||||||
|
|
||||||
|
from .viewsets import UserViewSet
|
||||||
|
|
||||||
|
# Routers provide an easy way of automatically determining the URL conf.
|
||||||
|
# Register each app API router and user viewset
|
||||||
|
router = routers.DefaultRouter()
|
||||||
|
router.register('user', UserViewSet)
|
||||||
|
|
||||||
|
app_name = 'api'
|
||||||
|
|
||||||
|
# Wire up our API using automatic URL routing.
|
||||||
|
# Additionally, we include login URLs for the browsable API.
|
||||||
|
urlpatterns = [
|
||||||
|
url('^', include(router.urls)),
|
||||||
|
url('^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
|
||||||
|
]
|
17
apps/api/viewsets.py
Normal file
17
apps/api/viewsets.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
from django.contrib.auth.models import User
|
||||||
|
from django_filters.rest_framework import DjangoFilterBackend
|
||||||
|
from rest_framework.filters import SearchFilter
|
||||||
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
|
from .serializers import UserSerializer
|
||||||
|
|
||||||
|
|
||||||
|
class UserViewSet(ModelViewSet):
|
||||||
|
"""
|
||||||
|
Display list of users.
|
||||||
|
"""
|
||||||
|
queryset = User.objects.all()
|
||||||
|
serializer_class = UserSerializer
|
||||||
|
filter_backends = [DjangoFilterBackend, SearchFilter]
|
||||||
|
filterset_fields = ['id', 'first_name', 'last_name', 'email', 'is_superuser', 'is_staff', 'is_active', ]
|
||||||
|
search_fields = ['$first_name', '$last_name', ]
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 8.6 KiB |
@ -1,47 +0,0 @@
|
|||||||
html, body {
|
|
||||||
height: 100%;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
:root {
|
|
||||||
--navbar-height: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
|
||||||
min-height: 78%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inner {
|
|
||||||
margin: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.alert {
|
|
||||||
text-align: justify;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
footer .alert {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#navbar-logo {
|
|
||||||
height: var(--navbar-height);
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul .deroule {
|
|
||||||
display: none;
|
|
||||||
position: absolute;
|
|
||||||
background: #f8f9fa !important;
|
|
||||||
list-style-type: none;
|
|
||||||
padding: 20px;
|
|
||||||
z-index: 42;
|
|
||||||
}
|
|
||||||
|
|
||||||
li:hover ul.deroule {
|
|
||||||
display:block;
|
|
||||||
}
|
|
||||||
|
|
||||||
a.nav-link:hover {
|
|
||||||
background-color: #d8d9da;
|
|
||||||
}
|
|
5
corres2math.cron
Normal file
5
corres2math.cron
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# m h dom mon dow user command
|
||||||
|
# Envoyer les mails en attente
|
||||||
|
* * * * * root cd /code && python manage.py send_mail -c 1
|
||||||
|
* * * * * root cd /code && python manage.py retry_deferred -c 1
|
||||||
|
00 0 * * * root cd /code && python manage.py purge_mail_log 7 -c 1
|
0
corres2math/__init__.py
Normal file
0
corres2math/__init__.py
Normal file
16
corres2math/asgi.py
Normal file
16
corres2math/asgi.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
"""
|
||||||
|
ASGI config for corres2math project.
|
||||||
|
|
||||||
|
It exposes the ASGI callable as a module-level variable named ``application``.
|
||||||
|
|
||||||
|
For more information on this file, see
|
||||||
|
https://docs.djangoproject.com/en/3.0/howto/deployment/asgi/
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from django.core.asgi import get_asgi_application
|
||||||
|
|
||||||
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'corres2math.settings')
|
||||||
|
|
||||||
|
application = get_asgi_application()
|
322
corres2math/inputs.py
Normal file
322
corres2math/inputs.py
Normal file
@ -0,0 +1,322 @@
|
|||||||
|
from json import dumps as json_dumps
|
||||||
|
|
||||||
|
from django.forms.widgets import DateTimeBaseInput, NumberInput, TextInput, Widget
|
||||||
|
|
||||||
|
|
||||||
|
class AmountInput(NumberInput):
|
||||||
|
"""
|
||||||
|
This input type lets the user type amounts in euros, but forms receive data in cents
|
||||||
|
"""
|
||||||
|
template_name = "amount_input.html"
|
||||||
|
|
||||||
|
def format_value(self, value):
|
||||||
|
return None if value is None or value == "" else "{:.02f}".format(int(value) / 100, )
|
||||||
|
|
||||||
|
def value_from_datadict(self, data, files, name):
|
||||||
|
val = super().value_from_datadict(data, files, name)
|
||||||
|
return str(int(100 * float(val))) if val else val
|
||||||
|
|
||||||
|
|
||||||
|
class Autocomplete(TextInput):
|
||||||
|
template_name = "autocomplete_model.html"
|
||||||
|
|
||||||
|
def __init__(self, model, attrs=None):
|
||||||
|
super().__init__(attrs)
|
||||||
|
|
||||||
|
self.model = model
|
||||||
|
self.model_pk = None
|
||||||
|
|
||||||
|
class Media:
|
||||||
|
"""JS/CSS resources needed to render the date-picker calendar."""
|
||||||
|
|
||||||
|
js = ('js/autocomplete_model.js', )
|
||||||
|
|
||||||
|
def format_value(self, value):
|
||||||
|
if value:
|
||||||
|
self.attrs["model_pk"] = int(value)
|
||||||
|
return str(self.model.objects.get(pk=int(value)))
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
class ColorWidget(Widget):
|
||||||
|
"""
|
||||||
|
Pulled from django-colorfield.
|
||||||
|
Select a color.
|
||||||
|
"""
|
||||||
|
template_name = 'colorfield/color.html'
|
||||||
|
|
||||||
|
class Media:
|
||||||
|
js = [
|
||||||
|
'colorfield/jscolor/jscolor.min.js',
|
||||||
|
'colorfield/colorfield.js',
|
||||||
|
]
|
||||||
|
|
||||||
|
def format_value(self, value):
|
||||||
|
if value is None:
|
||||||
|
value = 0xFFFFFF
|
||||||
|
return "#{:06X}".format(value)
|
||||||
|
|
||||||
|
def value_from_datadict(self, data, files, name):
|
||||||
|
val = super().value_from_datadict(data, files, name)
|
||||||
|
return int(val[1:], 16)
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
The remaining of this file comes from the project `django-bootstrap-datepicker-plus` available on Github:
|
||||||
|
https://github.com/monim67/django-bootstrap-datepicker-plus
|
||||||
|
This is distributed under Apache License 2.0.
|
||||||
|
|
||||||
|
This adds datetime pickers with bootstrap.
|
||||||
|
"""
|
||||||
|
|
||||||
|
"""Contains Base Date-Picker input class for widgets of this package."""
|
||||||
|
|
||||||
|
|
||||||
|
class DatePickerDictionary:
|
||||||
|
"""Keeps track of all date-picker input classes."""
|
||||||
|
|
||||||
|
_i = 0
|
||||||
|
items = dict()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def generate_id(cls):
|
||||||
|
"""Return a unique ID for each date-picker input class."""
|
||||||
|
cls._i += 1
|
||||||
|
return 'dp_%s' % cls._i
|
||||||
|
|
||||||
|
|
||||||
|
class BasePickerInput(DateTimeBaseInput):
|
||||||
|
"""Base Date-Picker input class for widgets of this package."""
|
||||||
|
|
||||||
|
template_name = 'bootstrap_datepicker_plus/date_picker.html'
|
||||||
|
picker_type = 'DATE'
|
||||||
|
format = '%Y-%m-%d'
|
||||||
|
config = {}
|
||||||
|
_default_config = {
|
||||||
|
'id': None,
|
||||||
|
'picker_type': None,
|
||||||
|
'linked_to': None,
|
||||||
|
'options': {} # final merged options
|
||||||
|
}
|
||||||
|
options = {} # options extended by user
|
||||||
|
options_param = {} # options passed as parameter
|
||||||
|
_default_options = {
|
||||||
|
'showClose': True,
|
||||||
|
'showClear': True,
|
||||||
|
'showTodayButton': True,
|
||||||
|
"locale": "fr",
|
||||||
|
}
|
||||||
|
|
||||||
|
# source: https://github.com/tutorcruncher/django-bootstrap3-datetimepicker
|
||||||
|
# file: /blob/31fbb09/bootstrap3_datetime/widgets.py#L33
|
||||||
|
format_map = (
|
||||||
|
('DDD', r'%j'),
|
||||||
|
('DD', r'%d'),
|
||||||
|
('MMMM', r'%B'),
|
||||||
|
('MMM', r'%b'),
|
||||||
|
('MM', r'%m'),
|
||||||
|
('YYYY', r'%Y'),
|
||||||
|
('YY', r'%y'),
|
||||||
|
('HH', r'%H'),
|
||||||
|
('hh', r'%I'),
|
||||||
|
('mm', r'%M'),
|
||||||
|
('ss', r'%S'),
|
||||||
|
('a', r'%p'),
|
||||||
|
('ZZ', r'%z'),
|
||||||
|
)
|
||||||
|
|
||||||
|
class Media:
|
||||||
|
"""JS/CSS resources needed to render the date-picker calendar."""
|
||||||
|
|
||||||
|
js = (
|
||||||
|
'https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.9.0/'
|
||||||
|
'moment-with-locales.min.js',
|
||||||
|
'https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/'
|
||||||
|
'4.17.47/js/bootstrap-datetimepicker.min.js',
|
||||||
|
'bootstrap_datepicker_plus/js/datepicker-widget.js'
|
||||||
|
)
|
||||||
|
css = {'all': (
|
||||||
|
'https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/'
|
||||||
|
'4.17.47/css/bootstrap-datetimepicker.css',
|
||||||
|
'bootstrap_datepicker_plus/css/datepicker-widget.css'
|
||||||
|
), }
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def format_py2js(cls, datetime_format):
|
||||||
|
"""Convert python datetime format to moment datetime format."""
|
||||||
|
for js_format, py_format in cls.format_map:
|
||||||
|
datetime_format = datetime_format.replace(py_format, js_format)
|
||||||
|
return datetime_format
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def format_js2py(cls, datetime_format):
|
||||||
|
"""Convert moment datetime format to python datetime format."""
|
||||||
|
for js_format, py_format in cls.format_map:
|
||||||
|
datetime_format = datetime_format.replace(js_format, py_format)
|
||||||
|
return datetime_format
|
||||||
|
|
||||||
|
def __init__(self, attrs=None, format=None, options=None):
|
||||||
|
"""Initialize the Date-picker widget."""
|
||||||
|
self.format_param = format
|
||||||
|
self.options_param = options if options else {}
|
||||||
|
self.config = self._default_config.copy()
|
||||||
|
self.config['id'] = DatePickerDictionary.generate_id()
|
||||||
|
self.config['picker_type'] = self.picker_type
|
||||||
|
self.config['options'] = self._calculate_options()
|
||||||
|
attrs = attrs if attrs else {}
|
||||||
|
if 'class' not in attrs:
|
||||||
|
attrs['class'] = 'form-control'
|
||||||
|
super().__init__(attrs, self._calculate_format())
|
||||||
|
|
||||||
|
def _calculate_options(self):
|
||||||
|
"""Calculate and Return the options."""
|
||||||
|
_options = self._default_options.copy()
|
||||||
|
_options.update(self.options)
|
||||||
|
if self.options_param:
|
||||||
|
_options.update(self.options_param)
|
||||||
|
return _options
|
||||||
|
|
||||||
|
def _calculate_format(self):
|
||||||
|
"""Calculate and Return the datetime format."""
|
||||||
|
_format = self.format_param if self.format_param else self.format
|
||||||
|
if self.config['options'].get('format'):
|
||||||
|
_format = self.format_js2py(self.config['options'].get('format'))
|
||||||
|
else:
|
||||||
|
self.config['options']['format'] = self.format_py2js(_format)
|
||||||
|
return _format
|
||||||
|
|
||||||
|
def get_context(self, name, value, attrs):
|
||||||
|
"""Return widget context dictionary."""
|
||||||
|
context = super().get_context(
|
||||||
|
name, value, attrs)
|
||||||
|
context['widget']['attrs']['dp_config'] = json_dumps(self.config)
|
||||||
|
return context
|
||||||
|
|
||||||
|
def start_of(self, event_id):
|
||||||
|
"""
|
||||||
|
Set Date-Picker as the start-date of a date-range.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
- event_id (string): User-defined unique id for linking two fields
|
||||||
|
"""
|
||||||
|
DatePickerDictionary.items[str(event_id)] = self
|
||||||
|
return self
|
||||||
|
|
||||||
|
def end_of(self, event_id, import_options=True):
|
||||||
|
"""
|
||||||
|
Set Date-Picker as the end-date of a date-range.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
- event_id (string): User-defined unique id for linking two fields
|
||||||
|
- import_options (bool): inherit options from start-date input,
|
||||||
|
default: TRUE
|
||||||
|
"""
|
||||||
|
event_id = str(event_id)
|
||||||
|
if event_id in DatePickerDictionary.items:
|
||||||
|
linked_picker = DatePickerDictionary.items[event_id]
|
||||||
|
self.config['linked_to'] = linked_picker.config['id']
|
||||||
|
if import_options:
|
||||||
|
backup_moment_format = self.config['options']['format']
|
||||||
|
self.config['options'].update(linked_picker.config['options'])
|
||||||
|
self.config['options'].update(self.options_param)
|
||||||
|
if self.format_param or 'format' in self.options_param:
|
||||||
|
self.config['options']['format'] = backup_moment_format
|
||||||
|
else:
|
||||||
|
self.format = linked_picker.format
|
||||||
|
# Setting useCurrent is necessary, see following issue
|
||||||
|
# https://github.com/Eonasdan/bootstrap-datetimepicker/issues/1075
|
||||||
|
self.config['options']['useCurrent'] = False
|
||||||
|
self._link_to(linked_picker)
|
||||||
|
else:
|
||||||
|
raise KeyError(
|
||||||
|
'start-date not specified for event_id "%s"' % event_id)
|
||||||
|
return self
|
||||||
|
|
||||||
|
def _link_to(self, linked_picker):
|
||||||
|
"""
|
||||||
|
Executed when two date-inputs are linked together.
|
||||||
|
|
||||||
|
This method for sub-classes to override to customize the linking.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class DatePickerInput(BasePickerInput):
|
||||||
|
"""
|
||||||
|
Widget to display a Date-Picker Calendar on a DateField property.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
- attrs (dict): HTML attributes of rendered HTML input
|
||||||
|
- format (string): Python DateTime format eg. "%Y-%m-%d"
|
||||||
|
- options (dict): Options to customize the widget, see README
|
||||||
|
"""
|
||||||
|
|
||||||
|
picker_type = 'DATE'
|
||||||
|
format = '%Y-%m-%d'
|
||||||
|
format_key = 'DATE_INPUT_FORMATS'
|
||||||
|
|
||||||
|
|
||||||
|
class TimePickerInput(BasePickerInput):
|
||||||
|
"""
|
||||||
|
Widget to display a Time-Picker Calendar on a TimeField property.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
- attrs (dict): HTML attributes of rendered HTML input
|
||||||
|
- format (string): Python DateTime format eg. "%Y-%m-%d"
|
||||||
|
- options (dict): Options to customize the widget, see README
|
||||||
|
"""
|
||||||
|
|
||||||
|
picker_type = 'TIME'
|
||||||
|
format = '%H:%M'
|
||||||
|
format_key = 'TIME_INPUT_FORMATS'
|
||||||
|
template_name = 'bootstrap_datepicker_plus/time_picker.html'
|
||||||
|
|
||||||
|
|
||||||
|
class DateTimePickerInput(BasePickerInput):
|
||||||
|
"""
|
||||||
|
Widget to display a DateTime-Picker Calendar on a DateTimeField property.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
- attrs (dict): HTML attributes of rendered HTML input
|
||||||
|
- format (string): Python DateTime format eg. "%Y-%m-%d"
|
||||||
|
- options (dict): Options to customize the widget, see README
|
||||||
|
"""
|
||||||
|
|
||||||
|
picker_type = 'DATETIME'
|
||||||
|
format = '%Y-%m-%d %H:%M'
|
||||||
|
format_key = 'DATETIME_INPUT_FORMATS'
|
||||||
|
|
||||||
|
|
||||||
|
class MonthPickerInput(BasePickerInput):
|
||||||
|
"""
|
||||||
|
Widget to display a Month-Picker Calendar on a DateField property.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
- attrs (dict): HTML attributes of rendered HTML input
|
||||||
|
- format (string): Python DateTime format eg. "%Y-%m-%d"
|
||||||
|
- options (dict): Options to customize the widget, see README
|
||||||
|
"""
|
||||||
|
|
||||||
|
picker_type = 'MONTH'
|
||||||
|
format = '01/%m/%Y'
|
||||||
|
format_key = 'DATE_INPUT_FORMATS'
|
||||||
|
|
||||||
|
|
||||||
|
class YearPickerInput(BasePickerInput):
|
||||||
|
"""
|
||||||
|
Widget to display a Year-Picker Calendar on a DateField property.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
- attrs (dict): HTML attributes of rendered HTML input
|
||||||
|
- format (string): Python DateTime format eg. "%Y-%m-%d"
|
||||||
|
- options (dict): Options to customize the widget, see README
|
||||||
|
"""
|
||||||
|
|
||||||
|
picker_type = 'YEAR'
|
||||||
|
format = '01/01/%Y'
|
||||||
|
format_key = 'DATE_INPUT_FORMATS'
|
||||||
|
|
||||||
|
def _link_to(self, linked_picker):
|
||||||
|
"""Customize the options when linked with other date-time input"""
|
||||||
|
yformat = self.config['options']['format'].replace('-01-01', '-12-31')
|
||||||
|
self.config['options']['format'] = yformat
|
93
corres2math/middlewares.py
Normal file
93
corres2math/middlewares.py
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
from django.conf import settings
|
||||||
|
from django.contrib.auth.models import AnonymousUser, User
|
||||||
|
|
||||||
|
from threading import local
|
||||||
|
|
||||||
|
from django.contrib.sessions.backends.db import SessionStore
|
||||||
|
|
||||||
|
USER_ATTR_NAME = getattr(settings, 'LOCAL_USER_ATTR_NAME', '_current_user')
|
||||||
|
SESSION_ATTR_NAME = getattr(settings, 'LOCAL_SESSION_ATTR_NAME', '_current_session')
|
||||||
|
IP_ATTR_NAME = getattr(settings, 'LOCAL_IP_ATTR_NAME', '_current_ip')
|
||||||
|
|
||||||
|
_thread_locals = local()
|
||||||
|
|
||||||
|
|
||||||
|
def _set_current_user_and_ip(user=None, session=None, ip=None):
|
||||||
|
setattr(_thread_locals, USER_ATTR_NAME, user)
|
||||||
|
setattr(_thread_locals, SESSION_ATTR_NAME, session)
|
||||||
|
setattr(_thread_locals, IP_ATTR_NAME, ip)
|
||||||
|
|
||||||
|
|
||||||
|
def get_current_user() -> User:
|
||||||
|
return getattr(_thread_locals, USER_ATTR_NAME, None)
|
||||||
|
|
||||||
|
|
||||||
|
def get_current_session() -> SessionStore:
|
||||||
|
return getattr(_thread_locals, SESSION_ATTR_NAME, None)
|
||||||
|
|
||||||
|
|
||||||
|
def get_current_ip() -> str:
|
||||||
|
return getattr(_thread_locals, IP_ATTR_NAME, None)
|
||||||
|
|
||||||
|
|
||||||
|
def get_current_authenticated_user():
|
||||||
|
current_user = get_current_user()
|
||||||
|
if isinstance(current_user, AnonymousUser):
|
||||||
|
return None
|
||||||
|
return current_user
|
||||||
|
|
||||||
|
|
||||||
|
class SessionMiddleware(object):
|
||||||
|
"""
|
||||||
|
This middleware get the current user with his or her IP address on each request.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, get_response):
|
||||||
|
self.get_response = get_response
|
||||||
|
|
||||||
|
def __call__(self, request):
|
||||||
|
if "_fake_user_id" in request.session:
|
||||||
|
request.user = User.objects.get(pk=request.session["_fake_user_id"])
|
||||||
|
|
||||||
|
user = request.user
|
||||||
|
if 'HTTP_X_FORWARDED_FOR' in request.META:
|
||||||
|
ip = request.META.get('HTTP_X_FORWARDED_FOR')
|
||||||
|
else:
|
||||||
|
ip = request.META.get('REMOTE_ADDR')
|
||||||
|
|
||||||
|
_set_current_user_and_ip(user, request.session, ip)
|
||||||
|
response = self.get_response(request)
|
||||||
|
_set_current_user_and_ip(None, None, None)
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
class TurbolinksMiddleware(object):
|
||||||
|
"""
|
||||||
|
Send the `Turbolinks-Location` header in response to a visit that was redirected,
|
||||||
|
and Turbolinks will replace the browser's topmost history entry.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, get_response):
|
||||||
|
self.get_response = get_response
|
||||||
|
|
||||||
|
def __call__(self, request):
|
||||||
|
response = self.get_response(request)
|
||||||
|
|
||||||
|
is_turbolinks = request.META.get('HTTP_TURBOLINKS_REFERRER')
|
||||||
|
is_response_redirect = response.has_header('Location')
|
||||||
|
|
||||||
|
if is_turbolinks:
|
||||||
|
if is_response_redirect:
|
||||||
|
location = response['Location']
|
||||||
|
prev_location = request.session.pop('_turbolinks_redirect_to', None)
|
||||||
|
if prev_location is not None:
|
||||||
|
# relative subsequent redirect
|
||||||
|
if location.startswith('.'):
|
||||||
|
location = prev_location.split('?')[0] + location
|
||||||
|
request.session['_turbolinks_redirect_to'] = location
|
||||||
|
else:
|
||||||
|
if request.session.get('_turbolinks_redirect_to'):
|
||||||
|
location = request.session.pop('_turbolinks_redirect_to')
|
||||||
|
response['Turbolinks-Location'] = location
|
||||||
|
return response
|
202
corres2math/settings.py
Normal file
202
corres2math/settings.py
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
"""
|
||||||
|
Django settings for corres2math project.
|
||||||
|
|
||||||
|
Generated by 'django-admin startproject' using Django 3.0.5.
|
||||||
|
|
||||||
|
For more information on this file, see
|
||||||
|
https://docs.djangoproject.com/en/3.0/topics/settings/
|
||||||
|
|
||||||
|
For the full list of settings and their values, see
|
||||||
|
https://docs.djangoproject.com/en/3.0/ref/settings/
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||||
|
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
PROJECT_DIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
|
||||||
|
APPS_DIR = os.path.realpath(os.path.join(BASE_DIR, "apps"))
|
||||||
|
sys.path.append(APPS_DIR)
|
||||||
|
|
||||||
|
ADMINS = [("Yohann D'ANELLO", "yohann.danello@animath.fr")]
|
||||||
|
|
||||||
|
|
||||||
|
# Quick-start development settings - unsuitable for production
|
||||||
|
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/
|
||||||
|
|
||||||
|
# SECURITY WARNING: keep the secret key used in production secret!
|
||||||
|
SECRET_KEY = '6$wl1=ehfoiymin3m3i-wyx5d3t=1h7g4(j2izn*my)*yiq#he'
|
||||||
|
|
||||||
|
# SECURITY WARNING: don't run with debug turned on in production!
|
||||||
|
DEBUG = True
|
||||||
|
|
||||||
|
SITE_ID = 1
|
||||||
|
|
||||||
|
ALLOWED_HOSTS = ['*']
|
||||||
|
|
||||||
|
|
||||||
|
# Application definition
|
||||||
|
|
||||||
|
INSTALLED_APPS = [
|
||||||
|
'django.contrib.admin',
|
||||||
|
'django.contrib.auth',
|
||||||
|
'django.contrib.contenttypes',
|
||||||
|
'django.contrib.sessions',
|
||||||
|
'django.contrib.sites',
|
||||||
|
'django.contrib.messages',
|
||||||
|
'django.contrib.staticfiles',
|
||||||
|
'django.forms',
|
||||||
|
|
||||||
|
'bootstrap_datepicker_plus',
|
||||||
|
'crispy_forms',
|
||||||
|
'django_extensions',
|
||||||
|
'django_tables2',
|
||||||
|
'mailer',
|
||||||
|
'polymorphic',
|
||||||
|
'rest_framework',
|
||||||
|
'rest_framework.authtoken',
|
||||||
|
]
|
||||||
|
|
||||||
|
MIDDLEWARE = [
|
||||||
|
'django.middleware.security.SecurityMiddleware',
|
||||||
|
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||||
|
'django.middleware.common.CommonMiddleware',
|
||||||
|
'django.middleware.csrf.CsrfViewMiddleware',
|
||||||
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||||
|
'django.contrib.messages.middleware.MessageMiddleware',
|
||||||
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||||
|
'django.middleware.locale.LocaleMiddleware',
|
||||||
|
'django.contrib.sites.middleware.CurrentSiteMiddleware',
|
||||||
|
'corres2math.middlewares.SessionMiddleware',
|
||||||
|
'corres2math.middlewares.TurbolinksMiddleware',
|
||||||
|
]
|
||||||
|
|
||||||
|
ROOT_URLCONF = 'corres2math.urls'
|
||||||
|
|
||||||
|
LOGIN_REDIRECT_URL = "index"
|
||||||
|
|
||||||
|
TEMPLATES = [
|
||||||
|
{
|
||||||
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||||
|
'DIRS': [os.path.join(BASE_DIR, 'templates')]
|
||||||
|
,
|
||||||
|
'APP_DIRS': True,
|
||||||
|
'OPTIONS': {
|
||||||
|
'context_processors': [
|
||||||
|
'django.template.context_processors.debug',
|
||||||
|
'django.template.context_processors.request',
|
||||||
|
'django.contrib.auth.context_processors.auth',
|
||||||
|
'django.contrib.messages.context_processors.messages',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
FORM_RENDERER = 'django.forms.renderers.TemplatesSetting'
|
||||||
|
|
||||||
|
WSGI_APPLICATION = 'corres2math.wsgi.application'
|
||||||
|
|
||||||
|
|
||||||
|
# Password validation
|
||||||
|
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators
|
||||||
|
|
||||||
|
AUTH_PASSWORD_VALIDATORS = [
|
||||||
|
{
|
||||||
|
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
PASSWORD_HASHERS = [
|
||||||
|
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
|
||||||
|
'django.contrib.auth.hashers.BCryptPasswordHasher',
|
||||||
|
]
|
||||||
|
|
||||||
|
REST_FRAMEWORK = {
|
||||||
|
'DEFAULT_PERMISSION_CLASSES': [
|
||||||
|
'rest_framework.permissions.IsAdminUser'
|
||||||
|
],
|
||||||
|
'DEFAULT_AUTHENTICATION_CLASSES': [
|
||||||
|
'rest_framework.authentication.SessionAuthentication',
|
||||||
|
'rest_framework.authentication.TokenAuthentication',
|
||||||
|
],
|
||||||
|
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
|
||||||
|
'PAGE_SIZE': 50,
|
||||||
|
}
|
||||||
|
|
||||||
|
# Internationalization
|
||||||
|
# https://docs.djangoproject.com/en/3.0/topics/i18n/
|
||||||
|
|
||||||
|
LANGUAGE_CODE = 'en'
|
||||||
|
|
||||||
|
LANGUAGES = [
|
||||||
|
('en', _('English')),
|
||||||
|
('fr', _('French')),
|
||||||
|
]
|
||||||
|
|
||||||
|
TIME_ZONE = 'Europe/Paris'
|
||||||
|
|
||||||
|
USE_I18N = True
|
||||||
|
|
||||||
|
USE_L10N = True
|
||||||
|
|
||||||
|
USE_TZ = True
|
||||||
|
|
||||||
|
LOCALE_PATHS = [os.path.join(BASE_DIR, "locale")]
|
||||||
|
|
||||||
|
|
||||||
|
# Static files (CSS, JavaScript, Images)
|
||||||
|
# https://docs.djangoproject.com/en/3.0/howto/static-files/
|
||||||
|
|
||||||
|
STATIC_URL = '/static/'
|
||||||
|
|
||||||
|
STATICFILES_DIRS = [
|
||||||
|
os.path.join(BASE_DIR, "corres2math/static"),
|
||||||
|
]
|
||||||
|
|
||||||
|
STATIC_ROOT = os.path.join(BASE_DIR, "static")
|
||||||
|
|
||||||
|
MEDIA_URL = '/media/'
|
||||||
|
|
||||||
|
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
|
||||||
|
|
||||||
|
CRISPY_TEMPLATE_PACK = 'bootstrap4'
|
||||||
|
|
||||||
|
DJANGO_TABLES2_TEMPLATE = 'django_tables2/bootstrap4.html'
|
||||||
|
|
||||||
|
_db_type = os.getenv('DJANGO_DB_TYPE', 'sqlite').lower()
|
||||||
|
|
||||||
|
if _db_type == 'mysql' or _db_type.startswith('postgres') or _db_type == 'psql':
|
||||||
|
DATABASES = {
|
||||||
|
'default': {
|
||||||
|
'ENGINE': 'django.db.backends.mysql' if _db_type == 'mysql' else 'django.db.backends.postgresql_psycopg2',
|
||||||
|
'NAME': os.environ.get('DJANGO_DB_NAME', 'corres2math'),
|
||||||
|
'USER': os.environ.get('DJANGO_DB_USER', 'corres2math'),
|
||||||
|
'PASSWORD': os.environ.get('DJANGO_DB_PASSWORD', 'CHANGE_ME_IN_ENV_SETTINGS'),
|
||||||
|
'HOST': os.environ.get('DJANGO_DB_HOST', 'localhost'),
|
||||||
|
'PORT': os.environ.get('DJANGO_DB_PORT', ''), # Use default port
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
DATABASES = {
|
||||||
|
'default': {
|
||||||
|
'ENGINE': 'django.db.backends.sqlite3',
|
||||||
|
'NAME': os.path.join(BASE_DIR, os.getenv('DJANGO_DB_HOST', 'db.sqlite3')),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if os.getenv("CORRES2MATH_STAGE", "dev") == "prod":
|
||||||
|
from .settings_prod import *
|
||||||
|
else:
|
||||||
|
from .settings_dev import *
|
5
corres2math/settings_dev.py
Normal file
5
corres2math/settings_dev.py
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Database
|
||||||
|
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
|
||||||
|
|
||||||
|
EMAIL_BACKEND = 'mailer.backend.DbBackend'
|
||||||
|
MAILER_EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
30
corres2math/settings_prod.py
Normal file
30
corres2math/settings_prod.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
# Break it, fix it!
|
||||||
|
DEBUG = False
|
||||||
|
|
||||||
|
# Mandatory !
|
||||||
|
ALLOWED_HOSTS = ['inscription.correspondances-maths.fr', 'plateforme.correspondances-maths.fr']
|
||||||
|
|
||||||
|
SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY', 'CHANGE_ME_IN_ENV_SETTINGS')
|
||||||
|
|
||||||
|
# Emails
|
||||||
|
EMAIL_BACKEND = 'mailer.backend.DbBackend'
|
||||||
|
MAILER_EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
||||||
|
EMAIL_USE_SSL = True
|
||||||
|
EMAIL_HOST = os.getenv("SMTP_HOST")
|
||||||
|
EMAIL_PORT = os.getenv("SMTP_PORT")
|
||||||
|
EMAIL_HOST_USER = os.getenv("SMTP_HOST_USER")
|
||||||
|
EMAIL_HOST_PASSWORD = os.getenv("SMTP_HOST_PASSWORD")
|
||||||
|
|
||||||
|
DEFAULT_FROM_EMAIL = os.getenv('FROM_EMAIL', 'Contact Correspondances <contact@correspondances-maths.fr>')
|
||||||
|
SERVER_EMAIL = os.getenv('SERVER_EMAIL', 'contact@correspondances-maths.fr')
|
||||||
|
|
||||||
|
# Security settings
|
||||||
|
SECURE_CONTENT_TYPE_NOSNIFF = False
|
||||||
|
SECURE_BROWSER_XSS_FILTER = False
|
||||||
|
SESSION_COOKIE_SECURE = False
|
||||||
|
CSRF_COOKIE_SECURE = False
|
||||||
|
CSRF_COOKIE_HTTPONLY = False
|
||||||
|
X_FRAME_OPTIONS = 'DENY'
|
||||||
|
SESSION_COOKIE_AGE = 60 * 60 * 3
|
BIN
corres2math/static/favicon.ico
Normal file
BIN
corres2math/static/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.1 KiB |
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
35
corres2math/urls.py
Normal file
35
corres2math/urls.py
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
"""corres2math URL Configuration
|
||||||
|
|
||||||
|
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||||
|
https://docs.djangoproject.com/en/3.0/topics/http/urls/
|
||||||
|
Examples:
|
||||||
|
Function views
|
||||||
|
1. Add an import: from my_app import views
|
||||||
|
2. Add a URL to urlpatterns: path('', views.home, name='home')
|
||||||
|
Class-based views
|
||||||
|
1. Add an import: from other_app.views import Home
|
||||||
|
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
|
||||||
|
Including another URLconf
|
||||||
|
1. Import the include() function: from django.urls import include, path
|
||||||
|
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||||
|
"""
|
||||||
|
|
||||||
|
from django.contrib import admin
|
||||||
|
from django.urls import path, include
|
||||||
|
from django.views.defaults import bad_request, permission_denied, page_not_found, server_error
|
||||||
|
from django.views.generic import TemplateView
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path('', TemplateView.as_view(template_name="index.html"), name='index'),
|
||||||
|
path('i18n/', include('django.conf.urls.i18n')),
|
||||||
|
path('admin/doc/', include('django.contrib.admindocs.urls')),
|
||||||
|
path('admin/', admin.site.urls, name="admin"),
|
||||||
|
path('accounts/', include('django.contrib.auth.urls')),
|
||||||
|
|
||||||
|
path('api/', include('api.urls')),
|
||||||
|
]
|
||||||
|
|
||||||
|
handler400 = bad_request
|
||||||
|
handler403 = permission_denied
|
||||||
|
handler404 = page_not_found
|
||||||
|
handler500 = server_error
|
16
corres2math/wsgi.py
Normal file
16
corres2math/wsgi.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
"""
|
||||||
|
WSGI config for corres2math project.
|
||||||
|
|
||||||
|
It exposes the WSGI callable as a module-level variable named ``application``.
|
||||||
|
|
||||||
|
For more information on this file, see
|
||||||
|
https://docs.djangoproject.com/en/3.0/howto/deployment/wsgi/
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from django.core.wsgi import get_wsgi_application
|
||||||
|
|
||||||
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'corres2math.settings')
|
||||||
|
|
||||||
|
application = get_wsgi_application()
|
@ -1,95 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require_once "server_files/config.php";
|
|
||||||
|
|
||||||
require_once "server_files/classes/Document.php";
|
|
||||||
require_once "server_files/classes/Phase.php";
|
|
||||||
require_once "server_files/classes/Question.php";
|
|
||||||
require_once "server_files/classes/Reason.php";
|
|
||||||
require_once "server_files/classes/Role.php";
|
|
||||||
require_once "server_files/classes/SchoolClass.php";
|
|
||||||
require_once "server_files/classes/Team.php";
|
|
||||||
require_once "server_files/classes/User.php";
|
|
||||||
require_once "server_files/classes/ValidationStatus.php";
|
|
||||||
require_once "server_files/classes/Video.php";
|
|
||||||
require_once "server_files/services/mail.php";
|
|
||||||
require_once "server_files/utils.php";
|
|
||||||
require_once "server_files/model.php";
|
|
||||||
|
|
||||||
loadUserValues();
|
|
||||||
|
|
||||||
if (!isset($_GET["path"]))
|
|
||||||
require_once "server_files/403.php";
|
|
||||||
|
|
||||||
$path = $_GET["path"];
|
|
||||||
|
|
||||||
$ROUTES = [];
|
|
||||||
|
|
||||||
# URL paths
|
|
||||||
|
|
||||||
$ROUTES["^(|accueil|index|accueil\.php|accueil\.html|accueil\.py|index\.php|index\.html|index\.py)/?$"] = ["server_files/controllers/index.php"];
|
|
||||||
$ROUTES["^(modifier-page)$"] = ["server_files/controllers/index.php", "edit"];
|
|
||||||
$ROUTES["^admins$"] = ["server_files/controllers/admins.php"];
|
|
||||||
$ROUTES["^ajouter-equipe$"] = ["server_files/controllers/ajouter_equipe.php"];
|
|
||||||
$ROUTES["^ajouter-admin$"] = ["server_files/controllers/ajouter_admin.php"];
|
|
||||||
$ROUTES["^calendrier/(modifier)$"] = ["server_files/controllers/calendrier.php", "edit"];
|
|
||||||
$ROUTES["^calendrier/?$"] = ["server_files/controllers/calendrier.php"];
|
|
||||||
$ROUTES["^commenter-echange-4$"] = ["server_files/controllers/commenter_echange.php"];
|
|
||||||
$ROUTES["^commenter-echange-4/([A-Z]{3})$"] = ["server_files/controllers/commenter_echange.php", "trigram"];
|
|
||||||
$ROUTES["^confirmer-mail/([a-z0-9]*)/?$"] = ["server_files/controllers/confirmer_mail.php", "token"];
|
|
||||||
$ROUTES["^connexion/(confirmation-mail)/?$"] = ["server_files/controllers/connexion.php", "confirmation-mail"];
|
|
||||||
$ROUTES["^connexion/(mdp-oublie)/?$"] = ["server_files/controllers/connexion.php", "mdp_oublie"];
|
|
||||||
$ROUTES["^connexion/(reinitialiser_mdp)/(.*)/?$"] = ["server_files/controllers/connexion.php", "reset_password", "token"];
|
|
||||||
$ROUTES["^connexion/?$"] = ["server_files/controllers/connexion.php"];
|
|
||||||
$ROUTES["^deconnexion/?$"] = ["server_files/controllers/deconnexion.php"];
|
|
||||||
$ROUTES["^envoyer-video-1$"] = ["server_files/controllers/envoyer_video.php"];
|
|
||||||
$ROUTES["^envoyer-video-1/([A-Z]{3})$"] = ["server_files/controllers/envoyer_video.php", "trigram"];
|
|
||||||
$ROUTES["^equipe/([A-Z]{3})/?$"] = ["server_files/controllers/equipe.php", "trigram"];
|
|
||||||
$ROUTES["^exporter-donnees/?$"] = ["server_files/controllers/exporter_donnees.php"];
|
|
||||||
$ROUTES["^file/([a-z0-9]{64})/?$"] = ["server_files/controllers/view_file.php", "file_id"];
|
|
||||||
$ROUTES["^informations/([0-9]*)/.*?$"] = ["server_files/controllers/informations.php", "id"];
|
|
||||||
$ROUTES["^inscription/?$"] = ["server_files/controllers/inscription.php"];
|
|
||||||
$ROUTES["^mon-compte/?$"] = ["server_files/controllers/mon_compte.php"];
|
|
||||||
$ROUTES["^mon-equipe/(diffusion-videos)/?$"] = ["server_files/controllers/mon_equipe.php", "publish_videos"];
|
|
||||||
$ROUTES["^mon-equipe/(modifier)/?$"] = ["server_files/controllers/mon_equipe.php", "modifier"];
|
|
||||||
$ROUTES["^mon-equipe/?$"] = ["server_files/controllers/mon_equipe.php"];
|
|
||||||
$ROUTES["^mon-equipe/([A-Z]{3})/?$"] = ["server_files/controllers/mon_equipe.php", "trigram"];
|
|
||||||
$ROUTES["^ma-participation/?$"] = ["server_files/controllers/ma_participation.php"];
|
|
||||||
$ROUTES["^ma-participation/([A-Z]{3})/?$"] = ["server_files/controllers/ma_participation.php", "trigram"];
|
|
||||||
$ROUTES["^poser-questions-2$"] = ["server_files/controllers/poser_questions.php"];
|
|
||||||
$ROUTES["^poser-questions-2/([A-Z]{3})$"] = ["server_files/controllers/poser_questions.php", "trigram"];
|
|
||||||
$ROUTES["^probleme/([0-4])/?$"] = ["server_files/controllers/probleme.php", "probleme"];
|
|
||||||
$ROUTES["^profils/?$"] = ["server_files/controllers/profiles.php"];
|
|
||||||
$ROUTES["^profils-(orphelins)/?$"] = ["server_files/controllers/profiles.php", "orphans"];
|
|
||||||
$ROUTES["^rejoindre-equipe/?$"] = ["server_files/controllers/rejoindre_equipe.php"];
|
|
||||||
$ROUTES["^repondre-questions-3$"] = ["server_files/controllers/repondre_questions.php"];
|
|
||||||
$ROUTES["^repondre-questions-3/([A-Z]{3})$"] = ["server_files/controllers/repondre_questions.php", "trigram"];
|
|
||||||
$ROUTES["^suivi-correspondances/?$"] = ["server_files/controllers/suivi_correspondances.php"];
|
|
||||||
$ROUTES["^suivi-correspondances/([1-4])/?$"] = ["server_files/controllers/suivi_correspondances.php", "problem"];
|
|
||||||
|
|
||||||
# Assets files
|
|
||||||
|
|
||||||
$ROUTES["^Autorisation de droit à l'image - majeur.pdf$"] = ["assets/Autorisation de droit à l'image - majeur.pdf", "application/pdf"];
|
|
||||||
$ROUTES["^Autorisation de droit à l'image - mineur.pdf$"] = ["assets/Autorisation de droit à l'image - mineur.pdf", "application/pdf"];
|
|
||||||
$ROUTES["^favicon\.ico$"] = ["assets/favicon.ico", "image/x-icon"];
|
|
||||||
$ROUTES["^logo\.png"] = ["assets/logo.png", "image/png"];
|
|
||||||
$ROUTES["^style\.css$"] = ["assets/style.css", "text/css"];
|
|
||||||
|
|
||||||
foreach ($ROUTES as $route => $file) {
|
|
||||||
if (preg_match('#' . $route . '#', $path, $matches)) {
|
|
||||||
for ($i = 1; $i < sizeof($file); ++$i)
|
|
||||||
$_GET[$file[$i]] = $matches[$i];
|
|
||||||
|
|
||||||
if (!preg_match("#php$#", $file[0])) {
|
|
||||||
header("Content-Type: " . $file[1]);
|
|
||||||
readfile($file[0]);
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @noinspection PhpIncludeInspection */
|
|
||||||
require $file[0];
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once "server_files/404.php";
|
|
12
entrypoint.sh
Executable file
12
entrypoint.sh
Executable file
@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
python manage.py compilemessages
|
||||||
|
python manage.py migrate
|
||||||
|
|
||||||
|
nginx
|
||||||
|
|
||||||
|
if [ "$CORRES2MATH_STAGE" = "prod" ]; then
|
||||||
|
gunicorn -b 0.0.0.0:8000 --workers=2 --threads=4 --worker-class=gthread corres2math.wsgi --access-logfile '-' --error-logfile '-';
|
||||||
|
else
|
||||||
|
./manage.py runserver 0.0.0.0:8000;
|
||||||
|
fi
|
270
locale/fr/LC_MESSAGES/django.po
Normal file
270
locale/fr/LC_MESSAGES/django.po
Normal file
@ -0,0 +1,270 @@
|
|||||||
|
# SOME DESCRIPTIVE TITLE.
|
||||||
|
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||||
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
|
#
|
||||||
|
#, fuzzy
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: Corres2math\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2020-09-20 22:31+0200\n"
|
||||||
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
|
"Last-Translator: Yohann D'ANELLO <yohann.danello@animath.fr>\n"
|
||||||
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
"Language: fr\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||||
|
|
||||||
|
#: apps/api/apps.py:10
|
||||||
|
msgid "API"
|
||||||
|
msgstr "API"
|
||||||
|
|
||||||
|
#: corres2math/settings.py:144
|
||||||
|
msgid "English"
|
||||||
|
msgstr "Anglais"
|
||||||
|
|
||||||
|
#: corres2math/settings.py:145
|
||||||
|
msgid "French"
|
||||||
|
msgstr "Français"
|
||||||
|
|
||||||
|
#: templates/400.html:6
|
||||||
|
msgid "Bad request"
|
||||||
|
msgstr "Requête invalide"
|
||||||
|
|
||||||
|
#: templates/400.html:7
|
||||||
|
msgid ""
|
||||||
|
"Sorry, your request was bad. Don't know what could be wrong. An email has "
|
||||||
|
"been sent to webmasters with the details of the error. You can now watch "
|
||||||
|
"some videos."
|
||||||
|
msgstr ""
|
||||||
|
"Désolé, votre requête est invalide. Aucune idée de ce qui a pu se passer. Un "
|
||||||
|
"email a été envoyé aux administrateurs avec les détails de l'erreur. Vous "
|
||||||
|
"pouvez désormais retourner voir des vidéos."
|
||||||
|
|
||||||
|
#: templates/403.html:6
|
||||||
|
msgid "Permission denied"
|
||||||
|
msgstr "Permission refusée"
|
||||||
|
|
||||||
|
#: templates/403.html:7
|
||||||
|
msgid "You don't have the right to perform this request."
|
||||||
|
msgstr "Vous n'avez pas le droit d'effectuer cette requête."
|
||||||
|
|
||||||
|
#: templates/403.html:10 templates/404.html:10
|
||||||
|
msgid "Exception message:"
|
||||||
|
msgstr "Message d'erreur :"
|
||||||
|
|
||||||
|
#: templates/404.html:6
|
||||||
|
msgid "Page not found"
|
||||||
|
msgstr "Page non trouvée"
|
||||||
|
|
||||||
|
#: templates/404.html:7
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"The requested path <code>%(request_path)s</code> was not found on the server."
|
||||||
|
msgstr ""
|
||||||
|
"Le chemin demandé <code>%(request_path)s</code> n'a pas été trouvé sur le "
|
||||||
|
"serveur."
|
||||||
|
|
||||||
|
#: templates/500.html:6
|
||||||
|
msgid "Server error"
|
||||||
|
msgstr "Erreur du serveur"
|
||||||
|
|
||||||
|
#: templates/500.html:7
|
||||||
|
msgid ""
|
||||||
|
"Sorry, an error occurred when processing your request. An email has been "
|
||||||
|
"sent to webmasters with the detail of the error, and this will be fixed "
|
||||||
|
"soon. You can now watch some videos."
|
||||||
|
msgstr ""
|
||||||
|
"Désolé, une erreur est survenue lors du traitement de votre requête. Aucune "
|
||||||
|
"idée de ce qui a pu se passer. Un email a été envoyé aux administrateurs "
|
||||||
|
"avec les détails de l'erreur. Vous pouvez désormais retourner voir des "
|
||||||
|
"vidéos."
|
||||||
|
|
||||||
|
#: templates/base.html:70
|
||||||
|
msgid "Home"
|
||||||
|
msgstr "Accueil"
|
||||||
|
|
||||||
|
#: templates/base.html:74
|
||||||
|
msgid "Make a gift"
|
||||||
|
msgstr "Faire un don"
|
||||||
|
|
||||||
|
#: templates/base.html:78
|
||||||
|
msgid "Administration"
|
||||||
|
msgstr "Administration"
|
||||||
|
|
||||||
|
#: templates/base.html:85
|
||||||
|
msgid "Return to admin view"
|
||||||
|
msgstr "Retourner à l'interface administrateur"
|
||||||
|
|
||||||
|
#: templates/base.html:90 templates/registration/login.html:7
|
||||||
|
#: templates/registration/login.html:8 templates/registration/login.html:22
|
||||||
|
#: templates/registration/password_reset_complete.html:10
|
||||||
|
msgid "Log in"
|
||||||
|
msgstr "Connexion"
|
||||||
|
|
||||||
|
#: templates/base.html:94
|
||||||
|
msgid "Log out"
|
||||||
|
msgstr "Déconnexion"
|
||||||
|
|
||||||
|
#: templates/base.html:118
|
||||||
|
msgid "Contact us"
|
||||||
|
msgstr "Nous contacter"
|
||||||
|
|
||||||
|
#: templates/base.html:141
|
||||||
|
msgid "Back to top"
|
||||||
|
msgstr "Retour en haut"
|
||||||
|
|
||||||
|
#: templates/registration/email_validation_complete.html:15
|
||||||
|
msgid "Your email have successfully been validated."
|
||||||
|
msgstr "Votre email a été validé avec succès."
|
||||||
|
|
||||||
|
#: templates/registration/email_validation_complete.html:18
|
||||||
|
#, python-format
|
||||||
|
msgid "You can now <a href=\"%(login_url)s\">log in</a>."
|
||||||
|
msgstr "Vous pouvez désormais vous <a href=\"%(login_url)s\">connecter</a>."
|
||||||
|
|
||||||
|
#: templates/registration/email_validation_complete.html:22
|
||||||
|
msgid ""
|
||||||
|
"The link was invalid. The token may have expired. Please send us an email to "
|
||||||
|
"activate your account."
|
||||||
|
msgstr ""
|
||||||
|
"Le lien est invalide. Le jeton a peut-être expiré. Merci de nous envoyer un "
|
||||||
|
"mail pour activer votre compte."
|
||||||
|
|
||||||
|
#: templates/registration/email_validation_email_sent.html:10
|
||||||
|
msgid "Account activation"
|
||||||
|
msgstr "Activation du compte"
|
||||||
|
|
||||||
|
#: templates/registration/email_validation_email_sent.html:14
|
||||||
|
msgid ""
|
||||||
|
"An email has been sent. Please click on the link to activate your account."
|
||||||
|
msgstr ""
|
||||||
|
"Un email a été envoyé. Merci de cliquer sur le lien pour activer votre "
|
||||||
|
"compte."
|
||||||
|
|
||||||
|
#: templates/registration/logged_out.html:8
|
||||||
|
msgid "Thanks for spending some quality time with the Web site today."
|
||||||
|
msgstr "Merci d'avoir utilisé la plateforme des Correspondances."
|
||||||
|
|
||||||
|
#: templates/registration/logged_out.html:9
|
||||||
|
msgid "Log in again"
|
||||||
|
msgstr "Se reconnecter"
|
||||||
|
|
||||||
|
#: templates/registration/login.html:13
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"You are authenticated as %(user)s, but are not authorized to access this "
|
||||||
|
"page. Would you like to login to a different account?"
|
||||||
|
msgstr ""
|
||||||
|
"Vous êtes connectés en tant que %(user)s, mais n'êtes pas autorisés à "
|
||||||
|
"accéder à cette page. Voulez-vous vous reconnecter avec un autre compte ?"
|
||||||
|
|
||||||
|
#: templates/registration/login.html:23
|
||||||
|
msgid "Forgotten your password or username?"
|
||||||
|
msgstr "Mot de passe oublié ?"
|
||||||
|
|
||||||
|
#: templates/registration/mails/email_validation_email.html:12
|
||||||
|
#: templates/registration/mails/email_validation_email.txt:3
|
||||||
|
msgid "Hi"
|
||||||
|
msgstr "Bonjour"
|
||||||
|
|
||||||
|
#: templates/registration/mails/email_validation_email.html:16
|
||||||
|
#: templates/registration/mails/email_validation_email.txt:5
|
||||||
|
msgid ""
|
||||||
|
"You recently registered on the Correspondances platform. Please click on the "
|
||||||
|
"link below to confirm your registration."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/registration/mails/email_validation_email.html:26
|
||||||
|
#: templates/registration/mails/email_validation_email.txt:9
|
||||||
|
msgid ""
|
||||||
|
"This link is only valid for a couple of days, after that you will need to "
|
||||||
|
"contact us to validate your email."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/registration/mails/email_validation_email.html:30
|
||||||
|
#: templates/registration/mails/email_validation_email.txt:11
|
||||||
|
msgid "Thanks"
|
||||||
|
msgstr "Merci"
|
||||||
|
|
||||||
|
#: templates/registration/mails/email_validation_email.html:35
|
||||||
|
#: templates/registration/mails/email_validation_email.txt:13
|
||||||
|
msgid "The CNO."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/registration/password_change_done.html:8
|
||||||
|
msgid "Your password was changed."
|
||||||
|
msgstr "Votre mot de passe a été changé."
|
||||||
|
|
||||||
|
#: templates/registration/password_change_form.html:9
|
||||||
|
msgid ""
|
||||||
|
"Please enter your old password, for security's sake, and then enter your new "
|
||||||
|
"password twice so we can verify you typed it in correctly."
|
||||||
|
msgstr ""
|
||||||
|
"Merci d'entrer votre ancien mot de passe pour des raisons de sécurité, et "
|
||||||
|
"d'entrer votre nouveau mot de passe deux fois afin de s'assurer que vous "
|
||||||
|
"l'ayez tapé correctement."
|
||||||
|
|
||||||
|
#: templates/registration/password_change_form.html:11
|
||||||
|
#: templates/registration/password_reset_confirm.html:12
|
||||||
|
msgid "Change my password"
|
||||||
|
msgstr "Changer mon mot de passe"
|
||||||
|
|
||||||
|
#: templates/registration/password_reset_complete.html:8
|
||||||
|
msgid "Your password has been set. You may go ahead and log in now."
|
||||||
|
msgstr "Votre mot de passe a été changé. Vous pouvez désormais vous connecter."
|
||||||
|
|
||||||
|
#: templates/registration/password_reset_confirm.html:9
|
||||||
|
msgid ""
|
||||||
|
"Please enter your new password twice so we can verify you typed it in "
|
||||||
|
"correctly."
|
||||||
|
msgstr ""
|
||||||
|
"Merci d'entrer votre nouveau mot de passe deux fois afin de vérifier que "
|
||||||
|
"vous l'ayez tapé correctement."
|
||||||
|
|
||||||
|
#: templates/registration/password_reset_confirm.html:15
|
||||||
|
msgid ""
|
||||||
|
"The password reset link was invalid, possibly because it has already been "
|
||||||
|
"used. Please request a new password reset."
|
||||||
|
msgstr ""
|
||||||
|
"Le lien de réinitialisation du mot de passe est invalide, probablement parce "
|
||||||
|
"qu'il a déjà été utilisé. Merci de demander une nouvelle réinitialisation du "
|
||||||
|
"mot de passe."
|
||||||
|
|
||||||
|
#: templates/registration/password_reset_done.html:8
|
||||||
|
msgid ""
|
||||||
|
"We've emailed you instructions for setting your password, if an account "
|
||||||
|
"exists with the email you entered. You should receive them shortly."
|
||||||
|
msgstr ""
|
||||||
|
"Nous vous avons envoyé un email contenant des instructions pour définir "
|
||||||
|
"votre mot de passe, si un compte existe avec l'adresse mail que vous avez "
|
||||||
|
"entrée. Vous devriez le recevoir très rapidement."
|
||||||
|
|
||||||
|
#: templates/registration/password_reset_done.html:9
|
||||||
|
msgid ""
|
||||||
|
"If you don't receive an email, please make sure you've entered the address "
|
||||||
|
"you registered with, and check your spam folder."
|
||||||
|
msgstr ""
|
||||||
|
"Si vous ne recevez pas de mail, merci de vous assurer que vous avez entré "
|
||||||
|
"l'adresse mail avec laquelle vous êtes inscrits, et de vérifier vos "
|
||||||
|
"courriers indésirables."
|
||||||
|
|
||||||
|
#: templates/registration/password_reset_form.html:8
|
||||||
|
msgid ""
|
||||||
|
"Forgotten your password? Enter your email address below, and we'll email "
|
||||||
|
"instructions for setting a new one."
|
||||||
|
msgstr ""
|
||||||
|
"Mot de passe oublié ? Entrez votre adresse mail ci-dessous, et nous vous "
|
||||||
|
"enverrons un mail avec les instructions pour en définir un nouveau."
|
||||||
|
|
||||||
|
#: templates/registration/password_reset_form.html:11
|
||||||
|
msgid "Reset my password"
|
||||||
|
msgstr "Réinitialiser mon mot de passe"
|
||||||
|
|
||||||
|
#: templates/registration/signup.html:5 templates/registration/signup.html:8
|
||||||
|
#: templates/registration/signup.html:14
|
||||||
|
msgid "Sign up"
|
||||||
|
msgstr "Inscription"
|
21
manage.py
Executable file
21
manage.py
Executable file
@ -0,0 +1,21 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
"""Django's command-line utility for administrative tasks."""
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'corres2math.settings')
|
||||||
|
try:
|
||||||
|
from django.core.management import execute_from_command_line
|
||||||
|
except ImportError as exc:
|
||||||
|
raise ImportError(
|
||||||
|
"Couldn't import Django. Are you sure it's installed and "
|
||||||
|
"available on your PYTHONPATH environment variable? Did you "
|
||||||
|
"forget to activate a virtual environment?"
|
||||||
|
) from exc
|
||||||
|
execute_from_command_line(sys.argv)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
19
nginx_corres2math.conf
Normal file
19
nginx_corres2math.conf
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
upstream corres2math {
|
||||||
|
server 127.0.0.1:8000;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name corres2math;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://corres2math;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_redirect off;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /static {
|
||||||
|
alias /code/static/;
|
||||||
|
}
|
||||||
|
}
|
15
requirements.txt
Normal file
15
requirements.txt
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
bcrypt
|
||||||
|
Django~=3.0
|
||||||
|
django-allauth
|
||||||
|
django-bootstrap-datepicker-plus
|
||||||
|
django-crispy-forms
|
||||||
|
django-extensions
|
||||||
|
django-filter
|
||||||
|
django-mailer
|
||||||
|
django-polymorphic
|
||||||
|
django-tables2
|
||||||
|
djangorestframework
|
||||||
|
django-rest-polymorphic
|
||||||
|
psycopg2-binary
|
||||||
|
ptpython
|
||||||
|
gunicorn
|
@ -1,16 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require_once "config.php";
|
|
||||||
require_once "views/header.php";
|
|
||||||
|
|
||||||
http_response_code(403);
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="alert alert-danger mt-4 mb-4">
|
|
||||||
<h2 class="display-5">
|
|
||||||
Vous n'êtes pas autorisé à accéder à cette page.
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
require_once "views/footer.php";
|
|
@ -1,16 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require_once "config.php";
|
|
||||||
require_once "views/header.php";
|
|
||||||
|
|
||||||
http_response_code(404);
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="alert alert-danger mt-4 mb-4">
|
|
||||||
<h2 class="display-5">
|
|
||||||
Cette page n'existe pas.
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
require_once "views/footer.php";
|
|
@ -1,91 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class Document
|
|
||||||
{
|
|
||||||
private $file_id;
|
|
||||||
private $user_id;
|
|
||||||
private $team_id;
|
|
||||||
private $problem;
|
|
||||||
private $uploaded_at;
|
|
||||||
private $version;
|
|
||||||
|
|
||||||
private function __construct() {}
|
|
||||||
|
|
||||||
public static function fromId($id)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$req = $DB->prepare("SELECT * FROM `documents` WHERE `file_id` = ?;");
|
|
||||||
$req->execute([htmlspecialchars($id)]);
|
|
||||||
$data = $req->fetch();
|
|
||||||
|
|
||||||
if ($data === false)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return self::fromData($data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function fromData($data)
|
|
||||||
{
|
|
||||||
$doc = new Document();
|
|
||||||
$doc->fill($data);
|
|
||||||
return $doc;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function fill($data)
|
|
||||||
{
|
|
||||||
$this->file_id = $data["file_id"];
|
|
||||||
$this->user_id = $data["user"];
|
|
||||||
$this->team_id = $data["team"];
|
|
||||||
$this->problem = $data["problem"];
|
|
||||||
$this->uploaded_at = $data["uploaded_at"];
|
|
||||||
$this->version = isset($data["version"]) ? $data["version"] : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getFileId()
|
|
||||||
{
|
|
||||||
return $this->file_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getUserId()
|
|
||||||
{
|
|
||||||
return $this->user_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTeamId()
|
|
||||||
{
|
|
||||||
return $this->team_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getProblem()
|
|
||||||
{
|
|
||||||
return $this->problem;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getUploadedAt()
|
|
||||||
{
|
|
||||||
return $this->uploaded_at;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getVersion()
|
|
||||||
{
|
|
||||||
return $this->version;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static function getAllDocuments($problem, $team_id = -1)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$req = $DB->query("SELECT * FROM `documents` AS `t1` "
|
|
||||||
. "INNER JOIN (SELECT `user`, `problem`, MAX(`uploaded_at`) AS `last_upload`, COUNT(`team`) AS `version` FROM `documents` GROUP BY `problem`, `user`) `t2` "
|
|
||||||
. "ON `t1`.`user` = `t2`.`user` AND `t1`.`problem` = `t2`.`problem` "
|
|
||||||
. "WHERE `t1`.`uploaded_at` = `t2`.`last_upload` AND `t1`.`problem` = $problem " . ($team_id >= 0 ? "AND `team` = $team_id" : "") . " ORDER BY `t1`.`user`;");
|
|
||||||
|
|
||||||
$docs = [];
|
|
||||||
|
|
||||||
while (($data = $req->fetch()) !== false)
|
|
||||||
$docs[] = Document::fromData($data);
|
|
||||||
|
|
||||||
return $docs;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,68 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class Phase
|
|
||||||
{
|
|
||||||
const INSCRIPTION = 0;
|
|
||||||
const PHASE1 = 1;
|
|
||||||
const PHASE12 = 2;
|
|
||||||
const PHASE2 = 3;
|
|
||||||
const PHASE23 = 4;
|
|
||||||
const PHASE3 = 5;
|
|
||||||
const PHASE34 = 6;
|
|
||||||
const PHASE4 = 7;
|
|
||||||
const END = 8;
|
|
||||||
|
|
||||||
public static function getCurrentPhase()
|
|
||||||
{
|
|
||||||
global $CONFIG;
|
|
||||||
|
|
||||||
$date = date("Y-m-d H:i:s");
|
|
||||||
|
|
||||||
if ($date < $CONFIG->getStartPhase1Date())
|
|
||||||
return self::INSCRIPTION;
|
|
||||||
|
|
||||||
if ($date < $CONFIG->getEndPhase1Date())
|
|
||||||
return self::PHASE1;
|
|
||||||
|
|
||||||
if ($date < $CONFIG->getStartPhase2Date())
|
|
||||||
return self::PHASE12;
|
|
||||||
|
|
||||||
if ($date < $CONFIG->getEndPhase2Date())
|
|
||||||
return self::PHASE2;
|
|
||||||
|
|
||||||
if ($date < $CONFIG->getStartPhase3Date())
|
|
||||||
return self::PHASE23;
|
|
||||||
|
|
||||||
if ($date < $CONFIG->getEndPhase3Date())
|
|
||||||
return self::PHASE3;
|
|
||||||
|
|
||||||
if ($date < $CONFIG->getStartPhase4Date())
|
|
||||||
return self::PHASE34;
|
|
||||||
|
|
||||||
if ($date < $CONFIG->getEndPhase4Date())
|
|
||||||
return self::PHASE4;
|
|
||||||
|
|
||||||
return self::END;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getTranslatedName($phase)
|
|
||||||
{
|
|
||||||
switch ($phase)
|
|
||||||
{
|
|
||||||
case self::INSCRIPTION:
|
|
||||||
return "Inscription";
|
|
||||||
case self::PHASE1:
|
|
||||||
return "Phase 1 (soumission des vidéos)";
|
|
||||||
case self::PHASE2:
|
|
||||||
return "Phase 2 (questions)";
|
|
||||||
case self::PHASE3:
|
|
||||||
return "Phase 3 (réponses)";
|
|
||||||
case self::PHASE4:
|
|
||||||
return "Phase 4 (vidéo de réponse)";
|
|
||||||
case self::END:
|
|
||||||
return "Les Correspondances sont terminées";
|
|
||||||
default:
|
|
||||||
return "Entre deux phases";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,185 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
|
|
||||||
class Question
|
|
||||||
{
|
|
||||||
const DEFAULT_QUESTIONS = ["Comment avez-vous obtenu vos résultats ?",
|
|
||||||
"Peut-on rendre votre algorithme plus efficace ? Pourquoi ?",
|
|
||||||
"Comment élargir vos travaux ?",
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null];
|
|
||||||
|
|
||||||
private $id;
|
|
||||||
private $from;
|
|
||||||
private $to;
|
|
||||||
private $problem;
|
|
||||||
private $number;
|
|
||||||
private $question;
|
|
||||||
private $attached_file;
|
|
||||||
private $answer;
|
|
||||||
private $attached_file_answer;
|
|
||||||
|
|
||||||
private function __construct()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function fromId($id)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
|
|
||||||
$req = $DB->prepare("SELECT * FROM `questions` WHERE `id` = ?;");
|
|
||||||
$req->execute(htmlspecialchars($id));
|
|
||||||
$data = $req->fetch();
|
|
||||||
|
|
||||||
if ($data === false)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
$question = new Question();
|
|
||||||
$question->fill($data);
|
|
||||||
return $question;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function fromAttachedFile($attached_file)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
|
|
||||||
$req = $DB->prepare("SELECT * FROM `questions` WHERE `attached_file` = ? OR `attached_file_answer` = ?;");
|
|
||||||
$req->execute([htmlspecialchars($attached_file), htmlspecialchars($attached_file)]);
|
|
||||||
$data = $req->fetch();
|
|
||||||
|
|
||||||
if ($data === false)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
$question = new Question();
|
|
||||||
$question->fill($data);
|
|
||||||
return $question;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function fill($data)
|
|
||||||
{
|
|
||||||
foreach ($data as $key => $value)
|
|
||||||
$this->$key = $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getQuestions(Team $from, Team $to)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
|
|
||||||
ensure($from->getProblem() == $to->getProblem(), "Les deux équipes doivent travailler sur le même problème.");
|
|
||||||
|
|
||||||
$req = $DB->prepare("SELECT * FROM `questions` WHERE `from` = ? AND `to` = ? ORDER BY `from`, `number`;");
|
|
||||||
$req->execute([$from->getId(), $to->getId()]);
|
|
||||||
|
|
||||||
$questions = [];
|
|
||||||
|
|
||||||
while (($data = $req->fetch()) !== false) {
|
|
||||||
$question = new Question();
|
|
||||||
$question->fill($data);
|
|
||||||
$questions[] = $question;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sizeof($questions) == 0) {
|
|
||||||
$req = $DB->prepare("INSERT INTO `questions`(`from`, `to`, `problem`, `number`, `question`) VALUES (?, ?, ?, ?, ?);");
|
|
||||||
$req->execute([$from->getId(), $to->getId(), $from->getProblem(), 0, ""]);
|
|
||||||
for ($i = 1; $i <= 6; ++$i) {
|
|
||||||
$req = $DB->prepare("INSERT INTO `questions`(`from`, `to`, `problem`, `number`, `question`) VALUES (?, ?, ?, ?, ?);");
|
|
||||||
$req->execute([$from->getId(), $to->getId(), $from->getProblem(), $i, self::DEFAULT_QUESTIONS[$i - 1]]);
|
|
||||||
}
|
|
||||||
return self::getQuestions($from, $to);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $questions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getQuestionsTo(Team $to)
|
|
||||||
{
|
|
||||||
global $DB, $YEAR;
|
|
||||||
$id = $to->getId();
|
|
||||||
$req = $DB->query("SELECT `id` from `teams` WHERE (`video_team1` = $id OR `video_team2` = $id) AND `year` = $YEAR;");
|
|
||||||
|
|
||||||
$questions = [];
|
|
||||||
|
|
||||||
while (($data = $req->fetch()) !== false)
|
|
||||||
$questions[] = self::getQuestions(Team::fromId($data["id"]), $to);
|
|
||||||
|
|
||||||
return $questions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getId()
|
|
||||||
{
|
|
||||||
return $this->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getFrom()
|
|
||||||
{
|
|
||||||
return $this->from;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTo()
|
|
||||||
{
|
|
||||||
return $this->to;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getProblem()
|
|
||||||
{
|
|
||||||
return $this->problem;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getNumber()
|
|
||||||
{
|
|
||||||
return $this->number;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getQuestion()
|
|
||||||
{
|
|
||||||
return $this->question;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setQuestion($question)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$this->question = $question;
|
|
||||||
$req = $DB->prepare("UPDATE `questions` SET `question` = ? WHERE `id` = ?;");
|
|
||||||
$req->execute([$question, $this->id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAttachedFile()
|
|
||||||
{
|
|
||||||
return $this->attached_file;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setAttachedFile($attached_file)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$this->attached_file = $attached_file;
|
|
||||||
$req = $DB->prepare("UPDATE `questions` SET `attached_file` = ? WHERE `id` = ?;");
|
|
||||||
$req->execute([$attached_file, $this->id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAnswer()
|
|
||||||
{
|
|
||||||
return $this->answer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setAnswer($answer)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$this->answer = $answer;
|
|
||||||
$req = $DB->prepare("UPDATE `questions` SET `answer` = ? WHERE `id` = ?;");
|
|
||||||
$req->execute([$answer, $this->id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAttachedFileAnswer()
|
|
||||||
{
|
|
||||||
return $this->attached_file_answer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setAttachedFileAnswer($attached_file)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$this->attached_file_answer = $attached_file;
|
|
||||||
$req = $DB->prepare("UPDATE `questions` SET `attached_file_answer` = ? WHERE `id` = ?;");
|
|
||||||
$req->execute([$attached_file, $this->id]);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
|
|
||||||
class Reason
|
|
||||||
{
|
|
||||||
const SOLUTION = 0;
|
|
||||||
const ANSWER1 = 1;
|
|
||||||
const ANSWER2 = 2;
|
|
||||||
|
|
||||||
public static function getTranslatedName($class) {
|
|
||||||
switch ($class) {
|
|
||||||
case self::ANSWER1:
|
|
||||||
case self::ANSWER2:
|
|
||||||
return "Réponse";
|
|
||||||
default:
|
|
||||||
return "Solution";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getName($class) {
|
|
||||||
switch ($class) {
|
|
||||||
case self::ANSWER1:
|
|
||||||
return "ANSWER1";
|
|
||||||
case self::ANSWER2:
|
|
||||||
return "ANSWER2";
|
|
||||||
default:
|
|
||||||
return "SOLUTION";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function fromName($name) {
|
|
||||||
switch ($name) {
|
|
||||||
case "ANSWER1":
|
|
||||||
return self::ANSWER1;
|
|
||||||
case "ANSWER2":
|
|
||||||
return self::ANSWER2;
|
|
||||||
default:
|
|
||||||
return self::SOLUTION;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class Role
|
|
||||||
{
|
|
||||||
const PARTICIPANT = 0;
|
|
||||||
const ENCADRANT = 1;
|
|
||||||
const ADMIN = 2;
|
|
||||||
|
|
||||||
public static function getTranslatedName($role) {
|
|
||||||
switch ($role) {
|
|
||||||
case self::ENCADRANT:
|
|
||||||
return "Encadrant";
|
|
||||||
case self::ADMIN:
|
|
||||||
return "Administrateur";
|
|
||||||
default:
|
|
||||||
return "Participant";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getName($role) {
|
|
||||||
switch ($role) {
|
|
||||||
case self::ENCADRANT:
|
|
||||||
return "ENCADRANT";
|
|
||||||
case self::ADMIN:
|
|
||||||
return "ADMIN";
|
|
||||||
default:
|
|
||||||
return "PARTICIPANT";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function fromName($name) {
|
|
||||||
switch ($name) {
|
|
||||||
case "ENCADRANT":
|
|
||||||
return self::ENCADRANT;
|
|
||||||
case "ADMIN":
|
|
||||||
return self::ADMIN;
|
|
||||||
default:
|
|
||||||
return self::PARTICIPANT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,54 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class SchoolClass
|
|
||||||
{
|
|
||||||
const SECONDE = 0;
|
|
||||||
const PREMIERE = 1;
|
|
||||||
const TERMINALE = 2;
|
|
||||||
const ADULT = 3;
|
|
||||||
|
|
||||||
public static function getTranslatedName($class) {
|
|
||||||
switch ($class) {
|
|
||||||
case self::SECONDE:
|
|
||||||
return "Seconde ou inférieur";
|
|
||||||
case self::PREMIERE:
|
|
||||||
return "Première";
|
|
||||||
case self::TERMINALE:
|
|
||||||
return "Terminale";
|
|
||||||
case self::ADULT:
|
|
||||||
return "Adulte";
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getName($class) {
|
|
||||||
switch ($class) {
|
|
||||||
case self::SECONDE:
|
|
||||||
return "SECONDE";
|
|
||||||
case self::PREMIERE:
|
|
||||||
return "PREMIERE";
|
|
||||||
case self::TERMINALE:
|
|
||||||
return "TERMINALE";
|
|
||||||
case self::ADULT:
|
|
||||||
return "ADULT";
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function fromName($name) {
|
|
||||||
switch ($name) {
|
|
||||||
case "SECONDE":
|
|
||||||
return self::SECONDE;
|
|
||||||
case "PREMIERE":
|
|
||||||
return self::PREMIERE;
|
|
||||||
case "TERMINALE":
|
|
||||||
return self::TERMINALE;
|
|
||||||
case "ADULT":
|
|
||||||
return self::ADULT;
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,261 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class Team
|
|
||||||
{
|
|
||||||
private $id;
|
|
||||||
private $name;
|
|
||||||
private $trigram;
|
|
||||||
private $problem;
|
|
||||||
private $encadrant;
|
|
||||||
private $participants;
|
|
||||||
private $inscription_date;
|
|
||||||
private $allow_publish;
|
|
||||||
private $validation_status;
|
|
||||||
private $video_team_ids;
|
|
||||||
private $access_code;
|
|
||||||
private $year;
|
|
||||||
|
|
||||||
private function __construct() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $id
|
|
||||||
* @return Team|null
|
|
||||||
*/
|
|
||||||
public static function fromId($id)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$req = $DB->prepare("SELECT * FROM `teams` WHERE `id` = ?;");
|
|
||||||
$req->execute([htmlspecialchars($id)]);
|
|
||||||
$data = $req->fetch();
|
|
||||||
|
|
||||||
if ($data === false)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
$team = new Team();
|
|
||||||
$team->fill($data);
|
|
||||||
return $team;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $trigram
|
|
||||||
* @return Team|null
|
|
||||||
*/
|
|
||||||
public static function fromTrigram($trigram)
|
|
||||||
{
|
|
||||||
global $DB, $YEAR;
|
|
||||||
$req = $DB->prepare("SELECT * FROM `teams` WHERE `trigram` = ? AND `year` = $YEAR;");
|
|
||||||
$req->execute([htmlspecialchars($trigram)]);
|
|
||||||
$data = $req->fetch();
|
|
||||||
|
|
||||||
if ($data === false)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
$team = new Team();
|
|
||||||
$team->fill($data);
|
|
||||||
return $team;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function fromAccessCode($access_code)
|
|
||||||
{
|
|
||||||
global $DB, $YEAR;
|
|
||||||
$req = $DB->prepare("SELECT * FROM `teams` WHERE `access_code` = ? AND `year` = $YEAR;");
|
|
||||||
$req->execute([htmlspecialchars($access_code)]);
|
|
||||||
$data = $req->fetch();
|
|
||||||
|
|
||||||
if ($data === false)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
$team = new Team();
|
|
||||||
$team->fill($data);
|
|
||||||
return $team;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getAllTeams($problem = -1, $only_validated = false, $only_with_solutions = true)
|
|
||||||
{
|
|
||||||
global $DB, $YEAR;
|
|
||||||
$req = $DB->prepare("SELECT * FROM `teams` WHERE " . ($problem < 0 ? "" : "`problem` = ? AND ") . ($only_validated ? "`validation_status` = 'VALIDATED' AND " : "") . "`year` = $YEAR;");
|
|
||||||
$req->execute([htmlspecialchars($problem)]);
|
|
||||||
|
|
||||||
$teams = [];
|
|
||||||
|
|
||||||
while (($data = $req->fetch()) != false) {
|
|
||||||
$team = new Team();
|
|
||||||
$team->fill($data);
|
|
||||||
$sol = $team->getSolution();
|
|
||||||
if ($sol != null && $sol->getValidation() == ValidationStatus::VALIDATED - 1)
|
|
||||||
$teams[] = $team;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $teams;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function fill($data)
|
|
||||||
{
|
|
||||||
$this->id = $data["id"];
|
|
||||||
$this->name = $data["name"];
|
|
||||||
$this->trigram = $data["trigram"];
|
|
||||||
$this->problem = $data["problem"];
|
|
||||||
$this->encadrant = $data["encadrant"];
|
|
||||||
$this->participants = [$data["participant_1"], $data["participant_2"], $data["participant_3"], $data["participant_4"], $data["participant_5"]];
|
|
||||||
$this->inscription_date = $data["inscription_date"];
|
|
||||||
$this->allow_publish = $data["allow_publish"] ? 1 : 0;
|
|
||||||
$this->validation_status = ValidationStatus::fromName($data["validation_status"]);
|
|
||||||
$this->video_team_ids = [$data["video_team1"], $data["video_team2"]];
|
|
||||||
$this->access_code = $data["access_code"];
|
|
||||||
$this->year = $data["year"];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getId()
|
|
||||||
{
|
|
||||||
return $this->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getName()
|
|
||||||
{
|
|
||||||
return $this->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setName($name)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$this->name = $name;
|
|
||||||
$DB->prepare("UPDATE `teams` SET `name` = ? WHERE `id` = ?;")->execute([$name, $this->id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTrigram()
|
|
||||||
{
|
|
||||||
return $this->trigram;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setTrigram($trigram)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$this->trigram = $trigram;
|
|
||||||
$DB->prepare("UPDATE `teams` SET `trigram` = ? WHERE `id` = ?;")->execute([$trigram, $this->id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getProblem()
|
|
||||||
{
|
|
||||||
return $this->problem;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setProblem($problem)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$this->problem = $problem;
|
|
||||||
$DB->prepare("UPDATE `teams` SET `problem` = ? WHERE `id` = ?;")->execute([$problem, $this->id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getEncadrantId()
|
|
||||||
{
|
|
||||||
return $this->encadrant;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setEncadrant($encadrant)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$this->encadrant = $encadrant;
|
|
||||||
/** @noinspection SqlResolve */
|
|
||||||
$DB->prepare("UPDATE `teams` SET `encadrant` = ? WHERE `id` = ?;")->execute([$encadrant, $this->id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getParticipants()
|
|
||||||
{
|
|
||||||
return $this->participants;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setParticipant($i, $participant)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$this->participants[$i - 1] = $participant;
|
|
||||||
/** @noinspection SqlResolve */
|
|
||||||
$DB->prepare("UPDATE `teams` SET `participant_$i` = ? WHERE `id` = ?;")->execute([$participant, $this->id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getInscriptionDate()
|
|
||||||
{
|
|
||||||
return $this->inscription_date;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function allowPublish()
|
|
||||||
{
|
|
||||||
return $this->allow_publish;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setAllowPublish($allow_publish)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$this->allow_publish = $allow_publish;
|
|
||||||
$DB->prepare("UPDATE `teams` SET `allow_publish` = ? WHERE `id` = ?;")->execute([$allow_publish ? 1 : 0, $this->id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getValidationStatus()
|
|
||||||
{
|
|
||||||
return $this->validation_status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setValidationStatus($status)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$this->validation_status = $status;
|
|
||||||
$DB->prepare("UPDATE `teams` SET `validation_status` = ? WHERE `id` = ?;")->execute([ValidationStatus::getName($status), $this->id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSolution()
|
|
||||||
{
|
|
||||||
return Video::getVideo(Reason::SOLUTION, $this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getVideoTeamIds()
|
|
||||||
{
|
|
||||||
return $this->video_team_ids;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setVideoTeamIds($video_team_ids)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
ensure(sizeof($video_team_ids) == 2, "Une équipe doit recevoir exactement deux vidéos.");
|
|
||||||
$this->video_team_ids = $video_team_ids;
|
|
||||||
$DB->prepare("UPDATE `teams` SET `video_team1` = ?, `video_team2` = ? WHERE `id` = ?;")->execute([$video_team_ids[0], $video_team_ids[1], $this->id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAccessCode()
|
|
||||||
{
|
|
||||||
return $this->access_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getYear()
|
|
||||||
{
|
|
||||||
return $this->year;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAllDocuments()
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$req = $DB->query("SELECT * FROM `documents` AS `t1` "
|
|
||||||
. "INNER JOIN (SELECT `team`, MAX(`uploaded_at`) AS `last_upload`, COUNT(`user`) AS `version` FROM `documents` GROUP BY `problem`, `user`, `team`) `t2` "
|
|
||||||
. "ON `t1`.`team` = `t2`.`team` "
|
|
||||||
. "WHERE `t1`.`uploaded_at` = `t2`.`last_upload` AND `t1`.`team` = $this->id;");
|
|
||||||
|
|
||||||
$docs = [];
|
|
||||||
|
|
||||||
while (($data = $req->fetch()) !== false)
|
|
||||||
$docs[] = Document::fromData($data);
|
|
||||||
|
|
||||||
return $docs;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAllEmails()
|
|
||||||
{
|
|
||||||
$emails = [];
|
|
||||||
if ($this->getEncadrantId() != null)
|
|
||||||
$emails[] = User::fromId($this->getEncadrantId())->getEmail();
|
|
||||||
|
|
||||||
foreach ($this->getParticipants() as $participantId) {
|
|
||||||
if ($participantId != 0)
|
|
||||||
$emails[] = User::fromId($participantId)->getEmail();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $emails;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,335 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class User
|
|
||||||
{
|
|
||||||
private $id;
|
|
||||||
public $email;
|
|
||||||
private $pwd_hash;
|
|
||||||
public $surname;
|
|
||||||
public $first_name;
|
|
||||||
public $school;
|
|
||||||
public $city;
|
|
||||||
public $country;
|
|
||||||
public $class;
|
|
||||||
public $description;
|
|
||||||
private $role;
|
|
||||||
private $team_id;
|
|
||||||
private $year;
|
|
||||||
private $confirm_email;
|
|
||||||
private $forgotten_password;
|
|
||||||
private $inscription_date;
|
|
||||||
private $receive_animath_mails;
|
|
||||||
|
|
||||||
private function __construct() {}
|
|
||||||
|
|
||||||
public static function fromId($id)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$req = $DB->prepare("SELECT * FROM `users` WHERE `id` = ?;");
|
|
||||||
$req->execute([htmlspecialchars($id)]);
|
|
||||||
$data = $req->fetch();
|
|
||||||
|
|
||||||
if ($data === false)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
$user = new User();
|
|
||||||
$user->fill($data);
|
|
||||||
return $user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function fromEmail($email)
|
|
||||||
{
|
|
||||||
global $DB, $YEAR;
|
|
||||||
$req = $DB->prepare("SELECT * FROM `users` WHERE `email` = ? AND `year` = $YEAR;");
|
|
||||||
$req->execute([htmlspecialchars($email)]);
|
|
||||||
$data = $req->fetch();
|
|
||||||
|
|
||||||
if ($data === false)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
$user = new User();
|
|
||||||
$user->fill($data);
|
|
||||||
return $user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getAdmins()
|
|
||||||
{
|
|
||||||
global $DB, $YEAR;
|
|
||||||
$admins = [];
|
|
||||||
$req = $DB->query("SELECT * FROM `users` WHERE `role` = 'ADMIN' AND `year` = $YEAR;");
|
|
||||||
|
|
||||||
while (($data = $req->fetch()) !== false) {
|
|
||||||
$admin = new User();
|
|
||||||
$admin->fill($data);
|
|
||||||
$admins[] = $admin;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $admins;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getAllUsers()
|
|
||||||
{
|
|
||||||
global $DB, $YEAR;
|
|
||||||
$orphans = [];
|
|
||||||
$req = $DB->query("SELECT * FROM `users` WHERE `role` != 'ADMIN' AND `year` = $YEAR ORDER BY `role`, `inscription_date`;");
|
|
||||||
|
|
||||||
while (($data = $req->fetch()) !== false) {
|
|
||||||
$orphan = new User();
|
|
||||||
$orphan->fill($data);
|
|
||||||
$orphans[] = $orphan;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $orphans;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getOrphanUsers()
|
|
||||||
{
|
|
||||||
global $DB, $YEAR;
|
|
||||||
$orphans = [];
|
|
||||||
$req = $DB->query("SELECT * FROM `users` WHERE `role` != 'ADMIN' AND `team_id` IS NULL "
|
|
||||||
. "AND NOT EXISTS (SELECT 1 FROM `teams` WHERE `encadrant` = `users`.`id`) "
|
|
||||||
. "AND `year` = $YEAR ORDER BY `role`, `inscription_date`;");
|
|
||||||
|
|
||||||
while (($data = $req->fetch()) !== false) {
|
|
||||||
$orphan = new User();
|
|
||||||
$orphan->fill($data);
|
|
||||||
$orphans[] = $orphan;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $orphans;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function fill($data)
|
|
||||||
{
|
|
||||||
$this->id = $data["id"];
|
|
||||||
$this->email = $data["email"];
|
|
||||||
$this->pwd_hash = $data["pwd_hash"];
|
|
||||||
$this->surname = $data["surname"];
|
|
||||||
$this->first_name = $data["first_name"];
|
|
||||||
$this->school = $data["school"];
|
|
||||||
$this->city = $data["city"];
|
|
||||||
$this->country = $data["country"];
|
|
||||||
$this->class = SchoolClass::fromName($data["class"]);
|
|
||||||
$this->description = $data["description"];
|
|
||||||
$this->role = Role::fromName($data["role"]);
|
|
||||||
$this->team_id = $data["team_id"];
|
|
||||||
$this->year = $data["year"];
|
|
||||||
$this->confirm_email = $data["confirm_email"];
|
|
||||||
$this->forgotten_password = $data["forgotten_password"];
|
|
||||||
$this->inscription_date = $data["inscription_date"];
|
|
||||||
$this->receive_animath_mails = $data["receive_animath_mails"];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getEmail()
|
|
||||||
{
|
|
||||||
return $this->email;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setEmail($email)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$this->email = $email;
|
|
||||||
$DB->prepare("UPDATE `users` SET `email` = ? WHERE `id` = ?;")->execute([$email, $this->getId()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getId()
|
|
||||||
{
|
|
||||||
return $this->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function checkPassword($password)
|
|
||||||
{
|
|
||||||
return password_verify($password, $this->pwd_hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setPassword($password)
|
|
||||||
{
|
|
||||||
$this->setPasswordHash(password_hash($password, PASSWORD_BCRYPT));
|
|
||||||
}
|
|
||||||
|
|
||||||
private function setPasswordHash($password_hash)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$this->pwd_hash = $password_hash;
|
|
||||||
$DB->prepare("UPDATE `users` SET `pwd_hash` = ? WHERE `id` = ?;")->execute([$password_hash, $this->getId()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSurname()
|
|
||||||
{
|
|
||||||
return $this->surname;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setSurname($surname)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$this->surname = $surname;
|
|
||||||
$DB->prepare("UPDATE `users` SET `surname` = ? WHERE `id` = ?;")->execute([$surname, $this->getId()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getFirstName()
|
|
||||||
{
|
|
||||||
return $this->first_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setFirstName($first_name)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$this->first_name = $first_name;
|
|
||||||
$DB->prepare("UPDATE `users` SET `first_name` = ? WHERE `id` = ?;")->execute([$first_name, $this->getId()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSchool()
|
|
||||||
{
|
|
||||||
return $this->school;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setSchool($school)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$this->school = $school;
|
|
||||||
$DB->prepare("UPDATE `users` SET `school` = ? WHERE `id` = ?;")->execute([$school, $this->getId()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getCity()
|
|
||||||
{
|
|
||||||
return $this->city;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setCity($city)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$this->city = $city;
|
|
||||||
$DB->prepare("UPDATE `users` SET `city` = ? WHERE `id` = ?;")->execute([$city, $this->getId()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getCountry()
|
|
||||||
{
|
|
||||||
return $this->country;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setCountry($country)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$this->country = $country;
|
|
||||||
$DB->prepare("UPDATE `users` SET `country` = ? WHERE `id` = ?;")->execute([$country, $this->getId()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getClass()
|
|
||||||
{
|
|
||||||
return $this->class;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setClass($class)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$this->class = $class;
|
|
||||||
$DB->prepare("UPDATE `users` SET `class` = ? WHERE `id` = ?;")->execute([SchoolClass::getName($class), $this->getId()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getDescription()
|
|
||||||
{
|
|
||||||
return $this->description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setDescription($desc)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$this->description = $desc;
|
|
||||||
$DB->prepare("UPDATE `users` SET `description` = ? WHERE `id` = ?;")->execute([$desc, $this->getId()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getRole()
|
|
||||||
{
|
|
||||||
return $this->role;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setRole($role)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$this->role = $role;
|
|
||||||
$DB->prepare("UPDATE `users` SET `role` = ? WHERE `id` = ?;")->execute([Role::getName($role), $this->getId()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTeamId()
|
|
||||||
{
|
|
||||||
return $this->team_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setTeamId($team_id)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$this->team_id = $team_id;
|
|
||||||
$DB->prepare("UPDATE `users` SET `team_id` = ? WHERE `id` = ?;")->execute([$team_id, $this->getId()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getConfirmEmailToken()
|
|
||||||
{
|
|
||||||
return $this->confirm_email;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setConfirmEmailToken($token)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$this->confirm_email = $token;
|
|
||||||
$DB->prepare("UPDATE `users` SET `confirm_email` = ? WHERE `id` = ?;")->execute([$token, $this->getId()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getForgottenPasswordToken()
|
|
||||||
{
|
|
||||||
return $this->forgotten_password;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setForgottenPasswordToken($token)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$this->forgotten_password = $token;
|
|
||||||
$DB->prepare("UPDATE `users` SET `forgotten_password` = ? WHERE `id` = ?;")->execute([$token, $this->getId()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getInscriptionDate()
|
|
||||||
{
|
|
||||||
return $this->inscription_date;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function doReceiveAnimathMails()
|
|
||||||
{
|
|
||||||
return $this->receive_animath_mails;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setReceiveAnimathMails($receive_animath_mails)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$this->receive_animath_mails = $receive_animath_mails;
|
|
||||||
$DB->prepare("UPDATE `users` SET `receive_animath_mails` = ? WHERE `id` = ?;")->execute([$receive_animath_mails ? 1 : 0, $this->getId()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAllDocuments()
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$req = $DB->query("SELECT * FROM `documents` AS `t1` "
|
|
||||||
. "INNER JOIN (SELECT `user`, MAX(`uploaded_at`) AS `last_upload`, COUNT(`team`) AS `version` FROM `documents` GROUP BY `problem`, `user`) `t2` "
|
|
||||||
. "ON `t1`.`user` = `t2`.`user` "
|
|
||||||
. "WHERE `t1`.`uploaded_at` = `t2`.`last_upload` AND `t1`.`user` = $this->id;");
|
|
||||||
|
|
||||||
$docs = [];
|
|
||||||
|
|
||||||
while (($data = $req->fetch()) !== false)
|
|
||||||
$docs[] = Document::fromData($data);
|
|
||||||
|
|
||||||
return $docs;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Seulement pour les encadrants
|
|
||||||
public function getTeams()
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$req = $DB->query("SELECT `id` FROM `teams` WHERE `encadrant` = $this->id OR `participant_1` = $this->id OR `participant_2` = $this->id OR `participant_3` = $this->id OR `participant_4` = $this->id OR `participant_5` = $this->id;");
|
|
||||||
|
|
||||||
$teams = [];
|
|
||||||
|
|
||||||
while (($data =$req->fetch()) !== false)
|
|
||||||
$teams[] = Team::fromId($data["id"]);
|
|
||||||
|
|
||||||
return $teams;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class ValidationStatus
|
|
||||||
{
|
|
||||||
const NOT_READY = 0;
|
|
||||||
const WAITING = 1;
|
|
||||||
const VALIDATED = 2;
|
|
||||||
|
|
||||||
public static function getTranslatedName($status) {
|
|
||||||
switch ($status) {
|
|
||||||
case self::WAITING:
|
|
||||||
return "En attente de validation";
|
|
||||||
case self::VALIDATED:
|
|
||||||
return "Inscription validée";
|
|
||||||
default:
|
|
||||||
return "Inscription non terminée";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getName($status) {
|
|
||||||
switch ($status) {
|
|
||||||
case self::WAITING:
|
|
||||||
return "WAITING";
|
|
||||||
case self::VALIDATED:
|
|
||||||
return "VALIDATED";
|
|
||||||
default:
|
|
||||||
return "NOT_READY";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function fromName($name) {
|
|
||||||
switch ($name) {
|
|
||||||
case "WAITING":
|
|
||||||
return self::WAITING;
|
|
||||||
case "VALIDATED":
|
|
||||||
return self::VALIDATED;
|
|
||||||
default:
|
|
||||||
return self::NOT_READY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,132 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
|
|
||||||
class Video
|
|
||||||
{
|
|
||||||
const NOT_CONTROLLED = 0;
|
|
||||||
const REJECTED = -1;
|
|
||||||
const ACCEPTED = 1;
|
|
||||||
|
|
||||||
private $id;
|
|
||||||
private $team;
|
|
||||||
private $problem;
|
|
||||||
private $link;
|
|
||||||
private $reason;
|
|
||||||
private $validation;
|
|
||||||
private $uploaded_at;
|
|
||||||
private $year;
|
|
||||||
private $version;
|
|
||||||
|
|
||||||
private function __construct() {}
|
|
||||||
|
|
||||||
public static function fromId($id)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$req = $DB->prepare("SELECT * FROM `videos` WHERE `id` = ?;");
|
|
||||||
$req->execute([htmlspecialchars($id)]);
|
|
||||||
$data = $req->fetch();
|
|
||||||
|
|
||||||
if ($data === false)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
$video = new Video();
|
|
||||||
$video->fill($data);
|
|
||||||
return $video;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getVideos($reason, $problem, $validation_min = -1, $team_id = -1)
|
|
||||||
{
|
|
||||||
global $DB, $YEAR;
|
|
||||||
$req = $DB->query("SELECT * FROM `videos` AS `t1` "
|
|
||||||
. "INNER JOIN (SELECT `team`, `problem`, `reason`, MAX(`uploaded_at`) AS `last_upload`, COUNT(`team`) AS `version` FROM `videos` "
|
|
||||||
. "WHERE `validation` >= $validation_min AND `year` = $YEAR GROUP BY `problem`, `reason`, `team`) `t2` "
|
|
||||||
. "ON `t1`.`team` = `t2`.`team` AND `t1`.`reason` = `t2`.`reason` AND `t1`.`problem` = `t2`.`problem` "
|
|
||||||
. "WHERE `t1`.`uploaded_at` = `t2`.`last_upload` AND `t1`.`problem` = $problem AND `t1`.`reason` = '" . Reason::getName($reason) . "'"
|
|
||||||
. ($team_id >= 0 ? " AND `t1`.`team` = $team_id" : "")
|
|
||||||
. " AND `validation` >= $validation_min AND `year` = $YEAR ORDER BY `t1`.`problem`, `t1`.`reason`;");
|
|
||||||
|
|
||||||
$videos = [];
|
|
||||||
|
|
||||||
while (($data = $req->fetch()) !== false) {
|
|
||||||
$video = new Video();
|
|
||||||
$video->fill($data);
|
|
||||||
$videos[] = $video;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $videos;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $reason
|
|
||||||
* @param Team $team
|
|
||||||
* @param int $validation_min
|
|
||||||
* @return Video|null
|
|
||||||
*/
|
|
||||||
public static function getVideo($reason, Team $team, $validation_min = -1) {
|
|
||||||
$videos = self::getVideos($reason, $team->getProblem(), $validation_min, $team->getId());
|
|
||||||
if (sizeof($videos) == 0)
|
|
||||||
return null;
|
|
||||||
else
|
|
||||||
return $videos[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
private function fill($data)
|
|
||||||
{
|
|
||||||
foreach ($data as $key => $value)
|
|
||||||
$this->$key = $value;
|
|
||||||
|
|
||||||
$this->reason = Reason::fromName($this->reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getId()
|
|
||||||
{
|
|
||||||
return $this->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTeam()
|
|
||||||
{
|
|
||||||
return $this->team;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getProblem()
|
|
||||||
{
|
|
||||||
return $this->problem;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getLink()
|
|
||||||
{
|
|
||||||
return $this->link;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getReason()
|
|
||||||
{
|
|
||||||
return $this->reason;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getValidation()
|
|
||||||
{
|
|
||||||
return $this->validation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setValidation($validation)
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$this->validation = $validation;
|
|
||||||
$DB->exec("UPDATE `videos` SET `validation` = $validation WHERE `id` = $this->id;");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getUploadedAt()
|
|
||||||
{
|
|
||||||
return $this->uploaded_at;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getYear()
|
|
||||||
{
|
|
||||||
return $this->year;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getVersion()
|
|
||||||
{
|
|
||||||
return $this->version;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,227 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Config options
|
|
||||||
*/
|
|
||||||
|
|
||||||
$YEAR = getenv("CORRES2MATH_YEAR");
|
|
||||||
$URL_BASE = getenv("CORRES2MATH_URL_BASE");
|
|
||||||
$LOCAL_PATH = getenv("CORRES2MATH_LOCAL_PATH");
|
|
||||||
$MAIL_DOMAIN = getenv("CORRES2MATH_MAIL_DOMAIN");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* DB infos
|
|
||||||
*/
|
|
||||||
|
|
||||||
$DB_HOST = getenv("CORRES2MATH_DB_HOST");
|
|
||||||
$DB_NAME = getenv("CORRES2MATH_DB_NAME");
|
|
||||||
$DB_USER = getenv("CORRES2MATH_DB_USER");
|
|
||||||
$DB_PASSWORD = getenv("CORRES2MATH_DB_PASSWORD");
|
|
||||||
|
|
||||||
try {
|
|
||||||
$DB = new PDO("mysql:host=$DB_HOST;dbname=$DB_NAME;charset=utf8", "$DB_USER", "$DB_PASSWORD", array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
|
|
||||||
}
|
|
||||||
catch (Exception $ex) {
|
|
||||||
die("Erreur lors de la connexion à la base de données : " . $ex->getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
$CONFIG = new Config();
|
|
||||||
$CONFIG->initDB();
|
|
||||||
$CONFIG->loadConfigValues();
|
|
||||||
|
|
||||||
class Config
|
|
||||||
{
|
|
||||||
private $inscription_date;
|
|
||||||
private $start_phase1_date;
|
|
||||||
private $end_phase1_date;
|
|
||||||
private $start_phase2_date;
|
|
||||||
private $end_phase2_date;
|
|
||||||
private $start_phase3_date;
|
|
||||||
private $end_phase3_date;
|
|
||||||
private $start_phase4_date;
|
|
||||||
private $end_phase4_date;
|
|
||||||
private $index_page;
|
|
||||||
private $views;
|
|
||||||
|
|
||||||
public function initDB()
|
|
||||||
{
|
|
||||||
global $DB, $LOCAL_PATH, $YEAR;
|
|
||||||
|
|
||||||
$index_template_page = htmlspecialchars(file_get_contents($LOCAL_PATH . "/server_files/views/index.html"));
|
|
||||||
|
|
||||||
$DB->exec("SET GLOBAL time_zone = 'Europe/Paris';");
|
|
||||||
$DB->prepare("INSERT IGNORE INTO `config`(`key`, `value`)
|
|
||||||
VALUES ('inscription_date_$YEAR', CURRENT_TIMESTAMP + INTERVAL 2 DAY),
|
|
||||||
('start_phase1_date_$YEAR', CURRENT_TIMESTAMP + INTERVAL 1 DAY),
|
|
||||||
('end_phase1_date_$YEAR', CURRENT_TIMESTAMP + INTERVAL 3 DAY),
|
|
||||||
('start_phase2_date_$YEAR', CURRENT_TIMESTAMP + INTERVAL 4 DAY),
|
|
||||||
('end_phase2_date_$YEAR', CURRENT_TIMESTAMP + INTERVAL 5 DAY),
|
|
||||||
('start_phase3_date_$YEAR', CURRENT_TIMESTAMP + INTERVAL 6 DAY),
|
|
||||||
('end_phase3_date_$YEAR', CURRENT_TIMESTAMP + INTERVAL 7 DAY),
|
|
||||||
('start_phase4_date_$YEAR', CURRENT_TIMESTAMP + INTERVAL 8 DAY),
|
|
||||||
('end_phase4_date_$YEAR', CURRENT_TIMESTAMP + INTERVAL 9 DAY),
|
|
||||||
('index_page_$YEAR', ?),
|
|
||||||
('views_$YEAR', 0);")->execute([$index_template_page]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function loadConfigValues()
|
|
||||||
{
|
|
||||||
global $DB, $YEAR;
|
|
||||||
|
|
||||||
$req = $DB->query("SELECT * FROM `config` WHERE `key` REGEXP '$YEAR';");
|
|
||||||
|
|
||||||
while (($data = $req->fetch()) !== false) {
|
|
||||||
$key = substr($data["key"], 0, -5);
|
|
||||||
$this->$key = $data["value"];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getInscriptionDate()
|
|
||||||
{
|
|
||||||
return $this->inscription_date;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setInscriptionDate($inscription_date)
|
|
||||||
{
|
|
||||||
global $DB, $YEAR;
|
|
||||||
$DB->exec("UPDATE `config` SET `value` = '$inscription_date' WHERE `key` = 'inscription_date_$YEAR'");
|
|
||||||
|
|
||||||
$this->inscription_date = $inscription_date;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getStartPhase1Date()
|
|
||||||
{
|
|
||||||
return $this->start_phase1_date;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setStartPhase1Date($start_phase1_date)
|
|
||||||
{
|
|
||||||
global $DB, $YEAR;
|
|
||||||
$DB->exec("UPDATE `config` SET `value` = '$start_phase1_date' WHERE `key` = 'start_phase1_date_$YEAR'");
|
|
||||||
|
|
||||||
$this->start_phase1_date = $start_phase1_date;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getEndPhase1Date()
|
|
||||||
{
|
|
||||||
return $this->end_phase1_date;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setEndPhase1Date($end_phase1_date)
|
|
||||||
{
|
|
||||||
global $DB, $YEAR;
|
|
||||||
$DB->exec("UPDATE `config` SET `value` = '$end_phase1_date' WHERE `key` = 'end_phase1_date_$YEAR'");
|
|
||||||
|
|
||||||
$this->end_phase1_date = $end_phase1_date;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getStartPhase2Date()
|
|
||||||
{
|
|
||||||
return $this->start_phase2_date;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setStartPhase2Date($start_phase2_date)
|
|
||||||
{
|
|
||||||
global $DB, $YEAR;
|
|
||||||
$DB->exec("UPDATE `config` SET `value` = '$start_phase2_date' WHERE `key` = 'start_phase2_date_$YEAR'");
|
|
||||||
|
|
||||||
$this->start_phase2_date = $start_phase2_date;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getEndPhase2Date()
|
|
||||||
{
|
|
||||||
return $this->end_phase2_date;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setEndPhase2Date($end_phase2_date)
|
|
||||||
{
|
|
||||||
global $DB, $YEAR;
|
|
||||||
$DB->exec("UPDATE `config` SET `value` = '$end_phase2_date' WHERE `key` = 'end_phase2_date_$YEAR'");
|
|
||||||
|
|
||||||
$this->end_phase2_date = $end_phase2_date;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getStartPhase3Date()
|
|
||||||
{
|
|
||||||
return $this->start_phase3_date;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setStartPhase3Date($start_phase3_date)
|
|
||||||
{
|
|
||||||
global $DB, $YEAR;
|
|
||||||
$DB->exec("UPDATE `config` SET `value` = '$start_phase3_date' WHERE `key` = 'start_phase3_date_$YEAR'");
|
|
||||||
|
|
||||||
$this->start_phase3_date = $start_phase3_date;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getEndPhase3Date()
|
|
||||||
{
|
|
||||||
return $this->end_phase3_date;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setEndPhase3Date($end_phase3_date)
|
|
||||||
{
|
|
||||||
global $DB, $YEAR;
|
|
||||||
$DB->exec("UPDATE `config` SET `value` = '$end_phase3_date' WHERE `key` = 'end_phase3_date_$YEAR'");
|
|
||||||
|
|
||||||
$this->end_phase3_date = $end_phase3_date;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getStartPhase4Date()
|
|
||||||
{
|
|
||||||
return $this->start_phase4_date;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setStartPhase4Date($start_phase4_date)
|
|
||||||
{
|
|
||||||
global $DB, $YEAR;
|
|
||||||
$DB->exec("UPDATE `config` SET `value` = '$start_phase4_date' WHERE `key` = 'start_phase4_date_$YEAR'");
|
|
||||||
|
|
||||||
$this->start_phase4_date = $start_phase4_date;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getEndPhase4Date()
|
|
||||||
{
|
|
||||||
return $this->end_phase4_date;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setEndPhase4Date($end_phase4_date)
|
|
||||||
{
|
|
||||||
global $DB, $YEAR;
|
|
||||||
$DB->exec("UPDATE `config` SET `value` = '$end_phase4_date' WHERE `key` = 'end_phase4_date_$YEAR'");
|
|
||||||
|
|
||||||
$this->end_phase4_date = $end_phase4_date;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getIndexPage()
|
|
||||||
{
|
|
||||||
return $this->index_page;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setIndexPage($index_page)
|
|
||||||
{
|
|
||||||
global $DB, $YEAR;
|
|
||||||
$DB->prepare("UPDATE `config` SET `value` = ? WHERE `key` = 'index_page_$YEAR'")->execute([$index_page]);
|
|
||||||
|
|
||||||
$this->index_page = $index_page;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getViews()
|
|
||||||
{
|
|
||||||
return $this->views;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function incrViews()
|
|
||||||
{
|
|
||||||
global $DB, $YEAR;
|
|
||||||
|
|
||||||
if (isset($_SESSION["user_id"]) && $_SESSION["role"] == Role::ADMIN || isset($_SESSION["admin"]))
|
|
||||||
return;
|
|
||||||
|
|
||||||
$DB->exec("UPDATE `config` SET `value` = " . ($this->views + 1) . " WHERE `key` = 'views_$YEAR';");
|
|
||||||
$this->views++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
session_start();
|
|
||||||
setlocale(LC_ALL, "fr_FR.utf8");
|
|
||||||
date_default_timezone_set("Europe/Paris");
|
|
@ -1,8 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
if ($_SESSION["role"] != Role::ADMIN)
|
|
||||||
require_once "server_files/403.php";
|
|
||||||
|
|
||||||
$admins = User::getAdmins();
|
|
||||||
|
|
||||||
require_once "server_files/views/admins.php";
|
|
@ -1,56 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
if (!isset($_SESSION["role"]) || $_SESSION["role"] != Role::ADMIN)
|
|
||||||
require_once "server_files/403.php";
|
|
||||||
|
|
||||||
$has_error = false;
|
|
||||||
$error_message = null;
|
|
||||||
|
|
||||||
if (isset($_POST["add_admin"])) {
|
|
||||||
$admin = new NewAdmin($_POST);
|
|
||||||
try {
|
|
||||||
$admin->makeVerifications();
|
|
||||||
$admin->register();
|
|
||||||
}
|
|
||||||
catch (AssertionError $e) {
|
|
||||||
$has_error = true;
|
|
||||||
$error_message = $e->getMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class NewAdmin {
|
|
||||||
public $surname;
|
|
||||||
public $first_name;
|
|
||||||
public $email;
|
|
||||||
public $password;
|
|
||||||
|
|
||||||
public function __construct($data)
|
|
||||||
{
|
|
||||||
foreach ($data as $key => $value)
|
|
||||||
$this->$key = htmlspecialchars($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function makeVerifications()
|
|
||||||
{
|
|
||||||
ensure($this->surname != null && $this->surname != "", "Le nom est invalide.");
|
|
||||||
ensure($this->first_name != null && $this->first_name != "", "Le prénom est invalide.");
|
|
||||||
ensure(filter_var($this->email, FILTER_VALIDATE_EMAIL), "L'adresse e-mail est invalide.");
|
|
||||||
$this->email = strtolower($this->email);
|
|
||||||
ensure(!userExists($this->email), "Cette adresse e-mail est déjà utilisée.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function register() {
|
|
||||||
global $DB, $YEAR;
|
|
||||||
|
|
||||||
$this->password = genRandomPhrase(16, true);
|
|
||||||
|
|
||||||
$req = $DB->prepare("INSERT INTO `users`(`email`, `pwd_hash`, `surname`, `first_name`, `class`, `role`, `year`)
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?);");
|
|
||||||
$req->execute([$this->email, password_hash($this->password, PASSWORD_BCRYPT), $this->surname,
|
|
||||||
$this->first_name, "ADULT", "ADMIN", $YEAR]);
|
|
||||||
|
|
||||||
Mailer::sendAddAdminMail($this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once "server_files/views/ajouter_admin.php";
|
|
@ -1,75 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
if (!isset($_SESSION["role"]) || ($_SESSION["role"] != Role::PARTICIPANT && $_SESSION["role"] != Role::ENCADRANT))
|
|
||||||
require_once "server_files/403.php";
|
|
||||||
|
|
||||||
$has_error = false;
|
|
||||||
$error_message = null;
|
|
||||||
|
|
||||||
if (isset($_POST["add_team"])) {
|
|
||||||
$new_team = new NewTeam($_POST);
|
|
||||||
try {
|
|
||||||
$new_team->makeVerifications();
|
|
||||||
$new_team->register();
|
|
||||||
}
|
|
||||||
catch (AssertionError $e) {
|
|
||||||
$has_error = true;
|
|
||||||
$error_message = $e->getMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class NewTeam {
|
|
||||||
public $name;
|
|
||||||
public $trigram;
|
|
||||||
public $problem;
|
|
||||||
public $allow_other_teams;
|
|
||||||
public $allow_publish;
|
|
||||||
public $access_code;
|
|
||||||
|
|
||||||
public function __construct($data)
|
|
||||||
{
|
|
||||||
foreach ($data as $key => $value)
|
|
||||||
$this->$key = htmlspecialchars($value);
|
|
||||||
|
|
||||||
$this->trigram = strtoupper($this->trigram);
|
|
||||||
|
|
||||||
$this->allow_other_teams = $this->allow_other_teams == "on" ? 1 : 0;
|
|
||||||
$this->allow_publish = $this->allow_publish == "on" ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function makeVerifications() {
|
|
||||||
global $CONFIG;
|
|
||||||
|
|
||||||
ensure(date("Y-m-d H:i:s") < $CONFIG->getInscriptionDate(), "La date limite d'inscription est dépassée.");
|
|
||||||
ensure($_SESSION["team"] == null || $_SESSION["role"] == Role::ENCADRANT, "Vous êtes déjà dans une équipe.");
|
|
||||||
ensure($this->name != null && $this->name != "", "Vous devez spécifier un nom d'équipe.");
|
|
||||||
ensure(preg_match("#^[\p{L} ]+$#ui", $this->name), "Le nom de l'équipe ne doit pas comporter de caractères spéciaux.");
|
|
||||||
ensure(preg_match("#^[A-Z]{3}$#", $this->trigram), "Le trigramme entré n'est pas valide.");
|
|
||||||
ensure(!teamExists($this->name), "Une équipe existe déjà avec ce nom.");
|
|
||||||
ensure(!trigramExists($this->trigram), "Une équipe a déjà choisi ce trigramme.");
|
|
||||||
ensure(preg_match("#[0-4]#", $this->problem), "Le problème choisi n'a pas été reconnu.");
|
|
||||||
ensure($this->allow_other_teams, "Vous devez autoriser de diffuser vos vidéos aux autres équipes participantes pour pouvoir participer.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function register() {
|
|
||||||
global $DB, $YEAR;
|
|
||||||
|
|
||||||
$this->access_code = genRandomPhrase(6);
|
|
||||||
|
|
||||||
$req = $DB->prepare("INSERT INTO `teams` (`name`, `trigram`, `problem`, `encadrant`, `participant_1`, `allow_publish`, `validation_status`, `access_code`, `year`)
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);");
|
|
||||||
$req->execute([$this->name, $this->trigram, $this->problem, $_SESSION["role"] == Role::ENCADRANT ? $_SESSION["user_id"] : NULL,
|
|
||||||
$_SESSION["role"] == Role::PARTICIPANT ? $_SESSION["user_id"] : NULL, $this->allow_publish, ValidationStatus::getName(ValidationStatus::NOT_READY), $this->access_code, $YEAR]);
|
|
||||||
|
|
||||||
$_SESSION["teams"] = $_SESSION["user"]->getTeams();
|
|
||||||
$team = Team::fromTrigram($this->trigram);
|
|
||||||
if ($_SESSION["role"] == Role::PARTICIPANT) {
|
|
||||||
$_SESSION["team"] = $team;
|
|
||||||
$_SESSION["user"]->setTeamId($_SESSION["team"]->getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
Mailer::sendAddTeamMail($_SESSION["user"], $team);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once "server_files/views/ajouter_equipe.php";
|
|
@ -1,76 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
$has_error = false;
|
|
||||||
$error_message = null;
|
|
||||||
|
|
||||||
if (isset($_GET["edit"]) && isset($_POST["update_calendar"])) {
|
|
||||||
$update_calendar = new UpdateCalendar($_POST);
|
|
||||||
try {
|
|
||||||
$update_calendar->makeVerifications();
|
|
||||||
$update_calendar->updateCalendar();
|
|
||||||
} catch (AssertionError $e) {
|
|
||||||
$has_error = true;
|
|
||||||
$error_message = $e->getMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class UpdateCalendar
|
|
||||||
{
|
|
||||||
private $date_inscription;
|
|
||||||
private $time_inscription;
|
|
||||||
private $date_start_phase1;
|
|
||||||
private $time_start_phase1;
|
|
||||||
private $date_end_phase1;
|
|
||||||
private $time_end_phase1;
|
|
||||||
private $date_start_phase2;
|
|
||||||
private $time_start_phase2;
|
|
||||||
private $date_end_phase2;
|
|
||||||
private $time_end_phase2;
|
|
||||||
private $date_start_phase3;
|
|
||||||
private $time_start_phase3;
|
|
||||||
private $date_end_phase3;
|
|
||||||
private $time_end_phase3;
|
|
||||||
private $date_start_phase4;
|
|
||||||
private $time_start_phase4;
|
|
||||||
private $date_end_phase4;
|
|
||||||
private $time_end_phase4;
|
|
||||||
|
|
||||||
public function __construct($data)
|
|
||||||
{
|
|
||||||
foreach ($data as $key => $value)
|
|
||||||
$this->$key = htmlspecialchars($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function makeVerifications()
|
|
||||||
{
|
|
||||||
ensure(dateWellFormed($this->date_inscription . " " . $this->time_inscription), "La date d'inscription n'est pas bien formée.");
|
|
||||||
ensure(dateWellFormed($this->date_start_phase1 . " " . $this->time_start_phase1), "La date de début de la phase 1 n'est pas bien formée.");
|
|
||||||
ensure(dateWellFormed($this->date_end_phase1 . " " . $this->time_end_phase1), "La date de fin de la phase 1 n'est pas bien formée.");
|
|
||||||
ensure(dateWellFormed($this->date_start_phase2 . " " . $this->time_start_phase2), "La date de début de la phase 2 n'est pas bien formée.");
|
|
||||||
ensure(dateWellFormed($this->date_end_phase2 . " " . $this->time_end_phase2), "La date de fin de la phase 2 n'est pas bien formée.");
|
|
||||||
ensure(dateWellFormed($this->date_start_phase3 . " " . $this->time_start_phase3), "La date de début de la phase 3 n'est pas bien formée.");
|
|
||||||
ensure(dateWellFormed($this->date_end_phase3 . " " . $this->time_end_phase3), "La date de fin de la phase 3 n'est pas bien formée.");
|
|
||||||
ensure(dateWellFormed($this->date_start_phase4 . " " . $this->time_start_phase4), "La date de début de la phase 4 n'est pas bien formée.");
|
|
||||||
ensure(dateWellFormed($this->date_end_phase4 . " " . $this->time_end_phase4), "La date de fin de la phase 4 n'est pas bien formée.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function updateCalendar()
|
|
||||||
{
|
|
||||||
global $CONFIG, $URL_BASE;
|
|
||||||
|
|
||||||
$CONFIG->setInscriptionDate($this->date_inscription . " " . $this->time_inscription);
|
|
||||||
$CONFIG->setStartPhase1Date($this->date_start_phase1 . " " . $this->time_start_phase1);
|
|
||||||
$CONFIG->setEndPhase1Date($this->date_end_phase1 . " " . $this->time_end_phase1);
|
|
||||||
$CONFIG->setStartPhase2Date($this->date_start_phase2 . " " . $this->time_start_phase2);
|
|
||||||
$CONFIG->setEndPhase2Date($this->date_end_phase2 . " " . $this->time_end_phase2);
|
|
||||||
$CONFIG->setStartPhase3Date($this->date_start_phase3 . " " . $this->time_start_phase3);
|
|
||||||
$CONFIG->setEndPhase3Date($this->date_end_phase3 . " " . $this->time_end_phase3);
|
|
||||||
$CONFIG->setStartPhase4Date($this->date_start_phase4 . " " . $this->time_start_phase4);
|
|
||||||
$CONFIG->setEndPhase4Date($this->date_end_phase4 . " " . $this->time_end_phase4);
|
|
||||||
|
|
||||||
header("Location: $URL_BASE/calendrier");
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once "server_files/views/calendrier.php";
|
|
@ -1,77 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
if (!isset($_SESSION["user_id"]) || $_SESSION["role"] != Role::PARTICIPANT && $_SESSION["role"] != Role::ENCADRANT || Phase::getCurrentPhase() != Phase::PHASE4)
|
|
||||||
require_once "server_files/403.php";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var User $user
|
|
||||||
* @var Team $team
|
|
||||||
*/
|
|
||||||
$user = $_SESSION["user"];
|
|
||||||
$team = $user->getRole() == Role::PARTICIPANT ? $_SESSION["team"] : Team::fromTrigram($_GET["trigram"]);
|
|
||||||
|
|
||||||
if ($team == null)
|
|
||||||
require_once "server_files/404.php";
|
|
||||||
|
|
||||||
if ($user->getRole() == Role::ENCADRANT && $team->getEncadrantId() != $user->getId() || $team->getValidationStatus() != ValidationStatus::VALIDATED)
|
|
||||||
require_once "server_files/403.php";
|
|
||||||
|
|
||||||
if (isset($_POST["upload_answer"])) {
|
|
||||||
$new_answer = new NewAnswer($_POST);
|
|
||||||
try {
|
|
||||||
$new_answer->makeVerifications();
|
|
||||||
$new_answer->uploadVideo();
|
|
||||||
} catch (AssertionError $e) {
|
|
||||||
$has_error = true;
|
|
||||||
$error_message = $e->getMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class NewAnswer
|
|
||||||
{
|
|
||||||
public $link;
|
|
||||||
public $team;
|
|
||||||
private $valid_link;
|
|
||||||
private $no_change;
|
|
||||||
|
|
||||||
public function __construct($data)
|
|
||||||
{
|
|
||||||
foreach ($data as $key => $value)
|
|
||||||
$this->$key = $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function makeVerifications()
|
|
||||||
{
|
|
||||||
ensure(preg_match("#(https?\:\/\/|)[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?#", $this->link), "Ce n'est pas une URL valide.");
|
|
||||||
$this->link = preg_replace('/^(?!https?:\/\/)/', 'https://', $this->link);
|
|
||||||
ensure(preg_match("#[1|2]#", $this->team), "L'équipe n'a pas été trouvée.");
|
|
||||||
ensure($this->valid_link != null, "Vous devez confirmer que le lien est valide.");
|
|
||||||
ensure($this->no_change != null, "Vous devez vous engager à ne pas changer le contenu du lien et de la vidéo.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function uploadVideo()
|
|
||||||
{
|
|
||||||
global $DB, $YEAR, $team;
|
|
||||||
|
|
||||||
$req = $DB->prepare("INSERT INTO `videos`(`team`, `problem`, `link`, `reason`, `year`) VALUES (?, ?, ?, ?, ?)");
|
|
||||||
$req->execute([$team->getId(), $team->getProblem(), $this->link, "ANSWER" . $this->team, $YEAR]);
|
|
||||||
|
|
||||||
Mailer::sendNewAnswer($this, $team);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$team1 = Team::fromId($team->getVideoTeamIds()[0]);
|
|
||||||
$sol1 = Video::getVideo(Reason::SOLUTION, $team1);
|
|
||||||
$answer1 = Video::getVideo(Reason::ANSWER1, $team);
|
|
||||||
$answer1_validated = Video::getVideo(Reason::ANSWER1, $team, Video::ACCEPTED);
|
|
||||||
$team2 = Team::fromId($team->getVideoTeamIds()[1]);
|
|
||||||
$sol2 = Video::getVideo(Reason::SOLUTION, $team2);
|
|
||||||
$answer2 = Video::getVideo(Reason::ANSWER2, $team);
|
|
||||||
$answer2_validated = Video::getVideo(Reason::ANSWER2, $team, Video::ACCEPTED);
|
|
||||||
|
|
||||||
$teams = [$team1, $team2];
|
|
||||||
$sols = [$sol1, $sol2];
|
|
||||||
$answers = [$answer1, $answer2];
|
|
||||||
$answers_validated = [$answer1_validated, $answer2_validated];
|
|
||||||
|
|
||||||
require_once "server_files/views/commenter_echange.php";
|
|
@ -1,25 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
$token = $_GET["token"];
|
|
||||||
|
|
||||||
$has_error = false;
|
|
||||||
|
|
||||||
if (isset($token)) {
|
|
||||||
$result = $DB->query("SELECT `email` FROM `users` WHERE `confirm_email` = '$token' AND `year` = '$YEAR';");
|
|
||||||
if (($data = $result->fetch()) === FALSE) {
|
|
||||||
$has_error = true;
|
|
||||||
$error_message = "Le jeton est invalide. Votre compte est peut-être déjà validé ?";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$DB->exec("UPDATE `users` SET `confirm_email` = NULL WHERE `confirm_email` = '$token';");
|
|
||||||
$error_message = "Votre adresse mail a été validée ! Vous pouvez désormais vous connecter.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$has_error = true;
|
|
||||||
$error_message = "Il n'y a pas de compte à valider !";
|
|
||||||
}
|
|
||||||
require_once "server_files/views/header.php";
|
|
||||||
if (!$has_error)
|
|
||||||
echo "<div class=\"alert alert-success\">$error_message</div>";
|
|
||||||
require_once "server_files/views/footer.php";
|
|
@ -1,170 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
$has_error = false;
|
|
||||||
$error_message = null;
|
|
||||||
|
|
||||||
if (isset($_POST["login"]) && !isset($_SESSION["user_id"])) {
|
|
||||||
$logging_in_user = new LoggingInUser($_POST);
|
|
||||||
try {
|
|
||||||
$logging_in_user->makeVerifications();
|
|
||||||
$logging_in_user->login();
|
|
||||||
} catch (AssertionError $e) {
|
|
||||||
$has_error = true;
|
|
||||||
$error_message = $e->getMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST["forgotten_password"]) && !isset($_SESSION["user_id"])) {
|
|
||||||
$recuperate_account = new RecuperateAccount($_POST);
|
|
||||||
try {
|
|
||||||
$recuperate_account->makeVerifications();
|
|
||||||
$recuperate_account->recuperateAccount();
|
|
||||||
} catch (AssertionError $e) {
|
|
||||||
$has_error = true;
|
|
||||||
$error_message = $e->getMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_GET["reset_password"]) && isset($_GET["token"]) && !isset($_SESSION["user_id"])) {
|
|
||||||
$reset_password = new ResetPassword($_GET, $_POST);
|
|
||||||
try {
|
|
||||||
$reset_password->makeVerifications();
|
|
||||||
if (isset($_POST["password"]))
|
|
||||||
$reset_password->resetPassword();
|
|
||||||
} catch (AssertionError $e) {
|
|
||||||
$has_error = true;
|
|
||||||
$error_message = $e->getMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_GET["confirmation-mail"]) && !isset($_SESSION["user_id"]))
|
|
||||||
sendConfirmEmail();
|
|
||||||
|
|
||||||
class LoggingInUser
|
|
||||||
{
|
|
||||||
public $email;
|
|
||||||
/** @var User $user */
|
|
||||||
public $user;
|
|
||||||
private $password;
|
|
||||||
|
|
||||||
public function __construct($data)
|
|
||||||
{
|
|
||||||
foreach ($data as $key => $value)
|
|
||||||
$this->$key = htmlspecialchars($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function makeVerifications()
|
|
||||||
{
|
|
||||||
ensure(filter_var($this->email, FILTER_VALIDATE_EMAIL), "L'adresse email est invalide.");
|
|
||||||
$this->user = User::fromEmail($this->email);
|
|
||||||
ensure($this->user != null, "Le compte n'existe pas.");
|
|
||||||
ensure($this->user->checkPassword($this->password), "Le mot de passe est incorrect.");
|
|
||||||
if ($this->user->getConfirmEmailToken() != null) {
|
|
||||||
$_SESSION["confirm_email"] = $this->email;
|
|
||||||
/** @noinspection HtmlUnknownTarget */
|
|
||||||
throw new AssertionError("L'adresse mail n'a pas été validée. Veuillez vérifier votre boîte mail (surtout vos spams). "
|
|
||||||
. "<a href=\"/connexion/confirmation-mail\">Cliquez ici pour renvoyer le mail de confirmation</a>.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function login()
|
|
||||||
{
|
|
||||||
$_SESSION["user_id"] = $this->user->getId();
|
|
||||||
$this->user->setForgottenPasswordToken(null);
|
|
||||||
loadUserValues();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class RecuperateAccount
|
|
||||||
{
|
|
||||||
public $email;
|
|
||||||
/** @var User $user */
|
|
||||||
public $user;
|
|
||||||
|
|
||||||
public function __construct($data)
|
|
||||||
{
|
|
||||||
foreach ($data as $key => $value)
|
|
||||||
$this->$key = htmlspecialchars($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function makeVerifications()
|
|
||||||
{
|
|
||||||
ensure(filter_var($this->email, FILTER_VALIDATE_EMAIL), "L'adresse email est invalide.");
|
|
||||||
$this->user = User::fromEmail($this->email);
|
|
||||||
ensure($this->user != null, "Le compte n'existe pas.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function recuperateAccount()
|
|
||||||
{
|
|
||||||
$token = genRandomPhrase(64);
|
|
||||||
$this->user->setForgottenPasswordToken($token);
|
|
||||||
Mailer::sendForgottenPasswordProcedureMail($this->user);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ResetPassword
|
|
||||||
{
|
|
||||||
public $token;
|
|
||||||
/** @var User $user */
|
|
||||||
public $user;
|
|
||||||
private $password;
|
|
||||||
private $confirm_password;
|
|
||||||
|
|
||||||
public function __construct($data, $data2)
|
|
||||||
{
|
|
||||||
foreach ($data as $key => $value)
|
|
||||||
$this->$key = htmlspecialchars($value);
|
|
||||||
foreach ($data2 as $key => $value)
|
|
||||||
$this->$key = htmlspecialchars($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function makeVerifications()
|
|
||||||
{
|
|
||||||
global $DB;
|
|
||||||
$data = $DB->query("SELECT `id` FROM `users` WHERE `forgotten_password` = '" . $this->token . "';")->fetch();
|
|
||||||
ensure($data !== false, "Il n'y a pas de compte à récupérer avec ce jeton.");
|
|
||||||
$this->user = User::fromId($data["id"]);
|
|
||||||
|
|
||||||
if (!isset($_POST["password"]))
|
|
||||||
return;
|
|
||||||
|
|
||||||
ensure($this->password == $this->confirm_password, "Les deux mots de passe sont différents.");
|
|
||||||
ensure(strlen($this->password) >= 8, "Le mot de passe doit comporter au moins 8 caractères.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function resetPassword()
|
|
||||||
{
|
|
||||||
$this->user->setForgottenPasswordToken(null);
|
|
||||||
$this->user->setPassword($this->password);
|
|
||||||
|
|
||||||
Mailer::sendChangePasswordMail($this->user);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function sendConfirmEmail()
|
|
||||||
{
|
|
||||||
global $URL_BASE;
|
|
||||||
|
|
||||||
$email = htmlspecialchars($_SESSION["confirm_email"]);
|
|
||||||
|
|
||||||
if (!isset($email)) {
|
|
||||||
header("Location: $URL_BASE/connexion");
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
$user = User::fromEmail($email);
|
|
||||||
|
|
||||||
if ($user === null) {
|
|
||||||
unset($_SESSION["confirm_email"]);
|
|
||||||
header("Location: $URL_BASE/connexion");
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
Mailer::sendConfirmEmail($user);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once "server_files/views/connexion.php";
|
|
@ -1,14 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
unset($_SESSION["user_id"]);
|
|
||||||
session_destroy();
|
|
||||||
|
|
||||||
require_once "server_files/views/header.php";
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="alert alert-success">
|
|
||||||
Déconnexion réussie !
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
require_once "server_files/views/footer.php";
|
|
@ -1,72 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
if (!isset($_SESSION["user_id"]) || $_SESSION["role"] != Role::PARTICIPANT && $_SESSION["role"] != Role::ENCADRANT)
|
|
||||||
require_once "server_files/403.php";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var User $user
|
|
||||||
* @var Team $team
|
|
||||||
*/
|
|
||||||
$user = $_SESSION["user"];
|
|
||||||
;$team = $user->getRole() == Role::PARTICIPANT ? $_SESSION["team"] : Team::fromTrigram($_GET["trigram"]);
|
|
||||||
|
|
||||||
if ($team == null)
|
|
||||||
require_once "server_files/404.php";
|
|
||||||
|
|
||||||
if ($user->getRole() == Role::ENCADRANT && $team->getEncadrantId() != $user->getId() || $team->getValidationStatus() != ValidationStatus::VALIDATED)
|
|
||||||
require_once "server_files/403.php";
|
|
||||||
|
|
||||||
if (Phase::getCurrentPhase() != Phase::PHASE1) {
|
|
||||||
if (!(Phase::getCurrentPhase() == Phase::PHASE12 && Video::getVideo(Reason::SOLUTION, $team) != NULL && (Video::getVideo(Reason::SOLUTION, $team, ValidationStatus::WAITING) == NULL || isset($_POST["upload"]))))
|
|
||||||
require_once "server_files/403.php";
|
|
||||||
}
|
|
||||||
|
|
||||||
$has_error = false;
|
|
||||||
$error_message = null;
|
|
||||||
|
|
||||||
if (isset($_POST["upload"])) {
|
|
||||||
$new_video = new NewVideo($_POST);
|
|
||||||
try {
|
|
||||||
$new_video->makeVerifications();
|
|
||||||
$new_video->uploadVideo();
|
|
||||||
} catch (AssertionError $e) {
|
|
||||||
$has_error = true;
|
|
||||||
$error_message = $e->getMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class NewVideo
|
|
||||||
{
|
|
||||||
public $link;
|
|
||||||
private $valid_link;
|
|
||||||
private $no_change;
|
|
||||||
|
|
||||||
public function __construct($data)
|
|
||||||
{
|
|
||||||
foreach ($data as $key => $value)
|
|
||||||
$this->$key = $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function makeVerifications()
|
|
||||||
{
|
|
||||||
ensure(preg_match("#(https?\:\/\/|)[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?#", $this->link), "Ce n'est pas une URL valide.");
|
|
||||||
$this->link = preg_replace('/^(?!https?:\/\/)/', 'https://', $this->link);
|
|
||||||
ensure($this->valid_link != null, "Vous devez confirmer que le lien est valide.");
|
|
||||||
ensure($this->no_change != null, "Vous devez vous engager à ne pas changer le contenu du lien et de la vidéo.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function uploadVideo()
|
|
||||||
{
|
|
||||||
global $DB, $YEAR, $team;
|
|
||||||
|
|
||||||
$req = $DB->prepare("INSERT INTO `videos`(`team`, `problem`, `link`, `reason`, `year`) VALUES (?, ?, ?, ?, ?)");
|
|
||||||
$req->execute([$team->getId(), $team->getProblem(), $this->link, Reason::getName(Reason::SOLUTION), $YEAR]);
|
|
||||||
|
|
||||||
Mailer::sendNewVideo($this, $team);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$video = Video::getVideo(Reason::SOLUTION, $team);
|
|
||||||
$video_validated = Video::getVideo(Reason::SOLUTION, $team, Video::ACCEPTED);
|
|
||||||
|
|
||||||
require_once "server_files/views/envoyer_video.php";
|
|
@ -1,112 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
if (!isset($_SESSION["user_id"]) || $_SESSION["role"] != Role::ADMIN)
|
|
||||||
require_once "server_files/403.php";
|
|
||||||
|
|
||||||
$trigram = htmlspecialchars($_GET["trigram"]);
|
|
||||||
|
|
||||||
$team = Team::fromTrigram($trigram);
|
|
||||||
|
|
||||||
if ($team === null)
|
|
||||||
require_once "server_files/404.php";
|
|
||||||
|
|
||||||
if (isset($_POST["validate"])) {
|
|
||||||
$team->setValidationStatus(ValidationStatus::VALIDATED);
|
|
||||||
Mailer::sendValidateTeam($team, $_POST["message"]);
|
|
||||||
}
|
|
||||||
elseif (isset($_POST["unvalidate"])) {
|
|
||||||
$team->setValidationStatus(ValidationStatus::NOT_READY);
|
|
||||||
Mailer::sendUnvalidateTeam($team, $_POST["message"]);
|
|
||||||
}
|
|
||||||
elseif (isset($_POST["select_problem"])) {
|
|
||||||
if ($team->getValidationStatus() == ValidationStatus::NOT_READY) {
|
|
||||||
$problem = $_POST["select_problem"];
|
|
||||||
if (preg_match("#[0-4]#", $problem)) {
|
|
||||||
$team->setProblem($problem);
|
|
||||||
$DB->prepare("UPDATE `documents` SET `problem` = ? WHERE `team` = ?;")->execute([$problem, $team->getId()]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$has_error = true;
|
|
||||||
$error_message = "Le problème indiqué n'existe pas.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$has_error = true;
|
|
||||||
$error_message = "Cette équipe est déjà validée ou en cours de validation.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
elseif (isset($_POST["delete_team"])) {
|
|
||||||
if ($team->getValidationStatus() == ValidationStatus::NOT_READY) {
|
|
||||||
$documents = Document::getAllDocuments($team->getProblem(), $team->getId());
|
|
||||||
/** @var Document $doc */
|
|
||||||
foreach ($documents as $doc)
|
|
||||||
unlink($LOCAL_PATH . "/files/" . $doc->getFileId());
|
|
||||||
$DB->prepare("DELETE FROM `documents` WHERE `team` = ?;")->execute([$team->getId()]);
|
|
||||||
$DB->prepare("DELETE FROM `teams` WHERE `id` = ?;")->execute([$team->getId()]);
|
|
||||||
$DB->prepare("UPDATE `users` SET `team_id` = NULL WHERE `team_id` = ?;")->execute([$team->getId()]);
|
|
||||||
header("Location: /");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$has_error = true;
|
|
||||||
$error_message = "Cette équipe est déjà validée ou en cours de validation.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST["download_zip"])) {
|
|
||||||
$file_name = getZipFile($team->getProblem(), $team->getId());
|
|
||||||
|
|
||||||
header("Content-Type: application/zip");
|
|
||||||
header("Content-Disposition: attachment; filename=\"Documents de l'équipe " . $team->getTrigram() . ".zip\"");
|
|
||||||
header("Content-Length: " . strval(filesize($file_name)));
|
|
||||||
|
|
||||||
readfile($file_name);
|
|
||||||
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST["update_video_teams"])) {
|
|
||||||
$update_video_teams = new UpdateVideoTeams($_POST);
|
|
||||||
try {
|
|
||||||
$update_video_teams->makeVerifications();
|
|
||||||
$update_video_teams->update();
|
|
||||||
} catch (AssertionError $e) {
|
|
||||||
$has_error = true;
|
|
||||||
$error_message = $e->getMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class UpdateVideoTeams
|
|
||||||
{
|
|
||||||
private $other_teams;
|
|
||||||
|
|
||||||
public function __construct($data)
|
|
||||||
{
|
|
||||||
foreach ($data as $key => $value)
|
|
||||||
$this->$key = $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function makeVerifications()
|
|
||||||
{
|
|
||||||
global $team;
|
|
||||||
|
|
||||||
ensure(Phase::getCurrentPhase() <= Phase::PHASE2, "Il est trop tard pour réaffecter les vidéos aux équipes.");
|
|
||||||
ensure($team->getSolution() != null, "L'équipe doit avoir soumis une vidéo.");
|
|
||||||
ensure($team->getSolution()->getValidation() == ValidationStatus::VALIDATED - 1, "L'équipe doit avoir soumis une vidéo validée.");
|
|
||||||
ensure(sizeof($this->other_teams) == 2, "L'équipe doit recevoir exactement deux vidéos.");
|
|
||||||
ensure(Team::fromId($this->other_teams[0]) != null, "La première équipe n'existe pas.");
|
|
||||||
ensure(Team::fromId($this->other_teams[1]) != null, "La seconde équipe n'existe pas.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update()
|
|
||||||
{
|
|
||||||
global $team;
|
|
||||||
|
|
||||||
$team->setVideoTeamIds($this->other_teams);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$other_teams = Team::getAllTeams($team->getProblem(), true, true);
|
|
||||||
$documents = Document::getAllDocuments($team->getProblem(), $team->getId());
|
|
||||||
|
|
||||||
require_once "server_files/views/equipe.php";
|
|
@ -1,42 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
if (!isset($_SESSION["user_id"]) || $_SESSION["role"] != Role::ADMIN)
|
|
||||||
require_once "server_files/403.php";
|
|
||||||
|
|
||||||
if (isset($_POST["export_user_data"])) {
|
|
||||||
$file_name = exportUserData();
|
|
||||||
|
|
||||||
header("Content-Type: text/csv");
|
|
||||||
header("Content-Disposition: inline; filename=\"Données utilisateurs.csv\"");
|
|
||||||
header("Content-Length: " . strval(filesize($file_name)));
|
|
||||||
|
|
||||||
readfile($file_name);
|
|
||||||
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST["export_team_data"])) {
|
|
||||||
$file_name = exportTeamData();
|
|
||||||
|
|
||||||
header("Content-Type: text/csv");
|
|
||||||
header("Content-Disposition: attachment; filename=\"Données équipes.csv\"");
|
|
||||||
header("Content-Length: " . strval(filesize($file_name)));
|
|
||||||
|
|
||||||
readfile($file_name);
|
|
||||||
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST["export_problems_data"])) {
|
|
||||||
$file_name = exportProblemsData();
|
|
||||||
|
|
||||||
header("Content-Type: text/csv");
|
|
||||||
header("Content-Disposition: attachment; filename=\"Données problèmes.csv\"");
|
|
||||||
header("Content-Length: " . strval(filesize($file_name)));
|
|
||||||
|
|
||||||
readfile($file_name);
|
|
||||||
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once "server_files/views/exporter_donnees.php";
|
|
@ -1,16 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
if (isset($_GET["edit"])) {
|
|
||||||
if (!isset($_SESSION["user_id"]) || $_SESSION["role"] != Role::ADMIN)
|
|
||||||
require_once "server_files/403.php";
|
|
||||||
|
|
||||||
if (isset($_POST["edit_page"])) {
|
|
||||||
$content = $_POST["content"];
|
|
||||||
|
|
||||||
$CONFIG->setIndexPage(htmlspecialchars($content));
|
|
||||||
header("Location: /");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once "server_files/views/index.php";
|
|
@ -1,117 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
if (!isset($_SESSION["role"]))
|
|
||||||
require_once "server_files/403.php";
|
|
||||||
|
|
||||||
$id = $_GET["id"];
|
|
||||||
$user = User::fromId($id);
|
|
||||||
|
|
||||||
if ($_SESSION["role"] != Role::ADMIN) {
|
|
||||||
if ($user->getId() != $_SESSION["user_id"])
|
|
||||||
require_once "server_files/403.php";
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($user === null)
|
|
||||||
require_once "server_files/404.php";
|
|
||||||
|
|
||||||
$teams = $user->getTeams();
|
|
||||||
if ($user->getRole() == Role::PARTICIPANT)
|
|
||||||
$team = sizeof($teams) == 0 ? null : $teams[0];
|
|
||||||
|
|
||||||
$has_error = false;
|
|
||||||
$error_message = null;
|
|
||||||
|
|
||||||
if (isset($_POST["kick"])) {
|
|
||||||
if (sizeof($teams) == null) {
|
|
||||||
$has_error = true;
|
|
||||||
$error_message = "La personne à expulser n'est dans aucune équipe.";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
quitTeam($id);
|
|
||||||
$team = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST["attribute_team"])) {
|
|
||||||
$attribute_team = new AttributeTeam($_POST);
|
|
||||||
try {
|
|
||||||
$attribute_team->makeVerifications();
|
|
||||||
$attribute_team->attribute();
|
|
||||||
} catch (AssertionError $e) {
|
|
||||||
$has_error = true;
|
|
||||||
$error_message = $e->getMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST["view_as"]) && $_SESSION["role"] == Role::ADMIN) {
|
|
||||||
if (!isset($_SESSION["admin"]))
|
|
||||||
$_SESSION["admin"] = $_SESSION["user_id"];
|
|
||||||
$_SESSION["user_id"] = $user->getId();
|
|
||||||
header("Location: /");
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST["delete_account"]) && $team == null && $_SESSION["role"] == Role::ADMIN) {
|
|
||||||
/** @var Document $document */
|
|
||||||
foreach ($user->getAllDocuments() as $document)
|
|
||||||
unlink($LOCAL_PATH . "/files/" . $document->getFileId());
|
|
||||||
$DB->prepare("DELETE FROM `documents` WHERE `user` = ?;")->execute([$user->getId()]);
|
|
||||||
$DB->prepare("DELETE FROM `users` WHERE `id` = ?;")->execute([$user->getId()]);
|
|
||||||
header("Location: /");
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
class AttributeTeam
|
|
||||||
{
|
|
||||||
private $team_id;
|
|
||||||
private $team;
|
|
||||||
private $min_null_index;
|
|
||||||
|
|
||||||
public function __construct($data)
|
|
||||||
{
|
|
||||||
$this->team_id = $data["team"];
|
|
||||||
$this->team = Team::fromId($this->team_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function makeVerifications()
|
|
||||||
{
|
|
||||||
global $user;
|
|
||||||
|
|
||||||
ensure($user->getConfirmEmailToken() == null, "Ce participant n'a pas encore validé son adresse e-mail.");
|
|
||||||
ensure($this->team_id != "no_team", "Vous n'avez pas choisi d'équipe.");
|
|
||||||
ensure($this->team != null, "Cette équipe n'existe pas.");
|
|
||||||
ensure($this->team->getValidationStatus() == ValidationStatus::NOT_READY, "Cette équipe est déjà validée ou en cours de validation.");
|
|
||||||
|
|
||||||
$role = $user->getRole();
|
|
||||||
for ($i = 1; $i <= $role == Role::ENCADRANT ? 1 : 5; ++$i) {
|
|
||||||
if (($role == Role::PARTICIPANT ? $this->team->getParticipants()[$i - 1] : $this->team->getEncadrantId()) == NULL)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->min_null_index = $i;
|
|
||||||
|
|
||||||
ensure($role == Role::PARTICIPANT && $this->min_null_index <= 5 || $role == Role::ENCADRANT && $this->min_null_index <= 2,
|
|
||||||
"Il n'y a plus de place pour vous dans l'équipe.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function attribute()
|
|
||||||
{
|
|
||||||
global $user, $team;
|
|
||||||
|
|
||||||
$user->setTeamId($this->team->getId());
|
|
||||||
|
|
||||||
if ($user->getRole() == Role::ENCADRANT)
|
|
||||||
$this->team->setEncadrant($user->getId());
|
|
||||||
else
|
|
||||||
$this->team->setParticipant($this->min_null_index, $user->getId());
|
|
||||||
|
|
||||||
Mailer::sendJoinTeamMail($user, $this->team);
|
|
||||||
|
|
||||||
$team = $this->team;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($teams != null)
|
|
||||||
$documents = $user->getAllDocuments();
|
|
||||||
|
|
||||||
require_once "server_files/views/informations.php";
|
|
@ -1,84 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
$has_error = false;
|
|
||||||
$error_message = null;
|
|
||||||
|
|
||||||
if (isset($_POST["register"])) {
|
|
||||||
$user = new NewUser($_POST);
|
|
||||||
|
|
||||||
try {
|
|
||||||
$user->makeVerifications();
|
|
||||||
$user->register();
|
|
||||||
} catch (AssertionError $e) {
|
|
||||||
$has_error = true;
|
|
||||||
$error_message = $e->getMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class NewUser
|
|
||||||
{
|
|
||||||
public $email;
|
|
||||||
public $first_name;
|
|
||||||
public $surname;
|
|
||||||
public $role;
|
|
||||||
public $school;
|
|
||||||
public $city;
|
|
||||||
public $country;
|
|
||||||
public $class;
|
|
||||||
public $receive_animath_mails;
|
|
||||||
|
|
||||||
public $description;
|
|
||||||
public $confirm_email_token;
|
|
||||||
private $password;
|
|
||||||
private $confirm_password;
|
|
||||||
|
|
||||||
public function __construct($data)
|
|
||||||
{
|
|
||||||
foreach ($data as $key => $value)
|
|
||||||
$this->$key = htmlspecialchars($value);
|
|
||||||
|
|
||||||
$this->receive_animath_mails = $this->receive_animath_mails ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function makeVerifications()
|
|
||||||
{
|
|
||||||
global $CONFIG;
|
|
||||||
|
|
||||||
ensure(date("Y-m-d H:i:s") < $CONFIG->getInscriptionDate(), "Les inscriptions sont terminées.");
|
|
||||||
ensure(filter_var($this->email, FILTER_VALIDATE_EMAIL), "L'adresse e-mail entrée est invalide.");
|
|
||||||
$this->email = strtolower($this->email);
|
|
||||||
ensure(!userExists($this->email), "Un compte existe déjà avec cette adresse e-mail.");
|
|
||||||
ensure(strlen($this->password) >= 8, "Le mot de passe doit comporter au moins 8 caractères.");
|
|
||||||
ensure($this->password == $this->confirm_password, "Les deux mots de passe sont différents.");
|
|
||||||
ensure($this->surname != "", "Le nom de famille est obligatoire.");
|
|
||||||
ensure($this->first_name != "", "Le prénom est obligatoire.");
|
|
||||||
$this->role = Role::fromName(strtoupper($this->role));
|
|
||||||
ensure($this->role == Role::PARTICIPANT || $this->role == Role::ENCADRANT, "Vous devez être participant ou encadrant.");
|
|
||||||
|
|
||||||
if ($this->role == Role::PARTICIPANT)
|
|
||||||
$this->class = SchoolClass::fromName(strtoupper($this->class));
|
|
||||||
else
|
|
||||||
$this->class = SchoolClass::ADULT;
|
|
||||||
|
|
||||||
$this->confirm_email_token = genRandomPhrase(64);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function register()
|
|
||||||
{
|
|
||||||
global $DB, $YEAR;
|
|
||||||
|
|
||||||
if (!$DB->query("SELECT `id` FROM `users` WHERE `year` = $YEAR;")->fetch())
|
|
||||||
$this->role = Role::ADMIN;
|
|
||||||
|
|
||||||
$req = $DB->prepare("INSERT INTO `users`(`email`, `pwd_hash`, `confirm_email`, `surname`, `first_name`,
|
|
||||||
`school`, `city`, `country`, `class`, `role`, `description`, `receive_animath_mails`, `year`)
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
|
|
||||||
$req->execute([$this->email, password_hash($this->password, PASSWORD_BCRYPT), $this->confirm_email_token,
|
|
||||||
$this->surname, $this->first_name, $this->school, $this->city, $this->country, SchoolClass::getName($this->class),
|
|
||||||
Role::getName($this->role), $this->description, $this->receive_animath_mails, $YEAR]);
|
|
||||||
|
|
||||||
Mailer::sendRegisterMail($this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once "server_files/views/inscription.php";
|
|
@ -1,23 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
if (isset($_SESSION["user_id"]) && isset($_SESSION["teams"]) && sizeof($_SESSION["teams"]) > 0) {
|
|
||||||
/**
|
|
||||||
* @var User $user
|
|
||||||
* @var Team team
|
|
||||||
*/
|
|
||||||
$user = $_SESSION["user"];
|
|
||||||
$team = $user->getRole() == Role::PARTICIPANT ? $_SESSION["team"] : Team::fromTrigram($_GET["trigram"]);
|
|
||||||
|
|
||||||
if ($team == null)
|
|
||||||
require_once "server_files/404.php";
|
|
||||||
|
|
||||||
if ($user->getRole() == Role::ENCADRANT && $team->getEncadrantId() != $user->getId())
|
|
||||||
require_once "server_files/403.php";
|
|
||||||
|
|
||||||
$video = Video::getVideo(Reason::SOLUTION, $team);
|
|
||||||
$questions_received = Question::getQuestionsTo($team);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
require_once "server_files/403.php";
|
|
||||||
|
|
||||||
require_once "server_files/views/ma_participation.php";
|
|
@ -1,177 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
if (!isset($_SESSION["user_id"]))
|
|
||||||
require_once "server_files/403.php";
|
|
||||||
|
|
||||||
/** @var User $user */
|
|
||||||
$user = $_SESSION["user"];
|
|
||||||
|
|
||||||
$has_error = false;
|
|
||||||
$error_message = null;
|
|
||||||
|
|
||||||
if (isset($_POST["update_account"])) {
|
|
||||||
$my_account = new MyAccount($_POST);
|
|
||||||
try {
|
|
||||||
$my_account->makeVerifications();
|
|
||||||
$my_account->updateAccount();
|
|
||||||
}
|
|
||||||
catch (AssertionError $e) {
|
|
||||||
$has_error = true;
|
|
||||||
$error_message = $e->getMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST["update_password"])) {
|
|
||||||
$new_password = new NewPassword($_POST);
|
|
||||||
try {
|
|
||||||
$new_password->makeVerifications();
|
|
||||||
$new_password->updatePassword();
|
|
||||||
}
|
|
||||||
catch (AssertionError $e) {
|
|
||||||
$has_error = true;
|
|
||||||
$error_message = $e->getMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST["send_document"])) {
|
|
||||||
$send_document = new SendDocument();
|
|
||||||
try {
|
|
||||||
$send_document->makeVerifications();
|
|
||||||
$send_document->sendDocument();
|
|
||||||
}
|
|
||||||
catch (AssertionError $e) {
|
|
||||||
$has_error = true;
|
|
||||||
$error_message = $e->getMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class MyAccount
|
|
||||||
{
|
|
||||||
public $email;
|
|
||||||
public $surname;
|
|
||||||
public $first_name;
|
|
||||||
public $school;
|
|
||||||
public $city;
|
|
||||||
public $country;
|
|
||||||
public $class;
|
|
||||||
public $description;
|
|
||||||
public $receive_animath_mails;
|
|
||||||
/** @var User */
|
|
||||||
private $user;
|
|
||||||
|
|
||||||
public function __construct($data)
|
|
||||||
{
|
|
||||||
foreach ($data as $key => $value)
|
|
||||||
$this->$key = htmlspecialchars($value);
|
|
||||||
|
|
||||||
$this->user = $_SESSION["user"];
|
|
||||||
|
|
||||||
$keys = ["email", "surname", "first_name", "school", "class", "description"];
|
|
||||||
|
|
||||||
if ($this->user->getRole() == Role::PARTICIPANT)
|
|
||||||
$this->class = SchoolClass::fromName($this->class);
|
|
||||||
|
|
||||||
foreach ($keys as $key)
|
|
||||||
$this->$key = $this->$key != null && $this->$key != "" ? $this->$key : $this->user->$key;
|
|
||||||
|
|
||||||
$this->receive_animath_mails = $this->receive_animath_mails == "on";
|
|
||||||
}
|
|
||||||
|
|
||||||
public function makeVerifications()
|
|
||||||
{
|
|
||||||
ensure(filter_var($this->email, FILTER_VALIDATE_EMAIL), "L'adresse e-mail entrée est invalide.");
|
|
||||||
$this->email = strtolower($this->email);
|
|
||||||
ensure($this->email == $this->user->getEmail() || !userExists($this->email), "Un compte existe déjà avec cette adresse e-mail.");
|
|
||||||
$this->receive_animath_mails = $this->receive_animath_mails != false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function updateAccount()
|
|
||||||
{
|
|
||||||
$this->user->setSurname($this->surname);
|
|
||||||
$this->user->setFirstName($this->first_name);
|
|
||||||
$this->user->setSchool($this->school);
|
|
||||||
$this->user->setCity($this->city);
|
|
||||||
$this->user->setCountry($this->country);
|
|
||||||
$this->user->setClass($this->class);
|
|
||||||
$this->user->setDescription($this->description);
|
|
||||||
$this->user->setReceiveAnimathMails($this->receive_animath_mails);
|
|
||||||
|
|
||||||
if ($this->email != $this->user->getEmail()) {
|
|
||||||
$this->user->setEmail($this->email);
|
|
||||||
$this->user->setConfirmEmailToken(genRandomPhrase(64));
|
|
||||||
|
|
||||||
Mailer::sendChangeEmailAddressMail($this->user);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class NewPassword
|
|
||||||
{
|
|
||||||
private $user;
|
|
||||||
private $old_password;
|
|
||||||
private $new_password;
|
|
||||||
private $confirm_password;
|
|
||||||
|
|
||||||
public function __construct($data)
|
|
||||||
{
|
|
||||||
foreach ($data as $key => $value)
|
|
||||||
$this->$key = htmlspecialchars($value);
|
|
||||||
|
|
||||||
$this->user = $_SESSION["user"];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function makeVerifications()
|
|
||||||
{
|
|
||||||
ensure($this->user->checkPassword($this->old_password), "L'ancien mot de passe est incorrect.");
|
|
||||||
ensure(strlen($this->new_password) >= 8, "Le mot de passe doit comporter au moins 8 caractères.");
|
|
||||||
ensure($this->new_password == $this->confirm_password, "Les deux mots de passe sont différents.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function updatePassword()
|
|
||||||
{
|
|
||||||
$this->user->setPassword($this->new_password);
|
|
||||||
|
|
||||||
Mailer::sendChangePasswordMail($this->user);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SendDocument
|
|
||||||
{
|
|
||||||
private $file;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->file = $_FILES["document"];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function makeVerifications()
|
|
||||||
{
|
|
||||||
global $LOCAL_PATH;
|
|
||||||
|
|
||||||
ensure($this->file["size"] <= 2e6, "Le fichier doit peser moins que 2 Mo.");
|
|
||||||
ensure(!$this->file["error"], "Une erreur est survenue.");
|
|
||||||
$mime_type = finfo_file(finfo_open(FILEINFO_MIME_TYPE), $this->file["tmp_name"]);
|
|
||||||
ensure($mime_type == "application/pdf" || $mime_type == "image/png" || $mime_type == "image/jpeg", "Le fichier doit être au format PDF.");
|
|
||||||
ensure(is_dir("$LOCAL_PATH/files") || mkdir("$LOCAL_PATH/files"), "Un problème est survenu dans l'envoi du fichier. Veuillez vérifier que le fichier pèse moins de 2 Mo. Merci de compresser votre fichier si tel n'est pas le cas. En cas de problème, merci de contacter l'administrateur du serveur.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function sendDocument()
|
|
||||||
{
|
|
||||||
global $LOCAL_PATH, $DB;
|
|
||||||
|
|
||||||
do
|
|
||||||
$id = genRandomPhrase(64);
|
|
||||||
while (file_exists("$LOCAL_PATH/files/$id"));
|
|
||||||
|
|
||||||
if (!rename($this->file["tmp_name"], "$LOCAL_PATH/files/$id"))
|
|
||||||
throw new AssertionError("Une erreur est survenue lors de l'envoi du fichier.");
|
|
||||||
|
|
||||||
$req = $DB->prepare("INSERT INTO `documents`(`file_id`, `user`, `team`, `problem`)
|
|
||||||
VALUES (?, ?, ?, ?);");
|
|
||||||
$req->execute([$id, $_SESSION["user_id"], $_SESSION["team"]->getId(), $_SESSION["team"]->getProblem()]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$documents = $user->getAllDocuments();
|
|
||||||
|
|
||||||
require_once "server_files/views/mon_compte.php";
|
|
@ -1,112 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
if (isset($_POST["leave_team"])) {
|
|
||||||
quitTeam();
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
$has_error = false;
|
|
||||||
$error_message = null;
|
|
||||||
|
|
||||||
if (isset($_POST["team_edit"])) {
|
|
||||||
$my_team = new MyTeam($_POST);
|
|
||||||
try {
|
|
||||||
$my_team->makeVerifications();
|
|
||||||
$my_team->updateTeam();
|
|
||||||
}
|
|
||||||
catch (AssertionError $e) {
|
|
||||||
$has_error = true;
|
|
||||||
$error_message = $e->getMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var User $user
|
|
||||||
* @var Team $team
|
|
||||||
*/
|
|
||||||
$user = $_SESSION["user"];
|
|
||||||
$team = $user->getRole() == Role::PARTICIPANT ? $_SESSION["team"] : Team::fromTrigram($_GET["trigram"]);
|
|
||||||
|
|
||||||
if (isset($_POST["request_validation"])) {
|
|
||||||
if (!canValidate($team)) {
|
|
||||||
$has_error = true;
|
|
||||||
$error_message = "Votre équipe ne peut pas demander la validation : il manque soit des participants, soit des documents.";
|
|
||||||
}
|
|
||||||
else if (!isset($_POST["engage"])) {
|
|
||||||
$has_error = true;
|
|
||||||
$error_message = "Vous devez cocher la case qui vous engage à participer à l'intégralité des Correspondances.";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$team->setValidationStatus(ValidationStatus::WAITING);
|
|
||||||
Mailer::sendRequestValidationMail($team);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @var Question[][] $questions_received */
|
|
||||||
$questions_received = [];
|
|
||||||
|
|
||||||
if (isset($_SESSION["user_id"]) && isset($_SESSION["teams"]) && sizeof($_SESSION["teams"]) > 0) {
|
|
||||||
if ($team == null)
|
|
||||||
require_once "server_files/404.php";
|
|
||||||
|
|
||||||
if ($user->getRole() == Role::ENCADRANT && $team->getEncadrantId() != $user->getId())
|
|
||||||
require_once "server_files/403.php";
|
|
||||||
|
|
||||||
$documents = $team->getAllDocuments();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
require_once "server_files/403.php";
|
|
||||||
|
|
||||||
if (isset($_GET["publish_videos"])) {
|
|
||||||
$team->setAllowPublish(!$team->allowPublish());
|
|
||||||
header("Location: /mon-equipe");
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
class MyTeam
|
|
||||||
{
|
|
||||||
public $name;
|
|
||||||
public $trigram;
|
|
||||||
public $problem;
|
|
||||||
/** @var Team */
|
|
||||||
private $team;
|
|
||||||
|
|
||||||
public function __construct($data)
|
|
||||||
{
|
|
||||||
foreach ($data as $key => $value)
|
|
||||||
$this->$key = htmlspecialchars($value);
|
|
||||||
|
|
||||||
$this->trigram = strtoupper($this->trigram);
|
|
||||||
$this->team = $_SESSION["team"];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function makeVerifications()
|
|
||||||
{
|
|
||||||
global $CONFIG;
|
|
||||||
|
|
||||||
ensure($this->name != "" && $this->name != null, "Veuillez spécifier un nom d'équipe.");
|
|
||||||
ensure($this->name == $this->team->getName() || !teamExists($this->name), "Une équipe existe déjà avec ce nom.");
|
|
||||||
ensure(preg_match("#^[\p{L} ]+$#ui", $this->name), "Le nom de l'équipe ne doit pas comporter de caractères spéciaux.");
|
|
||||||
ensure(preg_match("#^[A-Z]{3}$#", $this->trigram), "Le trigramme n'est pas valide.");
|
|
||||||
ensure($this->trigram == $this->team->getTrigram() || !trigramExists($this->trigram), "Une équipe a déjà choisi ce trigramme.");
|
|
||||||
ensure(preg_match("#^[0-4]$#", $this->problem), "Le problème indiqué n'existe pas.");
|
|
||||||
ensure(date("Y-m-d H:i:s") <= $CONFIG->getInscriptionDate(), "Les inscriptions sont terminées.");
|
|
||||||
ensure($this->team->getValidationStatus() == ValidationStatus::NOT_READY, "Votre équipe est déjà validée ou en cours de validation.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function updateTeam()
|
|
||||||
{
|
|
||||||
global $DB, $URL_BASE;
|
|
||||||
|
|
||||||
$this->team->setName($this->name);
|
|
||||||
$this->team->setTrigram($this->trigram);
|
|
||||||
$this->team->setProblem($this->problem);
|
|
||||||
|
|
||||||
$DB->exec("UPDATE `teams` SET `problem` = " . $this->problem . " WHERE `id` = " . $this->team->getId() . ";");
|
|
||||||
$DB->exec("UPDATE `documents` SET `problem` = " . $this->problem . " WHERE `team` = " . $this->team->getId() . ";");
|
|
||||||
|
|
||||||
header("Location: $URL_BASE/mon-equipe");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once "server_files/views/mon_equipe.php";
|
|
@ -1,137 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
if (!isset($_SESSION["user_id"]) || $_SESSION["role"] != Role::PARTICIPANT && $_SESSION["role"] != Role::ENCADRANT || Phase::getCurrentPhase() != Phase::PHASE2)
|
|
||||||
require_once "server_files/403.php";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var User $user
|
|
||||||
* @var Team $team
|
|
||||||
*/
|
|
||||||
$user = $_SESSION["user"];
|
|
||||||
$team = $user->getRole() == Role::PARTICIPANT ? $_SESSION["team"] : Team::fromTrigram($_GET["trigram"]);
|
|
||||||
|
|
||||||
if ($team == null)
|
|
||||||
require_once "server_files/404.php";
|
|
||||||
|
|
||||||
if ($user->getRole() == Role::ENCADRANT && $team->getEncadrantId() != $user->getId() || $team->getValidationStatus() != ValidationStatus::VALIDATED)
|
|
||||||
require_once "server_files/403.php";
|
|
||||||
|
|
||||||
$has_error = false;
|
|
||||||
$error_message = null;
|
|
||||||
|
|
||||||
if (isset($_POST["give_questions"])) {
|
|
||||||
$give_questions = new GiveQuestions($_POST, $_FILES);
|
|
||||||
try {
|
|
||||||
$give_questions->makeVerifications();
|
|
||||||
$give_questions->giveQuestions();
|
|
||||||
} catch (AssertionError $e) {
|
|
||||||
$has_error = true;
|
|
||||||
$error_message = $e->getMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class GiveQuestions
|
|
||||||
{
|
|
||||||
private $to;
|
|
||||||
/**
|
|
||||||
* @var Team $to_team
|
|
||||||
*/
|
|
||||||
private $to_team;
|
|
||||||
private $question_0;
|
|
||||||
private $question_1;
|
|
||||||
private $question_2;
|
|
||||||
private $question_3;
|
|
||||||
private $question_4;
|
|
||||||
private $question_5;
|
|
||||||
private $question_6;
|
|
||||||
private $questions;
|
|
||||||
private $no_drawing;
|
|
||||||
private $has_files;
|
|
||||||
private $files;
|
|
||||||
|
|
||||||
public function __construct($data, $files)
|
|
||||||
{
|
|
||||||
foreach ($data as $key => $value) {
|
|
||||||
$this->$key = $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->files = [];
|
|
||||||
$this->has_files = false;
|
|
||||||
|
|
||||||
for ($i = 0; $i <= 6; ++$i) {
|
|
||||||
if (strlen($files["file_$i"]["name"]) > 0) {
|
|
||||||
$this->files[] = $files["file_$i"];
|
|
||||||
$this->has_files = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
$this->files[] = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->questions = [$this->question_0, $this->question_1, $this->question_2, $this->question_3, $this->question_4, $this->question_5, $this->question_6];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function makeVerifications()
|
|
||||||
{
|
|
||||||
global $LOCAL_PATH, $team;
|
|
||||||
|
|
||||||
$this->to_team = Team::fromTrigram($this->to);
|
|
||||||
ensure($this->to_team, "L'équipe indiquée n'existe pas.");
|
|
||||||
ensure($team->getProblem() == $this->to_team->getProblem(), "Les équipes ne travaillent pas sur le même problème.");
|
|
||||||
ensure($this->question_1 != null && $this->question_1 != "" && $this->question_2 != null && $this->question_2 != "" && $this->question_3 != null && $this->question_3 != "",
|
|
||||||
"Vous devez poser au moins 3 questions.");
|
|
||||||
ensure(!$this->has_files || $this->no_drawing, "Vous devez confirmer ne pas avoir inclus de texte dans vos pièces jointes.");
|
|
||||||
|
|
||||||
for ($i = 4; $i <= 6; ++$i) {
|
|
||||||
if ($this->questions[$i] == "")
|
|
||||||
$this->questions[$i] = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ($i = 0; $i <= 6; ++$i) {
|
|
||||||
ensure($this->files[$i]["size"] <= 2e6, "Le fichier doit peser moins que 2 Mo.");
|
|
||||||
ensure(!$this->files[$i]["error"], "Une erreur est survenue. Veuillez vérifier vos pièces jointes. Elles ne doivent pas peser plus de 2 Mo chacune.");
|
|
||||||
}
|
|
||||||
|
|
||||||
ensure(is_dir("$LOCAL_PATH/files") || mkdir("$LOCAL_PATH/files"), "Un problème est survenue dans l'envoi du fichier. Veuillez contacter l'administrateur du serveur.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function giveQuestions()
|
|
||||||
{
|
|
||||||
global $LOCAL_PATH, $team;
|
|
||||||
|
|
||||||
/** @var Question[] $questions */
|
|
||||||
$questions = Question::getQuestions($team, $this->to_team);
|
|
||||||
for ($i = 0; $i <= 6; ++$i) {
|
|
||||||
$question = $questions[$i];
|
|
||||||
if ($question->getQuestion() != $this->questions[$i] && $question->getAttachedFile() != null) {
|
|
||||||
unlink("$LOCAL_PATH/files/" . $question->getAttachedFile());
|
|
||||||
$question->setAttachedFile(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
$question->setQuestion($this->questions[$i]);
|
|
||||||
|
|
||||||
if ($this->files[$i] != null) {
|
|
||||||
do
|
|
||||||
$file_id = genRandomPhrase(64);
|
|
||||||
while (file_exists("$LOCAL_PATH/files/$file_id"));
|
|
||||||
|
|
||||||
if (!rename($this->files[$i]["tmp_name"], "$LOCAL_PATH/files/$file_id"))
|
|
||||||
throw new AssertionError("Une erreur est survenue lors de l'envoi du fichier.");
|
|
||||||
|
|
||||||
$question->setAttachedFile($file_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var Team[] $receivers
|
|
||||||
* @var Video[] $videos
|
|
||||||
* @var Question[][] $questions
|
|
||||||
*/
|
|
||||||
$receivers = [Team::fromId($team->getVideoTeamIds()[0]), Team::fromId($team->getVideoTeamIds()[1])];
|
|
||||||
$videos = [Video::getVideo(Reason::SOLUTION, $receivers[0], Video::ACCEPTED),
|
|
||||||
Video::getVideo(Reason::SOLUTION, $receivers[1], Video::ACCEPTED)];
|
|
||||||
$questions = [Question::getQuestions($team, $receivers[0]),
|
|
||||||
Question::getQuestions($team, $receivers[1])];
|
|
||||||
|
|
||||||
require_once "server_files/views/poser_questions.php";
|
|
@ -1,26 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
$problem = htmlspecialchars($_GET["probleme"]);
|
|
||||||
|
|
||||||
if (!preg_match("#[0-4]#", $problem))
|
|
||||||
require_once "server_files/404.php";
|
|
||||||
|
|
||||||
if (!isset($_SESSION["user_id"]) || $_SESSION["role"] != Role::ADMIN)
|
|
||||||
require_once "server_files/403.php";
|
|
||||||
|
|
||||||
$has_error = false;
|
|
||||||
$error_message = null;
|
|
||||||
|
|
||||||
$teams = Team::getAllTeams($problem);
|
|
||||||
|
|
||||||
$validated_emails = [];
|
|
||||||
$not_validated_emails = [];
|
|
||||||
|
|
||||||
foreach ($teams as $team) {
|
|
||||||
if ($team->getValidationStatus() == ValidationStatus::VALIDATED)
|
|
||||||
$validated_emails = array_merge($validated_emails, $team->getAllEmails());
|
|
||||||
else
|
|
||||||
$not_validated_emails = array_merge($not_validated_emails, $team->getAllEmails());
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once "server_files/views/probleme.php";
|
|
@ -1,9 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
if (!isset($_SESSION["user_id"]) || $_SESSION["role"] != Role::ADMIN)
|
|
||||||
require_once "server_files/403.php";
|
|
||||||
|
|
||||||
$orphans = isset($_GET["orphans"]);
|
|
||||||
$users = $orphans ? User::getOrphanUsers() : User::getAllUsers();
|
|
||||||
|
|
||||||
require_once "server_files/views/profiles.php";
|
|
@ -1,71 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
if ((isset($_SESSION["team"]) && $_SESSION["role"] == Role::PARTICIPANT) || !isset($_SESSION["user"]) || ($_SESSION["role"] != Role::PARTICIPANT && $_SESSION["role"] != Role::ENCADRANT))
|
|
||||||
require_once "server_files/403.php";
|
|
||||||
|
|
||||||
$has_error = false;
|
|
||||||
$error_message = null;
|
|
||||||
|
|
||||||
if (isset($_POST["join_team"])) {
|
|
||||||
$join_team = new JoinTeam($_POST);
|
|
||||||
try {
|
|
||||||
$join_team->makeVerifications();
|
|
||||||
$join_team->joinTeam();
|
|
||||||
} catch (AssertionError $e) {
|
|
||||||
$has_error = true;
|
|
||||||
$error_message = $e->getMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class JoinTeam
|
|
||||||
{
|
|
||||||
private $access_code;
|
|
||||||
private $team;
|
|
||||||
private $min_null_index;
|
|
||||||
|
|
||||||
public function __construct($data)
|
|
||||||
{
|
|
||||||
$this->access_code = strtolower(htmlspecialchars($data["access_code"]));
|
|
||||||
$this->team = Team::fromAccessCode($this->access_code);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function makeVerifications()
|
|
||||||
{
|
|
||||||
global $CONFIG;
|
|
||||||
|
|
||||||
ensure(date("Y-m-d H:i:s") < $CONFIG->getInscriptionDate(), "La date limite d'inscription est dépassée.");
|
|
||||||
ensure($_SESSION["team"] == null || $_SESSION["role"] == Role::ENCADRANT, "Vous êtes déjà dans une équipe.");
|
|
||||||
ensure(preg_match("#[a-z0-9]{6}#", $this->access_code), "Le code d'accès doit comporter 6 caractères alphanumériques.");
|
|
||||||
ensure($this->team != null, "Ce code d'accès est invalide.");
|
|
||||||
ensure($this->team->getValidationStatus() == ValidationStatus::NOT_READY, "Cette équipe est déjà validée ou en cours de validation, vous ne pouvez pas la rejoindre.");
|
|
||||||
|
|
||||||
for ($i = 1; $i <= ($_SESSION["role"] == Role::PARTICIPANT ? 5 : 1); ++$i) {
|
|
||||||
if (($_SESSION["role"] == Role::PARTICIPANT ? $this->team->getParticipants()[$i - 1] : $this->team->getEncadrantId()) == NULL)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->min_null_index = $i;
|
|
||||||
|
|
||||||
ensure($_SESSION["role"] == Role::PARTICIPANT && $this->min_null_index <= 5 || $_SESSION["role"] == Role::ENCADRANT && $this->min_null_index <= 1, "Il n'y a plus de place pour vous dans l'équipe.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function joinTeam()
|
|
||||||
{
|
|
||||||
global $team;
|
|
||||||
|
|
||||||
$user = $_SESSION["user"];
|
|
||||||
|
|
||||||
$user->setTeamId($this->team->getId());
|
|
||||||
|
|
||||||
if ($_SESSION["role"] == Role::ENCADRANT)
|
|
||||||
$this->team->setEncadrant($user->getId());
|
|
||||||
else
|
|
||||||
$this->team->setParticipant($this->min_null_index, $user->getId());
|
|
||||||
|
|
||||||
$team = $_SESSION["team"] = $this->team;
|
|
||||||
|
|
||||||
Mailer::sendJoinTeamMail($user, $this->team);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once "server_files/views/rejoindre_equipe.php";
|
|
@ -1,126 +0,0 @@
|
|||||||
<?php
|
|
||||||
if (!isset($_SESSION["user_id"]) || $_SESSION["role"] != Role::PARTICIPANT && $_SESSION["role"] != Role::ENCADRANT || Phase::getCurrentPhase() != Phase::PHASE3)
|
|
||||||
require_once "server_files/403.php";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var User $user
|
|
||||||
* @var Team $team
|
|
||||||
*/
|
|
||||||
$user = $_SESSION["user"];
|
|
||||||
$team = $user->getRole() == Role::PARTICIPANT ? $_SESSION["team"] : Team::fromTrigram($_GET["trigram"]);
|
|
||||||
|
|
||||||
if ($team == null)
|
|
||||||
require_once "server_files/404.php";
|
|
||||||
|
|
||||||
if ($user->getRole() == Role::ENCADRANT && $team->getEncadrantId() != $user->getId() || $team->getValidationStatus() != ValidationStatus::VALIDATED)
|
|
||||||
require_once "server_files/403.php";
|
|
||||||
|
|
||||||
$has_error = false;
|
|
||||||
$error_message = null;
|
|
||||||
|
|
||||||
if (isset($_POST["answer"])) {
|
|
||||||
$answer_questions = new AnswerQuestions($_POST, $_FILES);
|
|
||||||
try {
|
|
||||||
$answer_questions->makeVerifications();
|
|
||||||
$answer_questions->answerQuestions();
|
|
||||||
} catch (AssertionError $e) {
|
|
||||||
$has_error = true;
|
|
||||||
$error_message = $e->getMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class AnswerQuestions
|
|
||||||
{
|
|
||||||
private $from;
|
|
||||||
/**
|
|
||||||
* @var Team $to_team
|
|
||||||
*/
|
|
||||||
private $from_team;
|
|
||||||
private $answer_0;
|
|
||||||
private $answer_1;
|
|
||||||
private $answer_2;
|
|
||||||
private $answer_3;
|
|
||||||
private $answer_4;
|
|
||||||
private $answer_5;
|
|
||||||
private $answer_6;
|
|
||||||
private $answers;
|
|
||||||
private $no_drawing;
|
|
||||||
private $has_files;
|
|
||||||
private $files;
|
|
||||||
|
|
||||||
public function __construct($data, $files)
|
|
||||||
{
|
|
||||||
foreach ($data as $key => $value) {
|
|
||||||
$this->$key = $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->files = [];
|
|
||||||
$this->has_files = false;
|
|
||||||
|
|
||||||
for ($i = 0; $i <= 6; ++$i) {
|
|
||||||
if (strlen($files["file_$i"]["name"]) > 0) {
|
|
||||||
$this->files[] = $files["file_$i"];
|
|
||||||
$this->has_files = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
$this->files[] = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->answers = [$this->answer_0, $this->answer_1, $this->answer_2, $this->answer_3, $this->answer_4, $this->answer_5, $this->answer_6];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function makeVerifications()
|
|
||||||
{
|
|
||||||
global $LOCAL_PATH, $team;
|
|
||||||
|
|
||||||
$this->from_team = Team::fromTrigram($this->from);
|
|
||||||
ensure($this->from_team != null, "L'équipe indiquée n'existe pas.");
|
|
||||||
ensure($team->getProblem() == $this->from_team->getProblem(), "Les équipes ne travaillent pas sur le même problème.");
|
|
||||||
ensure(!$this->has_files || $this->no_drawing, "Vous devez confirmer ne pas avoir inclus de texte dans vos pièces jointes.");
|
|
||||||
|
|
||||||
for ($i = 1; $i <= 6; ++$i) {
|
|
||||||
if ($this->answers[$i] == "")
|
|
||||||
$this->answers[$i] = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ($i = 0; $i <= 6; ++$i) {
|
|
||||||
ensure($this->files[$i]["size"] <= 2e6, "Le fichier doit peser moins que 2 Mo.");
|
|
||||||
ensure(!$this->files[$i]["error"], "Une erreur est survenue. Veuillez vérifier vos pièces jointes. Elles ne doivent pas peser plus de 2 Mo chacune.");
|
|
||||||
}
|
|
||||||
|
|
||||||
ensure(is_dir("$LOCAL_PATH/files") || mkdir("$LOCAL_PATH/files"), "Un problème est survenue dans l'envoi du fichier. Veuillez contacter l'administrateur du serveur.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function answerQuestions()
|
|
||||||
{
|
|
||||||
global $LOCAL_PATH, $team;
|
|
||||||
|
|
||||||
/** @var Question[] $questions */
|
|
||||||
$questions = Question::getQuestions($this->from_team, $team);
|
|
||||||
for ($i = 0; $i <= 6; ++$i) {
|
|
||||||
$question = $questions[$i];
|
|
||||||
if ($question->getAnswer() != $this->answers[$i] && $question->getAttachedFileAnswer() != null) {
|
|
||||||
unlink("$LOCAL_PATH/files/" . $question->getAttachedFileAnswer());
|
|
||||||
$question->setAttachedFileAnswer(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
$question->setAnswer($this->answers[$i]);
|
|
||||||
|
|
||||||
if ($this->files[$i] != null) {
|
|
||||||
do
|
|
||||||
$file_id = genRandomPhrase(64);
|
|
||||||
while (file_exists("$LOCAL_PATH/files/$file_id"));
|
|
||||||
|
|
||||||
if (!rename($this->files[$i]["tmp_name"], "$LOCAL_PATH/files/$file_id"))
|
|
||||||
throw new AssertionError("Une erreur est survenue lors de l'envoi du fichier.");
|
|
||||||
|
|
||||||
$question->setAttachedFileAnswer($file_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$questions = Question::getQuestionsTo($team);
|
|
||||||
$video = Video::getVideo(Reason::SOLUTION, $team);
|
|
||||||
|
|
||||||
require_once "server_files/views/repondre_questions.php";
|
|
@ -1,141 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
if (!isset($_SESSION["user_id"]) || $_SESSION["role"] != Role::ADMIN)
|
|
||||||
require_once "server_files/403.php";
|
|
||||||
|
|
||||||
$has_error = false;
|
|
||||||
$error_message = null;
|
|
||||||
|
|
||||||
if (isset($_POST["validate_video"])) {
|
|
||||||
$validate_video = new ValidateVideo($_POST);
|
|
||||||
try {
|
|
||||||
$validate_video->makeVerifications();
|
|
||||||
$validate_video->validate();
|
|
||||||
}
|
|
||||||
catch (AssertionError $e) {
|
|
||||||
$has_error = true;
|
|
||||||
$error_message = $e->getMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ValidateVideo
|
|
||||||
{
|
|
||||||
private $video_id;
|
|
||||||
private $accept;
|
|
||||||
private $reject;
|
|
||||||
/** @var Video */
|
|
||||||
private $video;
|
|
||||||
private $message;
|
|
||||||
|
|
||||||
public function __construct($data)
|
|
||||||
{
|
|
||||||
foreach ($data as $key => $value)
|
|
||||||
$this->$key = $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function makeVerifications()
|
|
||||||
{
|
|
||||||
$this->video = Video::fromId($this->video_id);
|
|
||||||
ensure($this->video != null, "La vidéo n'existe pas.");
|
|
||||||
ensure($this->video->getValidation() != 1, "La vidéo est déjà validée / rejetée.");
|
|
||||||
ensure(($this->accept == null || $this->reject == null) && $this->accept != $this->reject, "Impossible de déterminer s'il faut accepter ou non la vidéo.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function validate()
|
|
||||||
{
|
|
||||||
$this->video->setValidation($this->accept ? 1 : -1);
|
|
||||||
Mailer::validateVideo($this->video, $this->message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$videos = [];
|
|
||||||
|
|
||||||
if (!isset($_GET["problem"])) {
|
|
||||||
for ($problem = 1; $problem <= 4; ++$problem)
|
|
||||||
$videos[] = Video::getVideos(Reason::SOLUTION, $problem);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$videos = [[], [], [], []];
|
|
||||||
$videos[intval($_GET["problem"]) - 1] = Video::getVideos(Reason::SOLUTION, intval($_GET["problem"]));
|
|
||||||
}
|
|
||||||
|
|
||||||
$waiting_teams = [];
|
|
||||||
$waiting_emails = [];
|
|
||||||
|
|
||||||
switch (Phase::getCurrentPhase()) {
|
|
||||||
case Phase::PHASE1:
|
|
||||||
case Phase::PHASE12:
|
|
||||||
$req = $DB->query("SELECT DISTINCT `teams`.`id`, `teams`.`problem`, `teams`.`trigram` FROM `teams` WHERE `validation_status` = '" . ValidationStatus::getName(ValidationStatus::VALIDATED) . "'"
|
|
||||||
. " AND `id` NOT IN (SELECT DISTINCT `team` FROM `videos` WHERE `reason` = 'SOLUTION' AND `validation` = " . Video::ACCEPTED . ")"
|
|
||||||
. " AND `year` = $YEAR ORDER BY `problem`, `trigram`;");
|
|
||||||
break;
|
|
||||||
case Phase::PHASE2:
|
|
||||||
case Phase::PHASE23:
|
|
||||||
$req = $DB->query("SELECT DISTINCT `teams`.`id`, `teams`.`problem`, `teams`.`trigram` FROM `teams`"
|
|
||||||
. " WHERE `id` NOT IN (SELECT `q1`.`from` FROM `questions` AS `q1`"
|
|
||||||
. " JOIN `questions` AS `q2` ON `q2`.`from` = `q1`.`from` AND `q2`.`number` = 2"
|
|
||||||
. " JOIN `questions` AS `q3` ON `q3`.`from` = `q1`.`from` AND `q3`.`number` = 3"
|
|
||||||
. " JOIN `questions` AS `q4` ON `q4`.`from` = `q1`.`from` AND `q4`.`number` = 4"
|
|
||||||
. " JOIN `questions` AS `q5` ON `q5`.`from` = `q1`.`from` AND `q5`.`number` = 5"
|
|
||||||
. " JOIN `questions` AS `q6` ON `q6`.`from` = `q1`.`from` AND `q6`.`number` = 6"
|
|
||||||
. " WHERE `q1`.`number` = 1"
|
|
||||||
. " AND (`q1`.`question` != '" . Question::DEFAULT_QUESTIONS[0] . "'"
|
|
||||||
. " OR `q2`.`question` != '" . Question::DEFAULT_QUESTIONS[1] . "'"
|
|
||||||
. " OR `q3`.`question` != '" . Question::DEFAULT_QUESTIONS[2] . "'"
|
|
||||||
. " OR `q4`.`question` IS NOT NULL"
|
|
||||||
. " OR `q5`.`question` IS NOT NULL"
|
|
||||||
. " OR `q6`.`question` IS NOT NULL))"
|
|
||||||
. " AND `validation_status` = '" . ValidationStatus::getName(ValidationStatus::VALIDATED) . "'"
|
|
||||||
. " AND `year` = $YEAR ORDER BY `problem`, `trigram`;");
|
|
||||||
break;
|
|
||||||
case Phase::PHASE3:
|
|
||||||
case Phase::PHASE34:
|
|
||||||
$req = $DB->query("SELECT DISTINCT `teams`.`id`, `teams`.`problem`, `teams`.`trigram` FROM `teams`"
|
|
||||||
. " WHERE `id` NOT IN (SELECT `q1`.`to` FROM `questions` AS `q1`"
|
|
||||||
. " JOIN `questions` AS `q2` ON `q2`.`to` = `q1`.`to` AND `q2`.`number` = 2"
|
|
||||||
. " JOIN `questions` AS `q3` ON `q3`.`to` = `q1`.`to` AND `q3`.`number` = 3"
|
|
||||||
. " JOIN `questions` AS `q4` ON `q4`.`to` = `q1`.`to` AND `q4`.`number` = 4"
|
|
||||||
. " JOIN `questions` AS `q5` ON `q5`.`to` = `q1`.`to` AND `q5`.`number` = 5"
|
|
||||||
. " JOIN `questions` AS `q6` ON `q6`.`to` = `q1`.`to` AND `q6`.`number` = 6"
|
|
||||||
. " WHERE `q1`.`number` = 1"
|
|
||||||
. " AND (`q1`.`answer` IS NOT NULL"
|
|
||||||
. " OR `q2`.`answer` IS NOT NULL"
|
|
||||||
. " OR `q3`.`answer` IS NOT NULL"
|
|
||||||
. " OR `q4`.`answer` IS NOT NULL"
|
|
||||||
. " OR `q5`.`answer` IS NOT NULL"
|
|
||||||
. " OR `q6`.`answer` IS NOT NULL))"
|
|
||||||
. " AND `validation_status` = '" . ValidationStatus::getName(ValidationStatus::VALIDATED) . "'"
|
|
||||||
. " AND `year` = $YEAR ORDER BY `problem`, `trigram`;");
|
|
||||||
break;
|
|
||||||
case Phase::PHASE4:
|
|
||||||
case Phase::END:
|
|
||||||
$req = $DB->query("SELECT DISTINCT `teams`.`id`, `teams`.`problem`, `teams`.`trigram` FROM `teams` WHERE `validation_status` = '" . ValidationStatus::getName(ValidationStatus::VALIDATED) . "'"
|
|
||||||
. " AND (`id` NOT IN (SELECT DISTINCT `team` FROM `videos` WHERE `reason` = 'ANSWER1' AND `validation` = " . Video::ACCEPTED . ")"
|
|
||||||
. " OR `id` NOT IN (SELECT DISTINCT `team` FROM `videos` WHERE `reason` = 'ANSWER2' AND `validation` = " . Video::ACCEPTED . "))"
|
|
||||||
. " AND `year` = $YEAR ORDER BY `problem`, `trigram`;");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($req)) {
|
|
||||||
$waiting_emails = [];
|
|
||||||
while (($data = $req->fetch()) !== false) {
|
|
||||||
$team = Team::fromId($data["id"]);
|
|
||||||
if (Phase::getCurrentPhase() >= Phase::PHASE12 && $team->getSolution() == null)
|
|
||||||
continue;
|
|
||||||
if (isset($_GET["problem"]) && intval($_GET["problem"]) != $team->getProblem())
|
|
||||||
continue;
|
|
||||||
$waiting_teams[] = $team;
|
|
||||||
$waiting_emails = array_merge($waiting_emails, $team->getAllEmails());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$all_emails = [];
|
|
||||||
foreach (Team::getAllTeams() as $team) {
|
|
||||||
if (Phase::getCurrentPhase() >= Phase::PHASE12 && $team->getSolution() == null)
|
|
||||||
continue;
|
|
||||||
if (isset($_GET["problem"]) && intval($_GET["problem"]) != $team->getProblem())
|
|
||||||
continue;
|
|
||||||
$all_emails = array_merge($all_emails, $team->getAllEmails());
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once "server_files/views/suivi_correspondances.php";
|
|
@ -1,51 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
if (!isset($_GET["file_id"])) {
|
|
||||||
header("Location: $URL_BASE");
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isset($_SESSION["user_id"]))
|
|
||||||
require_once "server_files/403.php";
|
|
||||||
|
|
||||||
$id = htmlspecialchars($_GET["file_id"]);
|
|
||||||
|
|
||||||
$file = Document::fromId($id);
|
|
||||||
|
|
||||||
if ($file !== null) {
|
|
||||||
$team = Team::fromId($file->getTeamId());;
|
|
||||||
$trigram = $team->getTrigram();
|
|
||||||
|
|
||||||
$user = User::fromId($file->getUserId());
|
|
||||||
|
|
||||||
if (($_SESSION["role"] == Role::PARTICIPANT || $_SESSION["role"] == Role::ENCADRANT) && $user->getId() != $_SESSION["user_id"])
|
|
||||||
require_once "server_files/403.php";
|
|
||||||
|
|
||||||
$surname = $user->getSurname();
|
|
||||||
$first_name = $user->getFirstName();
|
|
||||||
$mime_type = finfo_file(finfo_open(FILEINFO_MIME_TYPE), "$LOCAL_PATH/files/$id");
|
|
||||||
$ext = $mime_type == "application/pdf" ? "pdf" : ($mime_type == "image/png" ? "png" : "jpg");
|
|
||||||
$name = "Autorisation de droit à l'image de $first_name $surname.$ext";
|
|
||||||
|
|
||||||
header("Content-Type: " . $mime_type);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$question = Question::fromAttachedFile($id);
|
|
||||||
if ($question != null)
|
|
||||||
{
|
|
||||||
$from = Team::fromId($question->getFrom());
|
|
||||||
$to = Team::fromId($question->getTo());
|
|
||||||
$mime_type = finfo_file(finfo_open(FILEINFO_MIME_TYPE), "$LOCAL_PATH/files/$id");
|
|
||||||
$name = "Pièce jointe n°" . $question->getNumber() . " de l'équipe " . $from->getTrigram() . " pour l'équipe " . $from->getTrigram() . " (problème " . $question->getProblem() . ")";
|
|
||||||
$name .= getExtFromMimeType($mime_type);
|
|
||||||
header("Content-Type: " . $mime_type);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
require_once "server_files/404.php";
|
|
||||||
}
|
|
||||||
|
|
||||||
header("Content-Disposition: inline; filename=\"$name\"");
|
|
||||||
|
|
||||||
readfile("$LOCAL_PATH/files/$id");
|
|
||||||
|
|
||||||
exit();
|
|
@ -1,326 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
function loadUserValues()
|
|
||||||
{
|
|
||||||
$_SESSION["user"] = $_SESSION["team"] = null;
|
|
||||||
unset($_SESSION["user"]);
|
|
||||||
unset($_SESSION["role"]);
|
|
||||||
unset($_SESSION["team"]);
|
|
||||||
unset($_SESSION["teams"]);
|
|
||||||
|
|
||||||
if (isset($_SESSION["user_id"])) {
|
|
||||||
$user = $_SESSION["user"] = User::fromId($_SESSION["user_id"]);
|
|
||||||
if ($user == null) {
|
|
||||||
unset($_SESSION["user_id"]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$_SESSION["role"] = $user->getRole();
|
|
||||||
|
|
||||||
$_SESSION["teams"] = $user->getTeams();
|
|
||||||
|
|
||||||
if ($user->getRole() == Role::PARTICIPANT)
|
|
||||||
$_SESSION["team"] = sizeof($_SESSION["teams"]) > 0 ? $_SESSION["teams"][0] : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_GET["view-as-admin"])) {
|
|
||||||
if (isset($_SESSION["admin"])) {
|
|
||||||
$_SESSION["user_id"] = $_SESSION["admin"];
|
|
||||||
unset($_SESSION["admin"]);
|
|
||||||
}
|
|
||||||
header("Location: /");
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function quitTeam($user_id = -1)
|
|
||||||
{
|
|
||||||
global $DB, $URL_BASE;
|
|
||||||
|
|
||||||
if ($user_id == -1)
|
|
||||||
header("Location: $URL_BASE");
|
|
||||||
|
|
||||||
$user_id = $user_id >= 0 ? $user_id : $_SESSION["user_id"];
|
|
||||||
/** @var User $user */
|
|
||||||
$user = User::fromId($user_id);
|
|
||||||
$role = $user->getRole();
|
|
||||||
|
|
||||||
if ($role == Role::ADMIN)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ($role == Role::PARTICIPANT)
|
|
||||||
for ($i = 1; $i <= 5; ++$i)
|
|
||||||
/** @noinspection SqlResolve */
|
|
||||||
$DB->exec("UPDATE `teams` SET `participant_$i` = NULL WHERE `participant_$i` = $user_id;");
|
|
||||||
else
|
|
||||||
$DB->exec("UPDATE `teams` SET `encadrant` = NULL WHERE `encadrant` = $user_id;");
|
|
||||||
$user->setTeamId(null);
|
|
||||||
for ($i = 1; $i <= 4; ++$i) {
|
|
||||||
/** @noinspection SqlResolve */
|
|
||||||
$DB->exec("UPDATE `teams` SET `participant_$i` = `participant_" . strval($i + 1) . "`, `participant_" . strval($i + 1) . "` = NULL WHERE `participant_$i` IS NULL;");
|
|
||||||
}
|
|
||||||
|
|
||||||
$DB->exec("DELETE FROM `teams` WHERE `encadrant` IS NULL AND `participant_1` IS NULL;");
|
|
||||||
$req = $DB->query("SELECT `file_id` FROM `documents` WHERE `user` = $user_id;");
|
|
||||||
while (($data = $req->fetch()) !== false)
|
|
||||||
unlink("$URL_BASE/files/" . $data["file_id"]);
|
|
||||||
$DB->exec("DELETE FROM `documents` WHERE `user` = $user_id;");
|
|
||||||
|
|
||||||
$_SESSION["team"] = null;
|
|
||||||
unset($_SESSION["team"]);
|
|
||||||
|
|
||||||
$_SESSION["teams"] = $user->getTeams();
|
|
||||||
}
|
|
||||||
|
|
||||||
function userExists($email)
|
|
||||||
{
|
|
||||||
global $DB, $YEAR;
|
|
||||||
|
|
||||||
$req = $DB->prepare("SELECT `id` FROM `users` WHERE `email` = ? AND `year` = '$YEAR';");
|
|
||||||
$req->execute([$email]);
|
|
||||||
return $req->fetch();
|
|
||||||
}
|
|
||||||
|
|
||||||
function teamExists($name)
|
|
||||||
{
|
|
||||||
global $DB, $YEAR;
|
|
||||||
|
|
||||||
$req = $DB->prepare("SELECT `id` FROM `teams` WHERE `name` = ? AND `year` = '$YEAR';");
|
|
||||||
$req->execute([$name]);
|
|
||||||
return $req->fetch();
|
|
||||||
}
|
|
||||||
|
|
||||||
function trigramExists($trigram)
|
|
||||||
{
|
|
||||||
global $DB, $YEAR;
|
|
||||||
|
|
||||||
$req = $DB->prepare("SELECT `id` FROM `teams` WHERE `trigram` = ? AND `year` = '$YEAR';");
|
|
||||||
$req->execute([$trigram]);
|
|
||||||
return $req->fetch();
|
|
||||||
}
|
|
||||||
|
|
||||||
function canValidate(Team $team)
|
|
||||||
{
|
|
||||||
global $DB, $CONFIG;
|
|
||||||
|
|
||||||
$can_validate = date("Y-m-d H:i:s") < $CONFIG->getInscriptionDate();
|
|
||||||
$can_validate &= $team->getValidationStatus() == ValidationStatus::NOT_READY;
|
|
||||||
$can_validate &= $team->getEncadrantId() != null;
|
|
||||||
$can_validate &= $team->getParticipants()[2] != null;
|
|
||||||
$can_validate &= preg_match("#[1-4]#", $team->getProblem());
|
|
||||||
|
|
||||||
for ($i = 0; $i < 5; ++$i) {
|
|
||||||
if ($team->getParticipants()[$i] === NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
$req = $DB->prepare("SELECT COUNT(*) AS `version` FROM `documents` WHERE `user` = ? AND `problem` = ?;");
|
|
||||||
$req->execute([$team->getParticipants()[$i], $team->getProblem()]);
|
|
||||||
$d = $req->fetch();
|
|
||||||
$can_validate &= $d["version"] > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $can_validate;
|
|
||||||
}
|
|
||||||
|
|
||||||
function printDocuments($documents)
|
|
||||||
{
|
|
||||||
if (sizeof($documents) == 0) {
|
|
||||||
echo "<div class=\"alert alert-warning\">\nPas de document envoyé pour le moment.\n</div>\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "<div class=\"alert alert-info\">\n";
|
|
||||||
foreach ($documents as $document) {
|
|
||||||
$file_id = $document->getFileId();
|
|
||||||
$user = User::fromId($document->getUserId());
|
|
||||||
$surname = $user->getSurname();
|
|
||||||
$first_name = $user->getFirstName();
|
|
||||||
$name = "Autorisation de droit à l'image";
|
|
||||||
$version = $document->getVersion();
|
|
||||||
echo "$name de $first_name $surname (version $version) : <a href=\"/file/$file_id\"><strong>Télécharger</strong></a><br />\n";
|
|
||||||
}
|
|
||||||
echo "</div>\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
function getZipFile($problem, $team_id = -1)
|
|
||||||
{
|
|
||||||
global $LOCAL_PATH;
|
|
||||||
|
|
||||||
$zip = new ZipArchive();
|
|
||||||
|
|
||||||
$file_name = tempnam("tmp", "corres2math-");
|
|
||||||
|
|
||||||
if ($zip->open($file_name, ZipArchive::CREATE) !== true) {
|
|
||||||
die("Impossible de créer le fichier zip.");
|
|
||||||
}
|
|
||||||
|
|
||||||
$data = Document::getAllDocuments($problem, $team_id);
|
|
||||||
|
|
||||||
/** @var Document $file */
|
|
||||||
foreach ($data as $file) {
|
|
||||||
$file_id = $file->getFileId();
|
|
||||||
$user = User::fromId($file->getUserId());
|
|
||||||
$mime_type = finfo_file(finfo_open(FILEINFO_MIME_TYPE), "$LOCAL_PATH/files/$file_id");
|
|
||||||
$ext = $mime_type == "application/pdf" ? "pdf" : ($mime_type == "image/png" ? "png" : "jpg");
|
|
||||||
$name = "Autorisation de droit à l'image de " . $user->getFirstName() . " " . $user->getSurname() . "." . $ext;
|
|
||||||
|
|
||||||
$zip->addFile("$LOCAL_PATH/files/$file_id", $name);
|
|
||||||
}
|
|
||||||
|
|
||||||
$zip->close();
|
|
||||||
|
|
||||||
return $file_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
function exportUserData() {
|
|
||||||
global $DB, $YEAR;
|
|
||||||
|
|
||||||
$file_name = tempnam("tmp", "corres2math-");
|
|
||||||
|
|
||||||
$csv = "Identifiant,Nom,Prénom,E-mail,École,Ville,Pays,Classe,Description,Rôle,Équipe,Autorise l'envoi de mails,Date d'inscription\n";
|
|
||||||
|
|
||||||
$req = $DB->query("SELECT `id` FROM `users` WHERE `year` = $YEAR;");
|
|
||||||
while (($data = $req->fetch()) !== false) {
|
|
||||||
$user = User::fromId($data["id"]);
|
|
||||||
|
|
||||||
$csv .= $user->getId() . ",";
|
|
||||||
$csv .= $user->getSurname() . ",";
|
|
||||||
$csv .= $user->getFirstName() . ",";
|
|
||||||
$csv .= $user->getEmail() . ",";
|
|
||||||
$csv .= $user->getSchool() . ",";
|
|
||||||
$csv .= $user->getCity() . ",";
|
|
||||||
$csv .= $user->getCountry() . ",";
|
|
||||||
$csv .= SchoolClass::getTranslatedName($user->getClass()) . ",";
|
|
||||||
$csv .= $user->getDescription() . ",";
|
|
||||||
$csv .= Role::getTranslatedName($user->getRole()) . ",";
|
|
||||||
$csv .= ($user->getTeamId() == null ? "" : Team::fromId($user->getTeamId())->getTrigram()) . ",";
|
|
||||||
$csv .= ($user->doReceiveAnimathMails() ? "oui" : "non") . ",";
|
|
||||||
$csv .= $user->getInscriptionDate() . "\n";
|
|
||||||
}
|
|
||||||
file_put_contents($file_name, $csv, FILE_APPEND);
|
|
||||||
|
|
||||||
return $file_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
function exportTeamData() {
|
|
||||||
global $DB, $YEAR;
|
|
||||||
|
|
||||||
$file_name = tempnam("tmp", "corres2math-");
|
|
||||||
|
|
||||||
$csv = "Identifiant,Nom,Trigramme,Problème,Encadrant,Participant 1,Participant 2,Participant 3,Participant 4,Participant 5,"
|
|
||||||
. "Date d'inscription,Autorise la publication,État de validation,Code d'accès\n";
|
|
||||||
|
|
||||||
$req = $DB->query("SELECT `id` FROM `teams` WHERE `year` = $YEAR ORDER BY `problem`;");
|
|
||||||
while (($data = $req->fetch()) !== false) {
|
|
||||||
$team = Team::fromId($data["id"]);
|
|
||||||
|
|
||||||
$csv .= $team->getId() . ",";
|
|
||||||
$csv .= $team->getName() . ",";
|
|
||||||
$csv .= $team->getTrigram() . ",";
|
|
||||||
$csv .= $team->getProblem() . ",";
|
|
||||||
$csv .= $team->getEncadrantId() . ",";
|
|
||||||
$csv .= $team->getParticipants()[0] . ",";
|
|
||||||
$csv .= $team->getParticipants()[1] . ",";
|
|
||||||
$csv .= $team->getParticipants()[2] . ",";
|
|
||||||
$csv .= $team->getParticipants()[3] . ",";
|
|
||||||
$csv .= $team->getParticipants()[4] . ",";
|
|
||||||
$csv .= $team->getInscriptionDate() . ",";
|
|
||||||
$csv .= $team->allowPublish() . ",";
|
|
||||||
$csv .= ValidationStatus::getTranslatedName($team->getValidationStatus()) . ",";
|
|
||||||
$csv .= $team->getAccessCode() . "\n";
|
|
||||||
}
|
|
||||||
file_put_contents($file_name, $csv, FILE_APPEND);
|
|
||||||
|
|
||||||
return $file_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
function exportProblemsData() {
|
|
||||||
global $DB, $URL_BASE, $YEAR;
|
|
||||||
|
|
||||||
$file_name = tempnam("tmp", "corres2math-");
|
|
||||||
|
|
||||||
$csv = "Équipe,Problème,Lien,Équipe 1 ayant reçu la vidéo,"
|
|
||||||
. "Question 1,Pièce jointe,Réponse,Pièce jointe,"
|
|
||||||
. "Question 2,Pièce jointe,Réponse,Pièce jointe,"
|
|
||||||
. "Question 3,Pièce jointe,Réponse,Pièce jointe,"
|
|
||||||
. "Question 4,Pièce jointe,Réponse,Pièce jointe,"
|
|
||||||
. "Question 5,Pièce jointe,Réponse,Pièce jointe,"
|
|
||||||
. "Question 6,Pièce jointe,Réponse,Pièce jointe,"
|
|
||||||
. "Vidéo de réponse,"
|
|
||||||
. "Équipe 2 ayant reçu la vidéo,"
|
|
||||||
. "Question 1,Pièce jointe,Réponse,Pièce jointe,"
|
|
||||||
. "Question 2,Pièce jointe,Réponse,Pièce jointe,"
|
|
||||||
. "Question 3,Pièce jointe,Réponse,Pièce jointe,"
|
|
||||||
. "Question 4,Pièce jointe,Réponse,Pièce jointe,"
|
|
||||||
. "Question 5,Pièce jointe,Réponse,Pièce jointe,"
|
|
||||||
. "Question 6,Pièce jointe,Réponse,Pièce jointe,"
|
|
||||||
. "Vidéo de réponse\n";
|
|
||||||
|
|
||||||
$req = $DB->query("SELECT `id` FROM `teams` WHERE `validation_status` = 'VALIDATED' AND `year` = $YEAR ORDER BY `problem`;");
|
|
||||||
while (($data = $req->fetch()) !== false) {
|
|
||||||
$team = Team::fromId($data["id"]);
|
|
||||||
$video = Video::getVideo(Reason::SOLUTION, $team);
|
|
||||||
$questions_received = Question::getQuestionsTo($team);
|
|
||||||
|
|
||||||
$csv .= $team->getTrigram() . ",";
|
|
||||||
$csv .= $team->getProblem() . ",";
|
|
||||||
$csv .= ($video == null ? "" : $video->getLink()) . ",";
|
|
||||||
for ($i = 0; $i < 2; ++$i) {
|
|
||||||
/** @var Question[] $questions */
|
|
||||||
$questions = $questions_received[$i];
|
|
||||||
$asker = Team::fromId($questions[0]->getFrom());
|
|
||||||
$csv .= $asker->getTrigram() . ",";
|
|
||||||
|
|
||||||
for ($j = 0; $j < 6; ++$j) {
|
|
||||||
$question = $questions[$j];
|
|
||||||
|
|
||||||
if ($question == null) {
|
|
||||||
$csv .= ",,,,";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$csv .= $question->getQuestion() . ",";
|
|
||||||
$csv .= ($question->getAttachedFile() == null ? "" : $URL_BASE . "/file/" . $question->getAttachedFile()) . ',';
|
|
||||||
$csv .= $question->getAnswer() . ",";
|
|
||||||
$csv .= ($question->getAttachedFileAnswer() == null ? "" : $URL_BASE . "/file/" . $question->getAttachedFileAnswer()) . ',';
|
|
||||||
}
|
|
||||||
|
|
||||||
$answer = Video::getVideo($asker->getVideoTeamIds()[0] == $team->getId() ? Reason::ANSWER1 : Reason::ANSWER2,
|
|
||||||
$asker, Video::ACCEPTED);
|
|
||||||
$csv .= $answer == null ? "" : $answer->getLink();
|
|
||||||
$csv .= ($i == 0 ? "," : "\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
file_put_contents($file_name, $csv, FILE_APPEND);
|
|
||||||
|
|
||||||
return $file_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
function displayVideo($link)
|
|
||||||
{
|
|
||||||
if (preg_match("#(https?://|)(www\.|)(youtube\.com/watch\?v=|youtu.be/)([a-zA-Z0-9,\-,_]*)?.*?#", $link, $matches)) {
|
|
||||||
$code = $matches[4];
|
|
||||||
/** @noinspection HtmlDeprecatedAttribute */
|
|
||||||
/** @noinspection HtmlDeprecatedTag */
|
|
||||||
echo "<center><iframe width=\"854px\" height=\"480px\" src=\"https://www.youtube.com/embed/$code\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe></center><br />\n";
|
|
||||||
}
|
|
||||||
elseif (preg_match("#(https?://|)drive\.google\.com/(file/d/|open\?id=)([a-zA-Z0-9\-_]*)/?.*?#", $link, $matches)) {
|
|
||||||
$code = $matches[3];
|
|
||||||
/** @noinspection HtmlDeprecatedAttribute */
|
|
||||||
/** @noinspection HtmlDeprecatedTag */
|
|
||||||
echo "<center><iframe width=\"854px\" height=\"480px\" src=\"https://drive.google.com/file/d/$code/preview\" allowfullscreen></iframe></center><br />\n";
|
|
||||||
}
|
|
||||||
elseif (preg_match("#(https?://|)(www\.|)vimeo\.com/([0-9]*)#", $link, $matches)) {
|
|
||||||
$code = $matches[3];
|
|
||||||
/** @noinspection HtmlDeprecatedAttribute */
|
|
||||||
/** @noinspection HtmlDeprecatedTag */
|
|
||||||
echo "<center><iframe src=\"https://player.vimeo.com/video/$code?color=3be6c3\" width=\"853\" height=\"480\" frameborder=\"0\" allow=\"autoplay; fullscreen\" allowfullscreen></iframe></center>";
|
|
||||||
|
|
||||||
}
|
|
||||||
elseif (preg_match("#(https?://|)(www\.|)dailymotion\.com/video/(.*)#", $link, $matches)) {
|
|
||||||
$code = $matches[3];
|
|
||||||
/** @noinspection HtmlDeprecatedAttribute */
|
|
||||||
/** @noinspection HtmlDeprecatedTag */
|
|
||||||
echo "<center><iframe frameborder=\"0\" width=\"853\" height=\"480\" src=\"https://www.dailymotion.com/embed/video/$code\" allowfullscreen allow=\"autoplay\"></iframe></center>";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,256 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
class Mailer
|
|
||||||
{
|
|
||||||
private static function sendMail($email, $subject, $content, $from = "contact")
|
|
||||||
{
|
|
||||||
global $MAIL_DOMAIN, $URL_BASE, $YEAR;
|
|
||||||
|
|
||||||
$content = preg_replace("#{URL_BASE}#", $URL_BASE, $content);
|
|
||||||
$content = preg_replace("#{YEAR}#", $YEAR . "- " . ($YEAR + 1), $content);
|
|
||||||
|
|
||||||
$headers = "From: \"Contact Corres2Math\" <" . $from . "@" . $MAIL_DOMAIN . ">\r\n";
|
|
||||||
$headers .= "Reply-To: \"Contact corres2Math\" <contact@" . $MAIL_DOMAIN . ">\r\n";
|
|
||||||
$headers .= "Content-Type: text/html; charset=UTF-8\r\n";
|
|
||||||
|
|
||||||
ensure(mail($email, $subject, $content, $headers), "Un problème est survenu dans l'envoi d'un mail. Veuiller contacter votre administrateur.");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static function broadcastToTeam(Team $team, $subject, $content, $from = "contact")
|
|
||||||
{
|
|
||||||
$content = preg_replace("#{TEAM_NAME}#", $team->getName(), $content);
|
|
||||||
$content = preg_replace("#{TRIGRAM}#", $team->getTrigram(), $content);
|
|
||||||
|
|
||||||
$encadrant = User::fromId($team->getEncadrantId());
|
|
||||||
|
|
||||||
if ($encadrant != null) {
|
|
||||||
$c = preg_replace("#{FIRST_NAME}#", $encadrant->getFirstName(), $content);
|
|
||||||
$c = preg_replace("#{SURNAME}#", $encadrant->getSurname(), $c);
|
|
||||||
self::sendMail($encadrant->getEmail(), $subject, $c, $from);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($team->getParticipants() as $participant_id) {
|
|
||||||
$participant = User::fromId($participant_id);
|
|
||||||
if ($participant == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
$c = preg_replace("#{FIRST_NAME}#", $participant->getFirstName(), $content);
|
|
||||||
$c = preg_replace("#{SURNAME}#", $participant->getSurname(), $c);
|
|
||||||
self::sendMail($participant->getEmail(), $subject, $c, $from);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static function broadcastToAdmins($subject, $content, $from = "contact")
|
|
||||||
{
|
|
||||||
/** @var User $admin */
|
|
||||||
foreach (User::getAdmins() as $admin) {
|
|
||||||
if (!$admin->doReceiveAnimathMails())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
$c = preg_replace("#{FIRST_NAME}#", $admin->getFirstName(), $content);
|
|
||||||
$c = preg_replace("#{SURNAME}#", $admin->getSurname(), $c);
|
|
||||||
self::sendMail($admin->getEmail(), $subject, $c, $from);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static function getTemplate($name)
|
|
||||||
{
|
|
||||||
global $LOCAL_PATH;
|
|
||||||
return file_get_contents("$LOCAL_PATH/server_files/services/mail_templates/$name.html");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function sendRegisterMail(NewUser $new_user)
|
|
||||||
{
|
|
||||||
global $YEAR;
|
|
||||||
|
|
||||||
$content = self::getTemplate("register");
|
|
||||||
$content = preg_replace("#{FIRST_NAME}#", $new_user->first_name, $content);
|
|
||||||
$content = preg_replace("#{SURNAME}#", $new_user->surname, $content);
|
|
||||||
$content = preg_replace("#{TOKEN}#", $new_user->confirm_email_token, $content);
|
|
||||||
|
|
||||||
self::sendMail($new_user->email, "Inscription aux Correspondances des Jeunes Mathématicien·ne·s $YEAR - " . ($YEAR + 1), $content);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function sendConfirmEmail(User $user)
|
|
||||||
{
|
|
||||||
global $YEAR;
|
|
||||||
|
|
||||||
$content = self::getTemplate("confirm_email");
|
|
||||||
$content = preg_replace("#{FIRST_NAME}#", $user->getFirstName(), $content);
|
|
||||||
$content = preg_replace("#{SURNAME}#", $user->getSurname(), $content);
|
|
||||||
$content = preg_replace("#{TOKEN}#", $user->getConfirmEmailToken(), $content);
|
|
||||||
|
|
||||||
self::sendMail($user->getEmail(), "Confirmation d'adresse e-mail – Correspondances des Jeunes Mathématicien·ne·s $YEAR - " . ($YEAR + 1), $content);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function sendChangeEmailAddressMail(User $user)
|
|
||||||
{
|
|
||||||
global $YEAR;
|
|
||||||
|
|
||||||
$content = self::getTemplate("change_email_address");
|
|
||||||
$content = preg_replace("#{FIRST_NAME}#", $user->getFirstName(), $content);
|
|
||||||
$content = preg_replace("#{SURNAME}#", $user->getSurname(), $content);
|
|
||||||
$content = preg_replace("#{TOKEN}#", $user->getConfirmEmailToken(), $content);
|
|
||||||
|
|
||||||
self::sendMail($user->getEmail(), "Changement d'adresse e-mail – Correspondances des Jeunes Mathématicien·ne·s $YEAR - " . ($YEAR + 1), $content);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function sendForgottenPasswordProcedureMail(User $user)
|
|
||||||
{
|
|
||||||
global $YEAR;
|
|
||||||
|
|
||||||
$content = self::getTemplate("forgotten_password");
|
|
||||||
$content = preg_replace("#{FIRST_NAME}#", $user->getFirstName(), $content);
|
|
||||||
$content = preg_replace("#{SURNAME}#", $user->getSurname(), $content);
|
|
||||||
$content = preg_replace("#{TOKEN}#", $user->getForgottenPasswordToken(), $content);
|
|
||||||
|
|
||||||
self::sendMail($user->getEmail(), "Mot de passe oublié – Correspondances des Jeunes Mathématicien·ne·s $YEAR - " . ($YEAR + 1), $content);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function sendChangePasswordMail(User $user)
|
|
||||||
{
|
|
||||||
global $YEAR;
|
|
||||||
|
|
||||||
$content = self::getTemplate("change_password");
|
|
||||||
$content = preg_replace("#{FIRST_NAME}#", $user->getFirstName(), $content);
|
|
||||||
$content = preg_replace("#{SURNAME}#", $user->getSurname(), $content);
|
|
||||||
|
|
||||||
self::sendMail($user->getEmail(), "Mot de passe changé – Correspondances des Jeunes Mathématicien·ne·s $YEAR - " . ($YEAR + 1), $content);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function sendAddAdminMail(NewAdmin $new_admin)
|
|
||||||
{
|
|
||||||
global $YEAR;
|
|
||||||
|
|
||||||
$content = self::getTemplate("add_admin");
|
|
||||||
$content = preg_replace("#{FIRST_NAME}#", $new_admin->first_name, $content);
|
|
||||||
$content = preg_replace("#{SURNAME}#", $new_admin->surname, $content);
|
|
||||||
$content = preg_replace("#{PASSWORD}#", $new_admin->password, $content);
|
|
||||||
|
|
||||||
self::sendMail($new_admin->email, "Ajout d'un administrateur – Correspondances des Jeunes Mathématicien·ne·s $YEAR - " . ($YEAR + 1), $content);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function sendAddTeamMail(User $user, Team $team)
|
|
||||||
{
|
|
||||||
global $YEAR;
|
|
||||||
|
|
||||||
$content = self::getTemplate("add_team");
|
|
||||||
$content = preg_replace("#{FIRST_NAME}#", $user->getFirstName(), $content);
|
|
||||||
$content = preg_replace("#{SURNAME}#", $user->getSurname(), $content);
|
|
||||||
$content = preg_replace("#{TEAM_NAME}#", $team->getName(), $content);
|
|
||||||
$content = preg_replace("#{TRIGRAM}#", $team->getTrigram(), $content);
|
|
||||||
$content = preg_replace("#{ACCESS_CODE}#", $team->getAccessCode(), $content);
|
|
||||||
if ($team->getProblem() > 0)
|
|
||||||
$content = preg_replace("#{PROBLEM}#", "pour le problème" . $team->getProblem(), $content);
|
|
||||||
else
|
|
||||||
$content = preg_replace("#{PROBLEM}#", "", $content);
|
|
||||||
|
|
||||||
self::sendMail($user->getEmail(), "Ajout d'une équipe – Correspondances des Jeunes Mathématicien·ne·s $YEAR - " . ($YEAR + 1), $content);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function sendJoinTeamMail(User $user, Team $team)
|
|
||||||
{
|
|
||||||
global $YEAR;
|
|
||||||
|
|
||||||
$content = self::getTemplate("join_team");
|
|
||||||
$content = preg_replace("#{FIRST_NAME}#", $user->getFirstName(), $content);
|
|
||||||
$content = preg_replace("#{SURNAME}#", $user->getSurname(), $content);
|
|
||||||
$content = preg_replace("#{TEAM_NAME}#", $team->getName(), $content);
|
|
||||||
$content = preg_replace("#{TRIGRAM}#", $team->getTrigram(), $content);
|
|
||||||
if ($team->getProblem() > 0)
|
|
||||||
$content = preg_replace("#{PROBLEM}#", "pour le problème" . $team->getProblem(), $content);
|
|
||||||
else
|
|
||||||
$content = preg_replace("#{PROBLEM}#", "", $content);
|
|
||||||
|
|
||||||
self::sendMail($user->getEmail(), "Équipe rejointe – Correspondances des Jeunes Mathématicien·ne·s $YEAR - " . ($YEAR + 1), $content);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function sendRequestValidationMail(Team $team)
|
|
||||||
{
|
|
||||||
global $YEAR;
|
|
||||||
|
|
||||||
$content = self::getTemplate("request_validation");
|
|
||||||
$content = preg_replace("#{TEAM_NAME}#", $team->getName(), $content);
|
|
||||||
$content = preg_replace("#{TRIGRAM}#", $team->getTrigram(), $content);
|
|
||||||
$content = preg_replace("#{PROBLEM}#", $team->getProblem(), $content);
|
|
||||||
$content = preg_replace("#{ACCESS_CODE}#", $team->getAccessCode(), $content);
|
|
||||||
|
|
||||||
self::broadcastToAdmins("Demande de validation – Correspondances des Jeunes Mathématicien·ne·s $YEAR - " . ($YEAR + 1), $content);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function sendValidateTeam($team, $message)
|
|
||||||
{
|
|
||||||
global $YEAR;
|
|
||||||
|
|
||||||
$content = self::getTemplate("validate_team");
|
|
||||||
if (strlen($message) > 0)
|
|
||||||
$message = " L'équipe d'organisation vous transmet le message suivant :\n\n" . $message;
|
|
||||||
$message = preg_replace("#\n#", "<br/>\n", $message);
|
|
||||||
$content = preg_replace("#{MESSAGE}#", $message, $content);
|
|
||||||
|
|
||||||
self::broadcastToTeam($team, "Équipe validée – Correspondances des Jeunes Mathématicien·ne·s $YEAR - " . ($YEAR + 1), $content);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function sendUnvalidateTeam($team, $message)
|
|
||||||
{
|
|
||||||
global $YEAR;
|
|
||||||
|
|
||||||
$content = self::getTemplate("unvalidate_team");
|
|
||||||
if (strlen($message) > 0)
|
|
||||||
$message = " L'équipe d'organisation vous transmet le message suivant :\n\n" . $message;
|
|
||||||
$message = preg_replace("#\n#", "<br/>\n", $message);
|
|
||||||
$content = preg_replace("#{MESSAGE}#", $message, $content);
|
|
||||||
|
|
||||||
self::broadcastToTeam($team, "Équipe non validée – Correspondances des Jeunes Mathématicien·ne·s $YEAR - " . ($YEAR + 1), $content);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function sendNewVideo(NewVideo $video, Team $team)
|
|
||||||
{
|
|
||||||
global $YEAR;
|
|
||||||
|
|
||||||
$content = self::getTemplate("new_video");
|
|
||||||
$content = preg_replace("#{TEAM_NAME}#", $team->getName(), $content);
|
|
||||||
$content = preg_replace("#{TRIGRAM}#", $team->getTrigram(), $content);
|
|
||||||
$content = preg_replace("#{PROBLEM}#", $team->getProblem(), $content);
|
|
||||||
$content = preg_replace("#{VIDEO_LINK}#", $video->link, $content);
|
|
||||||
self::broadcastToAdmins("Nouvelle vidéo – Correspondances des Jeunes Mathématicien·ne·s $YEAR - " . ($YEAR + 1), $content);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function sendNewAnswer(NewAnswer $video, Team $team)
|
|
||||||
{
|
|
||||||
global $YEAR;
|
|
||||||
|
|
||||||
$content = self::getTemplate("new_answer");
|
|
||||||
$content = preg_replace("#{TEAM_NAME}#", $team->getName(), $content);
|
|
||||||
$content = preg_replace("#{TRIGRAM}#", $team->getTrigram(), $content);
|
|
||||||
$dest = Team::fromId($team->getVideoTeamIds()[$video->team - 1]);
|
|
||||||
$content = preg_replace("#{DEST_TEAM_NAME}#", $dest->getName(), $content);
|
|
||||||
$content = preg_replace("#{DEST_TRIGRAM}#", $dest->getTrigram(), $content);
|
|
||||||
$content = preg_replace("#{PROBLEM}#", $team->getProblem(), $content);
|
|
||||||
$content = preg_replace("#{VIDEO_LINK}#", $video->link, $content);
|
|
||||||
|
|
||||||
self::broadcastToAdmins("Nouvelle vidéo de réponse – Correspondances des Jeunes Mathématicien·ne·s $YEAR - " . ($YEAR + 1), $content);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function validateVideo(Video $video, $message)
|
|
||||||
{
|
|
||||||
global $YEAR;
|
|
||||||
|
|
||||||
$team = Team::fromId($video->getTeam());
|
|
||||||
|
|
||||||
$template = "video_";
|
|
||||||
$template .= $video->getValidation() == Video::ACCEPTED ? "accepted" : "rejected";
|
|
||||||
$template .= $video->getReason() == Reason::SOLUTION ? "_solution" : "_answer";
|
|
||||||
$content = self::getTemplate($template);
|
|
||||||
$content = preg_replace("#{TRIGRAM}#", $team->getTrigram(), $content);
|
|
||||||
$content = preg_replace("#{PROBLEM}#", $team->getProblem(), $content);
|
|
||||||
$content = preg_replace("#{VIDEO_LINK}#", $video->getLink(), $content);
|
|
||||||
if (strlen($message) > 0)
|
|
||||||
$message = " L'équipe d'organisation vous transmet le message suivant :\n\n" . $message . "\n\n";
|
|
||||||
$message = preg_replace("#\n#", "<br/>\n", $message);
|
|
||||||
$content = preg_replace("#{MESSAGE}#", $message, $content);
|
|
||||||
|
|
||||||
self::broadcastToTeam($team, ($video->getValidation() == Video::REJECTED ? "Vidéo refusée " : "Vidéo acceptée ")
|
|
||||||
. $team->getTrigram() . " – Correspondances des Jeunes Mathématicien·ne·s $YEAR - " . ($YEAR + 1), $content);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="fr">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Administrateur des Correspondances des Jeunes Mathématicien·ne·s</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
Bonjour {FIRST_NAME} {SURNAME},<br />
|
|
||||||
<br />
|
|
||||||
Vous recevez ce message (envoyé automatiquement) car vous êtes administrateur pour les Correspondances des Jeunes Mathématicien·ne·s.
|
|
||||||
Veuillez trouver ci-dessous vos informations d'utilisateur pour le site officiel des inscriptions. Elles vous permettront de gérer les inscriptions des équipes.<br />
|
|
||||||
<br />
|
|
||||||
Votre mot de passe est : <strong style="color: red; font-size: 18px;">{PASSWORD}</strong><br />
|
|
||||||
Vous pouvez vous connecter ici : <a href="{URL_BASE}/connexion">{URL_BASE}/connexion</a><br />
|
|
||||||
<br />
|
|
||||||
Notez bien que ce mot de passe est temporaire, et pour des raisons de sécurité vous devrez le changer lors de votre prochaine connexion sur le site.<br />
|
|
||||||
<br />
|
|
||||||
Merci beaucoup pour votre aide !<br />
|
|
||||||
<br />
|
|
||||||
L'organisation des Correspondances des Jeunes Mathématicien·ne·s
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,17 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="fr">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Nouvelle équipe Correspondances des Jeunes Mathématicien·ne·s {YEAR}</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
Bonjour {FIRST_NAME} {SURNAME},<br />
|
|
||||||
<br />
|
|
||||||
Vous venez de créer l'équipe « {TEAM_NAME} » ({TRIGRAM}) pour les Correspondances des Jeunes Mathématicien·ne·s
|
|
||||||
{PROBLEM} et nous vous en remercions.<br />
|
|
||||||
Afin de permettre aux autres membres de votre équipe de vous rejoindre, veuillez leur transmettre le code d'accès :
|
|
||||||
<strong>{ACCESS_CODE}</strong><br/>
|
|
||||||
<br />
|
|
||||||
Le comité d'organisation des Correspondances des Jeunes Mathématicien·ne·s
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,16 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<!--suppress HtmlUnknownTarget -->
|
|
||||||
<html lang="fr">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Changement d'adresse e-mail – Correspondances des Jeunes Mathématicien·ne·s</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
Bonjour {FIRST_NAME} {SURNAME},<br/>
|
|
||||||
<br/>
|
|
||||||
Vous venez de changer votre adresse e-mail. Veuillez désormais la confirmer en cliquant ici : <a
|
|
||||||
href="{URL_BASE}/confirmer-mail/{TOKEN}">{URL_BASE}/confirmer-mail/{TOKEN}</a><br/>
|
|
||||||
<br/>
|
|
||||||
Le comité d'organisation des Correspondances des Jeunes Mathématicien·ne·s
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,18 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="fr">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Mot de passe changé – Correspondances des Jeunes Mathématicien·ne·s</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
Bonjour {FIRST_NAME} {SURNAME},<br/>
|
|
||||||
<br/>
|
|
||||||
Nous vous informons que votre mot de passe vient d'être modifié. Si vous n'êtes pas à l'origine de cette manipulation,
|
|
||||||
veuillez immédiatement vérifier vos accès à votre boîte mail et changer votre mot de passe sur la plateforme
|
|
||||||
d'inscription.<br/>
|
|
||||||
<br/>
|
|
||||||
Cordialement,<br/>
|
|
||||||
<br/>
|
|
||||||
Le comité d'organisation des Correspondances des Jeunes Mathématicien·ne·s
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,18 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<!--suppress HtmlUnknownTarget -->
|
|
||||||
<html lang="fr">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Inscription aux Correspondances des Jeunes Mathématicien·ne·s {YEAR}</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
Bonjour {FIRST_NAME} {SURNAME},<br/>
|
|
||||||
<br/>
|
|
||||||
Vous êtes inscrit aux Correspondances des Jeunes Mathématicien·ne·s {YEAR} et nous vous en remercions.<br/>
|
|
||||||
Pour valider votre adresse e-mail, veuillez cliquer sur le lien : <a href="{URL_BASE}/confirmer-mail/{TOKEN}">{URL_BASE}/confirmer-mail/{TOKEN}</a><br/>
|
|
||||||
<br/>
|
|
||||||
Cordialement,<br/>
|
|
||||||
<br/>
|
|
||||||
Le comité d'organisation des Correspondances des Jeunes Mathématicien·ne·s
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,20 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<!--suppress HtmlUnknownTarget -->
|
|
||||||
<html lang="fr">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Mot de passe oublié – Correspondances des Jeunes Mathématicien·ne·s</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
Bonjour,<br/>
|
|
||||||
<br/>
|
|
||||||
Vous avez indiqué avoir oublié votre mot de passe. Veuillez cliquer ici pour le réinitialiser : <a
|
|
||||||
href="{URL_BASE}/connexion/reinitialiser_mdp/{TOKEN}">{URL_BASE}/connexion/reinitialiser_mdp/{TOKEN}</a><br/>
|
|
||||||
<br/>
|
|
||||||
Si vous n'êtes pas à l'origine de cette manipulation, vous pouvez ignorer ce message.<br/>
|
|
||||||
<br/>
|
|
||||||
Cordialement,<br/>
|
|
||||||
<br/>
|
|
||||||
Le comité d'organisation des Correspondances des Jeunes Mathématicien·ne·s
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,17 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="fr">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Équipe rejointe – Correspondances des Jeunes Mathématicien·ne·s {YEAR}</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
Bonjour {FIRST_NAME} {SURNAME},<br/>
|
|
||||||
<br/>
|
|
||||||
Vous venez de rejoindre l'équipe « {TEAM_NAME} » ({TRIGRAM}) pour les Correspondances des Jeunes Mathématicien·ne·s
|
|
||||||
{PROBLEM} et nous vous en remercions.<br/>
|
|
||||||
<br/>
|
|
||||||
Cordialement,<br/>
|
|
||||||
<br/>
|
|
||||||
Le comité d'organisation des Correspondances des Jeunes Mathématicien·ne·s
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,19 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="fr">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Nouvelle vidéo – Correspondances des Jeunes Mathématicien·ne·s {YEAR}</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
Bonjour {FIRST_NAME} {SURNAME},<br/>
|
|
||||||
<br/>
|
|
||||||
L'équipe « {TEAM_NAME} » ({TRIGRAM}) vient d'ajouter une vidéo de réponse destinée à l'équipe « {DEST_TEAM_NAME} » ({DEST_TRIGRAM})
|
|
||||||
pour le problème {PROBLEM} des Correspondances des Jeunes Mathématicien·ne·s : <a href="{VIDEO_LINK}">{VIDEO_LINK}</a>.
|
|
||||||
Vous êtes désormais invité avant que quelqu'un d'autre ne le fasse à accepter ou refuser cette vidéo via la plateforme d'inscription (accessible après connexion) :
|
|
||||||
<a href="{URL_BASE}/suivi-correspondances">{URL_BASE}/suivi-correspondances</a><br/>
|
|
||||||
<br/>
|
|
||||||
Cordialement,<br/>
|
|
||||||
<br/>
|
|
||||||
Le comité d'organisation des Correspondances des Jeunes Mathématicien·ne·s
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,18 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="fr">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Nouvelle vidéo – Correspondances des Jeunes Mathématicien·ne·s {YEAR}</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
Bonjour {FIRST_NAME} {SURNAME},<br/>
|
|
||||||
<br/>
|
|
||||||
L'équipe « {TEAM_NAME} » ({TRIGRAM}) vient d'ajouter une vidéo pour le problème {PROBLEM} des Correspondances des Jeunes Mathématicien·ne·s : <a href="{VIDEO_LINK}">{VIDEO_LINK}</a>.
|
|
||||||
Vous êtes désormais invité avant que quelqu'un d'autre ne le fasse à accepter ou refuser cette vidéo via la plateforme d'inscription (accessible après connexion) :
|
|
||||||
<a href="{URL_BASE}/suivi-correspondances">{URL_BASE}/suivi-correspondances</a><br/>
|
|
||||||
<br/>
|
|
||||||
Cordialement,<br/>
|
|
||||||
<br/>
|
|
||||||
Le comité d'organisation des Correspondances des Jeunes Mathématicien·ne·s
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,16 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<!--suppress HtmlUnknownTarget -->
|
|
||||||
<html lang="fr">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Inscription aux Correspondances des Jeunes Mathématicien·ne·s {YEAR}</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
Bonjour {FIRST_NAME} {SURNAME},<br />
|
|
||||||
<br />
|
|
||||||
Vous venez de vous inscrire aux Correspondances des Jeunes Mathématicien·ne·s {YEAR} et nous vous en remercions.<br />
|
|
||||||
Pour valider votre adresse e-mail, veuillez cliquer sur le lien : <a href="{URL_BASE}/confirmer-mail/{TOKEN}">{URL_BASE}/confirmer-mail/{TOKEN}</a><br />
|
|
||||||
<br />
|
|
||||||
Le comité d'organisation des Correspondances des Jeunes Mathématicien·ne·s
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,19 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<!--suppress HtmlUnknownTarget -->
|
|
||||||
<html lang="fr">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Demande de validation - Correspondances des Jeunes Mathématicien·ne·s</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
Bonjour {FIRST_NAME} {SURNAME},<br />
|
|
||||||
<br />
|
|
||||||
L'équipe « {TEAM_NAME} » ({TRIGRAM}) vient de demander à valider son équipe pour participer au problème n°{PROBLEM} des
|
|
||||||
Correspondances des Jeunes Mathématicien·ne·s. Vous pouvez décider d'accepter ou de refuser l'équipe en vous rendant sur
|
|
||||||
la page de l'équipe : <a href="{URL_BASE}/equipe/{TRIGRAM}">{URL_BASE}/equipe/{TRIGRAM}</a><br/>
|
|
||||||
<br/>
|
|
||||||
Cordialement,<br/>
|
|
||||||
<br />
|
|
||||||
L'organisation des Correspondances des Jeunes Mathématicien·ne·s
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,21 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="fr">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Équipe non validée – Correspondances des Jeunes Mathématicien·ne·s {YEAR}</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
Bonjour {FIRST_NAME} {SURNAME},<br/>
|
|
||||||
<br/>
|
|
||||||
Maleureusement, votre équipe « {TEAM_NAME} » ({TRIGRAM}) n'a pas été validée. Veuillez vérifier que vos autorisations
|
|
||||||
de droit à l'image sont correctes.
|
|
||||||
{MESSAGE}<br />
|
|
||||||
<br />
|
|
||||||
N'hésitez pas à nous contacter à l'adresse <a href="contact@correspondances-maths.fr">contact@correspondances-maths.fr</a>
|
|
||||||
pour plus d'informations.
|
|
||||||
<br/>
|
|
||||||
Cordialement,<br/>
|
|
||||||
<br/>
|
|
||||||
Le comité d'organisation des Correspondances des Jeunes Mathématicien·ne·s
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,18 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="fr">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Équipe validée – Correspondances des Jeunes Mathématicien·ne·s {YEAR}</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
Bonjour {FIRST_NAME} {SURNAME},<br/>
|
|
||||||
<br/>
|
|
||||||
Félicitations ! Votre équipe « {TEAM_NAME} » ({TRIGRAM}) est désormais validée ! Vous êtes désormais apte à travailler sur
|
|
||||||
votre problème. Lorsque les Correspondances auront débutées, vous pourrez soumettre votre vidéo sur la plateforme d'inscription.
|
|
||||||
{MESSAGE}<br />
|
|
||||||
<br/>
|
|
||||||
Cordialement,<br/>
|
|
||||||
<br/>
|
|
||||||
Le comité d'organisation des Correspondances des Jeunes Mathématicien·ne·s
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,21 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="fr">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Vidéo acceptée – Correspondances des Jeunes Mathématicien·ne·s {YEAR}</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
Bonjour {FIRST_NAME} {SURNAME},<br />
|
|
||||||
<br />
|
|
||||||
Félicitations, votre vidéo de réponse pour le problème {PROBLEM} a été validée ! Pour rappel, vous aviez soumis ce lien : <a href="{VIDEO_LINK}">{VIDEO_LINK}</a>.<br />
|
|
||||||
Vous avez à présent terminé l'aventure des Correspondances. Bravo à vous ! Nous vous recontacterons dans les prochains jours pour vous tenir au courant des résultats.<br />
|
|
||||||
Si toutefois vous le souhaitez, vous pouvez à nouveau soumettre une vidéo avant la fin de la phase. Cette nouvelle vidéo ne remplacera l'actuelle qu'au moment de la validation de celle-ci.<br />
|
|
||||||
<br />
|
|
||||||
N'oubliez pas de contrôler que les paramètres de diffusion de vidéo sont cohérents avec ce que vous souhaitez : <a href="{URL_BASE}/mon-equipe">{URL_BASE}/mon-equipe</a><br />
|
|
||||||
<br />
|
|
||||||
{MESSAGE}
|
|
||||||
Cordialement,<br />
|
|
||||||
<br />
|
|
||||||
Le comité d'organisation des Correspondances des Jeunes Mathématicien·ne·s
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,21 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="fr">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Vidéo acceptée – Correspondances des Jeunes Mathématicien·ne·s {YEAR}</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
Bonjour {FIRST_NAME} {SURNAME},<br />
|
|
||||||
<br/>
|
|
||||||
Félicitations, votre vidéo pour le problème {PROBLEM} a été validée ! Pour rappel, vous aviez soumis ce lien : <a href="{VIDEO_LINK}">{VIDEO_LINK}</a>.<br />
|
|
||||||
Votre travail est à présent terminé, et vous pouvez attendre les prochaines phases. Bravo à vous !<br />
|
|
||||||
Si toutefois vous le souhaitez, vous pouvez à nouveau soumettre une vidéo avant la fin de la phase. Cette nouvelle vidéo ne remplacera l'actuelle qu'au moment de la validation de celle-ci.<br />
|
|
||||||
<br />
|
|
||||||
N'oubliez pas de contrôler que les paramètres de diffusion de vidéo sont cohérents avec ce que vous souhaitez : <a href="{URL_BASE}/mon-equipe">{URL_BASE}/mon-equipe</a><br />
|
|
||||||
<br />
|
|
||||||
{MESSAGE}
|
|
||||||
Cordialement,<br />
|
|
||||||
<br />
|
|
||||||
Le comité d'organisation des Correspondances des Jeunes Mathématicien·ne·s
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,23 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="fr">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Vidéo refusée – Correspondances des Jeunes Mathématicien·ne·s {YEAR}</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
Bonjour {FIRST_NAME} {SURNAME},<br/>
|
|
||||||
<br/>
|
|
||||||
Malheureusement, votre vidéo de réponse pour le problème {PROBLEM} n'a pas été validée. Pour rappel, vous aviez soumis
|
|
||||||
ce lien : <a href="{VIDEO_LINK}">{VIDEO_LINK}</a>.<br />
|
|
||||||
Si vous aviez soumis une précédente vidéo qui a été validée, elle reste conservée.
|
|
||||||
Vous êtes désormais invités à retravailler vos réponses ou votre présentation orale afin que votre prestation soit
|
|
||||||
validée par les organisateurs. N'hésitez pas à nous contacter à
|
|
||||||
<a href="mailto:contact@correspondances-maths.fr">contact@correspondances-maths.fr</a> si vous souhaitez avoir plus
|
|
||||||
d'informations ou contester ce refus.<br />
|
|
||||||
<br/>
|
|
||||||
{MESSAGE}
|
|
||||||
Cordialement,<br/>
|
|
||||||
<br/>
|
|
||||||
Le comité d'organisation des Correspondances des Jeunes Mathématicien·ne·s
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,23 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="fr">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Vidéo refusée – Correspondances des Jeunes Mathématicien·ne·s {YEAR}</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
Bonjour {FIRST_NAME} {SURNAME},<br/>
|
|
||||||
<br/>
|
|
||||||
Malheureusement, votre vidéo pour le problème {PROBLEM} n'a pas été validée. Pour rappel, vous aviez soumis ce lien :
|
|
||||||
<a href="{VIDEO_LINK}">{VIDEO_LINK}</a>.<br />
|
|
||||||
Si vous aviez soumis une précédente vidéo qui a été validée, elle reste conservée.
|
|
||||||
Vous êtes désormais invités à retravailler vos résultats ou votre présentation orale afin que votre prestation soit
|
|
||||||
validée par les organisateurs. N'hésitez pas à nous contacter à
|
|
||||||
<a href="mailto:contact@correspondances-maths.fr">contact@correspondances-maths.fr</a> si vous souhaitez avoir plus
|
|
||||||
d'informations ou contester ce refus.<br />
|
|
||||||
<br/>
|
|
||||||
{MESSAGE}
|
|
||||||
Cordialement,<br/>
|
|
||||||
<br/>
|
|
||||||
Le comité d'organisation des Correspondances des Jeunes Mathématicien·ne·s
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,48 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
function ensure($bool, $error_msg = "")
|
|
||||||
{
|
|
||||||
if (!$bool)
|
|
||||||
throw new AssertionError($error_msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatDate($date = NULL, $with_time = false)
|
|
||||||
{
|
|
||||||
if ($date == NULL)
|
|
||||||
$date = date("yyyy-mm-dd");
|
|
||||||
|
|
||||||
return strftime("%d %B %G" . ($with_time ? " %H:%M" : ""), strtotime($date));
|
|
||||||
}
|
|
||||||
|
|
||||||
function dateWellFormed($date, $with_time = false)
|
|
||||||
{
|
|
||||||
return date_parse_from_format($with_time ? "yyyy-mm-dd HH-MM:ss" : "yy-mm-dd", $date) !== false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function genRandomPhrase($size, $uppercase = false)
|
|
||||||
{
|
|
||||||
$alphabet = $uppercase ? "0123456789abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" : "0123456789abcdefghijklmnopqrstuvwxyz0123456789";
|
|
||||||
|
|
||||||
$phrase = "";
|
|
||||||
for ($i = 0; $i < $size; ++$i) {
|
|
||||||
$phrase .= $alphabet[rand(0, strlen($alphabet) - 1)];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $phrase;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getExtFromMimeType($mime_type)
|
|
||||||
{
|
|
||||||
switch ($mime_type) {
|
|
||||||
case "application/pdf":
|
|
||||||
return ".pdf";
|
|
||||||
case "image/png":
|
|
||||||
return ".png";
|
|
||||||
case "image/jpg":
|
|
||||||
case "image/jpeg":
|
|
||||||
return ".jpg";
|
|
||||||
case "application/zip":
|
|
||||||
return ".zip";
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
@ -1,67 +0,0 @@
|
|||||||
<?php
|
|
||||||
require_once "header.php";
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="mt-4 mb-4">
|
|
||||||
<h1 class="display-4">Liste des administrateurs</h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr />
|
|
||||||
|
|
||||||
<table class="table table-striped table-bordered table-hover">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th scope="col">
|
|
||||||
Nom
|
|
||||||
</th>
|
|
||||||
<th scope="col">
|
|
||||||
Prénom
|
|
||||||
</th>
|
|
||||||
<th scope="col">
|
|
||||||
Adresse e-mail
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<?php
|
|
||||||
/** @var User $admin */
|
|
||||||
foreach ($admins as $admin) {
|
|
||||||
?>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<a href="/informations/<?= $admin->getId() ?>/<?= $admin->getFirstName() . " " . $admin->getSurname() ?>">
|
|
||||||
<?= $admin->getSurname() ?>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a href="/informations/<?= $admin->getId() ?>/<?= $admin->getFirstName() . " " . $admin->getSurname() ?>">
|
|
||||||
<?= $admin->getFirstName() ?>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a href="mailto:<?= $admin->getEmail() ?>">
|
|
||||||
<?= $admin->getEmail() ?>
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</tbody>
|
|
||||||
<tfoot>
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
Nom
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
Prénom
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
Adresse e-mail
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
</tfoot>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
require_once "footer.php";
|
|
@ -1,43 +0,0 @@
|
|||||||
<?php
|
|
||||||
require_once "header.php";
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="mt-4 mb-4">
|
|
||||||
<h1 class="display-4">Ajouter un administrateur</h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php if (isset($admin) && !$has_error) { ?>
|
|
||||||
<div class="alert alert-success">
|
|
||||||
Administrateur ajouté avec succès ! Ses identifiants ont été transmis par mail.
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
<form method="POST">
|
|
||||||
<div class="form-row">
|
|
||||||
<div class="form-group col-md-6">
|
|
||||||
<label for="surname">Nom :</label>
|
|
||||||
<input class="form-control" type="text" id="surname" name="surname"
|
|
||||||
value="<?php if (isset($admin)) echo $admin->surname ?>" required/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group col-md-6">
|
|
||||||
<label for="first_name">Prénom :</label>
|
|
||||||
<input class="form-control" type="text" id="first_name" name="first_name"
|
|
||||||
value="<?php if (isset($admin)) echo $admin->first_name ?>" required/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-row">
|
|
||||||
<div class="form-group col-md-12">
|
|
||||||
<label for="email">E-mail :</label>
|
|
||||||
<input class="form-control" type="email" id="email" name="email"
|
|
||||||
value="<?php if (isset($admin)) echo $admin->email ?>" required/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group row">
|
|
||||||
<input class="btn btn-primary btn-lg btn-block" name="add_admin" type="submit" value="Ajouter un administrateur" />
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<?php require_once "footer.php" ?>
|
|
@ -1,78 +0,0 @@
|
|||||||
<?php
|
|
||||||
require_once "header.php";
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="mt-4 mb-4">
|
|
||||||
<h1 class="display-4">Ajouter une équipe</h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php if (isset($new_team) && !$has_error) { ?>
|
|
||||||
<div class="alert alert-success">
|
|
||||||
Votre équipe a bien été créée ! Voici le code d'accès à transmettre aux autres membres de votre équipe :
|
|
||||||
<strong><?= $new_team->access_code ?></strong>
|
|
||||||
</div>
|
|
||||||
<?php } elseif ($_SESSION["team"] != NULL && $_SESSION["role"] == Role::PARTICIPANT) { ?>
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
Vous êtes déjà dans une équipe.
|
|
||||||
</div>
|
|
||||||
<?php } elseif(date("Y-m-d H:i:s") >= $CONFIG->getInscriptionDate()) { ?>
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
La date limite d'inscription est dépassée.
|
|
||||||
</div>
|
|
||||||
<?php } else { ?>
|
|
||||||
|
|
||||||
<?php if ($_SESSION["role"] == Role::ENCADRANT && sizeof($_SESSION["teams"]) > 0) { ?>
|
|
||||||
<div class="alert alert-warning">
|
|
||||||
Vous êtes déjà inscrit dans une équipe. Vous pouvez toutefois encadrer plusieurs équipes.
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
<div class="alert alert-info">
|
|
||||||
Chacune des informations pourra être modifiée avant que l'équipe tant que l'équipe n'est pas validée.
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<form method="POST">
|
|
||||||
<div class="form-row">
|
|
||||||
<div class="form-group col-md-6">
|
|
||||||
<label for="name">Nom (<em>Pas de caractères spéciaux</em>) :</label>
|
|
||||||
<input class="form-control" type="text" id="name" name="name" pattern="[A-Za-zÀ-ÿ ]+"
|
|
||||||
value="<?php if (isset($new_team)) echo $new_team->name ?>" required/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group col-md-6">
|
|
||||||
<label for="trigram">Trigramme (<em>identifiant unique à trois lettres de l'équipe</em>) :</label>
|
|
||||||
<input class="form-control" type="text" id="trigram" name="trigram"
|
|
||||||
value="<?php if (isset($new_team)) echo $new_team->trigram ?>" pattern="[A-Z]{3}" maxlength="3" required/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group row">
|
|
||||||
<label for="problem">Problème :</label>
|
|
||||||
<select id="problem" name="problem" class="custom-select">
|
|
||||||
<option value="0">Choisir un problème ...</option>
|
|
||||||
<?php
|
|
||||||
for ($i = 1; $i <= 4; ++$i)
|
|
||||||
echo "<option value='$i' " . (isset($new_team) && $new_team->problem == $i ? "selected" : "") . ">Problème $i</option>";
|
|
||||||
?>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<label for="allow_other_teams">J'accepte que mes vidéos soient diffusées aux équipes avec lesquelles je vais concourir :</label>
|
|
||||||
<input type="checkbox" id="allow_other_teams" name="allow_other_teams"
|
|
||||||
<?= isset($new_team) && $new_team->allow_other_teams ? "checked" : "" ?> required/><br />
|
|
||||||
|
|
||||||
<label for="allow_publish">J'accepte qu'Animath diffuse mes vidéos à la fin des Correspondances (<em>facultatif</em>) :</label>
|
|
||||||
<input type="checkbox" id="allow_publish" name="allow_publish"
|
|
||||||
<?= isset($new_team) && $new_team->allow_publish ? "checked" : "" ?> />
|
|
||||||
|
|
||||||
<div class="alert alert-info">
|
|
||||||
Cette dernière option est modifiable à tout moment, et permet à <em>Animath</em> de diffuser les vidéos primées.
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group row">
|
|
||||||
<input class="btn btn-primary btn-lg btn-block" name="add_team" type="submit" value="Ajouter une équipe"/>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
<?php require_once "footer.php" ?>
|
|
@ -1,138 +0,0 @@
|
|||||||
<?php require_once "header.php"; ?>
|
|
||||||
|
|
||||||
<div class="mt-4 mb-4">
|
|
||||||
<h1 class="display-4">Calendrier</h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php if (isset($_GET["edit"])) { ?>
|
|
||||||
|
|
||||||
<form method="POST">
|
|
||||||
<div class="form-group row">
|
|
||||||
<label for="inscription">Fin des inscriptions :</label>
|
|
||||||
<div class="form-group col-md-10">
|
|
||||||
<input class="form-control" type="date" id="inscription" name="date_inscription"
|
|
||||||
value="<?= substr($CONFIG->getInscriptionDate(), 0, 10) ?>"/>
|
|
||||||
<input class="form-control" type="time" id="inscription" name="time_inscription"
|
|
||||||
value="<?= substr($CONFIG->getInscriptionDate(), 11, 5) ?>"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group row">
|
|
||||||
<label for="phase1">Dates de la phase 1 :</label>
|
|
||||||
<div class="form-group col-md-5">
|
|
||||||
<input class="form-control" type="date" id="phase1" name="date_start_phase1"
|
|
||||||
value="<?= substr($CONFIG->getStartPhase1Date(), 0, 10) ?>"/>
|
|
||||||
<input class="form-control" type="time" id="phase1" name="time_start_phase1"
|
|
||||||
value="<?= substr($CONFIG->getStartPhase1Date(), 11, 5) ?>"/>
|
|
||||||
</div>
|
|
||||||
<div class="form-group col-md-5">
|
|
||||||
<input class="form-control" type="date" id="phase1" name="date_end_phase1"
|
|
||||||
value="<?= substr($CONFIG->getEndPhase1Date(), 0, 10) ?>"/>
|
|
||||||
<input class="form-control" type="time" id="phase1" name="time_end_phase1"
|
|
||||||
value="<?= substr($CONFIG->getEndPhase1Date(), 11, 5) ?>"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group row">
|
|
||||||
<label for="phase2">Dates de la phase 2 :</label>
|
|
||||||
<div class="form-group col-md-5">
|
|
||||||
<input class="form-control" type="date" id="phase2" name="date_start_phase2"
|
|
||||||
value="<?= substr($CONFIG->getStartPhase2Date(), 0, 10) ?>"/>
|
|
||||||
<input class="form-control" type="time" id="phase1" name="time_start_phase2"
|
|
||||||
value="<?= substr($CONFIG->getStartPhase2Date(), 11, 5) ?>"/>
|
|
||||||
</div>
|
|
||||||
<div class="form-group col-md-5">
|
|
||||||
<input class="form-control" type="date" id="phase2" name="date_end_phase2"
|
|
||||||
value="<?= substr($CONFIG->getEndPhase2Date(), 0, 10) ?>"/>
|
|
||||||
<input class="form-control" type="time" id="phase2" name="time_end_phase2"
|
|
||||||
value="<?= substr($CONFIG->getEndPhase2Date(), 11, 5) ?>"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group row">
|
|
||||||
<label for="phase3">Dates de la phase 3 :</label>
|
|
||||||
<div class="form-group col-md-5">
|
|
||||||
<input class="form-control" type="date" id="phase3" name="date_start_phase3"
|
|
||||||
value="<?= substr($CONFIG->getStartPhase3Date(), 0, 10) ?>"/>
|
|
||||||
<input class="form-control" type="time" id="phase3" name="time_start_phase3"
|
|
||||||
value="<?= substr($CONFIG->getStartPhase3Date(), 11, 5) ?>"/>
|
|
||||||
</div>
|
|
||||||
<div class="form-group col-md-5">
|
|
||||||
<input class="form-control" type="date" id="phase3" name="date_end_phase3"
|
|
||||||
value="<?= substr($CONFIG->getEndPhase3Date(), 0, 10) ?>"/>
|
|
||||||
<input class="form-control" type="time" id="phase3" name="time_end_phase3"
|
|
||||||
value="<?= substr($CONFIG->getEndPhase3Date(), 11, 5) ?>"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group row">
|
|
||||||
<label for="phase4">Dates de la phase 4 :</label>
|
|
||||||
<div class="form-group col-md-5">
|
|
||||||
<input class="form-control" type="date" id="phase4" name="date_start_phase4"
|
|
||||||
value="<?= substr($CONFIG->getStartPhase4Date(), 0, 10) ?>"/>
|
|
||||||
<input class="form-control" type="time" id="phase4" name="time_start_phase4"
|
|
||||||
value="<?= substr($CONFIG->getStartPhase4Date(), 11, 5) ?>"/>
|
|
||||||
</div>
|
|
||||||
<div class="form-group col-md-5">
|
|
||||||
<input class="form-control" type="date" id="phase4" name="date_end_phase4"
|
|
||||||
value="<?= substr($CONFIG->getEndPhase4Date(), 0, 10) ?>"/>
|
|
||||||
<input class="form-control" type="time" id="phase4" name="time_end_phase4"
|
|
||||||
value="<?= substr($CONFIG->getEndPhase4Date(), 11, 5) ?>"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group row">
|
|
||||||
<input class="btn btn-primary btn-lg btn-block" type="submit" name="update_calendar"
|
|
||||||
value="Mettre à jour le calendrier"/>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<?php } else { ?>
|
|
||||||
|
|
||||||
<div class="alert alert-<?= date("Y-m-d H:i:s") <= $CONFIG->getInscriptionDate() ? "warning" : "success" ?>">
|
|
||||||
<?= Phase::getTranslatedName(Phase::INSCRIPTION) ?> :
|
|
||||||
<strong><?= formatDate($CONFIG->getInscriptionDate(), true) ?></strong>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="alert alert-<?= Phase::getCurrentPhase() < Phase::PHASE1 ? "danger" : (Phase::getCurrentPhase() == Phase::PHASE1 ? "warning" : "success") ?>">
|
|
||||||
<?= Phase::getTranslatedName(Phase::PHASE1) ?> :
|
|
||||||
Du <strong><?= formatDate($CONFIG->getStartPhase1Date(), true) ?></strong> au
|
|
||||||
<strong><?= formatDate($CONFIG->getEndPhase1Date(), true) ?></strong>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="alert alert-<?= Phase::getCurrentPhase() < Phase::PHASE2 ? "danger" : (Phase::getCurrentPhase() == Phase::PHASE2 ? "warning" : "success") ?>">
|
|
||||||
<?= Phase::getTranslatedName(Phase::PHASE2) ?> :
|
|
||||||
Du <strong><?= formatDate($CONFIG->getStartPhase2Date(), true) ?></strong> au
|
|
||||||
<strong><?= formatDate($CONFIG->getEndPhase2Date(), true) ?></strong>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="alert alert-<?= Phase::getCurrentPhase() < Phase::PHASE3 ? "danger" : (Phase::getCurrentPhase() == Phase::PHASE3 ? "warning" : "success") ?>">
|
|
||||||
<?= Phase::getTranslatedName(Phase::PHASE3) ?> :
|
|
||||||
Du <strong><?= formatDate($CONFIG->getStartPhase3Date(), true) ?></strong> au
|
|
||||||
<strong><?= formatDate($CONFIG->getEndPhase3Date(), true) ?></strong>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="alert alert-<?= Phase::getCurrentPhase() < Phase::PHASE4 ? "danger" : (Phase::getCurrentPhase() == Phase::PHASE4 ? "warning" : "success") ?>">
|
|
||||||
<?= Phase::getTranslatedName(Phase::PHASE4) ?> :
|
|
||||||
Du <strong><?= formatDate($CONFIG->getStartPhase4Date(), true) ?></strong> au
|
|
||||||
<strong><?= formatDate($CONFIG->getEndPhase4Date(), true) ?></strong>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php if ($_SESSION["role"] == Role::ADMIN) { ?>
|
|
||||||
<!--suppress HtmlUnknownTarget -->
|
|
||||||
<a href="/calendrier/modifier">
|
|
||||||
<button class="btn btn-primary btn-lg btn-block">Modifier le calendrier</button>
|
|
||||||
</a>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
<hr/>
|
|
||||||
|
|
||||||
<a href="https://correspondances-maths.fr/participer/" target="_blank">
|
|
||||||
<button class="btn btn-primary btn-lg btn-block">
|
|
||||||
Comment participer aux Correspondances ?
|
|
||||||
</button>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<?php }
|
|
||||||
|
|
||||||
require_once "footer.php";
|
|
@ -1,131 +0,0 @@
|
|||||||
<?php
|
|
||||||
require_once "header.php";
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="mt-4 mb-4">
|
|
||||||
<h1 class="display-4">Répondre aux questions</h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php if (isset($new_answer) && !$has_error) { ?>
|
|
||||||
<div class="alert alert-success">
|
|
||||||
Votre vidéo a bien été envoyée !
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
<div class="alert alert-info">
|
|
||||||
Pour clore vos Correspondances, vous devez produire, pour chaque vidéo reçue d'une autre équipe, une vidéo de
|
|
||||||
synthèse d'au plus 4 minutes.
|
|
||||||
Cette vidéo doit mettre en perspective de la vidéo initiale en tenant compte de l'échange qui a eu lieu.
|
|
||||||
Vous devez mettre en valeur l’échange questions/réponses, et montrer l'évolution de la résolution au problème.
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="alert alert-warning">
|
|
||||||
<strong>Date limite de soumission :</strong> <?= formatDate($CONFIG->getEndPhase4Date(), true) ?>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
for ($i = 0; $i < 2; ++$i) {
|
|
||||||
/** @var Team $answer_team */
|
|
||||||
$answer_team = $teams[$i];
|
|
||||||
/** @var Video $sol */
|
|
||||||
$sol = $sols[$i];
|
|
||||||
/** @var Video $answer */
|
|
||||||
$answer = $answers[$i];
|
|
||||||
/** @var Video $answer_validated */
|
|
||||||
$answer_validated = $answers_validated[$i];
|
|
||||||
/** @var Question[] $questions */
|
|
||||||
$questions = Question::getQuestions($team, $answer_team);
|
|
||||||
?>
|
|
||||||
<div class="jumbotron">
|
|
||||||
<h2>Vidéo de l'équipe <?= $answer_team->getName() ?> (<?= $answer_team->getTrigram() ?>) :</h2>
|
|
||||||
<div class="alert alert-info">
|
|
||||||
<strong>Lien de la vidéo de présentation de la solution au problème :</strong>
|
|
||||||
<a href="<?= $sol->getLink() ?>"><?= $sol->getLink() ?></a>
|
|
||||||
</div>
|
|
||||||
<?php displayVideo($sol->getLink()) ?>
|
|
||||||
|
|
||||||
<h5>Questions échangées :</h5>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
if (!strcmp($questions[1]->getQuestion(), Question::DEFAULT_QUESTIONS[0])
|
|
||||||
&& !strcmp($questions[2]->getQuestion(), Question::DEFAULT_QUESTIONS[1])
|
|
||||||
&& !strcmp($questions[3]->getQuestion(), Question::DEFAULT_QUESTIONS[2])) { ?>
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
L'équipe n'a malheureusement transmis aucune question. Vous n'avez donc pas de réponse à donner.
|
|
||||||
</div>
|
|
||||||
<?php } else {
|
|
||||||
for ($j = 0; $j <= 6; ++$j) {
|
|
||||||
/** @var Question $question */
|
|
||||||
$question = $questions[$j];
|
|
||||||
if ($j > 0 && $question->getQuestion() === null)
|
|
||||||
continue;
|
|
||||||
?>
|
|
||||||
<div class="alert alert-info">
|
|
||||||
<strong><?= $j == 0 ? "Remarques générales :" : "Question " . $question->getNumber() . " :" ?></strong>
|
|
||||||
<?= $question->getQuestion() ?><br/>
|
|
||||||
<?php
|
|
||||||
if ($question->getAttachedFile() !== null) { ?>
|
|
||||||
<em>Pièce jointe attachée :</em>
|
|
||||||
<a href="/file/<?= $question->getAttachedFile() ?>"><strong>Télécharger</strong></a><br/>
|
|
||||||
<?php } ?>
|
|
||||||
<strong>Réponse :</strong> <?= $question->getAnswer() ?><br/>
|
|
||||||
<?php
|
|
||||||
if ($question->getAttachedFileAnswer() !== null) { ?>
|
|
||||||
<em>Pièce jointe attachée :</em>
|
|
||||||
<a href="/file/<?= $question->getAttachedFileAnswer() ?>"><strong>Télécharger</strong></a><br/>
|
|
||||||
<?php } ?>
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
||||||
<br/>
|
|
||||||
<h5>Vidéo de réponse :</h5>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
if ($answer !== null) {
|
|
||||||
$link = $answer->getLink();
|
|
||||||
echo "<div class=\"alert alert-info\"><strong>Lien de la vidéo déjà envoyée :</strong> <a href=\"$link\">$link</a> (version " . $answer->getVersion() . ")</div>\n";
|
|
||||||
displayVideo($link);
|
|
||||||
switch ($answer->getValidation()) {
|
|
||||||
case 0:
|
|
||||||
echo "<div class=\"alert alert-warning\">La vidéo n'a pas encore été vérifiée par l'équipe d'organisation.</div>";
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
echo "<div class=\"alert alert-success\">La vidéo a été acceptée par l'équipe d'organisation.</div>";
|
|
||||||
break;
|
|
||||||
case -1:
|
|
||||||
echo "<div class=\"alert alert-danger\">La vidéo a été rejetée par l'équipe d'organisation.</div>";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($answer_validated != null && $answer_validated->getId() != $answer->getId()) {
|
|
||||||
$link = $answer_validated->getLink();
|
|
||||||
echo "<hr />\n<div class=\"alert alert-info\">Lien de la dernière vidéo validée : <a href=\"$link\">$link</a></div>\n";
|
|
||||||
displayVideo($link);
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
|
|
||||||
<form method="POST">
|
|
||||||
<input type="hidden" name="team" value="<?= $i + 1 ?>"/>
|
|
||||||
<div class="form-row">
|
|
||||||
<div class="form-group col-md-12">
|
|
||||||
<label for="link_<?= $i ?>">Lien de la vidéo à soumettre :</label>
|
|
||||||
<input class="form-control" type="url" id="link_<?= $i ?>" name="link"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<input type="checkbox" name="valid_link" id="valid_link_<?= $i ?>" required/> <label
|
|
||||||
for="valid_link_<?= $i ?>">Je
|
|
||||||
confirme que le lien est valide</label><br/>
|
|
||||||
|
|
||||||
<input type="checkbox" name="no_change" id="no_change_<?= $i ?>" required/> <label
|
|
||||||
for="no_change_<?= $i ?>">Je m'engage
|
|
||||||
à ne pas changer le contenu du lien et de la vidéo</label>
|
|
||||||
|
|
||||||
<input class="btn btn-primary btn-lg btn-block" type="submit" name="upload_answer"
|
|
||||||
value="Envoyer la vidéo"/>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once "footer.php";
|
|
@ -1,65 +0,0 @@
|
|||||||
<?php
|
|
||||||
require_once "header.php";
|
|
||||||
|
|
||||||
if (!$has_error) {
|
|
||||||
if (isset($recuperate_account))
|
|
||||||
echo "<div class=\"alert alert-warning\">Le mail de récupération de mot de passe a bien été envoyé.</div>";
|
|
||||||
elseif (isset($reset_password) && isset($_POST["password"]))
|
|
||||||
echo "<div class=\"alert alert-success\">Le mot de passe a bien été changé. Vous pouvez désormais vous connecter.</div>";
|
|
||||||
elseif (isset($_GET["confirmation-mail"]))
|
|
||||||
echo "<div class=\"alert alert-success\">Le mail a bien été renvoyé.</div>";
|
|
||||||
else if (isset($logging_in_user)) {
|
|
||||||
echo "<div class=\"alert alert-success\">Connexion réussie !</div>";
|
|
||||||
require_once "footer.php";
|
|
||||||
} else if (isset($_SESSION["user_id"])) {
|
|
||||||
echo "<div class=\"alert alert-danger\">Vous êtes déjà connecté !</div>";
|
|
||||||
require_once "footer.php";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_GET["mdp_oublie"])) { ?>
|
|
||||||
<form method="POST" class="jumbotron mt-5">
|
|
||||||
<h1 class="display-4">Réinitialisation du mot de passe</h1>
|
|
||||||
<label for="email">E-mail associée au compte :</label>
|
|
||||||
<input type="email" class="form-control" id="email" name="email" required/>
|
|
||||||
<input class="btn btn-lg btn-primary btn-block" type="submit" name="forgotten_password"
|
|
||||||
value="Envoyer l'e-mail de récupération"/>
|
|
||||||
</form>
|
|
||||||
<?php } elseif (isset($reset_password) && $reset_password->user != null && ($has_error || !isset($_POST["password"]))) { ?>
|
|
||||||
<form method="POST" class="jumbotron mt-5">
|
|
||||||
<h1 class="display-4">Connexion</h1>
|
|
||||||
<input type="hidden" name="token" value="<?= $_GET["token"] ?>"/>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="password">Nouveau mot de passe :</label>
|
|
||||||
<input type="password" id="password" name="password" class="form-control" required/>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="confirm_password">Confirmer le mot de passe :</label>
|
|
||||||
<input type="password" id="confirm_password" name="confirm_password" class="form-control" required/>
|
|
||||||
</div>
|
|
||||||
<input type="submit" name="reset_password" class="btn btn-block btn-primary"
|
|
||||||
value="Changer le mot de passe"/>
|
|
||||||
</form>
|
|
||||||
<?php } elseif (isset($_GET["confirmation-mail"])) { ?>
|
|
||||||
<?php } else { ?>
|
|
||||||
<form method="POST" class="jumbotron mt-5">
|
|
||||||
<h1 class="display-4">Connexion</h1>
|
|
||||||
<hr class="mt-2 mb-4"/>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="email">E-mail :</label>
|
|
||||||
<input class="form-control" type="email" id="email" name="email"
|
|
||||||
value="<?php if (isset($email)) echo $email ?>" required/>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="password">Mot de passe :</label>
|
|
||||||
<input class="form-control" type="password" id="password" name="password" required/>
|
|
||||||
</div>
|
|
||||||
<input class="btn btn-primary btn-block" name="login" type="submit" value="Se connecter"/>
|
|
||||||
</form>
|
|
||||||
<div class="alert">
|
|
||||||
<!--suppress HtmlUnknownTarget -->
|
|
||||||
<a href="/connexion/mdp-oublie">Mot de passe oublié ?</a>
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
<?php require_once "footer.php" ?>
|
|
@ -1,87 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
require_once "header.php";
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="mt-4 mb-4">
|
|
||||||
<h1 class="display-4">Envoyer la vidéo de solution</h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php if (isset($new_video) && !$has_error) { ?>
|
|
||||||
<div class="alert alert-success">
|
|
||||||
Votre vidéo a bien été envoyée !
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
<div class="alert alert-info">
|
|
||||||
<ul>
|
|
||||||
<li>Une fois vos travaux sur votre problème terminés, vous êtes invités dans le cadre des Correspondances à tourner
|
|
||||||
une vidéo dans laquelle vous présentez vos résultats.</li>
|
|
||||||
<li>La vidéo doit durer au maximum <strong>8 minutes</strong>.</li>
|
|
||||||
<li>Un travail de recherche, en équipe sur les problèmes, supervisé par l'encadrant·e, est attendu.</li>
|
|
||||||
<li>Au début de la vidéo, une brève présentation de l'énoncé est appréciée.</li>
|
|
||||||
<li>L'équipe doit présenter ses réponses trouvées aux questions de l'énoncé.</li>
|
|
||||||
<li>Toutes les plateformes d'hébergement vidéo sont supportées. Néanmoins, les plateformes
|
|
||||||
<a href="https://vimeo.com/">Viméo</a>, <a href="https://www.youtube.com/">YouTube</a>
|
|
||||||
et <a href="https://dailymotion.com/fr">Dailymotion</a> permettent une prévisualisation de la vidéo.
|
|
||||||
Cette liste pourra être étendue si besoin est.</li>
|
|
||||||
<li>Les liens de vos vidéos sont soumis à validation à l'équipe d'organisation.</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="alert alert-warning">
|
|
||||||
<strong>Date limite de soumission :</strong> <?= formatDate($CONFIG->getEndPhase1Date(), true) ?>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php if (Phase::getCurrentPhase() == Phase::PHASE12) { ?>
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
Vous avez soumis précédemment une vidéo, qui a été refusée par l'équipe d'organisation. Les détails ont du vous être transmis par mail.
|
|
||||||
Vous êtes désormais invités à poster une nouvelle vidéo, conforme aux attentes. En particulier, vérifiez que votre vidéo n'excède pas
|
|
||||||
la durée limite de <strong>8 minutes</strong>.
|
|
||||||
</div>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
if ($video !== null) {
|
|
||||||
$link = $video->getLink();
|
|
||||||
echo "<div class=\"alert alert-info\"><strong>Lien de la vidéo déjà envoyée :</strong> <a href=\"$link\">$link</a> (version " . $video->getVersion() . ")</div>\n";
|
|
||||||
displayVideo($link);
|
|
||||||
switch ($video->getValidation()) {
|
|
||||||
case 0:
|
|
||||||
echo "<div class=\"alert alert-warning\">La vidéo n'a pas encore été vérifiée par l'équipe d'organisation.</div>";
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
echo "<div class=\"alert alert-success\">La vidéo a été acceptée par l'équipe d'organisation.</div>";
|
|
||||||
break;
|
|
||||||
case -1:
|
|
||||||
echo "<div class=\"alert alert-danger\">La vidéo a été rejetée par l'équipe d'organisation.</div>";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($video_validated != null && $video_validated->getId() != $video->getId()) {
|
|
||||||
$link = $video_validated->getLink();
|
|
||||||
echo "<hr />\n<div class=\"alert alert-info\">Lien de la dernière vidéo validée : <a href=\"$link\">$link</a></div>\n";
|
|
||||||
displayVideo($link);
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
|
|
||||||
<hr/>
|
|
||||||
|
|
||||||
<form method="POST">
|
|
||||||
<div class="form-row">
|
|
||||||
<div class="form-group col-md-12">
|
|
||||||
<label for="link">Lien de la vidéo à soumettre :</label>
|
|
||||||
<input class="form-control" type="url" id="link" name="link"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<input type="checkbox" name="valid_link" id="valid_link" required/> <label for="valid_link">Je
|
|
||||||
confirme que le lien est valide</label><br/>
|
|
||||||
|
|
||||||
<input type="checkbox" name="no_change" id="no_change" required/> <label for="no_change">Je m'engage
|
|
||||||
à ne pas changer le contenu du lien et de la vidéo</label>
|
|
||||||
|
|
||||||
<input class="btn btn-primary btn-lg btn-block" type="submit" name="upload" value="Envoyer la vidéo"/>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<?php require_once "footer.php";
|
|
@ -1,134 +0,0 @@
|
|||||||
<?php require_once "header.php" ?>
|
|
||||||
|
|
||||||
<div class="mt-4 mb-4">
|
|
||||||
<h1 class="display-4">Informations sur l'équipe</h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="alert alert-info">
|
|
||||||
<strong>Nom de l'équipe :</strong> <?= $team->getName() ?>
|
|
||||||
</div>
|
|
||||||
<div class="alert alert-info">
|
|
||||||
<strong>Trigramme :</strong> <?= $team->getTrigram() ?>
|
|
||||||
</div>
|
|
||||||
<div class="alert alert-info">
|
|
||||||
<?php if (date("Y-m-d H:i:s") < $CONFIG->getInscriptionDate() && $team->getValidationStatus() == ValidationStatus::NOT_READY) { ?>
|
|
||||||
<label for="problem">Problème :</label>
|
|
||||||
<form method="POST">
|
|
||||||
<select class="custom-select" id="problem" name="select_problem" onchange="this.form.submit()">
|
|
||||||
<option value="0">Pas de problème choisi</option>
|
|
||||||
<?php
|
|
||||||
for ($i = 1; $i <= 4; ++$i) { ?>
|
|
||||||
<option value="<?= $i ?>" <?= $team->getProblem() == $i ? "selected" : "" ?>>
|
|
||||||
Problème <?= $i ?></option>
|
|
||||||
<?php } ?>
|
|
||||||
</select>
|
|
||||||
</form>
|
|
||||||
<?php } else { ?>
|
|
||||||
<strong>Problème :</strong> <a href="/probleme/<?= $team->getProblem() ?>">
|
|
||||||
<?= $team->getProblem() == 0 ? "Pas de problème choisi" : $team->getProblem() ?>
|
|
||||||
</a>
|
|
||||||
<?php } ?>
|
|
||||||
</div>
|
|
||||||
<div class="alert alert-<?= $team->getValidationStatus() == ValidationStatus::VALIDATED ? "success" : ($team->getValidationStatus() == ValidationStatus::WAITING ? "warning" : "danger") ?>">
|
|
||||||
<strong>Validation de l'équipe
|
|
||||||
:</strong> <?= ValidationStatus::getTranslatedName($team->getValidationStatus()) ?>
|
|
||||||
</div>
|
|
||||||
<div class="alert alert-info">
|
|
||||||
<?php
|
|
||||||
if ($team->getEncadrantId() !== null) {
|
|
||||||
$encadrant = User::fromId($team->getEncadrantId());
|
|
||||||
$id = $encadrant->getId();
|
|
||||||
echo "<strong>Encadrant :</strong> <a href=\"$URL_BASE/informations/$id/" . $encadrant->getFirstName() . " " . $encadrant->getSurname() . "\">" . $encadrant->getFirstName() . " " . $encadrant->getSurname() . "</a><br />";
|
|
||||||
}
|
|
||||||
for ($i = 1; $i <= 5; ++$i) {
|
|
||||||
if ($team->getParticipants()[$i - 1] == NULL)
|
|
||||||
continue;
|
|
||||||
$participant = User::fromId($team->getParticipants()[$i - 1]);
|
|
||||||
$id = $participant->getId();
|
|
||||||
echo "<strong>Participant $i :</strong> <a href=\"$URL_BASE/informations/$id/" . $participant->getFirstName() . " " . $participant->getSurname() . "\">" . $participant->getFirstName() . " " . $participant->getSurname() . "</a><br />";
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</div>
|
|
||||||
<div class="alert alert-info">
|
|
||||||
<strong>Autorise Animath à diffuser les vidéos :</strong> <?= $team->allowPublish() ? "oui" : "non" ?>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="alert alert-info">
|
|
||||||
<a href="mailto:contact@correspondances-maths.fr?<? foreach ($team->getAllEmails() as $email) echo "bcc=" . $email . "&" ?>subject=Correspondances de Jeunes Mathématicien·ne·s" target="_blank">Envoyer un mail à toute l'équipe</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<? if ($team->getValidationStatus() == ValidationStatus::VALIDATED && $team->getSolution() != null && $team->getSolution()->getValidation() == ValidationStatus::VALIDATED - 1) { ?>
|
|
||||||
<hr/>
|
|
||||||
<!--suppress HtmlUnknownTarget -->
|
|
||||||
<a href="/suivi-correspondances#team-<?= $team->getTrigram() ?>">
|
|
||||||
<button class="btn btn-primary btn-lg btn-block">
|
|
||||||
Aller aux vidéos de l'équipe
|
|
||||||
</button>
|
|
||||||
</a><br/>
|
|
||||||
<form method="POST">
|
|
||||||
<div class="form-group row">
|
|
||||||
<div class="form-group col-md-12">
|
|
||||||
<label for="other_teams">L'équipe va recevoir les vidéos des équipes suivantes (merci d'en
|
|
||||||
sélectionner exactement 2) :</label>
|
|
||||||
<select class="custom-select" id="other_teams" name="other_teams[]"
|
|
||||||
multiple <?= Phase::getCurrentPhase() >= Phase::PHASE2 ? "disabled" : "" ?>>
|
|
||||||
<?php
|
|
||||||
/** @var Team $other_team */
|
|
||||||
foreach ($other_teams as $other_team) {
|
|
||||||
if ($other_team->getId() == $team->getId())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
$team_name = $other_team->getName() . " (" . $other_team->getTrigram() . ")";
|
|
||||||
$team_id = $other_team->getId();
|
|
||||||
echo "<option value=\"$team_id\" " . (in_array($other_team->getId(), $team->getVideoTeamIds()) ? "selected" : "") . ">$team_name</option>\n";
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<?php if (Phase::getCurrentPhase() < Phase::PHASE2) { ?>
|
|
||||||
<input type="submit" class="btn btn-secondary btn-lg btn-block" name="update_video_teams"
|
|
||||||
value="Mettre à jour"/>
|
|
||||||
<?php } ?>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<?php } ?>
|
|
||||||
|
|
||||||
<hr/>
|
|
||||||
|
|
||||||
<h2>Autorisations de droit à l'image</h2>
|
|
||||||
|
|
||||||
<?php printDocuments($documents) ?>
|
|
||||||
|
|
||||||
<form method="POST">
|
|
||||||
<input type="submit" class="btn btn-secondary btn-lg btn-block" name="download_zip"
|
|
||||||
value="Télécharger l'archive"/>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<?php if ($team->getValidationStatus() == ValidationStatus::WAITING) { ?>
|
|
||||||
<hr/>
|
|
||||||
<form method="POST">
|
|
||||||
<div class="form-group row">
|
|
||||||
<label for="message">Message à adresser à l'équipe :</label>
|
|
||||||
<textarea class="form-control" id="message" name="message"></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="form-group row col-mod-6">
|
|
||||||
<input type="submit" class="btn btn-secondary btn-lg btn-block" name="unvalidate"
|
|
||||||
value="Refuser l'équipe"/>
|
|
||||||
<input type="submit" class="btn btn-primary btn-lg btn-block" name="validate" value="Valider l'équipe"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<?php
|
|
||||||
} elseif ($team->getValidationStatus() == ValidationStatus::NOT_READY) { ?>
|
|
||||||
<hr/>
|
|
||||||
<form method="POST">
|
|
||||||
<input type="submit" class="btn btn-primary btn-lg btn-block" name="delete_team" value="Supprimer l'équipe"
|
|
||||||
style="background-color: #ff2e34"/>
|
|
||||||
</form>
|
|
||||||
<?php }
|
|
||||||
|
|
||||||
require_once "footer.php" ?>
|
|
@ -1,33 +0,0 @@
|
|||||||
<?php
|
|
||||||
require_once "header.php";
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div class="mt-4 mb-4">
|
|
||||||
<h1 class="display-4">Exporter les données</h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<form method="POST">
|
|
||||||
<input class="btn btn-primary btn-lg btn-block" type="submit" name="export_user_data"
|
|
||||||
value="Exporter les données utilisateurs"/>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<hr/>
|
|
||||||
|
|
||||||
<form method="POST">
|
|
||||||
<input class="btn btn-primary btn-lg btn-block" type="submit" name="export_team_data"
|
|
||||||
value="Exporter les données équipes"/>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<hr/>
|
|
||||||
|
|
||||||
<form method="POST">
|
|
||||||
<input class="btn btn-primary btn-lg btn-block" type="submit" name="export_problems_data"
|
|
||||||
value="Exporter les données problèmes"/>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<hr />
|
|
||||||
|
|
||||||
<h4><em>Ce site a enregistré <?= $CONFIG->getViews() ?> visites.</em></h4>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
require_once "footer.php";
|
|
@ -1,18 +0,0 @@
|
|||||||
<div class="mt-4 mb-4">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<hr/>
|
|
||||||
<div class="container.fluid">
|
|
||||||
<div class="alert alert-light inner">
|
|
||||||
<em>Ce site a été conçu pour Animath, avec amour et passion. Il est récent et il est possible que
|
|
||||||
certaines pages ne fonctionnent pas correctement. Si vous remarquez des bugs, merci de les signaler à
|
|
||||||
l'adresse <a href="mailto:contact@correspondances-maths.fr">contact@correspondances-maths.fr</a>.</em><br/>
|
|
||||||
© <?= date("Y") ?> Correspondances de Jeunes Mathématicien·ne·s
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
<?php exit() ?>
|
|
@ -1,177 +0,0 @@
|
|||||||
<?php $CONFIG->incrViews() ?>
|
|
||||||
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="fr">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="description" content="Inscrivez-vous pour les Correspondances des Jeunes Mathématicien·ne·s <?= $YEAR . " - " . ($YEAR + 1) ?> !">
|
|
||||||
<meta name="keywords" content="Correspondances,Jeunes,Mathématicien·ne·s,Mathématiciens,Mathématiciennes,Corres2Math,Inscription,TFJM²,TFJM">
|
|
||||||
<meta name="author" content="Yohann D'ANELLO (yohann.danello[at]animath.fr)">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<meta name="google-site-verification" content="nTgyZnU1Uw0OYaAX-TMg-5hVIKkeKAYtj2sNQRDz_sQ">
|
|
||||||
<title>Site d'inscription pour les Correspondances des Jeunes Mathématicien·ne·s <?= $YEAR . " - " . ($YEAR + 1) ?></title>
|
|
||||||
<link rel="stylesheet" type="text/css" href="/style.css">
|
|
||||||
<link REL="shortcut icon" href="/favicon.ico">
|
|
||||||
|
|
||||||
<!-- Bootstrap -->
|
|
||||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
|
|
||||||
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class="container.fluid bg-light">
|
|
||||||
<nav class="navbar navbar-expand-lg navbar-light">
|
|
||||||
<div class="container">
|
|
||||||
<a class="navbar-brand" href="https://correspondances-maths.fr/" target="_blank">
|
|
||||||
<img src="/logo.png" alt="Logo Corres2Mat" id="navbar-logo">
|
|
||||||
</a>
|
|
||||||
<ul class="navbar-nav mr-auto">
|
|
||||||
<li class="nav-item active">
|
|
||||||
<a class="nav-link" href="/">Accueil</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item active">
|
|
||||||
<a class="nav-link" href="/calendrier">Calendrier</a>
|
|
||||||
</li>
|
|
||||||
<?php if (isset($_SESSION["user_id"])) { ?>
|
|
||||||
<li class="nav-item active">
|
|
||||||
<a class="nav-link" href="/mon-compte">Mon compte</a>
|
|
||||||
</li>
|
|
||||||
<?php if ($_SESSION["role"] == Role::ENCADRANT || $_SESSION["role"] == Role::PARTICIPANT) { ?>
|
|
||||||
<?php if ($_SESSION["team"] == NULL || $_SESSION["role"] == Role::ENCADRANT) {
|
|
||||||
if (date("Y-m-d H:i:s") < $CONFIG->getInscriptionDate()) { ?>
|
|
||||||
<li class="nav-item active"><a class="nav-link" href="/ajouter-equipe">
|
|
||||||
Ajouter une équipe</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item active"><a class="nav-link" href="/rejoindre-equipe">
|
|
||||||
Rejoindre une équipe</a>
|
|
||||||
</li>
|
|
||||||
<?php }
|
|
||||||
}
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var Team $_team
|
|
||||||
*/
|
|
||||||
foreach ($_SESSION["teams"] as $_team) {
|
|
||||||
$appendice = $_SESSION["role"] == Role::ENCADRANT ? "/" . $_team->getTrigram() : "";
|
|
||||||
?>
|
|
||||||
<li class="nav-item active">
|
|
||||||
<a class="nav-link">Équipe <?= $_team->getTrigram() ?></a>
|
|
||||||
<ul class="deroule">
|
|
||||||
<li class="nav-item active">
|
|
||||||
<a class="nav-link" href="/mon-equipe<?= $appendice ?>">Informations sur l'équipe</a>
|
|
||||||
</li>
|
|
||||||
<?php if ($_team->getValidationStatus() == ValidationStatus::VALIDATED) { ?>
|
|
||||||
<li class="nav-item active"><a class="nav-link" href="/ma-participation<?= $appendice ?>">Ma participation</a></li>
|
|
||||||
<?php
|
|
||||||
switch (Phase::getCurrentPhase()) {
|
|
||||||
case Phase::PHASE1:
|
|
||||||
case Phase::PHASE12:
|
|
||||||
if (Phase::getCurrentPhase() == Phase::PHASE12) {
|
|
||||||
if (Video::getVideo(Reason::SOLUTION, $_team) == NULL)
|
|
||||||
break;
|
|
||||||
else if (Video::getVideo(Reason::SOLUTION, $_team, ValidationStatus::WAITING) != NULL)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
<li class="nav-item active"><a class="nav-link" href="/envoyer-video-1<?= $appendice ?>">
|
|
||||||
Envoyer ma vidéo (phase 1)</a>
|
|
||||||
</li>
|
|
||||||
<?php break;
|
|
||||||
case Phase::PHASE2: ?>
|
|
||||||
<li class="nav-item active"><a class="nav-link" href="/poser-questions-2<?= $appendice ?>">
|
|
||||||
Poser des questions (phase 2)</a>
|
|
||||||
</li>
|
|
||||||
<?php break;
|
|
||||||
case Phase::PHASE3: ?>
|
|
||||||
<li class="nav-item active"><a class="nav-link" href="/repondre-questions-3<?= $appendice ?>">
|
|
||||||
Répondre aux questions (phase 3)</a>
|
|
||||||
</li>
|
|
||||||
<?php break;
|
|
||||||
case Phase::PHASE4: ?>
|
|
||||||
<li class="nav-item active"><a class="nav-link" href="/commenter-echange-4<?= $appendice ?>">
|
|
||||||
Commenter l'échange (phase 4)</a></li>
|
|
||||||
<?php break;
|
|
||||||
}
|
|
||||||
} ?>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<?php } ?>
|
|
||||||
<?php } ?>
|
|
||||||
<?php } ?>
|
|
||||||
<?php if ($_SESSION["role"] == Role::ADMIN) { ?>
|
|
||||||
<li class="nav-item active">
|
|
||||||
<a class="nav-link">Liste des équipes</a>
|
|
||||||
<ul class="deroule">
|
|
||||||
<li class="nav-item active"><a class="nav-link" href="/probleme/1">Problème 1</a></li>
|
|
||||||
<li class="nav-item active"><a class="nav-link" href="/probleme/2">Problème 2</a></li>
|
|
||||||
<li class="nav-item active"><a class="nav-link" href="/probleme/3">Problème 3</a></li>
|
|
||||||
<li class="nav-item active"><a class="nav-link" href="/probleme/4">Problème 4</a></li>
|
|
||||||
<li class="nav-item active"><a class="nav-link" href="/probleme/0">Équipes sans problème</a></li>
|
|
||||||
<li class="nav-item active"><a class="nav-link" href="/profils-orphelins">Profils orphelins</a></li>
|
|
||||||
<li class="nav-item active"><a class="nav-link" href="/profils">Tous les profils</a></li>
|
|
||||||
<li class="nav-item active"><a class="nav-link" href="/admins">Administrateurs</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item active">
|
|
||||||
<a class="nav-link" href="/ajouter-admin">Ajouter un admin</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item active">
|
|
||||||
<a class="nav-link">Suivi des Correspondances</a>
|
|
||||||
<ul class="deroule">
|
|
||||||
<li class="nav-item active"><a class="nav-link" href="/suivi-correspondances/1">Problème 1</a></li>
|
|
||||||
<li class="nav-item active"><a class="nav-link" href="/suivi-correspondances/2">Problème 2</a></li>
|
|
||||||
<li class="nav-item active"><a class="nav-link" href="/suivi-correspondances/3">Problème 3</a></li>
|
|
||||||
<li class="nav-item active"><a class="nav-link" href="/suivi-correspondances/4">Problème 4</a></li>
|
|
||||||
<li class="nav-item active"><a class="nav-link" href="/suivi-correspondances">Tous les problèmes</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item active">
|
|
||||||
<a class="nav-link" href="/exporter-donnees">Exporter les données</a>
|
|
||||||
</li>
|
|
||||||
<?php } ?>
|
|
||||||
<?php } ?>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<ul class="navbar-nav">
|
|
||||||
<?php if (isset($_SESSION["admin"])) { ?>
|
|
||||||
<li class="nav-item active">
|
|
||||||
<a class="nav-link" href="/?view-as-admin">Retourner en vue administrateur</a>
|
|
||||||
</li>
|
|
||||||
<?php } ?>
|
|
||||||
<?php if (isset($_SESSION["user_id"])) { ?>
|
|
||||||
<li class="nav-item active">
|
|
||||||
<a class="nav-link" href="/deconnexion">Déconnexion</a>
|
|
||||||
</li>
|
|
||||||
<?php } else { ?>
|
|
||||||
<?php if (date("Y-m-d H:i:s") < $CONFIG->getInscriptionDate()) { ?>
|
|
||||||
<li class="nav-item active">
|
|
||||||
<a class="nav-link" href="/inscription">Inscription</a>
|
|
||||||
</li>
|
|
||||||
<?php } ?>
|
|
||||||
<li class="nav-item active">
|
|
||||||
<a class="nav-link" href="/connexion">Connexion</a>
|
|
||||||
</li>
|
|
||||||
<?php } ?>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="container">
|
|
||||||
<div class="mt-4 mb-4">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
if (isset($has_error) && $has_error) { ?>
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
<strong>Erreur :</strong> <?= $error_message ?>
|
|
||||||
</div>
|
|
||||||
<?php }
|
|
||||||
|
|
||||||
/* if (!isset($_SESSION["role"]) || $_SESSION["role"] != Role::ADMIN && !isset($_SESSION["admin"])) { ?>
|
|
||||||
<div class="alert alert-warning">
|
|
||||||
Le site est actuellement en maintenance. Veuillez réessayer ultérieurement.
|
|
||||||
</div>
|
|
||||||
<?php
|
|
||||||
exit(-1);
|
|
||||||
}*/
|
|
@ -1,54 +0,0 @@
|
|||||||
<div>
|
|
||||||
|
|
||||||
<div class="jumbotron bg-white">
|
|
||||||
<div class="row">
|
|
||||||
<h1 class="display-3">
|
|
||||||
Bienvenue sur le site d'inscription aux <a href="https://correspondances-maths.fr/" target="_blank">
|
|
||||||
Correspondances des Jeunes Mathématicien·ne·s</a> !
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row jumbotron bg-white">
|
|
||||||
<div class="col-sm">
|
|
||||||
<h3>
|
|
||||||
Tu souhaites participer aux Correspondances ?
|
|
||||||
<br/>
|
|
||||||
Ton équipe est déjà formée ?
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm text-right">
|
|
||||||
<div class="btn-group-vertical">
|
|
||||||
<a class="btn btn-primary btn-lg" href="/inscription" role="button">Inscris-toi maintenant !</a>
|
|
||||||
<a class="btn btn-light btn-lg" href="/connexion" role="button">J'ai déjà un compte</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="jumbotron">
|
|
||||||
<h5 class="display-4">Comment ça marche ?</h5>
|
|
||||||
<p>
|
|
||||||
Pour participer aux Correspondances, il suffit de créer un compte sur la rubrique <strong>Inscription</strong>.
|
|
||||||
Vous devrez ensuite confirmer votre adresse e-mail.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Vous pouvez accéder à votre compte via la rubrique <b>Connexion</b>. Une fois connecté, vous pourrez créer une équipe
|
|
||||||
ou en rejoindre une déjà créée par l'un de vos camarades via un code d'accès qui vous aura été transmis. Vous serez ensuite
|
|
||||||
invité à soumettre une autorisation de droit à l'image, indispensable au bon déroulement des Correspondances. Une fois que votre équipe
|
|
||||||
comporte au moins 3 participants (maximum 5) et un encadrant, vous pourrez demander à valider votre équipe pour
|
|
||||||
être apte à travailler sur le problème de votre choix.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div class="alert alert-warning">
|
|
||||||
<strong>Attention aux dates !</strong> Si vous ne finalisez pas votre inscription dans le délai indiqué, vous
|
|
||||||
ne pourrez malheureusement pas participer aux Correspondances.
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="alert alert-info">
|
|
||||||
Si votre équipe est déjà formée mais que vous peinez à trouver un encadrant, n'hésitez pas à nous contacter à l'adresse
|
|
||||||
<a href="mailto:contact@correspondances-maths.fr">contact@correspondances-maths.fr</a> pour que nous vous aidions à
|
|
||||||
vous mettre éventuellement en contact avec un encadrant de votre région.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user