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 1 commit
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
65 changes: 59 additions & 6 deletions app/pages/settings/club_settings.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
<?php
restrict_access(Access::$ADD_EVENTS);
$club = em()
->createQuery("SELECT c from Club c WHERE c.slug = :slug")
->setParameters(["slug" => ClubManagementService::getSelectedClubSlug()])
->getResult()[0];
$club = ClubManagementService::getSelectedClub();

$google_form_values = [
'google_id' => $club->google_calendar_id,
Expand All @@ -25,8 +22,10 @@
$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');
$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()) {
Expand All @@ -53,6 +52,35 @@
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>
Expand All @@ -69,4 +97,29 @@
<?= $google_id->render() ?>
<input type="submit" class="outline" name="submitGoogle" value="Mettre à jour le calendrier">
</form>
<?php endif ?>
<?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
6 changes: 3 additions & 3 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 @@ -145,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();
}
}
32 changes: 32 additions & 0 deletions database/migrations_sqlite/Version20250201144837.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace intranose\Migrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250201144837 extends AbstractMigration
{
public function getDescription(): string
{
return 'add club features';
}

public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE TABLE orm_club_features (club_slug VARCHAR(255) NOT NULL, featureName VARCHAR(255) NOT NULL, enabled BOOLEAN NOT NULL, PRIMARY KEY(featureName, club_slug), CONSTRAINT FK_58EE7BA0FC555182 FOREIGN KEY (club_slug) REFERENCES orm_clubs (slug) NOT DEFERRABLE INITIALLY IMMEDIATE)');
$this->addSql('CREATE INDEX IDX_58EE7BA0FC555182 ON orm_club_features (club_slug)');
}

public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('DROP TABLE orm_club_features');
}
}
Loading