I have one application with a class user and document, every user have a picture profile (document) it works fine. But now I'm having problems, for example on the header of the page I show the picture:
{% if app.user.picture %}
<img src="{{ asset('uploads/' ~ app.user.picture.Id) }}" alt="" class="img-circle">
{% else %}
<img src="{{ asset('images/default.png') }}" alt="" class="img-circle">
{% endif %}
and I got the html code:
<img src="/Project/web/uploads/30" alt="" class="img-circle">
this code works perfect on my localhost, but now I uploaded this to the server and the picture is not showing. But if I add the extension on the browser It show me exactly what I want. Here is my Document entity:
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\UploadedFile;
/**
* @ORM\Entity
* @ORM\HasLifecycleCallbacks
*/
class Document {
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
public $id;
/**
* @ORM\Column(type="string", length=255)
* @Assert\NotBlank
*/
public $name;
/**
* @ORM\Column(type="datetime")
*/
protected $createdAt;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
public $path;
/**
* @Assert\File(maxSize="6000000")
*/
private $file;
private $temp;
public function __construct() {
$this->setCreatedAt(new \DateTime());
}
public function getId() {
return $this->id;
}
public function getName() {
return $this->name;
}
public function setName($n) {
$this->name = $n;
}
public function getCreatedAt() {
return $this->createdAt;
}
public function setCreatedAt($d) {
$this->createdAt = $d;
}
public function setPath() {
$this->path = $this->id;
}
public function getPath() {
return $this->path;
}
/**
* Sets file.
*
* @param UploadedFile $file
*/
public function setFile(UploadedFile $file = null) {
$this->file = $file;
// check if we have an old image path
if (isset($this->path)) {
// store the old name to delete after the update
$this->temp = $this->path;
$this->path = null;
} else {
$this->path = 'initial';
}
}
/**
* Get file.
*
* @return UploadedFile
*/
public function getFile() {
return $this->file;
}
public function getAbsolutePath() {
return null === $this->path ? null : $this->getUploadRootDir() . '/' . $this->id . '.' . $this->path;
}
public function getWebPath() {
return null === $this->path ? null : $this->getUploadDir() . '/' . $this->path;
}
protected function getUploadRootDir() {
// the absolute directory path where uploaded
// documents should be saved
return __DIR__ . '/../../../../../web/' . $this->getUploadDir();
}
protected function getUploadDir() {
// get rid of the __DIR__ so it doesn't screw up
// when displaying uploaded doc/image in the view.
return 'uploads/';
}
/**
* @ORM\PrePersist()
* @ORM\PreUpdate()
*/
public function preUpload() {
if (null !== $this->getFile()) {
$this->path = $this->getFile()->guessExtension();
}
}
/**
* @ORM\PostPersist()
* @ORM\PostUpdate()
*/
public function upload() {
if (null === $this->getFile()) {
return;
}
// check if we have an old image
if (isset($this->temp)) {
// delete the old image
unlink($this->temp);
// clear the temp image path
$this->temp = null;
}
// you must throw an exception here if the file cannot be moved
// so that the entity is not persisted to the database
// which the UploadedFile move() method does
$this->getFile()->move(
$this->getUploadRootDir(), $this->id . '.' . $this->getFile()->guessExtension()
);
$this->setFile(null);
}
/**
* @ORM\PreRemove()
*/
public function storeFilenameForRemove() {
$this->temp = $this->getAbsolutePath();
}
/**
* @ORM\PostRemove()
*/
public function removeUpload() {
if (isset($this->temp)) {
unlink($this->temp);
}
}
}
And my Document.orm.yml:
...\Entity\Document:
type: entity
table: null
repositoryClass: ...\Entity\DocumentRepository
fields:
id:
type: integer
id: true
generator:
strategy: AUTO
name:
type: string
length: '255'
path:
type: string
length: '255'
nullable: true
file:
type: string
length: '255'
lifecycleCallbacks: { }
In my account controller:
public function editAction(Request $request) {
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('...Bundle:User')->find($this->getUser()->getId());
$originalpic = $entity->getPicture();
$editForm = $this->createEditForm($entity);
$editForm->handleRequest($request);
$uploadedFile = $request->files->get('form_user');
if ($editForm->isValid()) {
if ($editForm->get('password')->getData()) {
$factory = $this->get('security.encoder_factory');
$encoder = $factory->getEncoder($entity);
$entity->setPassword($encoder->encodePassword($editForm->get('password')->getData(), $entity->getSalt()));
}
if ($uploadedFile['picture']) {
foreach ($uploadedFile as $file) {
$pic = new Document();
$pic->setName($entity->getUsername());
$pic->setFile($file);
$pic->setPath();
$entity->setPicture($pic);
$em->persist($pic);
$em->flush();
$pic->upload();
}
} else {
$entity->setPicture($originalpic);
}
$em->flush();
$this->container->get("session")->getFlashBag()->add('success', 'Information updated');
return $this->redirect($this->generateUrl('panel_profile'));
}
return $this->render('...Bundle:Panel\Pages\Account:edit.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView()
));
}
My question is, how can I change my code to show me the picture with the extension ///// The solution was add another raw to the table and in Document Entity:
public function upload() {
if (null === $this->getFile()) {
return;
}
// check if we have an old image
if (isset($this->temp)) {
// delete the old image
unlink($this->temp);
// clear the temp image path
$this->temp = null;
}
// you must throw an exception here if the file cannot be moved
// so that the entity is not persisted to the database
// which the UploadedFile move() method does
$this->extension = $this->getFile()->guessExtension();
$this->getFile()->move(
$this->getUploadRootDir(), $this->id . '.' . $this->getFile()->guessExtension()
);
$this->setFile(null);
}