I am using Symfony 5, I have successfully uploaded the image files and stored the file names into the database using the bundle, but now I have trouble getting the url to display them. I want to get only the uri to the file, not full path, like this www.abc.com/img instead of www.abc.com/img/1.jpg
my setting in yaml file:
vich_uploader:
db_driver: orm
mappings:
image:
uri_prefix: /img
upload_destination: '%kernel.project_dir%/public/images
controller:
public function index(UploaderHelper $helper)
{
$image = new Image(); // Image entity
$path = $helper->asset($image , 'imageFile');
var_dump($path );
}
I followed the instruction from the doc, passing in the image entity and imageFile to the helper function, but var_dump gives me a "NULL" value, no path.
I see 2 different issues here:
1) if you want to display path without filename, you need to do something on your side. Bundle is not offering such feature
2) if UploaderHelper is not getting anything from your entity, you're likely doing something wrong. We can't guess it without more code
I wanted to display all the images to the page, so I grab the image repository, ran a find all query, and pass it to the template. And then in the template I just stitch the image path and image file name together to form the url.
controller
$imageRepo = $this->getDoctrine()->getRepository(Image::class);
$images = $imageRepo->findAll();
$image = new Image(); // Image entity
$path = $helper->asset($image , 'imageFile');
return $this->render('/image/list_images.html.twig', [
'images' => $images,
'path' = $path
]);
twig
{% for image in images %}
<img src="{{ path }}/{{ image.fileName }}" />
{% endfor %}
image entity
/**
* @ORM\Entity(repositoryClass="App\Repository\ImageRepository")
* @Vich\Uploadable
*/
class Image
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @Vich\UploadableField(mapping="image", fileNameProperty="fileName", size="fileSize")
* @var File
*/
private $imageFile;
/**
* @ORM\Column(type="string", length=50)
*/
private $fileName;
...
/**
* @ORM\ManyToMany(targetEntity="App\Entity\SomeEntity", mappedBy="images")
*/
private $someEntity;
}
I can't see how this could make sense.
What's the purpose of using a single path?
So how do I do to retrieve all the images? There is no example in the doc for this, so I can only guess.
What do you mean with "all the images"?
I have a page to upload images to the database. And I want to display them in another page like this:
<img src="http://www.abc.com/image/01.jpg" />
<img src="http://www.abc.com/image/02.jpg" />
<img src="http://www.abc.com/image/03.jpg" />
The reason for the single path is that I will have another page in the project for ReactJS, where it will also display the images, so I need to pass the image path into javascript and stitch them back together like in the twig.
To display your images you can follow our documentation.
I guess that you can retrieve the path just by taking the first image and then calling pathinfo on it
I did followed the documentation, I tried both ways on generating the url but still have no idea what I did wrong.
https://github.com/dustin10/VichUploaderBundle/blob/master/docs/generating_urls.md
controller
$imageRepo = $this->getDoctrine()->getRepository(Image::class);
$images = $imageRepo->findAll();
return $this->render('/image/list_images.html.twig', [
'images' => $images,
]);
twig
{% for image in images %}
<img src="{{ vich_uploader_asset(image, 'imageFile', 'Entity\Image') }}" />
{% endfor %}
With this I got the runtime exception "Impossible to determine the class name. Either specify it explicitly or give an object"
Try with {{ vich_uploader_asset(image) }}
{{ vich_uploader_asset(image) }} gives error about missing argument.
Okay after more tests I have narrowed down the problem. First I tried getting a single image instead of a bunch
controller
$image = $imageRepo->find(1);
twig
<img src="{{ vich_uploader_asset(image, 'imageFile') }}" />
Now this gives me the supposed image url http://127.0.0.1:8000/img/01.jpg, the uri-prefix setting in the yaml is displaying correctly. But this gives a 404 not found, the image is not there.
I have found a similar problem on stackoverflow and changing the url to match the project's public folder structure works:
// public folder structure
app/public/image
// vich_uploader.yaml
uri_prefix: img
www.abc.com/image/01.jpg // this works
www.abc.com/img/01.jpg // this doesn't work
So this means the uri-prefix routing in the config yaml is not working.
The prefix works as soon as it matches your destination.
Oh so I can't have a custom uri_prefix ?
You can, as soon as it matches your destination (if you use a local filesystem)
I'm still kind of confuse, do you mean the uri_prefix and upload_destination setting has to be the same like this?
uri_prefix: /myfolder/category/shoes/img
upload_destination: %kernel.project_dir%/public/myfolder/category/shoes/img
Or do you mean it can be different and will work on the actual server?
uri_prefix: /shop/images
upload_destination: %kernel.project_dir%/public/myfolder/category/shoes/img
It has to be the same
In your code
$image = new Image(); // Image entity
$path = $helper->asset($image , 'imageFile');
You passing an empty entity to helper method, of course you will get null because it is empty inside.
You have few choices:
{{ asset('your_uri_path') ~ imageName }}{{ vich_uploader_asset( ) }}You want to render image url to your <img> html tag, why don't you just change your code to this:
$imageRepo = $this->getDoctrine()->getRepository(Image::class);
$images = $imageRepo->findAll();
$imagePath = [];
foreach( $images as $image) {
$imagePath [] = $helper->asset($image, 'imageFile');
}
return $this->render('/image/list_images.html.twig', [
'images' => $imagePath,
]);
And in your twig:
{% for image in images %}
<img src=" {{ image }}" >
{% endfor %}
And of course, your uri_path and upload_destination must be the same. Because uri_path is what you will obtain using $helper->asset( ) , and upload_destination is where your fill will be upload to.