Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add club parameters page #375

Merged
merged 7 commits into from
Feb 8, 2025
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 52 additions & 4 deletions app/management/club_view.php
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
<?php
managementPage("View club");
$slug = Router::getParameter("slug", pattern: '/[\w-]+/');
DB::setupForClub($slug);
$s = ClubManagementService::fromSlug($slug) ?? force_404("club not found");
$club = $s->getClub();
$club = ClubManagementService::getSelectedClub();

$backupService = new BackupService(dbPath: $s->db->sqlitePath);
$backupService = new BackupService(dbPath: DB::getInstance()->sqlitePath);

$v_backup = new Validator(action: "create_backup");
if ($v_backup->valid()) {
Expand All @@ -31,6 +32,31 @@
Toast::fromResult($r);
$r->success && redirect("/mgmt/view/$club->slug");
}

$club_features = FeatureService::list_club($slug);
$v_features = new Validator(action: "features");
$feature_options = [];
foreach (Feature::cases() as $f) {
$feature_options[$f->value] = $f->value;
}
$features = $v_features->select("add_new")->options($feature_options)->label("New feature")->required();

if ($v_features->valid()) {
$newFeature = $club_features[$features->value] ?? new ClubFeature($club, Feature::from($features->value));
em()->persist($newFeature);
em()->flush();
Toast::success("Feature added");
reload();
}

$v_removeFeature = new Validator(action: "remove_feature");
if ($v_removeFeature->valid() && isset($_POST['remove_name']) && isset($club_features[$_POST['remove_name']])) {
em()->remove($club_features[$_POST['remove_name']]);
em()->flush();
Toast::error("Feature removed");
reload();
}

?>
<?= actions()->back("/mgmt") ?>
<sl-tab-group>
Expand All @@ -56,9 +82,31 @@
<?= $color ?>
<button>Update</button>
<br><br>
<h3><i>Danger zone</i></h3>
</form>
<section>
<h3>Features</h3>
<ul>
<?php foreach ($club_features as $club_feature): ?>
<li style="display:flex;align-items:center;gap:1rem;padding: 0.5rem">
<?= $club_feature->featureName ?>
<form method="post">
<?= $v_removeFeature ?>
<input type="hidden" name="remove_name" value="<?= $club_feature->featureName ?>">
<button class="destructive">Remove</button>
</form>
</li>
<?php endforeach ?>
</ul>
<form method="post">
<?= $v_features ?>
<?= $features ?>
<button>Add</button>
</form>
</section>
<h3><i>Danger zone</i></h3>
<form method="post">
<button class="destructive" hx-post hx-confirm="Are you sure you want to delete the club?"
<?= $v_delete->hx_action() ?>>Delete</button>
<?= $v_delete->hx_action() ?>>Delete club</button>
</form>
</sl-tab-panel>
<sl-tab-panel name="backups">
Expand Down
4 changes: 4 additions & 0 deletions app/management/clubs_list.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
redirect("/mgmt/login");
}
managementPage("Clubs");
/* Workaround to handle the case where a club is selected, so that the color works in layout.php */
if ($club_slug = ClubManagementService::getSelectedClubSlug()) {
DB::setupForClub($club_slug);
}
$clubs = ClubManagementService::listClubs();
?>
<?= actions()->link("/mgmt/new-club", "Add", "fa-plus")->link("/mgmt/logout", "Logout", attributes: ["class" => "destructive"]) ?>
Expand Down
125 changes: 125 additions & 0 deletions app/pages/settings/club_settings.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<?php
restrict_access(Access::$ADD_EVENTS);
$club = ClubManagementService::getSelectedClub();

$google_form_values = [
'google_id' => $club->google_calendar_id,
];

$theme_form_values = [
'theme_color' => $club->themeColor->value,
];

$credentials_help = "<ul>
<li>Allez sur <a href='https://console.cloud.google.com'>https://console.cloud.google.com</a> </li>
<li>Créez un projet</li>
<li>Créez un service account</li>
<li>Téléchargez le fichier de credentials au format .json</li>
<li>Autoriser l'accès au calendrier cible pour le service account créé</li>
</ul>";

$v_google_calendar = new Validator($google_form_values, action: 'google_calendar_form');
$google_id = $v_google_calendar->text("google_id")->label("ID du calendrier")->placeholder()->help("Remplissez l'id du calendrier lié au service account créé.");
$google_credentials = $v_google_calendar->upload("credentials")->max_size(2 * 1024 * 1024)->label("Fichier de credentials du service account")->help($credentials_help);

/* THEME */

$v_theme = new Validator($theme_form_values, action: 'theme_form');
$theme_color = $v_theme->select('theme_color')->options(array_column(ThemeColor::cases(), 'value', 'name'))->label('Couleur du theme')->help("Changez la couleur de thème de votre club ici !");


if ($v_google_calendar->valid()) {
$club->google_calendar_id = $google_id->value;
if (GoogleCalendarService::clearCredentialFolder()) {
if ($path = $google_credentials->save_file(Path::credentials())) {
$club->google_credential_path = $path;
em()->flush();
} else {
$v_google_calendar->set_error("Erreur lors de l'enregistrement des credentials");
}
} else {
$v_google_calendar->set_error("Erreur lors du nettoyage du dossier des credentials");
}
em()->persist($club);
em()->flush();
Toast::create("Calendrier mis à jour");
}

if ($v_theme->valid()) {
$club->themeColor = ThemeColor::from($theme_color->value);
em()->persist($club);
em()->flush();
Toast::create("Thème mis à jour");
}

/* FEATURES */

$club_features = FeatureService::list_club();
$v_features = new Validator(action: "features");
$feature_options = [];
foreach ($club_features as $f) {
$feature_options[$f->featureName] = $f->featureName;
}
$features = $v_features->select("add_new")->options($feature_options)->label("Nouvelle fonctionnalité")->required();

if ($v_features->valid()) {
$newFeature = $club_features[$features->value];
$newFeature->enabled = true;
em()->persist($newFeature);
em()->flush();
Toast::success("Fonctionnalité ajoutée");
reload();
}

$v_removeFeature = new Validator(action: "remove_feature");
if ($v_removeFeature->valid() && isset($_POST['remove_name']) && isset($club_features[$_POST['remove_name']])) {
$newFeature = $club_features[$_POST['remove_name']];
$newFeature->enabled = false;
em()->persist($newFeature);
em()->flush();
Toast::error("Fonctionnalité retirée");
reload();
}

page("Paramètres du club")->enableHelp();
?>
<h2>Thème</h2>
<form method="post">
<?= $v_theme->render_validation() ?>
<?= $theme_color->render() ?>
<input type="submit" class="outline" name="submitTheme" value="Mettre à jour le thème">
</form>
<?php if (Feature::GoogleCalendar->on()): ?>
<h2 id="google">Google Calendar</h2>
<form method="post" enctype="multipart/form-data">
<?= $v_google_calendar->render_validation() ?>
<?= $google_credentials->render() ?>
<?= $google_id->render() ?>
<input type="submit" class="outline" name="submitGoogle" value="Mettre à jour le calendrier">
</form>
<?php endif ?>
<section>
<h3>Fonctionnalités du club</h3>
<ul>
<?php if (!$club_features): ?>
Pas de fonctionnalités disponibles pour ce club, contactez les développeurs pour accéder au nouvelles
fonctionnalités 🚀
<?php else: ?>
<?php foreach (array_filter($club_features, fn($f) => $f->enabled) as $club_feature): ?>
<li style="display:flex;align-items:center;gap:1rem;padding: 0.5rem">
<?= $club_feature->featureName ?>
<form method="post">
<?= $v_removeFeature ?>
<input type="hidden" name="remove_name" value="<?= $club_feature->featureName ?>">
<button class="destructive">Retirer</button>
</form>
</li>
<?php endforeach ?>
</ul>
<form method="post">
<?= $v_features ?>
<?= $features ?>
<button>Ajouter</button>
</form>
<?php endif ?>
</section>
50 changes: 28 additions & 22 deletions app/pages/users/user_debug.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
Toast::success("Lien créé");
}

$user_features = UserFeature::list($user_id);
$user_features = FeatureService::list_user($user_id);
$club_features = FeatureService::list_club();
$v_features = new Validator(action: "features");
$feature_options = [];
foreach (Feature::cases() as $f) {
$feature_options[$f->value] = $f->value;
foreach ($club_features as $f) {
$feature_options[$f->featureName] = $f->featureName;
}
$features = $v_features->select("add_new")->options($feature_options)->label("New feature")->required();

Expand All @@ -23,15 +24,15 @@
$newFeature->enabled = true;
em()->persist($newFeature);
em()->flush();
Toast::success("Feature added");
Toast::success("Fonctionnalité ajoutée");
reload();
}

$v_removeFeature = new Validator(action: "remove_feature");
if ($v_removeFeature->valid() && isset($_POST['remove_name']) && isset($user_features[$_POST['remove_name']])) {
em()->remove($user_features[$_POST['remove_name']]);
em()->flush();
Toast::error("Feature removed");
Toast::error("Fonctionnalité retirée");
reload();
}

Expand Down Expand Up @@ -74,24 +75,29 @@ class="fas fa-circle-info"></i></sl-tooltip>
</section>
<hr>
<section>
<h3>Features</h3>
<h3>Fonctionnalités</h3>
<ul>
<?php foreach ($user_features as $user_feature): ?>
<li style="display:flex;align-items:center;gap:1rem;padding: 0.5rem">
<?= $user_feature->featureName ?>
<form method="post">
<?= $v_removeFeature ?>
<input type="hidden" name="remove_name" value="<?= $user_feature->featureName ?>">
<button class="destructive">Remove</button>
</form>
</li>
<?php endforeach ?>
</ul>
<form method="post">
<?= $v_features ?>
<?= $features ?>
<button>Add</button>
</form>
<?php if (!$club_features): ?>
Pas de fonctionnalités disponibles pour ce club, contactez les développeurs pour accéder au nouvelles
fonctionnalités 🚀
<?php else: ?>
<?php foreach ($user_features as $user_feature): ?>
<li style="display:flex;align-items:center;gap:1rem;padding: 0.5rem">
<?= $user_feature->featureName ?>
<form method="post">
<?= $v_removeFeature ?>
<input type="hidden" name="remove_name" value="<?= $user_feature->featureName ?>">
<button class="destructive">Retirer</button>
</form>
</li>
<?php endforeach ?>
</ul>
<form method="post">
<?= $v_features ?>
<?= $features ?>
<button>Ajouter</button>
</form>
<?php endif ?>
</section>

<style>
Expand Down
17 changes: 13 additions & 4 deletions app/services/ClubManagementService.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ static function clubExists($slug)
return file_exists(club_data_path($slug));
}

function getClub(): Club
function getClub()
{
$results = $this->db->em()->createQuery("SELECT c FROM Club c")->getResult();
$results = em()->createQuery("SELECT c FROM Club c")->getResult();
if (!$results) {
$club = new Club("", $this->slug);
$this->db->em()->persist($club);
Expand Down Expand Up @@ -89,7 +89,7 @@ static function isClubSelectionAvailable()
return !env("SELECTED_CLUB");
}

static function getSelectedClub()
static function getSelectedClubSlug()
{
$club = env("SELECTED_CLUB") ?? $_SESSION["selected_club"] ?? null;
if ($club && !isset($_SESSION["selected_club_name"])) {
Expand All @@ -99,6 +99,15 @@ static function getSelectedClub()
return $club;
}

static function getSelectedClub(): Club
{
$club_slug = ClubManagementService::getSelectedClubSlug();
return em()
->createQuery("SELECT c from Club c WHERE c.slug = :slug")
->setParameters(["slug" => $club_slug])
->getResult()[0];
}

static function selectClub($slug)
{
if (!self::clubExists($slug)) {
Expand Down Expand Up @@ -136,7 +145,7 @@ static function getClubColor($slug)
if (!$slug) {
return null;
}
$c = self::fromSlug($slug)->getClub();
$c = self::getSelectedClub();
return $c->themeColor->value;
}
}
43 changes: 42 additions & 1 deletion app/services/FeatureService.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,47 @@ static function enabled(Feature $f, $uid = null)
if (env("FEATURE_" . $f->value) == 'true')
return true;
$uid ??= User::getMainUserId();
return UserFeature::hasFeature($uid, $f->value);
return self::hasFeature($uid, $f->value);
}

/**
* Get all feature from a user : first check the ClubFeatures level then the UserFeatures level
* @return bool
*/
static function hasFeature($uid, $feature)
{
$club_slug = ClubManagementService::getSelectedClubSlug();
if (
em()->createQuery("SELECT count(f) FROM ClubFeature f WHERE f.club = :c AND f.featureName = :feature AND f.enabled = :enabled")
->setParameters(["c" => $club_slug, "feature" => $feature, "enabled" => true])
->getSingleScalarResult()
) {
$is_disabled = em()->createQuery("SELECT count(f) FROM UserFeature f WHERE f.user = :u AND f.featureName = :feature AND f.enabled = :enabled")
->setParameters(["u" => $uid, "feature" => $feature, "enabled" => false])
->getSingleScalarResult();
return (!$is_disabled);
}
return false;
}

/**
* list all feature for one user
* @return UserFeature[]
*/
static function list_user($uid)
{
return em()->createQuery("SELECT f FROM UserFeature f INDEX BY f.featureName LEFT JOIN ClubFeature c WITH f.featureName = c.featureName WHERE f.user = :u")->setParameters(["u" => $uid])->getResult();
}

/**
* list all feature for one user
* @return ClubFeature[]
*/
static function list_club($slug = null)
{
if (!$slug) {
$slug = ClubManagementService::getSelectedClubSlug();
}
return em()->createQuery("SELECT f from ClubFeature f INDEX BY f.featureName WHERE f.club = :c")->setParameters(["c" => $slug])->getResult();
}
}
Loading