modalité uploder des ficher avec VichUploaderBundle
This commit is contained in:
@@ -21,7 +21,8 @@
|
||||
"symfony/translation": "8.0.*",
|
||||
"symfony/twig-bundle": "8.0.*",
|
||||
"symfony/validator": "8.0.*",
|
||||
"symfony/yaml": "8.0.*"
|
||||
"symfony/yaml": "8.0.*",
|
||||
"vich/uploader-bundle": "^2.9"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/maker-bundle": "^1.65",
|
||||
|
||||
347
composer.lock
generated
347
composer.lock
generated
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "a65a9ed16594341ca6c22d4c6316bce1",
|
||||
"content-hash": "754cd146956f25fd7cf8b7b7a01e4aa3",
|
||||
"packages": [
|
||||
{
|
||||
"name": "doctrine/collections",
|
||||
@@ -1120,6 +1120,70 @@
|
||||
},
|
||||
"time": "2025-10-26T09:35:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "jms/metadata",
|
||||
"version": "2.9.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/schmittjoh/metadata.git",
|
||||
"reference": "554319d2e5f0c5d8ccaeffe755eac924e14da330"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/schmittjoh/metadata/zipball/554319d2e5f0c5d8ccaeffe755eac924e14da330",
|
||||
"reference": "554319d2e5f0c5d8ccaeffe755eac924e14da330",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/cache": "^1.0|^2.0",
|
||||
"doctrine/coding-standard": "^8.0",
|
||||
"mikey179/vfsstream": "^1.6.7",
|
||||
"phpunit/phpunit": "^8.5.42|^9.6.23",
|
||||
"psr/container": "^1.0|^2.0",
|
||||
"symfony/cache": "^3.1|^4.0|^5.0|^6.0|^7.0|^8.0",
|
||||
"symfony/dependency-injection": "^3.1|^4.0|^5.0|^6.0|^7.0|^8.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Metadata\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Johannes M. Schmitt",
|
||||
"email": "schmittjoh@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Asmir Mustafic",
|
||||
"email": "goetas@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Class/method/property metadata management in PHP",
|
||||
"keywords": [
|
||||
"annotations",
|
||||
"metadata",
|
||||
"xml",
|
||||
"yaml"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/schmittjoh/metadata/issues",
|
||||
"source": "https://github.com/schmittjoh/metadata/tree/2.9.0"
|
||||
},
|
||||
"time": "2025-11-30T20:12:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/cache",
|
||||
"version": "3.0.0",
|
||||
@@ -3057,6 +3121,92 @@
|
||||
],
|
||||
"time": "2025-12-08T07:59:34+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/mime",
|
||||
"version": "v8.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/mime.git",
|
||||
"reference": "7576ce3b2b4d3a2a7fe7020a07a392065d6ffd40"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/mime/zipball/7576ce3b2b4d3a2a7fe7020a07a392065d6ffd40",
|
||||
"reference": "7576ce3b2b4d3a2a7fe7020a07a392065d6ffd40",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.4",
|
||||
"symfony/polyfill-intl-idn": "^1.10",
|
||||
"symfony/polyfill-mbstring": "^1.0"
|
||||
},
|
||||
"conflict": {
|
||||
"egulias/email-validator": "~3.0.0",
|
||||
"phpdocumentor/reflection-docblock": "<3.2.2",
|
||||
"phpdocumentor/type-resolver": "<1.4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"egulias/email-validator": "^2.1.10|^3.1|^4",
|
||||
"league/html-to-markdown": "^5.0",
|
||||
"phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0",
|
||||
"symfony/dependency-injection": "^7.4|^8.0",
|
||||
"symfony/process": "^7.4|^8.0",
|
||||
"symfony/property-access": "^7.4|^8.0",
|
||||
"symfony/property-info": "^7.4|^8.0",
|
||||
"symfony/serializer": "^7.4|^8.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\Mime\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Allows manipulating MIME messages",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"mime",
|
||||
"mime-type"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/mime/tree/v8.0.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-11-16T10:17:21+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/options-resolver",
|
||||
"version": "v8.0.0",
|
||||
@@ -3371,6 +3521,93 @@
|
||||
],
|
||||
"time": "2025-06-20T22:24:30+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-intl-idn",
|
||||
"version": "v1.33.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-intl-idn.git",
|
||||
"reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/9614ac4d8061dc257ecc64cba1b140873dce8ad3",
|
||||
"reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2",
|
||||
"symfony/polyfill-intl-normalizer": "^1.10"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-intl": "For best performance"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"url": "https://github.com/symfony/polyfill",
|
||||
"name": "symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Intl\\Idn\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Laurent Bassin",
|
||||
"email": "laurent@bassin.info"
|
||||
},
|
||||
{
|
||||
"name": "Trevor Rowbotham",
|
||||
"email": "trevor.rowbotham@pm.me"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"idn",
|
||||
"intl",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.33.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-09-10T14:38:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-intl-normalizer",
|
||||
"version": "v1.33.0",
|
||||
@@ -5395,6 +5632,114 @@
|
||||
}
|
||||
],
|
||||
"time": "2025-12-14T11:28:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "vich/uploader-bundle",
|
||||
"version": "v2.9.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dustin10/VichUploaderBundle.git",
|
||||
"reference": "945939a04a33c0b78c5fbb7ead31533d85112df5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/dustin10/VichUploaderBundle/zipball/945939a04a33c0b78c5fbb7ead31533d85112df5",
|
||||
"reference": "945939a04a33c0b78c5fbb7ead31533d85112df5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/persistence": "^3.0 || ^4.0",
|
||||
"ext-simplexml": "*",
|
||||
"jms/metadata": "^2.4",
|
||||
"php": "^8.1",
|
||||
"symfony/config": "^5.4 || ^6.0 || ^7.0 || ^8.0",
|
||||
"symfony/console": "^5.4 || ^6.0 || ^7.0 || ^8.0",
|
||||
"symfony/dependency-injection": "^5.4 || ^6.0 || ^7.0 || ^8.0",
|
||||
"symfony/event-dispatcher-contracts": "^3.1",
|
||||
"symfony/http-foundation": "^5.4 || ^6.0 || ^7.0 || ^8.0",
|
||||
"symfony/http-kernel": "^5.4 || ^6.0 || ^7.0 || ^8.0",
|
||||
"symfony/mime": "^5.4 || ^6.0 || ^7.0 || ^8.0",
|
||||
"symfony/property-access": "^5.4 || ^6.0 || ^7.0 || ^8.0",
|
||||
"symfony/string": "^5.4 || ^6.0 || ^7.0 || ^8.0"
|
||||
},
|
||||
"conflict": {
|
||||
"doctrine/annotations": "<1.12",
|
||||
"league/flysystem": "<2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"dg/bypass-finals": "^1.9",
|
||||
"doctrine/common": "^3.0",
|
||||
"doctrine/doctrine-bundle": "^2.7 || ^3.0",
|
||||
"doctrine/mongodb-odm": "^2.4",
|
||||
"doctrine/orm": "^2.13 || ^3.0",
|
||||
"ext-sqlite3": "*",
|
||||
"knplabs/knp-gaufrette-bundle": "dev-master",
|
||||
"league/flysystem-bundle": "^2.4 || ^3.0",
|
||||
"league/flysystem-memory": "^2.0 || ^3.0",
|
||||
"matthiasnoback/symfony-dependency-injection-test": "^5.1 || ^6.0",
|
||||
"mikey179/vfsstream": "^1.6.11",
|
||||
"phpunit/phpunit": "^10.5 || ^11.5 || ^12.2",
|
||||
"symfony/asset": "^5.4 || ^6.0 || ^7.0 || ^8.0",
|
||||
"symfony/browser-kit": "^5.4 || ^6.0 || ^7.0 || ^8.0",
|
||||
"symfony/css-selector": "^5.4 || ^6.0 || ^7.0 || ^8.0",
|
||||
"symfony/doctrine-bridge": "^5.4 || ^6.0 || ^7.0 || ^8.0",
|
||||
"symfony/dom-crawler": "^5.4 || ^6.0 || ^7.0 || ^8.0",
|
||||
"symfony/form": "^5.4 || ^6.0 || ^7.0 || ^8.0",
|
||||
"symfony/framework-bundle": "^5.4 || ^6.0 || ^7.0 || ^8.0",
|
||||
"symfony/phpunit-bridge": "^7.3",
|
||||
"symfony/security-csrf": "^5.4 || ^6.0 || ^7.0 || ^8.0",
|
||||
"symfony/translation": "^5.4 || ^6.0 || ^7.0 || ^8.0",
|
||||
"symfony/twig-bridge": "^5.4 || ^6.0 || ^7.0 || ^8.0",
|
||||
"symfony/twig-bundle": "^5.4 || ^6.0 || ^7.0 || ^8.0",
|
||||
"symfony/validator": "^5.4.22 || ^6.0 || ^7.0 || ^8.0",
|
||||
"symfony/var-dumper": "^5.4 || ^6.0 || ^7.0 || ^8.0",
|
||||
"symfony/yaml": "^5.4 || ^6.0 || ^7.0 || ^8.0"
|
||||
},
|
||||
"suggest": {
|
||||
"doctrine/doctrine-bundle": "For integration with Doctrine",
|
||||
"doctrine/mongodb-odm-bundle": "For integration with Doctrine ODM",
|
||||
"doctrine/orm": "For integration with Doctrine ORM",
|
||||
"doctrine/phpcr-odm": "For integration with Doctrine PHPCR",
|
||||
"knplabs/knp-gaufrette-bundle": "For integration with Gaufrette",
|
||||
"league/flysystem-bundle": "For integration with Flysystem",
|
||||
"liip/imagine-bundle": "To generate image thumbnails",
|
||||
"oneup/flysystem-bundle": "For integration with Flysystem",
|
||||
"symfony/asset": "To generate better links",
|
||||
"symfony/form": "To handle uploads in forms",
|
||||
"symfony/yaml": "To use YAML mapping"
|
||||
},
|
||||
"type": "symfony-bundle",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Vich\\UploaderBundle\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Dustin Dobervich",
|
||||
"email": "ddobervich@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Ease file uploads attached to entities",
|
||||
"homepage": "https://github.com/dustin10/VichUploaderBundle",
|
||||
"keywords": [
|
||||
"file uploads",
|
||||
"upload"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/dustin10/VichUploaderBundle/issues",
|
||||
"source": "https://github.com/dustin10/VichUploaderBundle/tree/v2.9.1"
|
||||
},
|
||||
"time": "2025-12-10T08:23:38+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
|
||||
@@ -8,4 +8,5 @@ return [
|
||||
Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true],
|
||||
Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
|
||||
Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
|
||||
Vich\UploaderBundle\VichUploaderBundle::class => ['all' => true],
|
||||
];
|
||||
|
||||
0
config/packages/csrf.yaml
Normal file → Executable file
0
config/packages/csrf.yaml
Normal file → Executable file
15
config/packages/vich_uploader.yaml
Executable file
15
config/packages/vich_uploader.yaml
Executable file
@@ -0,0 +1,15 @@
|
||||
vich_uploader:
|
||||
db_driver: orm
|
||||
|
||||
mappings:
|
||||
attachments:
|
||||
uri_prefix: /uploads/questions
|
||||
upload_destination: '%kernel.project_dir%/public/uploads/questions'
|
||||
namer: Vich\UploaderBundle\Naming\UniqidNamer
|
||||
directory_namer: ~
|
||||
|
||||
inject_on_load: false
|
||||
delete_on_update: true
|
||||
delete_on_remove: true
|
||||
# Optionnel : pour générer des URLs absolues
|
||||
# uri_prefix_absolute: true
|
||||
@@ -1242,6 +1242,44 @@ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||||
* intercept_redirects?: bool, // Default: false
|
||||
* excluded_ajax_paths?: scalar|null, // Default: "^/((index|app(_[\\w]+)?)\\.php/)?_wdt"
|
||||
* }
|
||||
* @psalm-type VichUploaderConfig = array{
|
||||
* default_filename_attribute_suffix?: scalar|null, // Default: "_name"
|
||||
* db_driver: scalar|null,
|
||||
* storage?: scalar|null, // Default: "file_system"
|
||||
* use_flysystem_to_resolve_uri?: bool, // Default: false
|
||||
* twig?: scalar|null, // twig requires templating // Default: true
|
||||
* form?: scalar|null, // Default: true
|
||||
* metadata?: array{
|
||||
* cache?: scalar|null, // Default: "file"
|
||||
* type?: scalar|null, // Default: "attribute"
|
||||
* file_cache?: array{
|
||||
* dir?: scalar|null, // Default: "%kernel.cache_dir%/vich_uploader"
|
||||
* },
|
||||
* auto_detection?: bool, // Default: true
|
||||
* directories?: list<array{ // Default: []
|
||||
* path: scalar|null,
|
||||
* namespace_prefix?: scalar|null, // Default: ""
|
||||
* }>,
|
||||
* },
|
||||
* mappings?: array<string, array{ // Default: []
|
||||
* uri_prefix?: scalar|null, // Default: "/uploads"
|
||||
* upload_destination?: scalar|null, // Default: null
|
||||
* namer?: string|array{
|
||||
* service?: scalar|null, // Default: null
|
||||
* options?: mixed, // Default: null
|
||||
* },
|
||||
* directory_namer?: string|array{
|
||||
* service?: scalar|null, // Default: null
|
||||
* options?: mixed, // Default: null
|
||||
* },
|
||||
* delete_on_remove?: scalar|null, // Default: true
|
||||
* erase_fields?: scalar|null, // Default: true
|
||||
* delete_on_update?: scalar|null, // Default: true
|
||||
* inject_on_load?: scalar|null, // Default: false
|
||||
* namer_keep_extension?: scalar|null, // Default: false
|
||||
* db_driver?: scalar|null, // Default: null
|
||||
* }>,
|
||||
* }
|
||||
* @psalm-type ConfigType = array{
|
||||
* imports?: ImportsConfig,
|
||||
* parameters?: ParametersConfig,
|
||||
@@ -1251,6 +1289,7 @@ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||||
* doctrine?: DoctrineConfig,
|
||||
* doctrine_migrations?: DoctrineMigrationsConfig,
|
||||
* security?: SecurityConfig,
|
||||
* vich_uploader?: VichUploaderConfig,
|
||||
* "when@dev"?: array{
|
||||
* imports?: ImportsConfig,
|
||||
* parameters?: ParametersConfig,
|
||||
@@ -1262,6 +1301,7 @@ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||||
* doctrine_migrations?: DoctrineMigrationsConfig,
|
||||
* security?: SecurityConfig,
|
||||
* web_profiler?: WebProfilerConfig,
|
||||
* vich_uploader?: VichUploaderConfig,
|
||||
* },
|
||||
* "when@prod"?: array{
|
||||
* imports?: ImportsConfig,
|
||||
@@ -1272,6 +1312,7 @@ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||||
* doctrine?: DoctrineConfig,
|
||||
* doctrine_migrations?: DoctrineMigrationsConfig,
|
||||
* security?: SecurityConfig,
|
||||
* vich_uploader?: VichUploaderConfig,
|
||||
* },
|
||||
* "when@test"?: array{
|
||||
* imports?: ImportsConfig,
|
||||
@@ -1283,6 +1324,7 @@ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||||
* doctrine_migrations?: DoctrineMigrationsConfig,
|
||||
* security?: SecurityConfig,
|
||||
* web_profiler?: WebProfilerConfig,
|
||||
* vich_uploader?: VichUploaderConfig,
|
||||
* },
|
||||
* ...<string, ExtensionType|array{ // extra keys must follow the when@%env% pattern or match an extension alias
|
||||
* imports?: ImportsConfig,
|
||||
|
||||
BIN
public/uploads/questions/6963c1f65cda2478279420.jpg
Normal file
BIN
public/uploads/questions/6963c1f65cda2478279420.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 MiB |
@@ -13,7 +13,7 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
use App\Entity\State;
|
||||
use App\Entity\Question;
|
||||
use App\Entity\Investigation;
|
||||
|
||||
use App\Repository\StateRepository;
|
||||
@@ -68,6 +68,16 @@ final class InvestigationController extends AbstractController
|
||||
$investigation = $form->getData();
|
||||
$investigation->setCreateBy($this->getUser());
|
||||
|
||||
;
|
||||
foreach($investigation->getQuestions() as $question){
|
||||
foreach ($question->getAttachments() as $attachment) {
|
||||
if ($attachment->getFile()) {
|
||||
// Optionnel : calculer les dimensions pour les images
|
||||
$attachment->setDimensionsFromFile($attachment->getFile());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->em->persist($investigation);
|
||||
$this->em->flush();
|
||||
|
||||
@@ -80,6 +90,31 @@ final class InvestigationController extends AbstractController
|
||||
]);
|
||||
}
|
||||
|
||||
private function handleAttachments($form, Question $question): void
|
||||
{
|
||||
// Récupérer le champ attachments du formulaire
|
||||
$attachmentsForm = $form->get('attachments');
|
||||
|
||||
// Parcourir tous les attachments du formulaire
|
||||
foreach ($attachmentsForm as $attachmentForm) {
|
||||
/** @var Attachment $attachment */
|
||||
$attachment = $attachmentForm->getData();
|
||||
|
||||
// Récupérer le fichier uploadé
|
||||
$file = $attachmentForm->get('file')->getData();
|
||||
|
||||
if ($file) {
|
||||
// Définir le fichier sur l'entité Attachment
|
||||
$attachment->setFile($file);
|
||||
|
||||
// Associer l'attachment à la question
|
||||
if (!$attachment->getQuestion()) {
|
||||
$attachment->setQuestion($question);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[Route('/show/{id}', name: 'app_investigation_show')]
|
||||
public function show(Investigation $investigation): Response
|
||||
{
|
||||
|
||||
174
src/Entity/Attachment.php
Normal file
174
src/Entity/Attachment.php
Normal file
@@ -0,0 +1,174 @@
|
||||
<?php
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\HttpFoundation\File\File;
|
||||
use Vich\UploaderBundle\Mapping\Annotation as Vich;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
#[ORM\Entity]
|
||||
#[Vich\Uploadable]
|
||||
class Attachment
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column]
|
||||
private ?int $id = null;
|
||||
|
||||
#[Vich\UploadableField(
|
||||
mapping: 'attachments',
|
||||
fileNameProperty: 'fileName',
|
||||
size: 'fileSize',
|
||||
mimeType: 'mimeType',
|
||||
originalName: 'originalName',
|
||||
dimensions: 'dimensions'
|
||||
)]
|
||||
private ?File $file = null;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
private ?string $fileName = null;
|
||||
|
||||
#[ORM\Column(nullable: true)]
|
||||
private ?int $fileSize = null;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
private ?string $mimeType = null;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
private ?string $originalName = null;
|
||||
|
||||
#[ORM\Column(type: 'simple_array', nullable: true)]
|
||||
private ?array $dimensions = null;
|
||||
|
||||
#[ORM\ManyToOne(targetEntity: Question::class, inversedBy: 'attachments')]
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
private ?Question $question = null;
|
||||
|
||||
#[ORM\Column(nullable: true)]
|
||||
private ?\DateTimeImmutable $updatedAt = null;
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setFile(?File $file = null): void
|
||||
{
|
||||
$this->file = $file;
|
||||
|
||||
if (null !== $file) {
|
||||
$this->updatedAt = new \DateTimeImmutable();
|
||||
}
|
||||
}
|
||||
|
||||
public function getFile(): ?File
|
||||
{
|
||||
return $this->file;
|
||||
}
|
||||
|
||||
public function setFileName(?string $fileName): void
|
||||
{
|
||||
$this->fileName = $fileName;
|
||||
}
|
||||
|
||||
public function getFileName(): ?string
|
||||
{
|
||||
return $this->fileName;
|
||||
}
|
||||
|
||||
public function setFileSize(?int $fileSize): void
|
||||
{
|
||||
$this->fileSize = $fileSize;
|
||||
}
|
||||
|
||||
public function getFileSize(): ?int
|
||||
{
|
||||
return $this->fileSize;
|
||||
}
|
||||
|
||||
public function setMimeType(?string $mimeType): void
|
||||
{
|
||||
$this->mimeType = $mimeType;
|
||||
}
|
||||
|
||||
public function getMimeType(): ?string
|
||||
{
|
||||
return $this->mimeType;
|
||||
}
|
||||
|
||||
public function setOriginalName(?string $originalName): void
|
||||
{
|
||||
$this->originalName = $originalName;
|
||||
}
|
||||
|
||||
public function getOriginalName(): ?string
|
||||
{
|
||||
return $this->originalName;
|
||||
}
|
||||
|
||||
public function setDimensions(?array $dimensions): void
|
||||
{
|
||||
$this->dimensions = $dimensions;
|
||||
}
|
||||
|
||||
public function getDimensions(): ?array
|
||||
{
|
||||
return $this->dimensions;
|
||||
}
|
||||
|
||||
public function getQuestion(): ?Question
|
||||
{
|
||||
return $this->question;
|
||||
}
|
||||
|
||||
public function setQuestion(?Question $question): void
|
||||
{
|
||||
$this->question = $question;
|
||||
}
|
||||
|
||||
public function getUpdatedAt(): ?\DateTimeImmutable
|
||||
{
|
||||
return $this->updatedAt;
|
||||
}
|
||||
|
||||
public function setUpdatedAt(?\DateTimeImmutable $updatedAt): void
|
||||
{
|
||||
$this->updatedAt = $updatedAt;
|
||||
}
|
||||
|
||||
// Méthode utilitaire pour afficher la taille en format lisible
|
||||
public function getReadableFileSize(): string
|
||||
{
|
||||
$bytes = $this->fileSize;
|
||||
$units = ['B', 'KB', 'MB', 'GB'];
|
||||
|
||||
$bytes = max($bytes, 0);
|
||||
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
|
||||
$pow = min($pow, count($units) - 1);
|
||||
|
||||
$bytes /= (1 << (10 * $pow));
|
||||
|
||||
return round($bytes, 2) . ' ' . $units[$pow];
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->originalName ?? $this->fileName ?? '';
|
||||
}
|
||||
|
||||
// Si vous utilisez les dimensions (pour les images)
|
||||
public function setDimensionsFromFile(File $file): void
|
||||
{
|
||||
if (str_starts_with($file->getMimeType(), 'image/')) {
|
||||
try {
|
||||
$size = getimagesize($file->getPathname());
|
||||
if ($size) {
|
||||
$this->dimensions = [$size[0], $size[1]];
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
// Ignorer l'erreur si ce n'est pas une image
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -56,6 +56,12 @@ class Question
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
private ?Investigation $investigation = null;
|
||||
|
||||
/**
|
||||
* @var Collection<int, Attachment>
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: Attachment::class, mappedBy: 'question', cascade: ['persist', 'remove'], orphanRemoval: true)]
|
||||
private Collection $attachments;
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
@@ -64,6 +70,7 @@ class Question
|
||||
$this->choice = false;
|
||||
$this->amount = 0;
|
||||
$this->max_participant = 0;
|
||||
$this->attachments = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function __clone()
|
||||
@@ -254,6 +261,36 @@ class Question
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<int, Attachment>
|
||||
*/
|
||||
public function getAttachments(): Collection
|
||||
{
|
||||
return $this->attachments;
|
||||
}
|
||||
|
||||
public function addAttachment(Attachment $attachment): static
|
||||
{
|
||||
if (!$this->attachments->contains($attachment)) {
|
||||
$this->attachments->add($attachment);
|
||||
$attachment->setQuestion($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeAttachment(Attachment $attachment): static
|
||||
{
|
||||
if ($this->attachments->removeElement($attachment)) {
|
||||
// set the owning side to null (unless already changed)
|
||||
if ($attachment->getQuestion() === $this) {
|
||||
$attachment->setQuestion(null);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
33
src/Form/AttachmentType.php
Normal file
33
src/Form/AttachmentType.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use App\Entity\Attachment;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use Vich\UploaderBundle\Form\Type\VichFileType; // Ajoutez cette ligne
|
||||
|
||||
class AttachmentType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$builder
|
||||
->add('file', VichFileType::class, [ // Utilisez VichFileType au lieu de FileType
|
||||
'label' => 'Fichier',
|
||||
'required' => false,
|
||||
'allow_delete' => true,
|
||||
'delete_label' => 'Supprimer',
|
||||
'download_label' => 'Télécharger',
|
||||
'download_uri' => true,
|
||||
'asset_helper' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'data_class' => Attachment::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,8 @@ use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
|
||||
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
|
||||
|
||||
use Symfony\Component\Form\Extension\Core\Type\FileType;
|
||||
|
||||
class QuestionType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
@@ -59,6 +61,17 @@ class QuestionType extends AbstractType
|
||||
'prototype' => true,
|
||||
'by_reference' => false
|
||||
))
|
||||
->add('attachments', CollectionType::class, [
|
||||
'label' => 'Pièces jointes',
|
||||
'entry_type' => AttachmentType::class,
|
||||
'entry_options' => ['label' => false],
|
||||
'allow_add' => true,
|
||||
'allow_delete' => true,
|
||||
'by_reference' => false,
|
||||
'prototype' => true,
|
||||
'prototype_name' => '__attachment_prot__',
|
||||
'required' => false,
|
||||
]);
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
43
src/Repository/AttachmentRepository.php
Normal file
43
src/Repository/AttachmentRepository.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\Attachment;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @extends ServiceEntityRepository<Attachment>
|
||||
*/
|
||||
class AttachmentRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, Attachment::class);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @return Attachment[] Returns an array of Attachment objects
|
||||
// */
|
||||
// public function findByExampleField($value): array
|
||||
// {
|
||||
// return $this->createQueryBuilder('a')
|
||||
// ->andWhere('a.exampleField = :val')
|
||||
// ->setParameter('val', $value)
|
||||
// ->orderBy('a.id', 'ASC')
|
||||
// ->setMaxResults(10)
|
||||
// ->getQuery()
|
||||
// ->getResult()
|
||||
// ;
|
||||
// }
|
||||
|
||||
// public function findOneBySomeField($value): ?Attachment
|
||||
// {
|
||||
// return $this->createQueryBuilder('a')
|
||||
// ->andWhere('a.exampleField = :val')
|
||||
// ->setParameter('val', $value)
|
||||
// ->getQuery()
|
||||
// ->getOneOrNullResult()
|
||||
// ;
|
||||
// }
|
||||
}
|
||||
12
symfony.lock
12
symfony.lock
@@ -189,5 +189,17 @@
|
||||
"config/packages/web_profiler.yaml",
|
||||
"config/routes/web_profiler.yaml"
|
||||
]
|
||||
},
|
||||
"vich/uploader-bundle": {
|
||||
"version": "2.9",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes-contrib",
|
||||
"branch": "main",
|
||||
"version": "1.13",
|
||||
"ref": "1b3064c2f6b255c2bc2f56461aaeb76b11e07e36"
|
||||
},
|
||||
"files": [
|
||||
"config/packages/vich_uploader.yaml"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
<div class="az-content-label mg-b-5"></div>
|
||||
<p class="mg-b-20">Créer une nouvelle enquête</p>
|
||||
|
||||
{{ form_start(form) }}
|
||||
{{ form_start(form, {'attr': {'enctype': 'multipart/form-data'}}) }}
|
||||
<div class="tab-vertical mb-3" id="investigation-information">
|
||||
<ul class="nav nav-tabs" id="myTab3" role="tablist">
|
||||
<li class="nav-item">
|
||||
@@ -162,6 +162,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# modalities #}
|
||||
<h4 class="card-title mt-4">Modalité</h4>
|
||||
<div class="row mt-3">
|
||||
<div class="col-md-6">
|
||||
@@ -242,9 +243,38 @@
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="card-body">
|
||||
<div class="attachments-container" data-prototype="{{ form_widget(formQuestion.attachments.vars.prototype)|e('html_attr') }}" data-index="{{ formQuestion.attachments|length }}" >
|
||||
{% for attachment in formQuestion.attachments %}
|
||||
<div class="attachment-item" id="attachment-{{ loop.index0 }}">
|
||||
{{ form_row(attachment.file, { 'row_attr': {'class': 'mb-0'} }) }}
|
||||
<button type="button" class="btn btn-outline-danger btn-sm remove-attachment mt-2">
|
||||
<i class="fas fa-trash"></i> Supprimer
|
||||
</button>
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="text-muted">Aucun fichier ajouté</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<button type="button" class="btn btn-primary add-modality">Ajouter une modalité</button>
|
||||
<button type="button" class="btn btn-primary add-modality mb-2">Ajouter une modalité</button>
|
||||
<button type="button" class="btn btn-outline-primary add-attachment mt-3"><i class="fas fa-plus"></i> Ajouter un fichier</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -337,6 +367,50 @@
|
||||
$(document).on('click', '.remove-modality', function() {
|
||||
$(this).closest('.modality-item').remove();
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 1. Ajouter un fichier
|
||||
$(document).on('click', '.add-attachment', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
// On remonte au parent pour trouver le conteneur spécifique à cette question
|
||||
var $container = $(this).closest('.row').find('.attachments-container');
|
||||
var prototype = $container.data('prototype');
|
||||
var index = $container.data('index');
|
||||
|
||||
// On remplace le prototype par l'index actuel
|
||||
var newForm = prototype.replace(/__attachment_prot__/g, index);
|
||||
|
||||
// On crée l'élément HTML
|
||||
var $newItem = $('<div class="attachment-item mb-2"></div>').append(newForm);
|
||||
|
||||
// On ajoute un bouton de suppression au nouvel élément
|
||||
$newItem.append('<button type="button" class="btn btn-outline-danger btn-sm remove-attachment mt-2"><i class="fas fa-trash"></i> Supprimer</button>');
|
||||
|
||||
// On ajoute au DOM et on incrémente l'index
|
||||
$container.append($newItem);
|
||||
$container.data('index', index + 1);
|
||||
|
||||
// Supprimer le message "Aucun fichier" s'il existe
|
||||
$container.find('p.text-muted').remove();
|
||||
});
|
||||
|
||||
// 2. Supprimer un fichier (existant ou nouveau)
|
||||
$(document).on('click', '.remove-attachment', function(e) {
|
||||
e.preventDefault();
|
||||
$(this).closest('.attachment-item').remove();
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -168,10 +168,29 @@
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="card-body">
|
||||
<div class="attachments-container" data-prototype="{{ form_widget(formQtn.attachments.vars.prototype)|e('html_attr') }}" data-index="{{ formQtn.attachments|length }}" >
|
||||
{% for attachment in formQtn.attachments %}
|
||||
<div class="attachment-item" id="attachment-{{ loop.index0 }}">
|
||||
{{ form_row(attachment.file, { 'row_attr': {'class': 'mb-0'} }) }}
|
||||
<button type="button" class="btn btn-outline-danger btn-sm remove-attachment mt-2">
|
||||
<i class="fas fa-trash"></i> Supprimer
|
||||
</button>
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="text-muted">Aucun fichier ajouté</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<button type="button" class="btn btn-primary add-modality">Ajouter une modalité</button>
|
||||
<button type="button" class="btn btn-outline-primary add-attachment mt-3"><i class="fas fa-plus"></i> Ajouter un fichier</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user