Fix staging server deployment #24

Merged
maxime.batista merged 2 commits from staging/fix into master 1 year ago

@ -30,6 +30,5 @@ echo "];" >> views-mappings.php
chmod +r views-mappings.php
// moshell does not supports file patterns
bash <<< "mv dist/* public/* front/assets/ front/style/ /outputs/public/"
mv dist/* front/assets/ front/style/ public/* /outputs/public/
mv views-mappings.php /outputs/

@ -27,7 +27,7 @@ function getAuthController(): APIAuthController {
function getRoutes(): AltoRouter {
$router = new AltoRouter();
$router->setBasePath(get_public_path() . "/api");
$router->setBasePath(get_public_path(__DIR__));
$router->map("POST", "/tactic/[i:id]/edit/name", Action::auth(fn(int $id, Account $acc) => getTacticController()->updateName($id, $acc)));
$router->map("POST", "/auth", Action::noAuth(fn() => getAuthController()->authorize()));

@ -0,0 +1 @@
../front/assets

@ -29,6 +29,9 @@ use IQBall\Core\Model\AuthModel;
use IQBall\Core\Model\TacticModel;
use IQBall\Core\Model\TeamModel;
use IQBall\Core\Validation\ValidationFail;
use Twig\Environment;
use Twig\Loader\FilesystemLoader;
use Twig\TwigFunction;
function getConnection(): Connection {
return new Connection(get_database());
@ -55,6 +58,16 @@ function getAuthController(): AuthController {
return new AuthController(new AuthModel(new AccountGateway(getConnection())));
}
function getTwig(): Environment {
global $basePath;
$fl = new FilesystemLoader("../src/App/Views");
$twig = new Environment($fl);
maxime.batista marked this conversation as resolved
Review

Because path concatenation cannot always be resumed to a simple string concatenation, exposing a path(string) function would hide this base path.

use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;

class PathExtension extends AbstractExtension {
    private string $basePath;

    public function __construct(string $basePath) {
        $this->basePath = $basePath;
    }

    /**
     * @return TwigFunction[]
     */
    public function getFunctions(): array {
        return [new TwigFunction('path', fn(string $path): string => $this->basePath . '/' . $path)];
    }
}
// Register the extension
$twig->addExtension(new PathExtension($basePath));

// Or just register use this shortcut:
$twig->addFunction(new TwigFunction('path', fn(string $path): string => $this->basePath . '/' . $path));
<a class="button" href="{{ path('home') }}">Retour à la page d'accueil</a>
Because path concatenation cannot always be resumed to a simple string concatenation, exposing a `path(string)` function would hide this base path. ```php use Twig\Extension\AbstractExtension; use Twig\TwigFunction; class PathExtension extends AbstractExtension { private string $basePath; public function __construct(string $basePath) { $this->basePath = $basePath; } /** * @return TwigFunction[] */ public function getFunctions(): array { return [new TwigFunction('path', fn(string $path): string => $this->basePath . '/' . $path)]; } } ``` ```php // Register the extension $twig->addExtension(new PathExtension($basePath)); // Or just register use this shortcut: $twig->addFunction(new TwigFunction('path', fn(string $path): string => $this->basePath . '/' . $path)); ``` ```twig <a class="button" href="{{ path('home') }}">Retour à la page d'accueil</a> ```
$twig->addFunction(new TwigFunction('path', fn(string $str) => "$basePath$str"));
return $twig;
}
function getRoutes(): AltoRouter {
global $basePath;
@ -104,6 +117,6 @@ function runMatch($match, MutableSessionHandle $session): HttpResponse {
//this is a global variable
$basePath = get_public_path();
$basePath = get_public_path(__DIR__);
App::render(runMatch(getRoutes()->match(), PhpSessionHandle::init()), "../src/App/Views/");
App::render(runMatch(getRoutes()->match(), PhpSessionHandle::init()), fn() => getTwig());

@ -19,8 +19,8 @@ class API {
if ($response instanceof JsonHttpResponse) {
header('Content-type: application/json');
echo $response->getJson();
} else {
throw new Exception("API returned a non-json response.");
} else if (get_class($response) != HttpResponse::class) {
throw new Exception("API returned unknown Http Response");
}
}

@ -2,8 +2,8 @@
namespace IQBall\Api\Controller;
use IQBall\App\Control;
use IQBall\Core\Http\HttpCodes;
use IQBall\Core\Route\Control;
use IQBall\Core\Http\HttpRequest;
use IQBall\Core\Http\HttpResponse;
use IQBall\Core\Http\JsonHttpResponse;

@ -2,7 +2,7 @@
namespace IQBall\Api\Controller;
use IQBall\Core\Route\Control;
use IQBall\App\Control;
use IQBall\Core\Data\Account;
use IQBall\Core\Http\HttpCodes;
use IQBall\Core\Http\HttpRequest;

@ -16,13 +16,13 @@ class App {
/**
* renders (prints out) given HttpResponse to the client
* @param HttpResponse $response
* @param string $twigViewsFolder
* @param callable(): Environment $twigSupplier
* @return void
* @throws LoaderError
* @throws RuntimeError
* @throws SyntaxError
*/
public static function render(HttpResponse $response, string $twigViewsFolder): void {
public static function render(HttpResponse $response, callable $twigSupplier): void {
http_response_code($response->getCode());
foreach ($response->getHeaders() as $header => $value) {
@ -30,7 +30,7 @@ class App {
}
if ($response instanceof ViewHttpResponse) {
self::renderView($response, $twigViewsFolder);
self::renderView($response, $twigSupplier);
} elseif ($response instanceof JsonHttpResponse) {
header('Content-type: application/json');
echo $response->getJson();
@ -40,13 +40,13 @@ class App {
/**
* renders (prints out) given ViewHttpResponse to the client
* @param ViewHttpResponse $response
* @param string $twigViewsFolder
* @param callable(): Environment $twigSupplier
* @return void
* @throws LoaderError
* @throws RuntimeError
* @throws SyntaxError
*/
private static function renderView(ViewHttpResponse $response, string $twigViewsFolder): void {
private static function renderView(ViewHttpResponse $response, callable $twigSupplier): void {
$file = $response->getFile();
$args = $response->getArguments();
@ -56,8 +56,7 @@ class App {
break;
case ViewHttpResponse::TWIG_VIEW:
try {
$fl = new FilesystemLoader($twigViewsFolder);
$twig = new Environment($fl);
$twig = call_user_func($twigSupplier);
$twig->display($file, $args);
} catch (RuntimeError|SyntaxError|LoaderError $e) {
http_response_code(500);

@ -1,12 +1,10 @@
<?php
namespace IQBall\Core\Route;
namespace IQBall\App;
use IQBall\App\ViewHttpResponse;
use IQBall\Core\Http\HttpCodes;
use IQBall\Core\Http\HttpRequest;
use IQBall\Core\Http\HttpResponse;
use IQBall\Core\Http\JsonHttpResponse;
use IQBall\Core\Validation\ValidationFail;
use IQBall\Core\Validation\Validator;

@ -16,9 +16,8 @@
</head>
<body>
<button onclick="location.pathname='/home'">Retour</button>
<button onclick="location.pathname='{{ path('/home') }}'">Retour</button>
<h1>Paramètres</h1>
</body>
</html>

@ -73,7 +73,7 @@
<div class="container">
<h2>Ajouter un membre à votre équipe</h2>
<form action="/team/members/add" method="POST">
<form action="{{ path('/team/members/add') }}" method="POST">
<div class="form-group">
<label for="team">Team où ajouter le membre :</label>
<input type="text" id="team" name="team" required>

@ -56,7 +56,7 @@
<div class="container">
<h2>Supprimez un membre de votre équipe</h2>
<form action="/team/members/remove" method="POST">
<form action="{{ path('/team/members/remove') }}" method="POST">
<div class="form-group">
<label for="team">Team où supprimer le membre :</label>
<input type="text" id="team" name="team" required>

@ -59,15 +59,20 @@
}
{% for err in fails %}
.form-group #{{ err.getFieldName() }} {
border-color: red;
.form-group
#
{{ err.getFieldName() }}
{
border-color: red
;
}
{% endfor %}
</style>
<div class="container">
<center><h2>Se connecter</h2></center>
<form action="login" method="post">
<form action="{{ path('/login') }}" method="post">
<div class="form-group">
{% for name in fails %}

@ -59,18 +59,22 @@
}
{% for err in fails %}
.form-group #{{ err.getFieldName() }} {
border-color: red;
.form-group
#
{{ err.getFieldName() }}
{
border-color: red
;
}
{% endfor %}
</style>
<div class="container">
<center><h2>S'enregistrer</h2></center>
<form action="register" method="post">
<form action="{{ path('/register') }}" method="post">
<div class="form-group">
{% for name in fails %}

@ -24,6 +24,7 @@
border: solid;
background-color: {{ team.getInfo().getMainColor().getValue() }};
}
#second_color {
background-color: {{ team.getInfo().getSecondColor().getValue() }};
border: solid;
@ -35,6 +36,7 @@
flex-direction: column;
align-items: center;
}
.team {
border-color: darkgrey;
border-radius: 20px;
@ -55,7 +57,7 @@
</head>
<body>
<header>
<h1><a href="/">IQBall</a></h1>
<h1><a href="{{ path('/') }}">IQBall</a></h1>
</header>
<section class="container">
@ -66,8 +68,12 @@
<img src="{{ team.getInfo().getPicture() }}" alt="Logo d'équipe" class="logo">
</div>
<div>
<div class="color"><p>Couleur principale : </p><div class="square" id="main_color"></div> </div>
<div class="color"><p>Couleur secondaire : </p><div class="square" id="second_color"></div></div>
<div class="color"><p>Couleur principale : </p>
<div class="square" id="main_color"></div>
</div>
<div class="color"><p>Couleur secondaire : </p>
<div class="square" id="second_color"></div>
</div>
</div>
{% for m in team.listMembers() %}

@ -10,7 +10,7 @@
<p>Aucune équipe n'a été trouvée</p>
<div class="container">
<h2>Chercher une équipe</h2>
<form action="/team/search" method="post">
<form action="{{ path('/team/search') }}" method="post">
<div class="form-group">
<label for="name">Nom de l'équipe :</label>
<input type="text" id="name" name="name" required>
@ -22,7 +22,7 @@
</div>
{% else %}
{% for t in teams %}
<div class="team" onclick="window.location.href = '/team/{{ t.id }}'">
<div class="team" onclick="window.location.href = '{{ path("/team/#{t.id}") }}'">
<p>Nom de l'équipe : {{ t.name }}</p>
<img src="{{ t.picture }}" alt="logo de l'équipe">
</div>

@ -51,7 +51,7 @@
{% endfor %}
<button class="button" onclick="location.href='/home'" type="button">Retour à la page d'accueil</button>
<button class="button" onclick="location.href='{{ path('/home') }}'" type="button">Retour à la page d'accueil</button>
</body>
</html>

@ -52,18 +52,19 @@
<body>
<div id="bandeau">
<h1>IQ Ball</h1>
<div id="account" onclick="location.pathname='/settings'">
<div id="account" onclick="location.pathname='{{ path('/settings') }}'">
<img
src="../../../front/assets/icon/account.svg"
src="{{ path('/assets/icon/account.svg') }}"
alt="Account logo"
/>
<p>Mon profil<p>
<p>Mon profil
<p>
</div>
</div>
<h2>Mes équipes</h2>
<button onclick="location.pathname='/team/new'"> Créer une nouvelle équipe </button>
<button onclick="location.pathname='{{ path('/team/new') }}'"> Créer une nouvelle équipe</button>
{% if recentTeam != null %}
{% for team in recentTeam %}
@ -77,13 +78,14 @@
<h2> Mes strategies </h2>
<button onclick="location.pathname='/tactic/new'"> Créer une nouvelle tactique </button>
<button onclick="location.pathname='{{ path('/tactic/new') }}'"> Créer une nouvelle tactique</button>
{% if recentTactic != null %}
{% for tactic in recentTactic %}
<div onclick="location.pathname=/tactic/{{ strategie.id }}/edit">
<div onclick="location.pathname='{{ path("/tactic/#{strategie.id}/edit") }}'">
<p> {{ tactic.id }} - {{ tactic.name }} - {{ tactic.creation_date }} </p>
<button onclick="location.pathname='/tactic/{{ tactic.id }}/edit'"> Editer la stratégie {{tactic.id}} </button>
<button onclick="location.pathname='{{ path("/tactic/#{tactic.id}/edit") }}'"> Editer la
stratégie {{ tactic.id }} </button>
</div>
{% endfor %}
{% else %}

@ -34,10 +34,7 @@
{% for item in bad_fields %}
#{{ item }}{
border-color: red;
}
{% endfor %}
input[type="text"], input[type="password"] {
}{% endfor %} input[type="text"], input[type="password"] {
width: 100%;
padding: 10px;
border: 1px solid #ccc;
@ -64,7 +61,7 @@
<div class="container">
<h2>Créer une équipe</h2>
<form action="/team/new" method="post">
<form action="{{ path('/team/new') }}" method="post">
<div class="form-group">
<label for="name">Nom de l'équipe :</label>
<input type="text" id="name" name="name" required>

@ -34,10 +34,7 @@
{% for item in bad_fields %}
#{{ item }}{
border-color: red;
}
{% endfor %}
input[type="text"], input[type="password"] {
}{% endfor %} input[type="text"], input[type="password"] {
width: 100%;
padding: 10px;
border: 1px solid #ccc;
@ -62,7 +59,7 @@
<div class="container">
<h2>Chercher une équipe</h2>
<form action="/team/search" method="post">
<form action="{{ path('/team/search') }}" method="post">
<div class="form-group">
<label for="name">Nom de l'équipe :</label>
<input type="text" id="name" name="name" required>

@ -3,9 +3,9 @@
/**
* relative path of the public directory from the server's document root.
*/
function get_public_path(): string {
function get_public_path(string $public_dir): string {
// find the server path of the index.php file
$basePath = substr(__DIR__, strlen($_SERVER['DOCUMENT_ROOT']));
$basePath = substr($public_dir, strlen($_SERVER['DOCUMENT_ROOT']));
$basePathLen = strlen($basePath);
if ($basePathLen == 0) {

Loading…
Cancel
Save