@ -18,7 +18,9 @@ Notre projet est divisé en plusieurs parties:
## Backend
### Validation et résilience des erreurs
#### Motivation
Un controlleur a pour but de valider les données d'une requête avant de les manipuler.
Nous nous sommes rendu compte que la vérification des données d'une requête était redondante, même en factorisant les différents
@ -56,6 +58,7 @@ Bien souvent, lorsque le prédicat échoue, un message est ajouté à la liste d
de la redondance sur les messages d'erreurs choisis lorsqu'une validation échoue.
#### Schéma
Toutes ces lignes de code pour définir que notre requête doit contenir un champ nommé `email`, dont la valeur est une adresse mail, d'une longueur comprise entre 6 et 64.
Nous avons donc trouvé l'idée de définir un système nous permettant de déclarer le schéma d'une requête,
et de reporter le plus d'erreurs possibles lorsqu'une requête ne valide pas le schéma :
@ -74,6 +77,7 @@ public function doPostAction(array $form): HttpResponse {
// traitement ...
}
```
Ce système nous permet de faire de la programmation _déclarative_, nous disons à _quoi_ ressemble la forme de la requête que l'on souhaite,
plustot que de définir _comment_ réagir face à notre requête.
Ce système permet d'être beaucoup plus clair sur la forme attendue d'une requête, et de garder une lisibilité satisfaisante peu importe le nombre de
@ -84,6 +88,7 @@ plus de précision sur une erreur, comme le nom du champ qui est invalidé, et q
les erreurs et facilement entourer les champs invalides en rouge, ainsi que d'afficher toutes les erreurs que l'utilisateur a fait, d'un coup.
### HttpRequest, HttpResponse
Nous avons choisi d'encapsuler les requêtes et les réponses afin de faciliter leur manipulation.
Cela permet de mieux repérer les endroits du code qui manipulent une requête d'un simple tableau,
et de garder à un seul endroit la responsabilitée d'écrire le contenu de la requête vers client.
@ -92,6 +97,7 @@ et de garder à un seul endroit la responsabilitée d'écrire le contenu de la r
C'est ensuite à la classe `src/App/App` d'afficher la réponse.
### index.php
Il y a deux points d'entrés, celui de la WebApp (`public/index.php`), et celui de l'API (`public/api/index.php`).
Ces fichiers ont pour but de définir ce qui va être utilisé dans l'application, comme les routes, la base de donnée, les classes métiers utilisés,
comment gérer l'authentification dans le cadre de l'API, et une session dans le cadre de la web app.
@ -100,12 +106,12 @@ L'index définit aussi quoi faire lorsque l'application retourne une réponse. D
l'affichage dans une classe (`IQBall\App\App` et `IQBall\API\API`).
### API
Nous avons définit une petite API (`src/Api`) pour nous permettre de faire des actions en arrière plan depuis le front end.
Par exemple, l'API permet de changer le nom d'une tactique, ou de sauvegarder son contenu.
C'est plus pratique de faire des requêtes en arrière-plan plustot que faire une requête directement à la partie WebApp, ce qui
aurait eu pour conséquences de recharger la page
## Frontend
### Utilisation de React
@ -120,4 +126,3 @@ il faut que les flèches qui y sont liés bougent aussi, il faut que les joueurs
Le front-end de l’éditeur et du visualiseur étant assez ambitieux, et occupant une place importante du projet, nous avons décidés de l’effectuer en utilisant
le framework React qui rend simple le développement d’interfaces dynamiques, et d’utiliser typescript parce qu’ici on code bien et qu’on impose une type safety a notre code.
As you can see our entire application is build around three main package.
@ -13,7 +14,7 @@ Allowing to operate on it.
The App now is more about the web application itself.
Having all the controllers of the MVC architecture the use the model, the validation system and the http system in the core.
It also calls the twig's views inside of App. Finally, it uses the package Session. This one replace the $_SESSION we all know in PHP.
It also calls the twig's views inside of App. Finally, it uses the package Session. This one replace the $\_SESSION we all know in PHP.
Thanks to this we have a way cleaner use of all session's data.
Nevertheless, all the controllers call not only twig views but also react ones.
Those are present in the package "front", dispatched in several other packages.
@ -22,6 +23,7 @@ Such as assets having all the image and stuff, model containing all the data's s
Finally, we have the package "Api" that allows to share code and bind all the different third-hand application such as the web admin one.
## Main data class diagram.

You can see how our data is structured contained in the package "data" as explained right above.
@ -42,6 +44,7 @@ The last class we have is the Account. It could directly be incorporated in User
Then, Account only has a user and a token which is an identifier.
## Validation's class diagram

We implemented our own validation system, here it is!
@ -54,6 +57,7 @@ The other part of the diagram is about the failure a specific field's validation
We have a concrete class to return a something more general. All the successors are just more precise about the failure.
## Http's class diagram

It were we centralize what the app can render, and what the api can receive.
Then, we got the "basic" response (HttpResponse) that just render a HttpCodes.
@ -61,21 +65,26 @@ We have two successors for now. ViewHttpResponse render not only a code but also
Finally, we have the JsonHttpResponse that renders, as it's name says, some Json.
## Session's class diagram

It encapsulates the PHP's array "$_SESSION". With two interfaces that dictate how a session should be handled, and same for a mutable one.
It encapsulates the PHP's array "$\_SESSION". With two interfaces that dictate how a session should be handled, and same for a mutable one.
## Model View Controller
All class diagram, separated by their range of action, of the imposed MVC architecture.
All of them have a controller that validates entries with the validation system and check the permission the user has,and whether or not actually do the action.
These controllers are composed by a Model that handle the pure data and is the point of contact between these and the gateways.
Speaking of which, Gateways are composing Models. They use the connection class to access the database and send their query.
@ -3,17 +3,13 @@ machine, and how it works under the hood.
# How to run the project on my local computer
1. Use phpstorm to run a local php server:
1) Use phpstorm to run a local php server:
* Go to configuration > add new configuration
* Select "PHP Built-in Web Server", then enter options as follow:

- port 8080
- name the configuration "RunServer" to be more explicit
- place the "Document Root" in `/public`
- host is localhost
* Click apply, OK
* Now run it.
- Go to configuration > add new configuration
- Select "PHP Built-in Web Server", then enter options as follow:
 - port 8080 - name the configuration "RunServer" to be more explicit - place the "Document Root" in `/public` - host is localhost
- Click apply, OK
- Now run it.
If you go to `http://localhost:8080` you'll see a blank page.
This is expected ! On your browser, open inspection tab (ctrl+shift+i) go to network and refresh the page.
@ -39,12 +35,14 @@ Now refresh your page, you should now see all request being fulfilled and a form
Caution: **NEVER** directly connect on the `localhost:5173` node development server, always pass through the php (`localhost:8080`) server.
# How it works
I'm glad you are interested in how that stuff works, it's a bit tricky, lets go.
If you look at our `index.php` (located in `/public` folder), you'll see that it define our routes, it uses an `AltoRouter` then delegates the request's action processing to a controller.
We can see that there are two registered routes, the `GET:/` (that then calls `SampleFormController#displayForm()`) and `POST:/result` (that calls `SampleFormController#displayResults()`).
Implementation of those two methods are very simple: there is no verification to make nor model to control, thus they directly sends the view back to the client.
here's the implementation of the `SampleFormController`
```php
require_once "react-display.php";
class SampleFormController {
@ -63,7 +61,7 @@ As our views are now done using react (and defined under the `front/views` folde
If you look at the `send_react_front($viewURI, $viewArguments)` function, you'll see that is simply loads the file `src/react-display-file.php` with given arguments.
The file is a simple html5 template with a `<script>` block in the `<body>` section.
The script block imports the requested view and will render it.
The view entry is a function, named in PascalCase, which __must__ be be exported by default (`export default function MyReactView(args: {..})`).
The view entry is a function, named in PascalCase, which **must** be be exported by default (`export default function MyReactView(args: {..})`).
```html
<!--
@ -86,6 +84,7 @@ This method then uses the `send_react_front`, to render the `views/SampleForm.ts
The view file **must export by default its react function component**.
## Server Profiles
If you go on the staging server, you'll see that, for the exact same request equivalent, the generated `src/render-display-file` file changes :
(we can also see that much less files are downloaded than with our localhost aka development server).
@ -101,6 +100,7 @@ By default, the `/config.php` file uses the `dev-config-profile.php` profile,
the file is replaced with `prod-config-file.php` by the CI when deploying to the staging server (see the pipeline "prepare php" step in `/ci/.drone.yml`)
The two profiles declares an `_asset(string $uri)` function, used by the `/config.php::asset` method, but with different implementations :
### Development profile
```php
@ -112,9 +112,11 @@ function _asset(string $assetURI): string {
return $front_url . "/" . $assetURI;
}
```
The simplest profile, simply redirect all assets to the development server
### Production profile
Before the CD workflow step deploys the generated files to the server,
it generates a `/views-mappings.php` file that will map the react views file names to their compiled javascript files :
@ -126,7 +128,9 @@ const ASSETS = [
... // other files that does not have to be directly used by the `send_react_front()` function
];
```
The `_asset` function will then get the right javascript for the given typescript file.