conception/update #93
conception/update
into master
1 year ago
@ -0,0 +1,81 @@
|
||||
# Welcome on the documentation's description
|
||||
|
||||
## Let's get started with the architecture diagram.
|
||||

|
||||
|
||||
As you can see our entire application is build around three main package.
|
||||
All of them contained in "src" package.
|
||||
The core represent the main code of the web application.
|
||||
It contains all the validation protocol, detailed below, the model of the imposed MVC architecture.
|
||||
It also has a package named "data", it is a package of the structure of all the data we use in our application.
|
||||
Of course there is package containing all the gateways as its name indicates. It is where we use the connection to our database.
|
||||
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.
|
||||
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.
|
||||
Such as assets having all the image and stuff, model containing all the data's structure, style centralizing all css file and eventually components the last package used for the editor.
|
||||
|
||||
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.
|
||||
There is two clear part.
|
||||
First of all, the Tactic one.
|
||||
We got a nice class named TacticInfo representing as it says the information about a tactic, nothing to discuss more about.
|
||||
It associates an attribute of type "CourtType". This last is just an "evoluated" type of enum with some more features.
|
||||
We had to do it this way because of the language PHP that doesn't implement such a thing as an enum.
|
||||
|
||||
Now, let's discuss a much bigger part of the diagram.
|
||||
In this part we find all the team logic. Actually, a team only have an array of members and a "TeamInfo".
|
||||
The class "TeamInfo" only exists to split the team's information data (name, id etc) from the members.
|
||||
The type Team does only link the information about a team and its members.
|
||||
Talking about them, their class indicate what role they have (either Coach or Player) in the team.
|
||||
Because a member is registered in the app, therefore he is a user of it. Represented by the type of the same name.
|
||||
This class does only contain all the user's basic information.
|
||||
The last class we have is the Account. It could directly be incorporated in User but we decided to split it the same way we did for the team.
|
||||
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!
|
||||
For the validation methods (for instance those in DefaultValidators) we use lambda to instantiate a Validator.
|
||||
In general, we use the implementation "SimpleFunctionValidator".
|
||||
We reconize the strategy pattern. Indeed, we need a family of algorithms because we have many classes that only differ by the way they validate.
|
||||
Futhermore, you may have notices the ComposedValidator that allows to chain several Validator.
|
||||
We can see that this system uses the composite pattern
|
||||
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.
|
||||
We have two successors for now. ViewHttpResponse render not only a code but also a view, either react or twig ones.
|
||||
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.
|
||||
## 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.
|
||||
|
||||
### Team
|
||||

|
||||
|
||||
### Editor
|
||||

|
||||
|
||||
### Authentification
|
||||

|
||||
|
@ -0,0 +1,60 @@
|
||||
@startuml
|
||||
'https://plantuml.com/component-diagram
|
||||
|
||||
package front{
|
||||
package assets
|
||||
package components
|
||||
package model
|
||||
package style
|
||||
package views
|
||||
}
|
||||
|
||||
database sql{
|
||||
|
||||
}
|
||||
|
||||
package src {
|
||||
|
||||
package "Api"{
|
||||
|
||||
}
|
||||
|
||||
package "App" {
|
||||
package Controller
|
||||
package Session
|
||||
package Views
|
||||
}
|
||||
|
||||
package Core{
|
||||
package Data
|
||||
package Gateway
|
||||
package Http
|
||||
package Model
|
||||
package Validation
|
||||
[Connection]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[sql] -- [Connection]
|
||||
|
||||
[views] -- [style]
|
||||
[views] -- [components]
|
||||
[views] -- [assets]
|
||||
[views] -- [model]
|
||||
|
||||
[Gateway] -- [Connection]
|
||||
|
||||
[Validation] -- [Controller]
|
||||
[Controller] -- [Session]
|
||||
[Controller] -- [Http]
|
||||
[Controller] -- [Views]
|
||||
[Controller] -- [views]
|
||||
[Controller] -- [Model]
|
||||
[Model] -- [Gateway]
|
||||
|
||||
[Api] -- [Validation]
|
||||
[Api] -- [Model]
|
||||
[Api] -- [Http]
|
||||
|
||||
@enduml
|
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 8.7 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 32 KiB |
@ -0,0 +1,44 @@
|
||||
@startuml
|
||||
class EditorController {
|
||||
+__construct (model : TacticModel)
|
||||
+ openEditorFor(tactic:TacticInfo): ViewHttpResponse
|
||||
+ createNew(): ViewHttpResponse
|
||||
+ openTestEditor(courtType:CourtType): ViewHttpResponse
|
||||
+ createNewOfKind(type:CourtType, session:SessionHandle): ViewHttpResponse
|
||||
+ openEditor(id:int, session:SessionHandle): ViewHttpResponse
|
||||
}
|
||||
EditorController *-- "- model" TacticModel
|
||||
|
||||
class TacticModel {
|
||||
+ TACTIC_DEFAULT_NAME:int {static}{frozen}
|
||||
+ __construct(tactics : TacticInfoGateway)
|
||||
+ makeNew(name:string, ownerId:int, type:CourtType): TacticInfo
|
||||
+ makeNewDefault(ownerId:int, type:CourtType): ?TacticInfo
|
||||
+ get(id:int): ?TacticInfo
|
||||
+ getLast(nb:int, ownerId:int): array
|
||||
+ getAll(ownerId:int): ?array
|
||||
+ updateName(id:int, name:string, authId:int): array
|
||||
+ updateContent(id:int, json:string): ?ValidationFail
|
||||
}
|
||||
|
||||
TacticModel *-- "- tactics" TacticInfoGateway
|
||||
|
||||
class TacticInfoGateway{
|
||||
+ __construct(con : Connexion)
|
||||
+ get(id:int): ?TacticInfo
|
||||
+ getLast(nb:int, ownerId:int): ?array
|
||||
+ getAll(ownerId:int): ?array
|
||||
+ insert(name:string, owner:int, type:CourtType): int
|
||||
+ updateName(id:int, name:string): bool
|
||||
+ updateContent(id:int, json:string): bool
|
||||
}
|
||||
|
||||
TacticInfoGateway *--"- con" Connexion
|
||||
|
||||
class TacticValidator{
|
||||
+ validateAccess(tacticId:int, tactic:?TacticInfo, ownerId:int): ?ValidationFail {static}
|
||||
}
|
||||
|
||||
EditorController ..> TacticValidator
|
||||
|
||||
@enduml
|
@ -1,63 +1,87 @@
|
||||
@startuml
|
||||
class Team {
|
||||
- name: string
|
||||
- picture: Url
|
||||
- members: array<int, MemberRole>
|
||||
|
||||
+ __construct(name : string, picture : string, mainColor : Colo, secondColor : Color)
|
||||
+ getName(): string
|
||||
+ getPicture(): Url
|
||||
+ getMainColor(): Color
|
||||
+ getSecondColor(): Color
|
||||
+ listMembers(): array<Member>
|
||||
}
|
||||
|
||||
Team --> "- mainColor" Color
|
||||
Team --> "- secondColor" Color
|
||||
|
||||
class Color {
|
||||
- value: string
|
||||
- __construct(value : string)
|
||||
+ getValue(): string
|
||||
+ from(value: string): Color
|
||||
+ tryFrom(value : string) : ?Color
|
||||
}
|
||||
|
||||
class TeamGateway{
|
||||
--
|
||||
|
||||
+ __construct(con : Connexion)
|
||||
+ insert(name : string ,picture : string, mainColor : Color, secondColor : Color)
|
||||
+ listByName(name : string): array
|
||||
+ getTeamById(id:int): ?TeamInfo
|
||||
+ getTeamIdByName(name:string): ?int
|
||||
+ deleteTeam(idTeam:int): void
|
||||
+ editTeam(idTeam:int, newName:string, newPicture:string, newMainColor:string, newSecondColor:string)
|
||||
+ getAll(user:int): array
|
||||
}
|
||||
|
||||
TeamGateway *--"- con" Connexion
|
||||
TeamGateway ..> Color
|
||||
|
||||
|
||||
class MemberGateway{
|
||||
|
||||
+ __construct(con : Connexion)
|
||||
+ insert(idTeam:int, userId:int, role:string): void
|
||||
+ getMembersOfTeam(teamId:int): array
|
||||
+ remove(idTeam:int, idMember:int): void
|
||||
+ isCoach(email:string, idTeam:int): bool
|
||||
+ isMemberOfTeam(idTeam:int, idCurrentUser:int): bool
|
||||
}
|
||||
|
||||
MemberGateway *--"- con" Connexion
|
||||
|
||||
class AccountGateway{
|
||||
+ __construct(con : Connexion)
|
||||
+ insertAccount(name:string, email:string, token:string, hash:string, profilePicture:string): int
|
||||
+ getRowsFromMail(email:string): ?array
|
||||
+ getHash(email:string): ?string
|
||||
+ exists(email:string): bool
|
||||
+ getAccountFromMail(email:string): ?Account
|
||||
+ getAccountFromToken(token:string): ?Account
|
||||
}
|
||||
|
||||
AccountGateway *--"- con" Connexion
|
||||
|
||||
class TeamModel{
|
||||
---
|
||||
|
||||
+ __construct(gateway : TeamGateway)
|
||||
+ createTeam(name : string,picture : string, mainColorValue : int, secondColorValue : int, errors : array)
|
||||
+ addMember(mail:string, teamId:int, role:string): int
|
||||
+ listByName(name : string ,errors : array) : ?array
|
||||
+ displayTeam(id : int): Team
|
||||
+ getTeam(idTeam:int, idCurrentUser:int): ?Team
|
||||
+ deleteMember(idMember:int, teamId:int): int
|
||||
+ deleteTeam(email:string, idTeam:int): int
|
||||
+ isCoach(idTeam:int, email:string): bool
|
||||
+ editTeam(idTeam:int, newName:string, newPicture:string, newMainColor:string, newSecondColor:string)
|
||||
+ getAll(user:int): array
|
||||
}
|
||||
|
||||
TeamModel *--"- gateway" TeamGateway
|
||||
TeamModel ..> Team
|
||||
TeamModel ..> Color
|
||||
TeamModel *--"- members" MemberGateway
|
||||
TeamModel *--"- teams" TeamGateway
|
||||
TeamModel *--"- teams" AccountGateway
|
||||
|
||||
|
||||
class TeamController{
|
||||
- twig : Environement
|
||||
--
|
||||
+ __construct( model : TeamModel, twig : Environement)
|
||||
+ displaySubmitTeam() : HttpResponse
|
||||
+ submitTeam(request : array) : HttpResponse
|
||||
+ displayListTeamByName(): HttpResponse
|
||||
+ listTeamByName(request : array) : HttpResponse
|
||||
+ displayTeam(id : int): HttpResponse
|
||||
+ __construct( model : TeamModel)
|
||||
+ displayCreateTeam(session:SessionHandle): ViewHttpResponse
|
||||
+ displayDeleteMember(session:SessionHandle): ViewHttpResponse
|
||||
+ submitTeam(request:array, session:SessionHandle): HttpResponse
|
||||
+ displayListTeamByName(session:SessionHandle): ViewHttpResponse
|
||||
+ listTeamByName(request:array, session:SessionHandle): HttpResponse
|
||||
+ deleteTeamById(id:int, session:SessionHandle): HttpResponse
|
||||
+ displayTeam(id:int, session:SessionHandle): ViewHttpResponse
|
||||
+ displayAddMember(idTeam:int, session:SessionHandle): ViewHttpResponse
|
||||
+ addMember(idTeam:int, request:array, session:SessionHandle): HttpResponse
|
||||
+ deleteMember(idTeam:int, idMember:int, session:SessionHandle): HttpResponse
|
||||
+ displayEditTeam(idTeam:int, session:SessionHandle): ViewHttpResponse
|
||||
+ editTeam(idTeam:int, request:array, session:SessionHandle): HttpResponse
|
||||
}
|
||||
|
||||
TeamController *--"- model" TeamModel
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class Connexion { }
|
||||
|
||||
@enduml
|
@ -0,0 +1,27 @@
|
||||
@startuml
|
||||
|
||||
interface SessionHandle{
|
||||
+ getInitialTarget(): ?string {abstract}
|
||||
+ getAccount(): ?Account {abstract}
|
||||
}
|
||||
|
||||
interface MutableSessionHandle{
|
||||
+ setInitialTarget(url:?string): void
|
||||
+ setAccount(account:Account): void
|
||||
+ destroy(): void
|
||||
}
|
||||
|
||||
class PhpSessionHandle{
|
||||
+ init(): self {static}
|
||||
+ getAccount(): ?Account
|
||||
+ getInitialTarget(): ?string
|
||||
+ setAccount(account:Account): void
|
||||
+ setInitialTarget(url:?string): void
|
||||
+ destroy(): void
|
||||
}
|
||||
|
||||
|
||||
PhpSessionHandle ..|> MutableSessionHandle
|
||||
MutableSessionHandle ..|> SessionHandle
|
||||
|
||||
@enduml
|