Add Project entity, user routes and clipper controls

This commit is contained in:
Nicolò P 2025-03-31 16:25:31 +02:00
parent 4c0e212650
commit ce3b17b683
24 changed files with 2989 additions and 21 deletions

6
.env.test Normal file
View File

@ -0,0 +1,6 @@
# define your env variables for the test env here
KERNEL_CLASS='App\Kernel'
APP_SECRET='$ecretf0rt3st'
SYMFONY_DEPRECATIONS_HELPER=999999
PANTHER_APP_ENV=panther
PANTHER_ERROR_SCREENSHOT_DIR=./var/error-screenshots

10
.gitignore vendored
View File

@ -18,3 +18,13 @@ config.js
/public/assets/
/assets/vendor/
###< symfony/asset-mapper ###
###> symfony/phpunit-bridge ###
.phpunit.result.cache
/phpunit.xml
###< symfony/phpunit-bridge ###
###> phpunit/phpunit ###
/phpunit.xml
.phpunit.result.cache
###< phpunit/phpunit ###

View File

@ -7,6 +7,7 @@ import * as WEBIFC from 'web-ifc';
* @namespace BIM
*/
const BIM = {};
BIM.clipper = undefined;
/**
*
@ -52,7 +53,7 @@ BIM.activateClipper = function () {
clipper.enabled = true;
clipper.create(this.world);
clipper.visible = true;
this.clipper = clipper;
BIM.clipper = clipper;
}
/**
* Delete a selected clipping plane

View File

@ -0,0 +1,22 @@
import { Controller } from "@hotwired/stimulus"
import * as THREE from "three"
import BIM from '../bim.js';
export default class extends Controller {
static targets = ['hex'];
color(event) {
let color = event.target.value;
this.hexTarget.querySelector('span').textContent = color;
BIM.clipper.config.color = new THREE.Color(color);
}
size(event) {
BIM.clipper.config.size = event.target.value
}
deleteAll() {
BIM.clipper.deleteAll();
}
}

View File

@ -0,0 +1,26 @@
import { Controller } from '@hotwired/stimulus';
/**
* Activate a dropdown menu and toggle icon
* [template: data_entry.html.twig]
*/
export default class extends Controller {
static targets = ['drop', 'caret'];
toggle() {
// Show / hide dropdown
this.dropTarget.classList.toggle('is-active');
const caretTarget = this.caretTarget;
const caretState = caretTarget.className.includes('down') ? 'down' : 'up';
const caretAction = {
'down': function(target) {
target.className = target.className.replace('down', 'up');
},
'up': function(target) {
target.className = target.className.replace('up', 'down');
}
};
caretAction[caretState](this.caretTarget);
}
}

23
bin/phpunit Executable file
View File

@ -0,0 +1,23 @@
#!/usr/bin/env php
<?php
if (!ini_get('date.timezone')) {
ini_set('date.timezone', 'UTC');
}
if (is_file(dirname(__DIR__).'/vendor/phpunit/phpunit/phpunit')) {
if (PHP_VERSION_ID >= 80000) {
require dirname(__DIR__).'/vendor/phpunit/phpunit/phpunit';
} else {
define('PHPUNIT_COMPOSER_INSTALL', dirname(__DIR__).'/vendor/autoload.php');
require PHPUNIT_COMPOSER_INSTALL;
PHPUnit\TextUI\Command::main();
}
} else {
if (!is_file(dirname(__DIR__).'/vendor/symfony/phpunit-bridge/bin/simple-phpunit.php')) {
echo "Unable to find the `simple-phpunit.php` script in `vendor/symfony/phpunit-bridge/bin/`.\n";
exit(1);
}
require dirname(__DIR__).'/vendor/symfony/phpunit-bridge/bin/simple-phpunit.php';
}

View File

@ -84,7 +84,11 @@
}
},
"require-dev": {
"phpunit/phpunit": "^9.5",
"symfony/browser-kit": "7.1.*",
"symfony/css-selector": "7.1.*",
"symfony/maker-bundle": "^1.61",
"symfony/phpunit-bridge": "^7.2",
"symfony/stopwatch": "7.1.*",
"symfony/web-profiler-bundle": "7.1.*"
}

1968
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -39,8 +39,8 @@ security:
access_control:
- { path: ^/$, roles: ROLE_USER }
- { path: ^/api, roles: ROLE_USER }
# - { path: ^/admin, roles: ROLE_ADMIN }
# - { path: ^/profile, roles: ROLE_USER }
- { path: ^/admin, roles: ROLE_ADMIN }
- { path: ^/user, roles: ROLE_USER }
when@test:
security:

View File

@ -0,0 +1,377 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250331072951 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql(<<<'SQL'
ALTER TABLE elemento DROP FOREIGN KEY elemento_ibfk_4
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE elemento DROP FOREIGN KEY elemento_ibfk_6
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE elemento DROP FOREIGN KEY elemento_ibfk_3
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE elemento DROP FOREIGN KEY elemento_ibfk_5
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE elemento DROP FOREIGN KEY elemento_ibfk_1
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE oriz_fonte DROP FOREIGN KEY oriz_fonte_ibfk_2
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE oriz_fonte DROP FOREIGN KEY oriz_fonte_ibfk_1
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE trattamento DROP FOREIGN KEY trattamento_ibfk_1
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE elemento_fonte DROP FOREIGN KEY elemento_fonte_ibfk_2
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE elemento_fonte DROP FOREIGN KEY elemento_fonte_ibfk_1
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE elemento_degrado DROP FOREIGN KEY elemento_degrado_ibfk_1
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE elemento_degrado DROP FOREIGN KEY elemento_degrado_ibfk_2
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE interv_el_degrado DROP FOREIGN KEY interv_el_degrado_ibfk_3
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE interv_el_degrado DROP FOREIGN KEY interv_el_degrado_ibfk_1
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE interv_el_degrado DROP FOREIGN KEY interv_el_degrado_ibfk_2
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE strutt_oriz DROP FOREIGN KEY strutt_oriz_ibfk_3
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE strutt_oriz DROP FOREIGN KEY strutt_oriz_ibfk_1
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE strutt_oriz DROP FOREIGN KEY strutt_oriz_ibfk_4
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE strutt_oriz DROP FOREIGN KEY strutt_oriz_ibfk_2
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE strutt_oriz DROP FOREIGN KEY strutt_oriz_ibfk_5
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE architettura_fonte DROP FOREIGN KEY architettura_fonte_ibfk_1
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE architettura_fonte DROP FOREIGN KEY architettura_fonte_ibfk_2
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE intervento DROP FOREIGN KEY intervento_trattamento_fk
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE degrado_fonte DROP FOREIGN KEY degrado_fonte_ibfk_1
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE degrado_fonte DROP FOREIGN KEY degrado_fonte_ibfk_2
SQL);
$this->addSql(<<<'SQL'
DROP TABLE voc_posa
SQL);
$this->addSql(<<<'SQL'
DROP TABLE oriz_fonte
SQL);
$this->addSql(<<<'SQL'
DROP TABLE trattamento
SQL);
$this->addSql(<<<'SQL'
DROP TABLE elemento_fonte
SQL);
$this->addSql(<<<'SQL'
DROP TABLE voc_genere_oriz
SQL);
$this->addSql(<<<'SQL'
DROP TABLE elemento_degrado
SQL);
$this->addSql(<<<'SQL'
DROP TABLE voc_tipo_oriz
SQL);
$this->addSql(<<<'SQL'
DROP TABLE voc_ricon
SQL);
$this->addSql(<<<'SQL'
DROP TABLE interv_el_degrado
SQL);
$this->addSql(<<<'SQL'
DROP TABLE users
SQL);
$this->addSql(<<<'SQL'
DROP TABLE voc_lavorazione
SQL);
$this->addSql(<<<'SQL'
DROP TABLE strutt_oriz
SQL);
$this->addSql(<<<'SQL'
DROP TABLE architettura_fonte
SQL);
$this->addSql(<<<'SQL'
DROP TABLE voc_tipo_el
SQL);
$this->addSql(<<<'SQL'
DROP TABLE intervento
SQL);
$this->addSql(<<<'SQL'
DROP TABLE degrado_fonte
SQL);
$this->addSql(<<<'SQL'
DROP TABLE fonte
SQL);
$this->addSql(<<<'SQL'
DROP TABLE voc_qualificazione_oriz
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE architettura CHANGE id id INT AUTO_INCREMENT NOT NULL, CHANGE denominazione denominazione VARCHAR(255) NOT NULL
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE degrado DROP FOREIGN KEY degrado_ibfk_1
SQL);
$this->addSql(<<<'SQL'
DROP INDEX materiale ON degrado
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE degrado CHANGE id id INT AUTO_INCREMENT NOT NULL, CHANGE materiale materiale BIGINT DEFAULT NULL, CHANGE lemma lemma VARCHAR(50) NOT NULL
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE elemento DROP FOREIGN KEY elemento_ibfk_2
SQL);
$this->addSql(<<<'SQL'
DROP INDEX posa ON elemento
SQL);
$this->addSql(<<<'SQL'
DROP INDEX tipo ON elemento
SQL);
$this->addSql(<<<'SQL'
DROP INDEX strutt_oriz ON elemento
SQL);
$this->addSql(<<<'SQL'
DROP INDEX materiale ON elemento
SQL);
$this->addSql(<<<'SQL'
DROP INDEX riconoscimento ON elemento
SQL);
$this->addSql(<<<'SQL'
DROP INDEX lavorazione ON elemento
SQL);
$this->addSql(<<<'SQL'
DROP INDEX etichetta ON elemento
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE elemento CHANGE id id INT AUTO_INCREMENT NOT NULL, CHANGE tipo tipo BIGINT DEFAULT NULL, CHANGE materiale materiale BIGINT DEFAULT NULL, CHANGE lavorazione lavorazione BIGINT DEFAULT NULL, CHANGE posa posa BIGINT DEFAULT NULL, CHANGE strutt_oriz strutt_oriz BIGINT NOT NULL, CHANGE riconoscimento riconoscimento BIGINT DEFAULT NULL, CHANGE note note LONGTEXT DEFAULT NULL
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE user ADD firstname VARCHAR(255) NOT NULL, ADD lastname VARCHAR(255) NOT NULL, ADD email VARCHAR(255) NOT NULL
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE voc_materiale CHANGE id id INT AUTO_INCREMENT NOT NULL, CHANGE lemma lemma VARCHAR(50) NOT NULL
SQL);
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql(<<<'SQL'
CREATE TABLE voc_posa (id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, lemma VARCHAR(50) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_general_ci`, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_general_ci` ENGINE = InnoDB COMMENT = ''
SQL);
$this->addSql(<<<'SQL'
CREATE TABLE oriz_fonte (id_strutt_oriz BIGINT UNSIGNED NOT NULL, id_fonte BIGINT UNSIGNED NOT NULL, INDEX id_fonte (id_fonte), INDEX IDX_26A2F8B8D31AE9FE (id_strutt_oriz), PRIMARY KEY(id_strutt_oriz, id_fonte)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_general_ci` ENGINE = InnoDB COMMENT = ''
SQL);
$this->addSql(<<<'SQL'
CREATE TABLE trattamento (id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, materiale BIGINT UNSIGNED DEFAULT NULL, lemma VARCHAR(70) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_general_ci`, natura VARCHAR(50) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_general_ci`, tipologia VARCHAR(50) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_general_ci`, applicazione VARCHAR(50) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_general_ci`, rif_normativo VARCHAR(70) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_general_ci`, INDEX materiale (materiale), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_general_ci` ENGINE = InnoDB COMMENT = ''
SQL);
$this->addSql(<<<'SQL'
CREATE TABLE elemento_fonte (id_elemento BIGINT UNSIGNED NOT NULL, id_fonte BIGINT UNSIGNED NOT NULL, INDEX id_fonte (id_fonte), INDEX IDX_2C9B1DF090B787 (id_elemento), PRIMARY KEY(id_elemento, id_fonte)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_general_ci` ENGINE = InnoDB COMMENT = ''
SQL);
$this->addSql(<<<'SQL'
CREATE TABLE voc_genere_oriz (id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, lemma VARCHAR(50) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_general_ci`, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_general_ci` ENGINE = InnoDB COMMENT = ''
SQL);
$this->addSql(<<<'SQL'
CREATE TABLE elemento_degrado (id_elemento BIGINT UNSIGNED NOT NULL, id_degrado BIGINT UNSIGNED NOT NULL, stato VARCHAR(20) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_general_ci`, INDEX id_degrado (id_degrado), INDEX IDX_F389C65490B787 (id_elemento), PRIMARY KEY(id_elemento, id_degrado)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_general_ci` ENGINE = InnoDB COMMENT = ''
SQL);
$this->addSql(<<<'SQL'
CREATE TABLE voc_tipo_oriz (id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, lemma VARCHAR(50) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_general_ci`, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_general_ci` ENGINE = InnoDB COMMENT = ''
SQL);
$this->addSql(<<<'SQL'
CREATE TABLE voc_ricon (id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, lemma VARCHAR(50) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_general_ci`, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_general_ci` ENGINE = InnoDB COMMENT = ''
SQL);
$this->addSql(<<<'SQL'
CREATE TABLE interv_el_degrado (id_intervento BIGINT UNSIGNED NOT NULL, id_elemento BIGINT UNSIGNED NOT NULL, id_degrado BIGINT UNSIGNED NOT NULL, INDEX id_degrado (id_degrado), INDEX id_elemento (id_elemento), INDEX IDX_E54AD936E650F980 (id_intervento), PRIMARY KEY(id_intervento, id_elemento, id_degrado)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_general_ci` ENGINE = InnoDB COMMENT = ''
SQL);
$this->addSql(<<<'SQL'
CREATE TABLE users (ID INT AUTO_INCREMENT NOT NULL, username VARCHAR(255) CHARACTER SET utf8mb3 DEFAULT NULL COLLATE `utf8mb3_general_ci`, password VARCHAR(255) CHARACTER SET utf8mb3 DEFAULT NULL COLLATE `utf8mb3_general_ci`, email VARCHAR(255) CHARACTER SET utf8mb3 DEFAULT NULL COLLATE `utf8mb3_general_ci`, fullname VARCHAR(255) CHARACTER SET utf8mb3 DEFAULT NULL COLLATE `utf8mb3_general_ci`, groupid VARCHAR(255) CHARACTER SET utf8mb3 DEFAULT NULL COLLATE `utf8mb3_general_ci`, active INT DEFAULT NULL, ext_security_id VARCHAR(100) CHARACTER SET utf8mb3 DEFAULT NULL COLLATE `utf8mb3_general_ci`, PRIMARY KEY(ID)) DEFAULT CHARACTER SET utf8mb3 COLLATE `utf8mb3_general_ci` ENGINE = InnoDB COMMENT = ''
SQL);
$this->addSql(<<<'SQL'
CREATE TABLE voc_lavorazione (id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, lemma VARCHAR(50) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_general_ci`, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_general_ci` ENGINE = InnoDB COMMENT = ''
SQL);
$this->addSql(<<<'SQL'
CREATE TABLE strutt_oriz (id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, tipo BIGINT UNSIGNED DEFAULT NULL, genere BIGINT UNSIGNED DEFAULT NULL, qualificazione BIGINT UNSIGNED DEFAULT NULL, architettura BIGINT UNSIGNED NOT NULL, riconoscimento BIGINT UNSIGNED DEFAULT NULL, note TEXT CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_general_ci`, etichetta VARCHAR(6) CHARACTER SET utf8mb4 NOT NULL COLLATE `utf8mb4_general_ci`, INDEX architettura (architettura), INDEX tipo (tipo), INDEX riconoscimento (riconoscimento), INDEX genere (genere), INDEX qualificazione (qualificazione), UNIQUE INDEX etichetta (etichetta), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_general_ci` ENGINE = InnoDB COMMENT = ''
SQL);
$this->addSql(<<<'SQL'
CREATE TABLE architettura_fonte (id_architettura BIGINT UNSIGNED NOT NULL, id_fonte BIGINT UNSIGNED NOT NULL, INDEX id_fonte (id_fonte), INDEX IDX_DEF7611A82F5A403 (id_architettura), PRIMARY KEY(id_architettura, id_fonte)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_general_ci` ENGINE = InnoDB COMMENT = ''
SQL);
$this->addSql(<<<'SQL'
CREATE TABLE voc_tipo_el (id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, lemma VARCHAR(50) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_general_ci`, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_general_ci` ENGINE = InnoDB COMMENT = ''
SQL);
$this->addSql(<<<'SQL'
CREATE TABLE intervento (id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, trattamento BIGINT UNSIGNED DEFAULT NULL, incaricato VARCHAR(50) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_general_ci`, data_interv DATE DEFAULT NULL, INDEX trattamento (trattamento), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_general_ci` ENGINE = InnoDB COMMENT = ''
SQL);
$this->addSql(<<<'SQL'
CREATE TABLE degrado_fonte (id_degrado BIGINT UNSIGNED NOT NULL, id_fonte BIGINT UNSIGNED NOT NULL, INDEX id_fonte (id_fonte), INDEX IDX_24F62C731B9C3026 (id_degrado), PRIMARY KEY(id_degrado, id_fonte)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_general_ci` ENGINE = InnoDB COMMENT = ''
SQL);
$this->addSql(<<<'SQL'
CREATE TABLE fonte (id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, tipo VARCHAR(20) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_general_ci`, riferimento VARCHAR(150) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_general_ci`, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_general_ci` ENGINE = InnoDB COMMENT = ''
SQL);
$this->addSql(<<<'SQL'
CREATE TABLE voc_qualificazione_oriz (id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, lemma VARCHAR(50) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_general_ci`, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_general_ci` ENGINE = InnoDB COMMENT = ''
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE oriz_fonte ADD CONSTRAINT oriz_fonte_ibfk_2 FOREIGN KEY (id_fonte) REFERENCES fonte (id)
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE oriz_fonte ADD CONSTRAINT oriz_fonte_ibfk_1 FOREIGN KEY (id_strutt_oriz) REFERENCES strutt_oriz (id)
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE trattamento ADD CONSTRAINT trattamento_ibfk_1 FOREIGN KEY (materiale) REFERENCES voc_materiale (id)
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE elemento_fonte ADD CONSTRAINT elemento_fonte_ibfk_2 FOREIGN KEY (id_fonte) REFERENCES fonte (id)
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE elemento_fonte ADD CONSTRAINT elemento_fonte_ibfk_1 FOREIGN KEY (id_elemento) REFERENCES elemento (id)
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE elemento_degrado ADD CONSTRAINT elemento_degrado_ibfk_1 FOREIGN KEY (id_elemento) REFERENCES elemento (id)
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE elemento_degrado ADD CONSTRAINT elemento_degrado_ibfk_2 FOREIGN KEY (id_degrado) REFERENCES degrado (id)
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE interv_el_degrado ADD CONSTRAINT interv_el_degrado_ibfk_3 FOREIGN KEY (id_degrado) REFERENCES degrado (id)
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE interv_el_degrado ADD CONSTRAINT interv_el_degrado_ibfk_1 FOREIGN KEY (id_intervento) REFERENCES intervento (id)
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE interv_el_degrado ADD CONSTRAINT interv_el_degrado_ibfk_2 FOREIGN KEY (id_elemento) REFERENCES elemento (id)
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE strutt_oriz ADD CONSTRAINT strutt_oriz_ibfk_3 FOREIGN KEY (qualificazione) REFERENCES voc_qualificazione_oriz (id)
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE strutt_oriz ADD CONSTRAINT strutt_oriz_ibfk_1 FOREIGN KEY (tipo) REFERENCES voc_tipo_oriz (id)
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE strutt_oriz ADD CONSTRAINT strutt_oriz_ibfk_4 FOREIGN KEY (architettura) REFERENCES architettura (id)
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE strutt_oriz ADD CONSTRAINT strutt_oriz_ibfk_2 FOREIGN KEY (genere) REFERENCES voc_genere_oriz (id)
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE strutt_oriz ADD CONSTRAINT strutt_oriz_ibfk_5 FOREIGN KEY (riconoscimento) REFERENCES voc_ricon (id)
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE architettura_fonte ADD CONSTRAINT architettura_fonte_ibfk_1 FOREIGN KEY (id_architettura) REFERENCES architettura (id)
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE architettura_fonte ADD CONSTRAINT architettura_fonte_ibfk_2 FOREIGN KEY (id_fonte) REFERENCES fonte (id)
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE intervento ADD CONSTRAINT intervento_trattamento_fk FOREIGN KEY (trattamento) REFERENCES trattamento (id) ON UPDATE CASCADE ON DELETE CASCADE
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE degrado_fonte ADD CONSTRAINT degrado_fonte_ibfk_1 FOREIGN KEY (id_degrado) REFERENCES degrado (id)
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE degrado_fonte ADD CONSTRAINT degrado_fonte_ibfk_2 FOREIGN KEY (id_fonte) REFERENCES fonte (id)
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE architettura CHANGE id id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, CHANGE denominazione denominazione VARCHAR(50) DEFAULT NULL
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE degrado CHANGE id id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, CHANGE lemma lemma VARCHAR(50) DEFAULT NULL, CHANGE materiale materiale BIGINT UNSIGNED DEFAULT NULL
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE degrado ADD CONSTRAINT degrado_ibfk_1 FOREIGN KEY (materiale) REFERENCES voc_materiale (id)
SQL);
$this->addSql(<<<'SQL'
CREATE INDEX materiale ON degrado (materiale)
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE elemento CHANGE id id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, CHANGE tipo tipo BIGINT UNSIGNED DEFAULT NULL, CHANGE materiale materiale BIGINT UNSIGNED DEFAULT NULL, CHANGE lavorazione lavorazione BIGINT UNSIGNED DEFAULT NULL, CHANGE posa posa BIGINT UNSIGNED DEFAULT NULL, CHANGE strutt_oriz strutt_oriz BIGINT UNSIGNED NOT NULL, CHANGE riconoscimento riconoscimento BIGINT UNSIGNED DEFAULT NULL, CHANGE note note TEXT DEFAULT NULL
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE elemento ADD CONSTRAINT elemento_ibfk_3 FOREIGN KEY (lavorazione) REFERENCES voc_lavorazione (id)
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE elemento ADD CONSTRAINT elemento_ibfk_6 FOREIGN KEY (riconoscimento) REFERENCES voc_ricon (id)
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE elemento ADD CONSTRAINT elemento_ibfk_1 FOREIGN KEY (tipo) REFERENCES voc_tipo_el (id)
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE elemento ADD CONSTRAINT elemento_ibfk_4 FOREIGN KEY (posa) REFERENCES voc_posa (id)
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE elemento ADD CONSTRAINT elemento_ibfk_2 FOREIGN KEY (materiale) REFERENCES voc_materiale (id)
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE elemento ADD CONSTRAINT elemento_ibfk_5 FOREIGN KEY (strutt_oriz) REFERENCES strutt_oriz (id)
SQL);
$this->addSql(<<<'SQL'
CREATE INDEX posa ON elemento (posa)
SQL);
$this->addSql(<<<'SQL'
CREATE INDEX tipo ON elemento (tipo)
SQL);
$this->addSql(<<<'SQL'
CREATE INDEX strutt_oriz ON elemento (strutt_oriz)
SQL);
$this->addSql(<<<'SQL'
CREATE INDEX materiale ON elemento (materiale)
SQL);
$this->addSql(<<<'SQL'
CREATE INDEX riconoscimento ON elemento (riconoscimento)
SQL);
$this->addSql(<<<'SQL'
CREATE INDEX lavorazione ON elemento (lavorazione)
SQL);
$this->addSql(<<<'SQL'
CREATE UNIQUE INDEX etichetta ON elemento (etichetta)
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE user DROP firstname, DROP lastname, DROP email
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE voc_materiale CHANGE id id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, CHANGE lemma lemma VARCHAR(50) DEFAULT NULL
SQL);
}
}

View File

@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250331103338 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql(<<<'SQL'
CREATE TABLE progetto (id INT AUTO_INCREMENT NOT NULL, id_utente BIGINT NOT NULL, id_architettura BIGINT NOT NULL, ifc VARCHAR(255) DEFAULT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB
SQL);
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql(<<<'SQL'
DROP TABLE progetto
SQL);
}
}

38
phpunit.xml.dist Normal file
View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- https://phpunit.readthedocs.io/en/latest/configuration.html -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="tests/bootstrap.php"
convertDeprecationsToExceptions="false"
>
<php>
<ini name="display_errors" value="1" />
<ini name="error_reporting" value="-1" />
<server name="APP_ENV" value="test" force="true" />
<server name="SHELL_VERBOSITY" value="-1" />
<server name="SYMFONY_PHPUNIT_REMOVE" value="" />
<server name="SYMFONY_PHPUNIT_VERSION" value="9.6" />
</php>
<testsuites>
<testsuite name="Project Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<coverage processUncoveredFiles="true">
<include>
<directory suffix=".php">src</directory>
</include>
</coverage>
<listeners>
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener" />
</listeners>
<extensions>
</extensions>
</phpunit>

View File

@ -0,0 +1,18 @@
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
final class UserController extends AbstractController
{
#[Route('/user', name: 'app_user')]
public function index(): Response
{
return $this->render('user/index.html.twig', [
'controller_name' => 'UserController',
]);
}
}

92
src/Entity/Project.php Normal file
View File

@ -0,0 +1,92 @@
<?php
namespace App\Entity;
use App\Repository\ProjectRepository;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\Post;
use ApiPlatform\Metadata\GetCollection;
use Symfony\Component\Serializer\Attribute\Groups;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: ProjectRepository::class)]
#[ORM\Table(name: 'progetto')]
#[ApiResource(
operations: [
new Get(normalizationContext: ['groups' => 'project:item']),
new GetCollection(normalizationContext: ['groups' => 'project:list']),
new Post(security: "is_granted('ROLE_USER')"),
],
order: ['name' => 'DESC'],
paginationEnabled: false,
)]
class Project
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(type: Types::BIGINT, name: 'id_utente')]
#[ORM\OneToOne(User::class, )]
private ?string $userid = null;
#[ORM\Column(type: Types::BIGINT, name: 'id_architettura')]
private ?string $buildingid = null;
#[ORM\Column(length: 255, nullable: true)]
/**
* @var string $ifc Path to IFC file for this project
*/
private ?string $ifc = null;
public function getId(): ?int
{
return $this->id;
}
public function setId(string $id): static
{
$this->id = $id;
return $this;
}
public function getUserid(): ?string
{
return $this->userid;
}
public function setUserid(string $userid): static
{
$this->userid = $userid;
return $this;
}
public function getBuildingid(): ?string
{
return $this->buildingid;
}
public function setBuildingid(string $buildingid): static
{
$this->buildingid = $buildingid;
return $this;
}
public function getIfc(): ?string
{
return $this->ifc;
}
public function setIfc(?string $ifc): static
{
$this->ifc = $ifc;
return $this;
}
}

View File

@ -31,6 +31,15 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
#[ORM\Column]
private ?string $password = null;
#[ORM\Column]
private ?string $firstname = null;
#[ORM\Column]
private ?string $lastname = null;
#[ORM\Column]
private ?string $email = null;
public function getId(): ?int
{
return $this->id;
@ -55,7 +64,7 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
*/
public function getUserIdentifier(): string
{
return (string) $this->username;
return "{$this->firstname} {$this->lastname}";
}
/**
@ -97,6 +106,41 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
return $this;
}
public function getFirstname(): ?string
{
return $this->firstname;
}
public function setFirstname(string $firstname): static
{
$this->firstname = $firstname;
return $this;
}
public function getLastname(): ?string
{
return $this->lastname;
}
public function setLastname(string $lastname): static
{
$this->lastname = $lastname;
return $this;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): static
{
$this->email = $email;
return $this;
}
/**
* @see UserInterface
*/

View File

@ -0,0 +1,43 @@
<?php
namespace App\Repository;
use App\Entity\Project;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
* @extends ServiceEntityRepository<Project>
*/
class ProjectRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Project::class);
}
// /**
// * @return Project[] Returns an array of Project objects
// */
// public function findByExampleField($value): array
// {
// return $this->createQueryBuilder('p')
// ->andWhere('p.exampleField = :val')
// ->setParameter('val', $value)
// ->orderBy('p.id', 'ASC')
// ->setMaxResults(10)
// ->getQuery()
// ->getResult()
// ;
// }
// public function findOneBySomeField($value): ?Project
// {
// return $this->createQueryBuilder('p')
// ->andWhere('p.exampleField = :val')
// ->setParameter('val', $value)
// ->getQuery()
// ->getOneOrNullResult()
// ;
// }
}

View File

@ -52,6 +52,20 @@
"config/packages/nelmio_cors.yaml"
]
},
"phpunit/phpunit": {
"version": "9.6",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "9.6",
"ref": "6a9341aa97d441627f8bd424ae85dc04c944f8b4"
},
"files": [
".env.test",
"phpunit.xml.dist",
"tests/bootstrap.php"
]
},
"symfony/asset-mapper": {
"version": "7.1",
"recipe": {
@ -120,6 +134,21 @@
"ref": "fadbfe33303a76e25cb63401050439aa9b1a9c7f"
}
},
"symfony/phpunit-bridge": {
"version": "7.2",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "6.3",
"ref": "a411a0480041243d97382cac7984f7dce7813c08"
},
"files": [
".env.test",
"bin/phpunit",
"phpunit.xml.dist",
"tests/bootstrap.php"
]
},
"symfony/routing": {
"version": "7.1",
"recipe": {

View File

@ -4,22 +4,13 @@
{% block body %}
<nav class="navbar has-background-light" role="navigation" aria-label="main navigation">
<div class="navbar-brand">
<a class="navbar-item" href="/">
<span class="icon mr-2">
<i class="fas fa-home"></i>
</span>
WebArchi
</a>
<!-- navbar items, navbar burger... -->
</div>
</nav>
{% include 'partials/navbar.html.twig' %}
<div class="columns">
<div class="column is-full">
<div id="scene"></div>
<div id="ui" data-theme="light" data-controller="form">
<aside class="menu ml-4 mt-3">
<aside class="menu ml-4 mt-3" data-controller="clipper">
<p class="menu-label is-size-6">Progetto</p>
<div class="file mt-4 is-link">
<label class="file-label">
@ -66,9 +57,36 @@
<ul class="menu-list">
<li id="selected-prop"></li>
</ul>
<p class="menu-label is-size-6">Strumenti</p>
<ul class="menu-list">
<li class="menu-item">
Clipper
<ul class="menu-list">
<li class="menu-item"><label class="checkbox">Attivo <input class="checkbox ml-2" id="clip-en" type="checkbox" checked></label></li>
<li class="menu-item">
Colore piani
<div class="mt-2 p-2 input is-small" data-clipper-target="hex">
<input type="color" data-action="input->clipper#color change->clipper#color"
class="is-small is-clickable mr-2" aria-label="Colore clipper" value="#202932" style="border: none">
<span>#202932</span>
</div>
</li>
<li class="menu-item">
Grandezza piani
<div class="mt-2 input is-small" data-clipper-target="range">
<input class="is-clickable is-small" data-action="change->clipper#size"
type="range" step="0.1" min="5" max="15" style="width: 100%;">
</div>
</li>
</ul>
</li>
</ul>
<div class="buttons ml-6">
<button class="button is-danger" data-action="clipper#deleteAll" title="Elimina tutti i piani">Elimina</button>
</div>
</aside>
</div>
</div>
</div>
{% endblock %}

View File

@ -1,6 +1,6 @@
{% extends 'base.html.twig' %}
{% block title %}Login | ArCOA{% endblock %}
{% block title %}Login | WebArchi{% endblock %}
{% block body %}

View File

@ -0,0 +1,18 @@
<nav class="navbar has-background-light" role="navigation" aria-label="main navigation">
<div class="navbar-brand">
<a class="navbar-item" href="/">
<span class="icon mr-2">
<i class="fas fa-home"></i>
</span>
WebArchi
</a>
<!-- navbar items, navbar burger... -->
</div>
{% if app.user %}
<div class="navbar-end">
<div class="navbar-item" data-controller="dropdown">
{% include 'partials/user.html.twig' %}
</div>
</div>
{% endif %}
</nav>

View File

@ -0,0 +1,51 @@
<div class="buttons dropdown is-right" data-dropdown-target="drop">
<div class="dropdown-trigger" data-action="click->dropdown#toggle">
<a class="button is-primary">
<span class="icon">
<i class="fa fa-user-circle"></i>
</span>
<span class="pl-3">
{{ app.user.useridentifier }}
</span>
<span class="icon">
<i class="fa fa-caret-down" data-dropdown-target="caret"></i>
</span>
</a>
</div>
<div class="dropdown-menu" role="menu">
<div class="dropdown-content">
<a href="/user" class="dropdown-item">
<span class="icon is-small">
<i class="fa fa-user"></i>
</span>
<span class="pl-2 is-size-6">Profilo</span>
</a>
<a href="/projects" class="dropdown-item">
<span class="icon is-small">
<i class="fa fa-pen-nib"></i>
</span>
<span class="pl-2 is-size-6">Progetti</span>
</a>
{% if is_granted('ROLE_ADMIN') %}
<a href="/admin" class="dropdown-item">
<span class="icon is-small">
<i class="fa fa-cogs"></i>
</span>
<span class="pl-2 is-size-6">Admin</span>
</a>
{% endif %}
<a href="https://git.electricmandarine.cloud/nicolo/ifc-web-app/issues" class="dropdown-item">
<span class="icon is-small">
<i class="fa fa-bug"></i>
</span>
<span class="pl-2 is-size-6">Segnala un bug</span>
</a>
<hr class="dropdown-divider" />
<a href="/logout" class="button is-link is-fullwidth">
<span class="icon is-small">
<i class="fa fa-sign-out"></i>
</span>
<span class="has-text-centered"> Logout</span>
</a>
</div>
</div>

View File

@ -0,0 +1,122 @@
{% extends 'base.html.twig' %}
{% block title %}Profilo | WebArchi{% endblock %}
{% block body %}
{% include 'partials/navbar.html.twig' %}
<div class="container" style="max-width: 50vw">
<h1 class="is-size-1 mt-2 has-text-centered">Profilo utente</h1>
<div class="container mt-6">
<div class="card">
<div class="card-content">
<div class="media">
<div class="media-left">
<span class="icon is-large">
<i class="fa fa-user-circle fa-2x"></i>
</span>
</div>
<div class="media-content">
<p class="title is-4">{{ app.user.useridentifier }}</p>
<p class="subtitle is-6">
<span class="icon is-small">
<i class="fa fa-envelope"></i>
</span>
{{ app.user.email ?? 'no email' }}
</p>
</div>
</div>
<div class="content">
<p class="is-size-4 pl-3">
<strong>Ruolo utente:</strong>
{% if 'ROLE_ADMIN' in app.user.roles %}
Amministratore
{% elseif 'ROLE_REVISOR' in app.user.roles %}
Revisore
{% else %}
Utente
{% endif %}
</p>
<article class="message is-info">
<div class="message-header">
<p>
<span class="icon is-small is-size-5 mr-3">
<i class="fa fa-info-circle"></i>
</span>
Permessi
</p>
</div>
<div class="message-body">
{% if 'ROLE_ADMIN' in app.user.roles %}
<p>
Administrators can create and edit users of the ArCOA data entry system,
including changing passwords and user roles, and disabling accounts.
</p>
<p>
They can perform all actions on all records and vocabularies
(create, view, edit, delete).
</p>
{% elseif 'ROLE_REVISOR' in app.user.roles %}
<p>Revisors can perform all actions (create, view, edit, delete) on all records and vocabs.</p>
{% elseif 'ROLE_EDITOR' in app.user.roles %}
<p>
Editors can view vocabs, view and search all records, create new records with "draft" or "complete" status,
edit their own records and those created by other editors; they can only delete their own records, as long as the status
is "draft" or "complete".
</p>
{% else %}
<p>
Readers can view and search records that are either published, excluded or unindexed (draft and complete records cannot be viewed).
</p>
{% endif %}
</div>
</article>
</div>
</div>
</div>
<div class="card content">
{% for message in app.flashes('error') %}
<article class="message is-danger">
<div class="message-body">{{ message }}</div>
</article>
{% endfor %}
{% for message in app.flashes('notice') %}
<article class="message is-success">
<div class="message-body">{{ message }}</div>
</article>
{% endfor %}
<form class="card-content" id="change-password" method="post" action="">
<div class="field">
<h3 class="is-size-4 has-text-centered">Modifica password</h3>
</div>
<div class="field">
<label class="label">Password attuale</label>
<p class="control">
<input class="input" name="_current_pass" required type="password" placeholder="Current password">
</p>
</div>
<div class="field">
<label class="label">Nuova password</label>
<p class="control">
<input class="input" name="_new_pass" required type="password" placeholder="New password">
</p>
</div>
<div class="field">
<label class="label">Conferma password</label>
<p class="control">
<input class="input" name="_confirm_pass" required type="password" placeholder="Confirm password">
</p>
</div>
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">
<div class="field mt-5">
<p class="control" id="submit">
<button class="button is-link is-fullwidth" type="submit">
Invio
</button>
</p>
</div>
</form>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,16 @@
<?php
namespace App\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
final class UserControllerTest extends WebTestCase
{
public function testIndex(): void
{
$client = static::createClient();
$client->request('GET', '/user');
self::assertResponseIsSuccessful();
}
}

13
tests/bootstrap.php Normal file
View File

@ -0,0 +1,13 @@
<?php
use Symfony\Component\Dotenv\Dotenv;
require dirname(__DIR__).'/vendor/autoload.php';
if (method_exists(Dotenv::class, 'bootEnv')) {
(new Dotenv())->bootEnv(dirname(__DIR__).'/.env');
}
if ($_SERVER['APP_DEBUG']) {
umask(0000);
}