✨ Ajout de la gestion des rôles sur les dossiers parents + gestion des liens public si le dossier parent est relié au rôle Visiteur (Mais pas possible de lister les fichiers)
This commit is contained in:
parent
14c6ce39ab
commit
38f7355d42
@ -7,12 +7,12 @@
|
|||||||
"php": ">=8.2",
|
"php": ">=8.2",
|
||||||
"ext-ctype": "*",
|
"ext-ctype": "*",
|
||||||
"ext-iconv": "*",
|
"ext-iconv": "*",
|
||||||
"doctrine/dbal": "^4.2.1",
|
"doctrine/dbal": "^4.2.2",
|
||||||
"doctrine/doctrine-bundle": "^2.13.1",
|
"doctrine/doctrine-bundle": "^2.13.2",
|
||||||
"doctrine/doctrine-migrations-bundle": "^3.3.1",
|
"doctrine/doctrine-migrations-bundle": "^3.4.0",
|
||||||
"doctrine/orm": "^3.3.1",
|
"doctrine/orm": "^3.3.1",
|
||||||
"league/flysystem": "^3.29.1",
|
"league/flysystem": "^3.29.1",
|
||||||
"oneup/flysystem-bundle": "^4.12.3",
|
"oneup/flysystem-bundle": "^4.12.4",
|
||||||
"phpdocumentor/reflection-docblock": "^5.6.1",
|
"phpdocumentor/reflection-docblock": "^5.6.1",
|
||||||
"phpstan/phpdoc-parser": "^2.0",
|
"phpstan/phpdoc-parser": "^2.0",
|
||||||
"symfony/apache-pack": "^1.0.1",
|
"symfony/apache-pack": "^1.0.1",
|
||||||
@ -50,7 +50,7 @@
|
|||||||
"symfony/validator": "7.2.*",
|
"symfony/validator": "7.2.*",
|
||||||
"symfony/web-link": "7.2.*",
|
"symfony/web-link": "7.2.*",
|
||||||
"symfony/yaml": "7.2.*",
|
"symfony/yaml": "7.2.*",
|
||||||
"symfonycasts/reset-password-bundle": "^1.23",
|
"symfonycasts/reset-password-bundle": "^1.23.1",
|
||||||
"symfonycasts/tailwind-bundle": "^0.6.1",
|
"symfonycasts/tailwind-bundle": "^0.6.1",
|
||||||
"tales-from-a-dev/flowbite-bundle": "^0.7.1",
|
"tales-from-a-dev/flowbite-bundle": "^0.7.1",
|
||||||
"twig/extra-bundle": "^2.12|^3.18",
|
"twig/extra-bundle": "^2.12|^3.18",
|
||||||
@ -109,16 +109,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"friendsofphp/php-cs-fixer": "^3.68",
|
"friendsofphp/php-cs-fixer": "^3.68.1",
|
||||||
"phpstan/extension-installer": "^1.4",
|
"phpstan/extension-installer": "^1.4.3",
|
||||||
"phpstan/phpstan-strict-rules": "^2.0",
|
"phpstan/phpstan-strict-rules": "^2.0.3",
|
||||||
"phpstan/phpstan-symfony": "^2.0",
|
"phpstan/phpstan-symfony": "^2.0.2",
|
||||||
"phpunit/phpunit": "^11.5.2",
|
"phpunit/phpunit": "^11.5.3",
|
||||||
"rector/rector": "^2.0",
|
"rector/rector": "^2.0.7",
|
||||||
"symfony/browser-kit": "7.2.*",
|
"symfony/browser-kit": "7.2.*",
|
||||||
"symfony/css-selector": "7.2.*",
|
"symfony/css-selector": "7.2.*",
|
||||||
"symfony/debug-bundle": "7.2.*",
|
"symfony/debug-bundle": "7.2.*",
|
||||||
"symfony/maker-bundle": "^1.61",
|
"symfony/maker-bundle": "^1.62.1",
|
||||||
"symfony/phpunit-bridge": "^7.2",
|
"symfony/phpunit-bridge": "^7.2",
|
||||||
"symfony/stopwatch": "7.2.*",
|
"symfony/stopwatch": "7.2.*",
|
||||||
"symfony/web-profiler-bundle": "7.2.*"
|
"symfony/web-profiler-bundle": "7.2.*"
|
||||||
|
38
composer.lock
generated
38
composer.lock
generated
@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "d58d5009e09974e2358412fe10fa1005",
|
"content-hash": "6438b8b149fca5ad2f3c96aa06e93da2",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "composer/semver",
|
"name": "composer/semver",
|
||||||
@ -9371,16 +9371,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpstan/phpstan",
|
"name": "phpstan/phpstan",
|
||||||
"version": "2.1.1",
|
"version": "2.1.2",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/phpstan/phpstan.git",
|
"url": "https://github.com/phpstan/phpstan.git",
|
||||||
"reference": "cd6e973e04b4c2b94c86e8612b5a65f0da0e08e7"
|
"reference": "7d08f569e582ade182a375c366cbd896eccadd3a"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/cd6e973e04b4c2b94c86e8612b5a65f0da0e08e7",
|
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/7d08f569e582ade182a375c366cbd896eccadd3a",
|
||||||
"reference": "cd6e973e04b4c2b94c86e8612b5a65f0da0e08e7",
|
"reference": "7d08f569e582ade182a375c366cbd896eccadd3a",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -9425,20 +9425,20 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2025-01-05T16:43:48+00:00"
|
"time": "2025-01-21T14:54:06+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpstan/phpstan-strict-rules",
|
"name": "phpstan/phpstan-strict-rules",
|
||||||
"version": "2.0.2",
|
"version": "2.0.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/phpstan/phpstan-strict-rules.git",
|
"url": "https://github.com/phpstan/phpstan-strict-rules.git",
|
||||||
"reference": "02277ce4b0dd03d74f15282064f8f027d1dec9cc"
|
"reference": "8b88b5f818bfa301e0c99154ab622dace071c3ba"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/02277ce4b0dd03d74f15282064f8f027d1dec9cc",
|
"url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/8b88b5f818bfa301e0c99154ab622dace071c3ba",
|
||||||
"reference": "02277ce4b0dd03d74f15282064f8f027d1dec9cc",
|
"reference": "8b88b5f818bfa301e0c99154ab622dace071c3ba",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@ -9471,28 +9471,28 @@
|
|||||||
"description": "Extra strict and opinionated rules for PHPStan",
|
"description": "Extra strict and opinionated rules for PHPStan",
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/phpstan/phpstan-strict-rules/issues",
|
"issues": "https://github.com/phpstan/phpstan-strict-rules/issues",
|
||||||
"source": "https://github.com/phpstan/phpstan-strict-rules/tree/2.0.2"
|
"source": "https://github.com/phpstan/phpstan-strict-rules/tree/2.0.3"
|
||||||
},
|
},
|
||||||
"time": "2025-01-19T13:03:11+00:00"
|
"time": "2025-01-21T10:52:14+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpstan/phpstan-symfony",
|
"name": "phpstan/phpstan-symfony",
|
||||||
"version": "2.0.1",
|
"version": "2.0.2",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/phpstan/phpstan-symfony.git",
|
"url": "https://github.com/phpstan/phpstan-symfony.git",
|
||||||
"reference": "c08cd8e54a08d651bc402d304cfa161c3c3766c4"
|
"reference": "65f02c7e585f3c7372e42e14d3d87da034031553"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/phpstan/phpstan-symfony/zipball/c08cd8e54a08d651bc402d304cfa161c3c3766c4",
|
"url": "https://api.github.com/repos/phpstan/phpstan-symfony/zipball/65f02c7e585f3c7372e42e14d3d87da034031553",
|
||||||
"reference": "c08cd8e54a08d651bc402d304cfa161c3c3766c4",
|
"reference": "65f02c7e585f3c7372e42e14d3d87da034031553",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"ext-simplexml": "*",
|
"ext-simplexml": "*",
|
||||||
"php": "^7.4 || ^8.0",
|
"php": "^7.4 || ^8.0",
|
||||||
"phpstan/phpstan": "^2.0"
|
"phpstan/phpstan": "^2.1.2"
|
||||||
},
|
},
|
||||||
"conflict": {
|
"conflict": {
|
||||||
"symfony/framework-bundle": "<3.0"
|
"symfony/framework-bundle": "<3.0"
|
||||||
@ -9542,9 +9542,9 @@
|
|||||||
"description": "Symfony Framework extensions and rules for PHPStan",
|
"description": "Symfony Framework extensions and rules for PHPStan",
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/phpstan/phpstan-symfony/issues",
|
"issues": "https://github.com/phpstan/phpstan-symfony/issues",
|
||||||
"source": "https://github.com/phpstan/phpstan-symfony/tree/2.0.1"
|
"source": "https://github.com/phpstan/phpstan-symfony/tree/2.0.2"
|
||||||
},
|
},
|
||||||
"time": "2025-01-04T13:58:15+00:00"
|
"time": "2025-01-21T18:57:07+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpunit/php-code-coverage",
|
"name": "phpunit/php-code-coverage",
|
||||||
|
@ -1,37 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace DoctrineMigrations;
|
|
||||||
|
|
||||||
use Doctrine\DBAL\Schema\Schema;
|
|
||||||
use Doctrine\Migrations\AbstractMigration;
|
|
||||||
|
|
||||||
final class Version20241229133017 extends AbstractMigration
|
|
||||||
{
|
|
||||||
public function getDescription(): string
|
|
||||||
{
|
|
||||||
return 'Ajout de la table user et messenger_messages';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function up(Schema $schema): void
|
|
||||||
{
|
|
||||||
$this->addSql('CREATE TABLE "user" (id BLOB NOT NULL --(DC2Type:uuid)
|
|
||||||
, email VARCHAR(255) NOT NULL, roles CLOB NOT NULL --(DC2Type:json)
|
|
||||||
, password VARCHAR(255) NOT NULL, PRIMARY KEY(id))');
|
|
||||||
$this->addSql('CREATE UNIQUE INDEX UNIQ_IDENTIFIER_EMAIL ON "user" (email)');
|
|
||||||
$this->addSql('CREATE TABLE messenger_messages (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, body CLOB NOT NULL, headers CLOB NOT NULL, queue_name VARCHAR(190) NOT NULL, created_at DATETIME NOT NULL --(DC2Type:datetime_immutable)
|
|
||||||
, available_at DATETIME NOT NULL --(DC2Type:datetime_immutable)
|
|
||||||
, delivered_at DATETIME DEFAULT NULL --(DC2Type:datetime_immutable)
|
|
||||||
)');
|
|
||||||
$this->addSql('CREATE INDEX IDX_75EA56E0FB7336F0 ON messenger_messages (queue_name)');
|
|
||||||
$this->addSql('CREATE INDEX IDX_75EA56E0E3BD61CE ON messenger_messages (available_at)');
|
|
||||||
$this->addSql('CREATE INDEX IDX_75EA56E016BA31DB ON messenger_messages (delivered_at)');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function down(Schema $schema): void
|
|
||||||
{
|
|
||||||
$this->addSql('DROP TABLE "user"');
|
|
||||||
$this->addSql('DROP TABLE messenger_messages');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,64 +0,0 @@
|
|||||||
<?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 Version20250116210156 extends AbstractMigration
|
|
||||||
{
|
|
||||||
public function getDescription(): string
|
|
||||||
{
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function up(Schema $schema): void
|
|
||||||
{
|
|
||||||
$this->addSql('CREATE TABLE reset_password_request (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, selector VARCHAR(20) NOT NULL, hashed_token VARCHAR(100) NOT NULL, requested_at DATETIME NOT NULL, expires_at DATETIME NOT NULL, user_id BLOB NOT NULL, CONSTRAINT FK_7CE748AA76ED395 FOREIGN KEY (user_id) REFERENCES "user" (id) NOT DEFERRABLE INITIALLY IMMEDIATE)');
|
|
||||||
$this->addSql('CREATE INDEX IDX_7CE748AA76ED395 ON reset_password_request (user_id)');
|
|
||||||
$this->addSql('CREATE TEMPORARY TABLE __temp__user AS SELECT id, email, roles, password FROM user');
|
|
||||||
$this->addSql('DROP TABLE user');
|
|
||||||
$this->addSql('CREATE TABLE user (id BLOB NOT NULL, email VARCHAR(255) NOT NULL, roles CLOB NOT NULL, password VARCHAR(255) NOT NULL, PRIMARY KEY(id))');
|
|
||||||
$this->addSql('INSERT INTO user (id, email, roles, password) SELECT id, email, roles, password FROM __temp__user');
|
|
||||||
$this->addSql('DROP TABLE __temp__user');
|
|
||||||
$this->addSql('CREATE UNIQUE INDEX UNIQ_IDENTIFIER_EMAIL ON user (email)');
|
|
||||||
$this->addSql('CREATE TEMPORARY TABLE __temp__messenger_messages AS SELECT id, body, headers, queue_name, created_at, available_at, delivered_at FROM messenger_messages');
|
|
||||||
$this->addSql('DROP TABLE messenger_messages');
|
|
||||||
$this->addSql('CREATE TABLE messenger_messages (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, body CLOB NOT NULL, headers CLOB NOT NULL, queue_name VARCHAR(190) NOT NULL, created_at DATETIME NOT NULL, available_at DATETIME NOT NULL, delivered_at DATETIME DEFAULT NULL)');
|
|
||||||
$this->addSql('INSERT INTO messenger_messages (id, body, headers, queue_name, created_at, available_at, delivered_at) SELECT id, body, headers, queue_name, created_at, available_at, delivered_at FROM __temp__messenger_messages');
|
|
||||||
$this->addSql('DROP TABLE __temp__messenger_messages');
|
|
||||||
$this->addSql('CREATE INDEX IDX_75EA56E016BA31DB ON messenger_messages (delivered_at)');
|
|
||||||
$this->addSql('CREATE INDEX IDX_75EA56E0E3BD61CE ON messenger_messages (available_at)');
|
|
||||||
$this->addSql('CREATE INDEX IDX_75EA56E0FB7336F0 ON messenger_messages (queue_name)');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function down(Schema $schema): void
|
|
||||||
{
|
|
||||||
// this down() migration is auto-generated, please modify it to your needs
|
|
||||||
$this->addSql('DROP TABLE reset_password_request');
|
|
||||||
$this->addSql('CREATE TEMPORARY TABLE __temp__messenger_messages AS SELECT id, body, headers, queue_name, created_at, available_at, delivered_at FROM messenger_messages');
|
|
||||||
$this->addSql('DROP TABLE messenger_messages');
|
|
||||||
$this->addSql('CREATE TABLE messenger_messages (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, body CLOB NOT NULL, headers CLOB NOT NULL, queue_name VARCHAR(190) NOT NULL, created_at DATETIME NOT NULL --(DC2Type:datetime_immutable)
|
|
||||||
, available_at DATETIME NOT NULL --(DC2Type:datetime_immutable)
|
|
||||||
, delivered_at DATETIME DEFAULT NULL --(DC2Type:datetime_immutable)
|
|
||||||
)');
|
|
||||||
$this->addSql('INSERT INTO messenger_messages (id, body, headers, queue_name, created_at, available_at, delivered_at) SELECT id, body, headers, queue_name, created_at, available_at, delivered_at FROM __temp__messenger_messages');
|
|
||||||
$this->addSql('DROP TABLE __temp__messenger_messages');
|
|
||||||
$this->addSql('CREATE INDEX IDX_75EA56E0FB7336F0 ON messenger_messages (queue_name)');
|
|
||||||
$this->addSql('CREATE INDEX IDX_75EA56E0E3BD61CE ON messenger_messages (available_at)');
|
|
||||||
$this->addSql('CREATE INDEX IDX_75EA56E016BA31DB ON messenger_messages (delivered_at)');
|
|
||||||
$this->addSql('CREATE TEMPORARY TABLE __temp__user AS SELECT id, email, roles, password FROM "user"');
|
|
||||||
$this->addSql('DROP TABLE "user"');
|
|
||||||
$this->addSql('CREATE TABLE "user" (id BLOB NOT NULL --(DC2Type:uuid)
|
|
||||||
, email VARCHAR(255) NOT NULL, roles CLOB NOT NULL --(DC2Type:json)
|
|
||||||
, password VARCHAR(255) NOT NULL, PRIMARY KEY(id))');
|
|
||||||
$this->addSql('INSERT INTO "user" (id, email, roles, password) SELECT id, email, roles, password FROM __temp__user');
|
|
||||||
$this->addSql('DROP TABLE __temp__user');
|
|
||||||
$this->addSql('CREATE UNIQUE INDEX UNIQ_IDENTIFIER_EMAIL ON "user" (email)');
|
|
||||||
}
|
|
||||||
}
|
|
40
migrations/Version20250122182101.php
Normal file
40
migrations/Version20250122182101.php
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<?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 Version20250122182101 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('CREATE TABLE reset_password_request (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, selector VARCHAR(20) NOT NULL, hashed_token VARCHAR(100) NOT NULL, requested_at DATETIME NOT NULL, expires_at DATETIME NOT NULL, user_id INTEGER NOT NULL, CONSTRAINT FK_7CE748AA76ED395 FOREIGN KEY (user_id) REFERENCES "user" (id) NOT DEFERRABLE INITIALLY IMMEDIATE)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_7CE748AA76ED395 ON reset_password_request (user_id)');
|
||||||
|
$this->addSql('CREATE TABLE "user" (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, email VARCHAR(255) NOT NULL, roles CLOB NOT NULL, password VARCHAR(255) NOT NULL)');
|
||||||
|
$this->addSql('CREATE UNIQUE INDEX UNIQ_IDENTIFIER_EMAIL ON "user" (email)');
|
||||||
|
$this->addSql('CREATE TABLE messenger_messages (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, body CLOB NOT NULL, headers CLOB NOT NULL, queue_name VARCHAR(190) NOT NULL, created_at DATETIME NOT NULL, available_at DATETIME NOT NULL, delivered_at DATETIME DEFAULT NULL)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_75EA56E0FB7336F0 ON messenger_messages (queue_name)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_75EA56E0E3BD61CE ON messenger_messages (available_at)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_75EA56E016BA31DB ON messenger_messages (delivered_at)');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this down() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('DROP TABLE reset_password_request');
|
||||||
|
$this->addSql('DROP TABLE "user"');
|
||||||
|
$this->addSql('DROP TABLE messenger_messages');
|
||||||
|
}
|
||||||
|
}
|
31
migrations/Version20250122182130.php
Normal file
31
migrations/Version20250122182130.php
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?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 Version20250122182130 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('CREATE TABLE parent_directory (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name VARCHAR(255) NOT NULL, owner_role VARCHAR(255) NOT NULL)');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this down() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('DROP TABLE parent_directory');
|
||||||
|
}
|
||||||
|
}
|
35
migrations/Version20250122183447.php
Normal file
35
migrations/Version20250122183447.php
Normal 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 Version20250122183447 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql('ALTER TABLE user ADD COLUMN folder_role VARCHAR(255) NOT NULL');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this down() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('CREATE TEMPORARY TABLE __temp__user AS SELECT id, email, roles, password FROM "user"');
|
||||||
|
$this->addSql('DROP TABLE "user"');
|
||||||
|
$this->addSql('CREATE TABLE "user" (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, email VARCHAR(255) NOT NULL, roles CLOB NOT NULL, password VARCHAR(255) NOT NULL)');
|
||||||
|
$this->addSql('INSERT INTO "user" (id, email, roles, password) SELECT id, email, roles, password FROM __temp__user');
|
||||||
|
$this->addSql('DROP TABLE __temp__user');
|
||||||
|
$this->addSql('CREATE UNIQUE INDEX UNIQ_IDENTIFIER_EMAIL ON "user" (email)');
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||||||
namespace App\Command;
|
namespace App\Command;
|
||||||
|
|
||||||
use App\Entity\User;
|
use App\Entity\User;
|
||||||
|
use App\Enum\RoleEnum;
|
||||||
use App\Repository\UserRepository;
|
use App\Repository\UserRepository;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Symfony\Component\Console\Attribute\AsCommand;
|
use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
@ -36,6 +37,7 @@ class CreateUserCommand extends Command
|
|||||||
$email = $io->ask('Email de l\'utilisateur');
|
$email = $io->ask('Email de l\'utilisateur');
|
||||||
$password = $io->askHidden('Mot de passe de l\'utilisateur');
|
$password = $io->askHidden('Mot de passe de l\'utilisateur');
|
||||||
$isAdmin = $io->confirm('Est-ce un administrateur ?');
|
$isAdmin = $io->confirm('Est-ce un administrateur ?');
|
||||||
|
$folderRole = $io->choice('Rôle du dossier', array_map(static fn ($role) => $role->value, RoleEnum::cases()), RoleEnum::VISITEUR->value);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$user = $this->userRepository->findOneBy(['email' => $email]);
|
$user = $this->userRepository->findOneBy(['email' => $email]);
|
||||||
@ -43,19 +45,18 @@ class CreateUserCommand extends Command
|
|||||||
$io->error('Un utilisateur existe déjà avec cet email');
|
$io->error('Un utilisateur existe déjà avec cet email');
|
||||||
return Command::FAILURE;
|
return Command::FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = new User();
|
$user = new User();
|
||||||
$user->setEmail($email);
|
$user->setEmail($email);
|
||||||
$user->setPassword($this->passwordHasher->hashPassword($user, $password));
|
$user->setPassword($this->passwordHasher->hashPassword($user, $password));
|
||||||
$user->setRoles($isAdmin ? ['ROLE_ADMIN'] : ['ROLE_USER']);
|
$user->setRoles($isAdmin ? ['ROLE_ADMIN'] : ['ROLE_USER']);
|
||||||
$user->initId();
|
$user->setFolderRole(RoleEnum::from($folderRole));
|
||||||
|
|
||||||
$this->entityManager->persist($user);
|
$this->entityManager->persist($user);
|
||||||
$this->entityManager->flush();
|
$this->entityManager->flush();
|
||||||
|
|
||||||
$io->success('Utilisateur créé avec succès');
|
$io->success('Utilisateur créé avec succès');
|
||||||
} catch (\Exception) {
|
} catch (\Exception $e) {
|
||||||
$io->error('Une erreur est survenue lors de la création de l\'utilisateur');
|
$io->error('Une erreur est survenue lors de la création de l\'utilisateur : ' . $e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
return Command::SUCCESS;
|
return Command::SUCCESS;
|
||||||
|
@ -59,7 +59,6 @@ class AdminController extends AbstractController
|
|||||||
if ($form->isSubmitted() && $form->isValid()) {
|
if ($form->isSubmitted() && $form->isValid()) {
|
||||||
$role = $form->get('role')->getData();
|
$role = $form->get('role')->getData();
|
||||||
$user->setRoles([$role]);
|
$user->setRoles([$role]);
|
||||||
$user->initId();
|
|
||||||
|
|
||||||
if ($form->has('plainPassword')) {
|
if ($form->has('plainPassword')) {
|
||||||
$plainPassword = $form->get('plainPassword')->getData();
|
$plainPassword = $form->get('plainPassword')->getData();
|
||||||
|
@ -4,9 +4,14 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace App\Controller;
|
namespace App\Controller;
|
||||||
|
|
||||||
|
use App\Entity\ParentDirectory;
|
||||||
|
use App\Entity\User;
|
||||||
|
use App\Enum\RoleEnum;
|
||||||
use App\Form\CreateDirectoryType;
|
use App\Form\CreateDirectoryType;
|
||||||
use App\Form\RenameType;
|
use App\Form\RenameType;
|
||||||
use App\Form\UploadType;
|
use App\Form\UploadType;
|
||||||
|
use App\Repository\ParentDirectoryRepository;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use League\Flysystem\Filesystem;
|
use League\Flysystem\Filesystem;
|
||||||
use League\Flysystem\FilesystemException;
|
use League\Flysystem\FilesystemException;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
@ -22,21 +27,39 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
|||||||
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
||||||
|
|
||||||
#[Route('/files', 'app_files_')]
|
#[Route('/files', 'app_files_')]
|
||||||
#[IsGranted('ROLE_USER')]
|
|
||||||
class FilesController extends AbstractController
|
class FilesController extends AbstractController
|
||||||
{
|
{
|
||||||
|
public function __construct(
|
||||||
|
private readonly EntityManagerInterface $entityManager,
|
||||||
|
private readonly ParentDirectoryRepository $parentDirectoryRepository
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws FilesystemException
|
* @throws FilesystemException
|
||||||
*/
|
*/
|
||||||
#[Route('/', name: 'index')]
|
#[Route('/', name: 'index')]
|
||||||
|
#[IsGranted('ROLE_USER')]
|
||||||
public function index(Filesystem $defaultAdapter, UrlGeneratorInterface $urlGenerator, #[MapQueryParameter('path')] string $path = ''): Response
|
public function index(Filesystem $defaultAdapter, UrlGeneratorInterface $urlGenerator, #[MapQueryParameter('path')] string $path = ''): Response
|
||||||
{
|
{
|
||||||
$path = $this->normalizePath($path);
|
$path = $this->normalizePath($path);
|
||||||
|
/**
|
||||||
|
* @var User $user
|
||||||
|
*/
|
||||||
|
$user = $this->getUser();
|
||||||
|
|
||||||
if ('' !== $path && !$defaultAdapter->directoryExists($path)) {
|
if ('' !== $path) {
|
||||||
|
$parentDir = $this->parentDirectoryRepository->findOneBy(['name' => $path]);
|
||||||
|
|
||||||
|
if (null === $parentDir || !$defaultAdapter->directoryExists($path)) {
|
||||||
throw $this->createNotFoundException("Ce dossier n'existe pas !");
|
throw $this->createNotFoundException("Ce dossier n'existe pas !");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($parentDir->getOwnerRole() !== $user->getFolderRole() && !in_array($user->getFolderRole(), $parentDir->getOwnerRole()->getHigherRoles(), true)) {
|
||||||
|
throw $this->createNotFoundException("Vous n'avez pas le droit d'accéder à ce dossier !");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$files = $defaultAdapter->listContents('/' . $path);
|
$files = $defaultAdapter->listContents('/' . $path);
|
||||||
|
|
||||||
$realFiles = [];
|
$realFiles = [];
|
||||||
@ -44,6 +67,22 @@ class FilesController extends AbstractController
|
|||||||
foreach ($files as $file) {
|
foreach ($files as $file) {
|
||||||
$filename = basename((string) $file['path']);
|
$filename = basename((string) $file['path']);
|
||||||
if (!str_starts_with($filename, '.')) {
|
if (!str_starts_with($filename, '.')) {
|
||||||
|
// On vérifie si l'utilisateur a le droit d'accéder au fichier (vérifier que owner_role du parentDirectory correspondant est bien le folderRole de l'utilisateur)
|
||||||
|
$pathFile = explode('/', $file['path']);
|
||||||
|
if ('' !== $path) {
|
||||||
|
$parentDir = $this->parentDirectoryRepository->findOneBy(['name' => $pathFile[0]]);
|
||||||
|
|
||||||
|
if (null === $parentDir || ($parentDir->getOwnerRole() !== $user->getFolderRole() && !in_array($user->getFolderRole(), $parentDir->getOwnerRole()->getHigherRoles(), true))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} elseif ('file' !== $file['type']) {
|
||||||
|
$parentDir = $this->parentDirectoryRepository->findOneBy(['name' => $filename]);
|
||||||
|
|
||||||
|
if (null === $parentDir || ($parentDir->getOwnerRole() !== $user->getFolderRole() && !in_array($user->getFolderRole(), $parentDir->getOwnerRole()->getHigherRoles(), true))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$realFiles[] = [
|
$realFiles[] = [
|
||||||
'type' => $file['type'],
|
'type' => $file['type'],
|
||||||
'path' => $file['path'],
|
'path' => $file['path'],
|
||||||
@ -70,10 +109,34 @@ class FilesController extends AbstractController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws FilesystemException
|
||||||
|
*/
|
||||||
#[Route('/file-proxy', name: 'app_file_proxy')]
|
#[Route('/file-proxy', name: 'app_file_proxy')]
|
||||||
public function fileProxy(Filesystem $defaultAdapter, #[MapQueryParameter('filename')] string $filename)
|
public function fileProxy(Filesystem $defaultAdapter, #[MapQueryParameter('filename')] string $filename)
|
||||||
{
|
{
|
||||||
$file = $this->normalizePath($filename);
|
$file = $this->normalizePath($filename);
|
||||||
|
|
||||||
|
$parentDir = $this->parentDirectoryRepository->findOneBy(['name' => explode('/', $file)[0]]);
|
||||||
|
|
||||||
|
if (null === $parentDir) {
|
||||||
|
throw $this->createNotFoundException("Vous n'avez pas le droit d'accéder à ce fichier !");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Si l'owner role sur le parent est visiteur, on peut accéder au fichier sans être connecté
|
||||||
|
if (RoleEnum::VISITEUR !== $parentDir->getOwnerRole()) {
|
||||||
|
$this->denyAccessUnlessGranted('ROLE_USER');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var User $user
|
||||||
|
*/
|
||||||
|
$user = $this->getUser();
|
||||||
|
|
||||||
|
if ($parentDir->getOwnerRole() !== $user->getFolderRole() && !in_array($user->getFolderRole(), $parentDir->getOwnerRole()->getHigherRoles(), true)) {
|
||||||
|
throw $this->createNotFoundException("Vous n'avez pas le droit d'accéder à ce fichier !");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$mimetype = $defaultAdapter->mimeType($file);
|
$mimetype = $defaultAdapter->mimeType($file);
|
||||||
if ('' === $mimetype) {
|
if ('' === $mimetype) {
|
||||||
$mimetype = 'application/octet-stream';
|
$mimetype = 'application/octet-stream';
|
||||||
@ -99,10 +162,25 @@ class FilesController extends AbstractController
|
|||||||
* @throws FilesystemException
|
* @throws FilesystemException
|
||||||
*/
|
*/
|
||||||
#[Route('/file-delete', name: 'delete')]
|
#[Route('/file-delete', name: 'delete')]
|
||||||
|
#[IsGranted('ROLE_USER')]
|
||||||
public function fileDelete(Filesystem $defaultAdapter, #[MapQueryParameter('filename')] string $filename): RedirectResponse
|
public function fileDelete(Filesystem $defaultAdapter, #[MapQueryParameter('filename')] string $filename): RedirectResponse
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var User $user
|
||||||
|
*/
|
||||||
|
$user = $this->getUser();
|
||||||
$file = $this->normalizePath($filename);
|
$file = $this->normalizePath($filename);
|
||||||
|
|
||||||
|
$realPath = explode('/', $file);
|
||||||
|
|
||||||
|
if (count($realPath) > 1) {
|
||||||
|
$parentDir = $this->parentDirectoryRepository->findOneBy(['name' => $realPath[0]]);
|
||||||
|
|
||||||
|
if (null === $parentDir || ($parentDir->getOwnerRole() !== $user->getFolderRole() && !in_array($user->getFolderRole(), $parentDir->getOwnerRole()->getHigherRoles(), true))) {
|
||||||
|
throw $this->createNotFoundException("Vous n'avez pas le droit de supprimer ce fichier !");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ('' !== $file && !str_starts_with($file, '.') && $defaultAdapter->fileExists($file)) {
|
if ('' !== $file && !str_starts_with($file, '.') && $defaultAdapter->fileExists($file)) {
|
||||||
$defaultAdapter->delete($file);
|
$defaultAdapter->delete($file);
|
||||||
|
|
||||||
@ -120,9 +198,21 @@ class FilesController extends AbstractController
|
|||||||
* @throws FilesystemException
|
* @throws FilesystemException
|
||||||
*/
|
*/
|
||||||
#[Route('/directory-delete', name: 'delete_directory')]
|
#[Route('/directory-delete', name: 'delete_directory')]
|
||||||
|
#[IsGranted('ROLE_USER')]
|
||||||
public function directoryDelete(Filesystem $defaultAdapter, #[MapQueryParameter('path')] string $path): RedirectResponse
|
public function directoryDelete(Filesystem $defaultAdapter, #[MapQueryParameter('path')] string $path): RedirectResponse
|
||||||
{
|
{
|
||||||
$path = $this->normalizePath($path);
|
$path = $this->normalizePath($path);
|
||||||
|
/**
|
||||||
|
* @var User $user
|
||||||
|
*/
|
||||||
|
$user = $this->getUser();
|
||||||
|
|
||||||
|
$realPath = explode('/', $path);
|
||||||
|
$parentDir = $this->parentDirectoryRepository->findOneBy(['name' => $realPath[0]]);
|
||||||
|
|
||||||
|
if (null === $parentDir || ($parentDir->getOwnerRole() !== $user->getFolderRole() && !in_array($user->getFolderRole(), $parentDir->getOwnerRole()->getHigherRoles(), true))) {
|
||||||
|
throw $this->createNotFoundException("Vous n'avez pas le droit de supprimer ce dossier !");
|
||||||
|
}
|
||||||
|
|
||||||
if ('' !== $path && !str_starts_with($path, '.') && $defaultAdapter->directoryExists($path)) {
|
if ('' !== $path && !str_starts_with($path, '.') && $defaultAdapter->directoryExists($path)) {
|
||||||
$defaultAdapter->deleteDirectory($path);
|
$defaultAdapter->deleteDirectory($path);
|
||||||
@ -141,14 +231,29 @@ class FilesController extends AbstractController
|
|||||||
* @throws FilesystemException
|
* @throws FilesystemException
|
||||||
*/
|
*/
|
||||||
#[Route('/rename', name: 'rename')]
|
#[Route('/rename', name: 'rename')]
|
||||||
|
#[IsGranted('ROLE_USER')]
|
||||||
public function rename(#[MapQueryParameter('path')] string $filepath, Request $request, Filesystem $defaultAdapter): Response
|
public function rename(#[MapQueryParameter('path')] string $filepath, Request $request, Filesystem $defaultAdapter): Response
|
||||||
{
|
{
|
||||||
$filepath = $this->normalizePath($filepath);
|
$filepath = $this->normalizePath($filepath);
|
||||||
|
/**
|
||||||
|
* @var User $user
|
||||||
|
*/
|
||||||
|
$user = $this->getUser();
|
||||||
|
|
||||||
if ('' === $filepath || str_starts_with($filepath, '.') || !$defaultAdapter->fileExists($filepath)) {
|
if ('' === $filepath || str_starts_with($filepath, '.') || !$defaultAdapter->fileExists($filepath)) {
|
||||||
throw $this->createNotFoundException("Ce fichier n'existe pas !");
|
throw $this->createNotFoundException("Ce fichier n'existe pas !");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$realPath = explode('/', $filepath);
|
||||||
|
|
||||||
|
if (count($realPath) > 1) {
|
||||||
|
$parentDir = $this->parentDirectoryRepository->findOneBy(['name' => $realPath[0]]);
|
||||||
|
|
||||||
|
if (null === $parentDir || ($parentDir->getOwnerRole() !== $user->getFolderRole() && !in_array($user->getFolderRole(), $parentDir->getOwnerRole()->getHigherRoles(), true))) {
|
||||||
|
throw $this->createNotFoundException("Vous n'avez pas le droit de renommer ce fichier !");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'newName' => pathinfo($filepath, PATHINFO_BASENAME),
|
'newName' => pathinfo($filepath, PATHINFO_BASENAME),
|
||||||
];
|
];
|
||||||
@ -183,9 +288,22 @@ class FilesController extends AbstractController
|
|||||||
* @throws FilesystemException
|
* @throws FilesystemException
|
||||||
*/
|
*/
|
||||||
#[Route('/create-directory', name: 'create_directory')]
|
#[Route('/create-directory', name: 'create_directory')]
|
||||||
|
#[IsGranted('ROLE_USER')]
|
||||||
public function createDirectory(Request $request, Filesystem $defaultAdapter, #[MapQueryParameter('base')] string $basePath): Response
|
public function createDirectory(Request $request, Filesystem $defaultAdapter, #[MapQueryParameter('base')] string $basePath): Response
|
||||||
{
|
{
|
||||||
$basePath = $this->normalizePath($basePath);
|
$basePath = $this->normalizePath($basePath);
|
||||||
|
$realPath = explode('/', $basePath);
|
||||||
|
/**
|
||||||
|
* @var User $user
|
||||||
|
*/
|
||||||
|
$user = $this->getUser();
|
||||||
|
|
||||||
|
if (count($realPath) > 1) {
|
||||||
|
$parentDir = $this->parentDirectoryRepository->findOneBy(['name' => $realPath[0]]);
|
||||||
|
if (null === $parentDir || ($parentDir->getOwnerRole() !== $user->getFolderRole() && !in_array($user->getFolderRole(), $parentDir->getOwnerRole()->getHigherRoles(), true))) {
|
||||||
|
throw $this->createNotFoundException("Vous n'avez pas le droit de créer de sous-dossier dans ce dossier !");
|
||||||
|
}
|
||||||
|
}
|
||||||
$form = $this->createForm(CreateDirectoryType::class);
|
$form = $this->createForm(CreateDirectoryType::class);
|
||||||
|
|
||||||
$form->handleRequest($request);
|
$form->handleRequest($request);
|
||||||
@ -195,10 +313,36 @@ class FilesController extends AbstractController
|
|||||||
|
|
||||||
$name = $data['name'];
|
$name = $data['name'];
|
||||||
|
|
||||||
|
if (explode('/', $name) > 1) {
|
||||||
|
$name = explode('/', $name)[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($defaultAdapter->directoryExists($basePath . '/' . $name)) {
|
||||||
|
$this->addFlash('error', 'Le dossier existe déjà.');
|
||||||
|
|
||||||
|
return $this->redirectToRoute('app_files_index', [
|
||||||
|
'path' => $basePath,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
$defaultAdapter->createDirectory($basePath . '/' . $name);
|
$defaultAdapter->createDirectory($basePath . '/' . $name);
|
||||||
|
|
||||||
$defaultAdapter->write($basePath . '/' . $name . '/.gitkeep', '');
|
$defaultAdapter->write($basePath . '/' . $name . '/.gitkeep', '');
|
||||||
|
|
||||||
|
// si basePath est vide, on crée un parentDirectory
|
||||||
|
if ('' === $basePath) {
|
||||||
|
/**
|
||||||
|
* @var User $user
|
||||||
|
*/
|
||||||
|
$user = $this->getUser();
|
||||||
|
$parentDirectory = new ParentDirectory();
|
||||||
|
$parentDirectory->setName($name);
|
||||||
|
$parentDirectory->setOwnerRole($user->getFolderRole());
|
||||||
|
|
||||||
|
$this->entityManager->persist($parentDirectory);
|
||||||
|
$this->entityManager->flush();
|
||||||
|
}
|
||||||
|
|
||||||
$this->addFlash('success', 'Le dossier a bien été créé.');
|
$this->addFlash('success', 'Le dossier a bien été créé.');
|
||||||
|
|
||||||
return $this->redirectToRoute('app_files_index', [
|
return $this->redirectToRoute('app_files_index', [
|
||||||
@ -216,9 +360,21 @@ class FilesController extends AbstractController
|
|||||||
* @throws FilesystemException
|
* @throws FilesystemException
|
||||||
*/
|
*/
|
||||||
#[Route('/rename-directory', name: 'rename-directory')]
|
#[Route('/rename-directory', name: 'rename-directory')]
|
||||||
|
#[IsGranted('ROLE_USER')]
|
||||||
public function renameDirectory(#[MapQueryParameter('path')] string $filepath, Request $request, Filesystem $defaultAdapter): Response
|
public function renameDirectory(#[MapQueryParameter('path')] string $filepath, Request $request, Filesystem $defaultAdapter): Response
|
||||||
{
|
{
|
||||||
$filepath = $this->normalizePath($filepath);
|
$filepath = $this->normalizePath($filepath);
|
||||||
|
/**
|
||||||
|
* @var User $user
|
||||||
|
*/
|
||||||
|
$user = $this->getUser();
|
||||||
|
|
||||||
|
$realPath = explode('/', $filepath);
|
||||||
|
$parentDir = $this->parentDirectoryRepository->findOneBy(['name' => $realPath[0]]);
|
||||||
|
|
||||||
|
if (null === $parentDir || ($parentDir->getOwnerRole() !== $user->getFolderRole() && !in_array($user->getFolderRole(), $parentDir->getOwnerRole()->getHigherRoles(), true))) {
|
||||||
|
throw $this->createNotFoundException("Vous n'avez pas le droit de renommer ce dossier !");
|
||||||
|
}
|
||||||
|
|
||||||
if ('' === $filepath || str_starts_with($filepath, '.') || !$defaultAdapter->directoryExists($filepath)) {
|
if ('' === $filepath || str_starts_with($filepath, '.') || !$defaultAdapter->directoryExists($filepath)) {
|
||||||
throw $this->createNotFoundException("Ce dossier n'existe pas !");
|
throw $this->createNotFoundException("Ce dossier n'existe pas !");
|
||||||
@ -258,13 +414,30 @@ class FilesController extends AbstractController
|
|||||||
* @throws FilesystemException
|
* @throws FilesystemException
|
||||||
*/
|
*/
|
||||||
#[Route('/upload', name: 'upload')]
|
#[Route('/upload', name: 'upload')]
|
||||||
|
#[IsGranted('ROLE_USER')]
|
||||||
public function upload(#[MapQueryParameter('path')] string $path, Request $request, Filesystem $defaultAdapter): Response
|
public function upload(#[MapQueryParameter('path')] string $path, Request $request, Filesystem $defaultAdapter): Response
|
||||||
{
|
{
|
||||||
$path = $this->normalizePath($path);
|
$path = $this->normalizePath($path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var User $user
|
||||||
|
*/
|
||||||
|
$user = $this->getUser();
|
||||||
|
|
||||||
|
if ('' === $path) {
|
||||||
|
throw $this->createNotFoundException("Vous ne pouvez pas uploader de fichier à la racine !");
|
||||||
|
}
|
||||||
|
|
||||||
|
$realPath = explode('/', $path);
|
||||||
|
$parentDir = $this->parentDirectoryRepository->findOneBy(['name' => $realPath[0]]);
|
||||||
|
|
||||||
|
if (null === $parentDir || ($parentDir->getOwnerRole() !== $user->getFolderRole() && !in_array($user->getFolderRole(), $parentDir->getOwnerRole()->getHigherRoles(), true))) {
|
||||||
|
throw $this->createNotFoundException("Vous n'avez pas le droit d'uploader des fichiers dans ce dossier !");
|
||||||
|
}
|
||||||
|
|
||||||
$form = $this->createForm(UploadType::class);
|
$form = $this->createForm(UploadType::class);
|
||||||
|
|
||||||
if ('' !== $path && !$defaultAdapter->directoryExists($path)) {
|
if (!$defaultAdapter->directoryExists($path)) {
|
||||||
throw $this->createNotFoundException("Ce dossier n'existe pas !");
|
throw $this->createNotFoundException("Ce dossier n'existe pas !");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
51
src/Entity/ParentDirectory.php
Normal file
51
src/Entity/ParentDirectory.php
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Entity;
|
||||||
|
|
||||||
|
use App\Enum\RoleEnum;
|
||||||
|
use App\Repository\ParentDirectoryRepository;
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
|
||||||
|
#[ORM\Entity(repositoryClass: ParentDirectoryRepository::class)]
|
||||||
|
class ParentDirectory
|
||||||
|
{
|
||||||
|
#[ORM\Id]
|
||||||
|
#[ORM\GeneratedValue]
|
||||||
|
#[ORM\Column]
|
||||||
|
private ?int $id = null;
|
||||||
|
|
||||||
|
#[ORM\Column(length: 255)]
|
||||||
|
private ?string $name = null;
|
||||||
|
|
||||||
|
#[ORM\Column(enumType: RoleEnum::class)]
|
||||||
|
private ?RoleEnum $ownerRole = null;
|
||||||
|
|
||||||
|
public function getId(): ?int
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(): ?string
|
||||||
|
{
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setName(string $name): static
|
||||||
|
{
|
||||||
|
$this->name = $name;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getOwnerRole(): ?RoleEnum
|
||||||
|
{
|
||||||
|
return $this->ownerRole;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setOwnerRole(RoleEnum $ownerRole): static
|
||||||
|
{
|
||||||
|
$this->ownerRole = $ownerRole;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace App\Entity;
|
namespace App\Entity;
|
||||||
|
|
||||||
|
use App\Enum\RoleEnum;
|
||||||
use App\Repository\UserRepository;
|
use App\Repository\UserRepository;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||||
@ -18,8 +19,9 @@ use Symfony\Component\Uid\Uuid;
|
|||||||
class User implements UserInterface, PasswordAuthenticatedUserInterface
|
class User implements UserInterface, PasswordAuthenticatedUserInterface
|
||||||
{
|
{
|
||||||
#[ORM\Id]
|
#[ORM\Id]
|
||||||
#[ORM\Column(type: 'uuid', length: 180)]
|
#[ORM\GeneratedValue]
|
||||||
private ?Uuid $id = null;
|
#[ORM\Column]
|
||||||
|
private ?int $id = null;
|
||||||
|
|
||||||
#[ORM\Column(length: 255)]
|
#[ORM\Column(length: 255)]
|
||||||
private ?string $email = null;
|
private ?string $email = null;
|
||||||
@ -36,16 +38,13 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
|
|||||||
#[ORM\Column]
|
#[ORM\Column]
|
||||||
private ?string $password = null;
|
private ?string $password = null;
|
||||||
|
|
||||||
public function initId(): void
|
#[ORM\Column(enumType: RoleEnum::class)]
|
||||||
{
|
private ?RoleEnum $folder_role = null;
|
||||||
if ($this->id instanceof \Symfony\Component\Uid\Uuid) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->id = Uuid::v4();
|
/**
|
||||||
}
|
* @return int|null
|
||||||
|
*/
|
||||||
public function getId(): ?Uuid
|
public function getId(): ?int
|
||||||
{
|
{
|
||||||
return $this->id;
|
return $this->id;
|
||||||
}
|
}
|
||||||
@ -119,4 +118,16 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
|
|||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getFolderRole(): ?RoleEnum
|
||||||
|
{
|
||||||
|
return $this->folder_role;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setFolderRole(RoleEnum $folder_role): static
|
||||||
|
{
|
||||||
|
$this->folder_role = $folder_role;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
35
src/Enum/RoleEnum.php
Normal file
35
src/Enum/RoleEnum.php
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Enum;
|
||||||
|
|
||||||
|
enum RoleEnum: string
|
||||||
|
{
|
||||||
|
case CONSEIL_ADMINISTRATION = 'Conseil d\'administration';
|
||||||
|
case ADMINISTRATEUR = 'Administrateur';
|
||||||
|
case MEMBRE = 'Membre';
|
||||||
|
case MEMBRE_HONORAIRE = 'Membre honoraire';
|
||||||
|
case PARTENAIRE = 'Partenaire';
|
||||||
|
case VISITEUR = 'Visiteur';
|
||||||
|
|
||||||
|
public function getHigherRoles(): array
|
||||||
|
{
|
||||||
|
$roles = [];
|
||||||
|
|
||||||
|
$isFound = false;
|
||||||
|
foreach (RoleEnum::cases() as $role) {
|
||||||
|
if ($role === $this) {
|
||||||
|
$isFound = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($isFound) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$roles[] = $role;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $roles;
|
||||||
|
}
|
||||||
|
}
|
43
src/Repository/ParentDirectoryRepository.php
Normal file
43
src/Repository/ParentDirectoryRepository.php
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Repository;
|
||||||
|
|
||||||
|
use App\Entity\ParentDirectory;
|
||||||
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends ServiceEntityRepository<ParentDirectory>
|
||||||
|
*/
|
||||||
|
class ParentDirectoryRepository extends ServiceEntityRepository
|
||||||
|
{
|
||||||
|
public function __construct(ManagerRegistry $registry)
|
||||||
|
{
|
||||||
|
parent::__construct($registry, ParentDirectory::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @return ParentDirectory[] Returns an array of ParentDirectory 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): ?ParentDirectory
|
||||||
|
// {
|
||||||
|
// return $this->createQueryBuilder('p')
|
||||||
|
// ->andWhere('p.exampleField = :val')
|
||||||
|
// ->setParameter('val', $value)
|
||||||
|
// ->getQuery()
|
||||||
|
// ->getOneOrNullResult()
|
||||||
|
// ;
|
||||||
|
// }
|
||||||
|
}
|
@ -12,9 +12,11 @@
|
|||||||
<a href="{{ path('app_files_create_directory', {
|
<a href="{{ path('app_files_create_directory', {
|
||||||
base: path
|
base: path
|
||||||
}) }}" class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 me-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800">Créer un dossier</a>
|
}) }}" class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 me-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800">Créer un dossier</a>
|
||||||
|
{% if path != '' %}
|
||||||
<a href="{{ path('app_files_upload', {
|
<a href="{{ path('app_files_upload', {
|
||||||
path: path
|
path: path
|
||||||
}) }}" class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 me-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800">Ajouter des fichiers</a>
|
}) }}" class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 me-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800">Ajouter des fichiers</a>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
{% include 'partials/breadbrumb.html.twig' %}
|
{% include 'partials/breadbrumb.html.twig' %}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user