Allow uploading images (#13)
continuous-integration/drone/push Build is passing Details

Adds an optional field for the post image.

Fixes #12

Co-authored-by: clfreville2 <clement.freville2@etu.uca.fr>
Reviewed-on: #13
Reviewed-by: Bastien OLLIER <bastien.ollier@noreply.codefirst.iut.uca.fr>
pull/14/head
Clément FRÉVILLE 3 weeks ago
parent 8859cd0000
commit 6a6a135891

1
.gitignore vendored

@ -33,3 +33,4 @@ phpstan.neon
###< phpstan/phpstan ###
migrations
public/images

@ -46,7 +46,8 @@
"symfony/yaml": "7.0.*",
"symfonycasts/verify-email-bundle": "^1.17",
"twig/extra-bundle": "^2.12|^3.0",
"twig/twig": "^2.12|^3.0"
"twig/twig": "^2.12|^3.0",
"vich/uploader-bundle": "^2.3"
},
"config": {
"allow-plugins": {

175
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": "9df70d112adfdfa4fbcde08b504d0bb9",
"content-hash": "0f3c68d9e3c5fbe96fcb3367231dc539",
"packages": [
{
"name": "api-platform/core",
@ -1565,6 +1565,70 @@
],
"time": "2023-10-06T06:47:41+00:00"
},
{
"name": "jms/metadata",
"version": "2.8.0",
"source": {
"type": "git",
"url": "https://github.com/schmittjoh/metadata.git",
"reference": "7ca240dcac0c655eb15933ee55736ccd2ea0d7a6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/schmittjoh/metadata/zipball/7ca240dcac0c655eb15933ee55736ccd2ea0d7a6",
"reference": "7ca240dcac0c655eb15933ee55736ccd2ea0d7a6",
"shasum": ""
},
"require": {
"php": "^7.2|^8.0"
},
"require-dev": {
"doctrine/cache": "^1.0",
"doctrine/coding-standard": "^8.0",
"mikey179/vfsstream": "^1.6.7",
"phpunit/phpunit": "^8.5|^9.0",
"psr/container": "^1.0|^2.0",
"symfony/cache": "^3.1|^4.0|^5.0",
"symfony/dependency-injection": "^3.1|^4.0|^5.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.8.0"
},
"time": "2023-02-15T13:44:18+00:00"
},
{
"name": "monolog/monolog",
"version": "3.6.0",
@ -7742,6 +7806,115 @@
],
"time": "2024-05-16T10:04:27+00:00"
},
{
"name": "vich/uploader-bundle",
"version": "2.3.3",
"source": {
"type": "git",
"url": "https://github.com/dustin10/VichUploaderBundle.git",
"reference": "4002ecc83bae414b5be287907ccecb27611eaa69"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/dustin10/VichUploaderBundle/zipball/4002ecc83bae414b5be287907ccecb27611eaa69",
"reference": "4002ecc83bae414b5be287907ccecb27611eaa69",
"shasum": ""
},
"require": {
"doctrine/persistence": "^3",
"ext-simplexml": "*",
"jms/metadata": "^2.4",
"php": "^8.1",
"symfony/config": "^5.4 || ^6.0 || ^7.0",
"symfony/console": "^5.4 || ^6.0 || ^7.0",
"symfony/dependency-injection": "^5.4 || ^6.0 || ^7.0",
"symfony/event-dispatcher-contracts": "^3.1",
"symfony/http-foundation": "^5.4 || ^6.0 || ^7.0",
"symfony/http-kernel": "^5.4 || ^6.0 || ^7.0",
"symfony/mime": "^5.4 || ^6.0 || ^7.0",
"symfony/property-access": "^5.4 || ^6.0 || ^7.0",
"symfony/string": "^5.4 || ^6.0 || ^7.0"
},
"conflict": {
"doctrine/annotations": "<1.12",
"league/flysystem": "<2.0"
},
"require-dev": {
"dg/bypass-finals": "^1.3",
"doctrine/doctrine-bundle": "^2.7",
"doctrine/mongodb-odm": "^2.4",
"doctrine/orm": "^2.13",
"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",
"mikey179/vfsstream": "^1.6.11",
"phpunit/phpunit": "^9.6",
"symfony/asset": "^5.4 || ^6.0 || ^7.0",
"symfony/browser-kit": "^5.4 || ^6.0 || ^7.0",
"symfony/css-selector": "^5.4 || ^6.0 || ^7.0",
"symfony/doctrine-bridge": "^5.4 || ^6.0 || ^7.0",
"symfony/dom-crawler": "^5.4 || ^6.0 || ^7.0",
"symfony/form": "^5.4 || ^6.0 || ^7.0",
"symfony/framework-bundle": "^5.4 || ^6.0 || ^7.0",
"symfony/phpunit-bridge": "^7.0",
"symfony/security-csrf": "^5.4 || ^6.0 || ^7.0",
"symfony/translation": "^5.4 || ^6.0 || ^7.0",
"symfony/twig-bridge": "^5.4 || ^6.0 || ^7.0",
"symfony/twig-bundle": "^5.4 || ^6.0 || ^7.0",
"symfony/validator": "^5.4 || ^6.0 || ^7.0",
"symfony/var-dumper": "^5.4 || ^6.0 || ^7.0",
"symfony/yaml": "^5.4 || ^6.0 || ^7.0",
"yoast/phpunit-polyfills": "^2.0"
},
"suggest": {
"doctrine/annotations": "If you use doctrine/doctrine-bundle >2.7, this package is required to use annotations",
"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/2.3.3"
},
"time": "2024-04-24T07:17:05+00:00"
},
{
"name": "webmozart/assert",
"version": "1.11.0",

@ -18,4 +18,5 @@ return [
Nelmio\CorsBundle\NelmioCorsBundle::class => ['all' => true],
ApiPlatform\Symfony\Bundle\ApiPlatformBundle::class => ['all' => true],
DAMA\DoctrineTestBundle\DAMADoctrineTestBundle::class => ['test' => true],
Vich\UploaderBundle\VichUploaderBundle::class => ['all' => true],
];

@ -0,0 +1,11 @@
vich_uploader:
db_driver: orm
metadata:
type: attribute
mappings:
posts:
uri_prefix: /images/posts
upload_destination: '%kernel.project_dir%/public/images/posts'
namer: Vich\UploaderBundle\Naming\SmartUniqueNamer

@ -12,8 +12,10 @@ use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\Serializer\Attribute\Groups;
use Symfony\Component\Validator\Constraints as Assert;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
#[ORM\Entity(repositoryClass: PostRepository::class)]
#[ORM\HasLifecycleCallbacks]
@ -23,6 +25,7 @@ use Symfony\Component\Validator\Constraints as Assert;
)]
#[GetCollection(normalizationContext: ['groups' => ['post:collection:read']])]
#[Metadata\ApiFilter(filterClass: SearchFilter::class, properties: ['species' => 'exact'])]
#[Vich\Uploadable]
class Post
{
#[ORM\Id]
@ -41,6 +44,9 @@ class Post
#[Groups(['post:collection:read'])]
private ?\DateTimeImmutable $publicationDate = null;
#[ORM\Column]
private ?\DateTimeImmutable $updatedAt = null;
#[ORM\Column(nullable: true)]
#[Groups(['post:collection:read'])]
private ?float $latitude = null;
@ -53,6 +59,13 @@ class Post
#[Groups(['post:collection:read'])]
private ?float $altitude = null;
#[ORM\Column(length: 255, nullable: true)]
private ?string $image = null;
#[Vich\UploadableField(mapping: 'posts', fileNameProperty: 'image')]
#[Assert\Image]
private ?File $imageFile = null;
#[ORM\Column(type: Types::TEXT)]
#[Groups(['post:read'])]
#[Assert\NotBlank]
@ -103,6 +116,18 @@ class Post
return $this;
}
public function getUpdatedAt(): ?\DateTimeImmutable
{
return $this->updatedAt;
}
public function setUpdatedAt(\DateTimeImmutable $updatedAt): static
{
$this->updatedAt = $updatedAt;
return $this;
}
public function getLatitude(): ?float
{
return $this->latitude;
@ -139,6 +164,30 @@ class Post
return $this;
}
public function getImage(): ?string
{
return $this->image;
}
public function setImage(?string $image): static
{
$this->image = $image;
return $this;
}
public function getImageFile(): ?File
{
return $this->imageFile;
}
public function setImageFile(?File $imageFile): static
{
$this->imageFile = $imageFile;
return $this;
}
public function getCommentary(): ?string
{
return $this->commentary;
@ -170,6 +219,7 @@ class Post
if ($this->publicationDate === null) {
$this->publicationDate = new \DateTimeImmutable();
}
$this->updatedAt = new \DateTimeImmutable();
}
/**

@ -6,6 +6,7 @@ use App\Entity\Post;
use App\Entity\Species;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
@ -20,6 +21,7 @@ class PostType extends AbstractType
->add('latitude')
->add('longitude')
->add('altitude')
->add('imageFile', FileType::class)
->add('commentary')
->add('species', EntityType::class, [
'class' => Species::class,

@ -343,5 +343,17 @@
},
"twig/extra-bundle": {
"version": "v3.10.0"
},
"vich/uploader-bundle": {
"version": "2.3",
"recipe": {
"repo": "github.com/symfony/recipes-contrib",
"branch": "main",
"version": "1.13",
"ref": "1b3064c2f6b255c2bc2f56461aaeb76b11e07e36"
},
"files": [
"config/packages/vich_uploader.yaml"
]
}
}

@ -31,6 +31,12 @@
<th>Altitude</th>
<td>{{ post.altitude }}</td>
</tr>
{% if post.image %}
<tr>
<th>Image</th>
<td><img src="{{ vich_uploader_asset(post, 'imageFile') }}" class="img-thumbnail" width="200" alt=""></td>
</tr>
{% endif %}
<tr>
<th>Commentary</th>
<td>{{ post.commentary }}</td>

@ -8,6 +8,7 @@ use App\Repository\PostRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class PostControllerTest extends WebTestCase
{
@ -147,4 +148,24 @@ class PostControllerTest extends WebTestCase
$comments = $this->repository->find($fixture->getId())->getComments();
self::assertSame(1, $comments->count());
}
public function testUploadImage()
{
$fixture = new Post();
$fixture->setFoundDate(new \DateTimeImmutable('2024-01-01 00:00:00'));
$fixture->setCommentary('Cool stuff');
$this->manager->persist($fixture);
$this->manager->flush();
$file = new UploadedFile(__DIR__ . '/../image.png', 'image.png');
$this->client->request('GET', sprintf('%s%s/edit', $this->path, $fixture->getId()));
$this->client->submitForm('Update', [
'post[imageFile]' => $file,
]);
self::assertNotNull($this->repository->find($fixture->getId())->getImage());
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 B

Loading…
Cancel
Save