From 6a096de179ac682ad8b04263fddc4162cf398994 Mon Sep 17 00:00:00 2001 From: h7x4 Date: Tue, 13 Jan 2026 15:25:04 +0900 Subject: [PATCH] WIP more stuff lol --- dist/sql/pvv_mysql.sql | 5 +- dist/sql/pvv_sqlite.sql | 5 +- src/pvv/side/project.php | 39 +++++++ src/pvv/side/projectmanager.php | 162 +++++++++++++++++---------- www/admin/prosjekter/delete.php | 3 +- www/admin/prosjekter/index.php | 10 +- www/css/projects.css | 18 ++- www/prosjekt/edit.php | 188 +++++++++++++++++++++++--------- www/prosjekt/index.php | 6 +- www/prosjekt/info.php | 6 +- www/prosjekt/update.php | 78 ++++++++----- 11 files changed, 369 insertions(+), 151 deletions(-) diff --git a/dist/sql/pvv_mysql.sql b/dist/sql/pvv_mysql.sql index ba8bd20..fcd76b2 100644 --- a/dist/sql/pvv_mysql.sql +++ b/dist/sql/pvv_mysql.sql @@ -37,11 +37,12 @@ CREATE TABLE project ( `gitea_link` TEXT, `issue_board_link` TEXT, `wiki_link` TEXT, - `languages` TEXT, + `programming_languages` TEXT, `technologies` TEXT, `keywords` TEXT, `license` TEXT, `logo_url` TEXT, + `is_hidden` BOOLEAN DEFAULT FALSE, FOREIGN KEY (group_id) REFERENCES project_group (id) ON DELETE SET DEFAULT ); @@ -50,7 +51,7 @@ CREATE TABLE project_maintainer ( `project_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `email` TEXT, - `is_owner` BOOLEAN DEFAULT FALSE, + `is_organizer` BOOLEAN DEFAULT FALSE, PRIMARY KEY (uname, project_id), FOREIGN KEY (project_id) REFERENCES project (id) ON DELETE CASCADE ); diff --git a/dist/sql/pvv_sqlite.sql b/dist/sql/pvv_sqlite.sql index d928a65..51367b3 100644 --- a/dist/sql/pvv_sqlite.sql +++ b/dist/sql/pvv_sqlite.sql @@ -39,11 +39,12 @@ CREATE TABLE "project" ( "gitea_link" TEXT, "issue_board_link" TEXT, "wiki_link" TEXT, - "languages" TEXT, + "programming_languages" TEXT, "technologies" TEXT, "keywords" TEXT, "license" TEXT, "logo_url" TEXT, + "is_hidden" BOOLEAN DEFAULT FALSE, FOREIGN KEY (group_id) REFERENCES project_group (id) ON DELETE SET DEFAULT ); @@ -52,7 +53,7 @@ CREATE TABLE "project_maintainer" ( "project_id" INTEGER NOT NULL, "name" TEXT NOT NULL, "email" TEXT, - "is_owner" BOOLEAN DEFAULT FALSE, + "is_organizer" BOOLEAN DEFAULT FALSE, PRIMARY KEY (uname, project_id), FOREIGN KEY (project_id) REFERENCES project (id) ON DELETE CASCADE ); diff --git a/src/pvv/side/project.php b/src/pvv/side/project.php index eab8b6e..9d8d575 100644 --- a/src/pvv/side/project.php +++ b/src/pvv/side/project.php @@ -18,6 +18,7 @@ class Project { // NOTE: spdx identifier private ?string $license; private ?string $logo_url; + private bool $is_hidden; public function __construct( int $id, @@ -32,6 +33,7 @@ class Project { ?string $keywords, ?string $license, ?string $logo_url, + bool $is_hidden = false, ) { $this->id = $id; $this->title = $title; @@ -58,6 +60,7 @@ class Project { = $keywords === null || $keywords === '' ? [] : explode(',', $keywords); $this->license = $license; $this->logo_url = $logo_url; + $this->is_hidden = $is_hidden; } public function getID(): int { @@ -122,4 +125,40 @@ class Project { public function getLogoURL(): ?string { return $this->logo_url; } + + public function isHidden(): bool { + return $this->is_hidden; + } +} + +class ProjectMaintainer { + private string $uname; + private string $name; + private string $email; + private bool $is_organizer; + + public function __construct( + string $uname, + string $name, + string $email, + bool $is_organizer, + ) { + $this->uname = $uname; + $this->name = $name; + $this->email = $email; + $this->is_organizer = $is_organizer; + } + + public function getUname(): string { + return $this->uname; + } + public function getName(): string { + return $this->name; + } + public function getEmail(): string { + return $this->email; + } + public function isOrganizer(): bool { + return $this->is_organizer; + } } diff --git a/src/pvv/side/projectmanager.php b/src/pvv/side/projectmanager.php index 7232f81..1af1153 100644 --- a/src/pvv/side/projectmanager.php +++ b/src/pvv/side/projectmanager.php @@ -17,7 +17,24 @@ class ProjectManager { * @return Project[] */ public function getAll(): array { - $query = 'SELECT * FROM project ORDER BY id ASC'; + $query = ' + SELECT + id, + title, + description_en, + description_no, + gitea_link, + issue_board_link, + wiki_link, + programming_languages, + technologies, + keywords, + license, + logo_url, + is_hidden + FROM project + ORDER BY title ASC + '; $statement = $this->pdo->prepare($query); $statement->execute(); @@ -31,11 +48,12 @@ class ProjectManager { $dbProj['gitea_link'], $dbProj['issue_board_link'], $dbProj['wiki_link'], - $dbProj['languages'], + $dbProj['programming_languages'], $dbProj['technologies'], $dbProj['keywords'], $dbProj['license'], - $dbProj['logo_url'] + $dbProj['logo_url'], + (bool) $dbProj['is_hidden'] ); $projects[] = $project; } @@ -45,7 +63,24 @@ class ProjectManager { // TODO: groupid public function getByID(int $id): ?Project { - $query = 'SELECT * FROM project WHERE id=:id LIMIT 1'; + $query = ' + SELECT + id, + title, + description_en, + description_no, + gitea_link, + issue_board_link, + wiki_link, + programming_languages, + technologies, + keywords, + license, + logo_url, + is_hidden + FROM project + WHERE id = :id + '; $statement = $this->pdo->prepare($query); $statement->bindParam(':id', $id, \PDO::PARAM_INT); $statement->execute(); @@ -63,11 +98,12 @@ class ProjectManager { $dbProj['gitea_link'], $dbProj['issue_board_link'], $dbProj['wiki_link'], - $dbProj['languages'], + $dbProj['programming_languages'], $dbProj['technologies'], $dbProj['keywords'], $dbProj['license'], - $dbProj['logo_url'] + $dbProj['logo_url'], + (bool) $dbProj['is_hidden'] ); } @@ -76,30 +112,33 @@ class ProjectManager { /** * @return Project[] */ - public function getByOwner(string $uname): array { + public function getByMaintainer(string $uname): array { $query = ' - SELECT project.id FROM project - JOIN project_maintainer ON project.id = project_maintainer.project_id + SELECT + project.id, + project.title + project.description_en, + project.description_no, + project.gitea_link, + project.issue_board_link, + project.wiki_link, + project.programming_languages, + project.technologies, + project.keywords, + project.license, + project.logo_url, + project.is_hidden + FROM project_maintainer + JOIN project ON project.id = project_maintainer.project_id WHERE project_maintainer.uname = :uname - AND project_maintainer.is_owner = TRUE '; - $statement = $this->pdo->prepare($query); $statement->bindParam(':uname', $uname, \PDO::PARAM_STR); $statement->execute(); - $projectIDs = $statement->fetchAll(); - $projects = []; - foreach ($projectIDs as $id) { - $id = $id['projectid']; - - $query = 'SELECT * FROM projects WHERE id=:id'; - $statement = $this->pdo->prepare($query); - $statement->bindParam(':id', $id, \PDO::PARAM_INT); - $statement->execute(); - - foreach ($statement->fetchAll() as $dbProj) { - $project = new Project( + $result = array_map( + function ($dbProj) { + return new Project( $dbProj['id'], $dbProj['title'], $dbProj['description_en'], @@ -107,29 +146,30 @@ class ProjectManager { $dbProj['gitea_link'], $dbProj['issue_board_link'], $dbProj['wiki_link'], - $dbProj['languages'], + $dbProj['programming_languages'], $dbProj['technologies'], $dbProj['keywords'], $dbProj['license'], - $dbProj['logo_url'] + $dbProj['logo_url'], + (bool) $dbProj['is_hidden'] ); - $projects[] = $project; - } - } + }, + $statement->fetchAll() + ); - return $projects; + return $result; } /** - * @return {uname:string,name:string,link:string,email:string,is_owner:bool}[] + * @return ProjectMaintainer[] */ - public function getProjectMembers(int $project_id): array { + public function getProjectMaintainers(int $project_id): array { $query = ' SELECT project_maintainer.uname, project_maintainer.name, project_maintainer.email, - project_maintainer.is_owner + project_maintainer.is_organizer FROM project_maintainer WHERE project_maintainer.project_id = :id '; @@ -138,49 +178,53 @@ class ProjectManager { $statement->bindParam(':id', $project_id, \PDO::PARAM_STR); $statement->execute(); - $maintainers = []; - foreach ($statement->fetchAll() as $dbUsr) { - $maintainers[] = [ - 'uname' => $dbUsr['uname'], - 'name' => $dbUsr['name'], - 'email' => $dbUsr['email'], - 'is_owner' => (bool)$dbUsr['is_owner'], - ]; - } + $result = array_map( + function ($dbUsr) { + return new ProjectMaintainer( + $dbUsr['uname'], + $dbUsr['name'], + $dbUsr['email'], + (bool)$dbUsr['is_organizer'] + ); + }, + $statement->fetchAll() + ); - return $maintainers; + return $result; } /** - * @return array{name:string,uname:string,email:string,is_owner:bool}|null + * @return ProjectMaintainer[] */ - public function getProjectOwner(int $project_id): ?array { + public function getProjectOrganizers(int $project_id): array { $query = ' SELECT - project_maintainer.name, project_maintainer.uname, + project_maintainer.name, project_maintainer.email, - project_maintainer.is_owner + project_maintainer.is_organizer FROM project_maintainer - WHERE project_maintainer.project_id = :id - AND project_maintainer.is_owner = TRUE - LIMIT 1 + WHERE + project_maintainer.project_id = :id + AND project_maintainer.is_organizer = True '; $statement = $this->pdo->prepare($query); $statement->bindParam(':id', $project_id, \PDO::PARAM_STR); $statement->execute(); - $owner = $statement->fetch(); - if (!$owner) { - return null; - } + $result = array_map( + function ($dbUsr) { + return new ProjectMaintainer( + $dbUsr['uname'], + $dbUsr['name'], + $dbUsr['email'], + (bool)$dbUsr['is_organizer'] + ); + }, + $statement->fetchAll() + ); - return [ - 'name' => $owner['name'], - 'uname' => $owner['uname'], - 'email' => $owner['email'], - 'is_owner' => (bool)$owner['is_owner'], - ]; + return $result; } } diff --git a/www/admin/prosjekter/delete.php b/www/admin/prosjekter/delete.php index 2a42555..0497b1c 100644 --- a/www/admin/prosjekter/delete.php +++ b/www/admin/prosjekter/delete.php @@ -18,8 +18,9 @@ if (!$userManager->hasGroup($uname, 'prosjekt')) { $projectID = $_GET['id']; -$query = 'DELETE FROM project WHERE id=\'' . $projectID . '\''; +$query = 'DELETE FROM project WHERE id=:projectID'; $statement = $pdo->prepare($query); +$statement->bindParam(':projectID', $projectID, PDO::PARAM_INT); $statement->execute(); header('Location: ' . $_SERVER['HTTP_REFERER']); diff --git a/www/admin/prosjekter/index.php b/www/admin/prosjekter/index.php index 5e67067..7f5026b 100644 --- a/www/admin/prosjekter/index.php +++ b/www/admin/prosjekter/index.php @@ -43,7 +43,7 @@ if(isset($_POST['organiser'])){ // filter $projects = array_values(array_filter( $projects, - static fn($project) => preg_match('/.*' . $filterTitle . '.*/i', $project->getName()) + static fn($project) => preg_match('/.*' . $filterTitle . '.*/i', $project->getTitle()) )); ?> @@ -87,17 +87,17 @@ $projects = array_values(array_filter( $project = $projects[$i]; $projectID = $project->getID(); - $owner = $projectManager->getProjectOwner($projectID); + $organizers = $projectManager->getProjectOrganizers($projectID); ?>
  • -

    getName() . ' (ID: ' . $projectID . ')'; ?>

    -

    +

    getTitle() . ' (ID: ' . $projectID . ')'; ?>

    +

    getName(); }, $organizers)); ?>

    text(implode("\n", $project->getDescription())); + echo $Parsedown->text(implode("\n", $project->getDescriptionNo())); ?>
    diff --git a/www/css/projects.css b/www/css/projects.css index 1d7cebc..64fffdf 100644 --- a/www/css/projects.css +++ b/www/css/projects.css @@ -91,14 +91,30 @@ /* edit */ form .wide { - min-width: 66%; + min-width: 100%; } + form .tall { min-height: calc(100vh - 28em); } + @media screen and (max-width: 50rem) { form .wide { width: calc(100% - 2em); margin: 0 1em; } } + +form .input-group { + display: flex; +} + +form .input-group-item { + flex: 1; + margin: 0 0.5em; +} + +form .input-group-item input.boxinput,textarea { + width: 100%; + box-sizing: border-box; +} diff --git a/www/prosjekt/edit.php b/www/prosjekt/edit.php index 66aa49f..03158fa 100644 --- a/www/prosjekt/edit.php +++ b/www/prosjekt/edit.php @@ -70,68 +70,156 @@ if (!$project_is_new) { - + -
    -

    Nytt prosjekt

    +
    +

    Nytt prosjekt

    -
    -

    Prosjektnavn

    -

    Gi prosjektet ditt et passende navn

    -
    + +

    Prosjektnavn

    +

    Gi prosjektet ditt et passende navn

    +
    -

    Beskrivelse (markdown)

    -

    Hva går prosjektet ditt ut på?

    -

    De første to linjene blir vist på prosjektkortet, prøv å gjøre de til et fint sammendrag eller intro!

    - +
    +
    +

    Beskrivelse (markdown)

    +

    Hva går prosjektet ditt ut på?

    +

    De første to linjene blir vist på prosjektkortet, prøv å gjøre de til et fint sammendrag eller intro!

    + +
    -

    Beskrivelse på engelsk (markdown)

    -

    Gjenta på engelsk

    - +
    +

    Beskrivelse på engelsk (markdown)

    +

    Gjenta på engelsk

    +
    + +
    +
    -

    Gitea-link

    -

    Link til prosjektet på Gitea

    -
    +
    +
    +

    Gitea-link

    +

    Link til prosjektet på Gitea

    + +
    -

    Issue board-link

    -

    Link til issue board på Gitea

    -
    +
    +

    Issue board-link

    +

    Link til issue board på Gitea

    + +
    +
    -

    Wiki-link

    -

    Link til wiki-side

    -
    +
    +
    +

    Logo-URL

    +

    Link til logo for prosjektet

    + +
    -

    Programmeringsspråk

    -

    Hvilke programmeringsspråk brukes i prosjektet?

    - getProgrammingLanguages()); ?>" class="boxinput">
    +
    +

    Wiki-link

    +

    Link til wiki-side

    + +
    +
    -

    Teknologier

    -

    Hvilke teknologier brukes i prosjektet?

    - getTechnologies()); ?>" class="boxinput">
    +
    +
    +

    Programmeringsspråk

    +

    Hvilke programmeringsspråk brukes i prosjektet?

    + getProgrammingLanguages()); ?>" + class="boxinput" + > +
    -

    Nøkkelord

    -

    Nøkkelord som beskriver prosjektet

    - getKeywords()); ?>" class="boxinput">
    +
    +

    Teknologier

    +

    Hvilke teknologier brukes i prosjektet?

    + getTechnologies()); ?>" + class="boxinput" + > +
    -

    Lisens

    -

    Hvilken lisens bruker prosjektet?

    -
    +
    +

    Nøkkelord

    +

    Nøkkelord som beskriver prosjektet

    + getKeywords()); ?>" + class="boxinput" + > +
    +
    -

    Logo-URL

    -

    Link til logo for prosjektet

    -
    +
    +
    +

    Lisens

    +

    Hvilken lisens bruker prosjektet?

    + +
    +
    +

    Skult

    +

    Skal prosjektet være skjult fra prosjektindeksen?

    + +
    +
    - getID() . '" />'; ?> - + getID() . '" />'; ?> + -
    -
    - - -
    -
    -
    +
    +
    + + +
    + +
    diff --git a/www/prosjekt/index.php b/www/prosjekt/index.php index 0bb4810..bd75a97 100644 --- a/www/prosjekt/index.php +++ b/www/prosjekt/index.php @@ -89,7 +89,7 @@ $projects = $projectManager->getAll(); } foreach ($randProjects as $i) { $project = $projects[$i]; - $owner = $projectManager->getProjectOwner($project->getID()); + $organizers = $projectManager->getProjectOrganizers($project->getID()); ?> @@ -128,7 +128,9 @@ $projects = $projectManager->getAll();