0

I need to get maximum ID of a table inside of symfony 2.7 entity. But instead of having the id I'm getting this issue.

Notice: Undefined property: AppBundle\Entity\BlogPost::$container

This is my BlogPost entity,

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\UploadedFile;

/**
 * BlogPost
 *
 * @ORM\Table()
 * @ORM\Entity
 */
class BlogPost {

    const SERVER_PATH_TO_IMAGE_FOLDER = '/uploads';

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="title", type="string", length=255)
     */
    private $title;

    /**
     * @var string
     *
     * @ORM\Column(name="body", type="text")
     */
    private $body;

    /**
     * @var string
     *
     * @ORM\Column(name="filename", type="text")
     */
    private $filename;

    /**
     * Set filename
     *
     * @param string $filename
     * @return BlogPost
     */
    public function setFilename($filename) {
        $this->filename = $filename;

        return $this;
    }

    public function setUploader(UploadedFile $file) {
        $em = $this->container->get('doctrine.orm.entity_manager');
        $highest_id = $em->createQueryBuilder()
                ->select('MAX(b.id)')
                ->from('AppBundle:BlogPost', 'b')
                ->getQuery()
                ->getSingleScalarResult();

        var_dump($highest_id);
        exit();// exit for check value

        $url = 'uploads/events';
        $file_name = 'fsdf.' . $file->guessExtension();
        $file->move($url, $file_name);
    }

    /**
     * Get filename
     *
     * @return string 
     */
    public function getFilename() {
        return $this->filename;
    }

    /**
     * @var boolean
     *
     * @ORM\Column(name="draft", type="boolean")
     */
    private $draft;

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId() {
        return $this->id;
    }

    /**
     * Set title
     *
     * @param string $title
     * @return BlogPost
     */
    public function setTitle($title) {
        $this->title = $title;

        return $this;
    }

    /**
     * Get title
     *
     * @return string 
     */
    public function getTitle() {
        return $this->title;
    }

    /**
     * Set body
     *
     * @param string $body
     * @return BlogPost
     */
    public function setBody($body) {
        $this->body = $body;

        return $this;
    }

    /**
     * Get body
     *
     * @return string 
     */
    public function getBody() {
        return $this->body;
    }

    /**
     * Set draft
     *
     * @param boolean $draft
     * @return BlogPost
     */
    public function setDraft($draft) {
        $this->draft = $draft;

        return $this;
    }

    /**
     * Get draft
     *
     * @return boolean 
     */
    public function getDraft() {
        return $this->draft;
    }

    /**
     * @ORM\ManyToOne(targetEntity="Category", inversedBy="blogPosts")
     */
    private $category;

    public function setCategory(Category $category) {
        $this->category = $category;
    }

    public function getCategory() {
        return $this->category;
    }

    /**
     * Unmapped property to handle file uploads
     */
    public $file;

    /**
     * Sets file.
     *
     * @param UploadedFile $file
     */
    public function setFile(UploadedFile $file = null) {
        $this->file = $file;
    }

    /**
     * Get file.
     *
     * @return UploadedFile
     */
    public function getFile() {
        return $this->file;
    }

    /**
     * Manages the copying of the file to the relevant place on the server
     */
    public function upload() {
        // the file property can be empty if the field is not required
        if (null === $this->getFile()) {
            return;
        }

        // we use the original file name here but you should
        // sanitize it at least to avoid any security issues
        // move takes the target directory and target filename as params
        $this->getFile()->move(
                self::SERVER_PATH_TO_IMAGE_FOLDER, $this->getFile()->getClientOriginalName()
        );

        // set the path property to the filename where you've saved the file
        $this->filename = $this->getFile()->getClientOriginalName();

        // clean up the file property as you won't need it anymore
        $this->setFile(null);
    }

    /**
     * Lifecycle callback to upload the file to the server
     */
    public function lifecycleFileUpload() {
        $this->upload();
    }

    /**
     * Updates the hash value to force the preUpdate and postUpdate events to fire
     */
    public function refreshUpdated() {
//        $this->setUpdated(new \DateTime());
    }

// ... the rest of your class lives under here, including the generated fields
//     such as filename and updated
}

This is the part I'm trying to get max id,

public function setUploader(UploadedFile $file) {
        $em = $this->container->get('doctrine.orm.entity_manager');
        $highest_id = $em->createQueryBuilder()
                ->select('MAX(b.id)')
                ->from('AppBundle:BlogPost', 'b')
                ->getQuery()
                ->getSingleScalarResult();

        var_dump($highest_id);
        exit();// exit for check value

        $url = 'uploads/events';
        $file_name = 'fsdf.' . $file->guessExtension();
        $file->move($url, $file_name);
    }

With the help of comments and few research I figured out the issue is in 'entity_manager' part. Is there a way to call doctrine queries inside Entity?

Imanali Mamadiev
  • 2,604
  • 2
  • 15
  • 23
vimuth
  • 5,064
  • 33
  • 79
  • 116
  • 1
    Have you set `$this->container` at some point? Also you should reconsider this, your model classes should not be aware of the container. – Yoshi Apr 29 '16 at 12:07
  • 2
    It's your call of entity manager, I don't know if you can do like that in a Entity class. Try to do this in a Repository class and do your logic in a controller. In addition, call em in an entity is not a good pratice – Letsrocks Apr 29 '16 at 12:07
  • In addition to what all others said (don't do it within an entity!) it's probably as well a bad practice to ask for the highest id anyway - can you explain a bit why you would need that? – LBA Apr 29 '16 at 14:39

4 Answers4

6

If I were you, i would do something like that :

Controller:

$blogPost= new BlogPost () ; 
$em = $this->getDoctrine()->getManager();
//..your code
// I assume you want to do that after a form post 
$blogPost = $form->getData();
$id = $em->getRepository('AppBundle:BlogPost')->getMaxId();
$blogPost->setUploader($id);
//...

Repository:

public function getMaxId()
{
    $qb = $this->createQueryBuilder('u');
    $qb->select('u, MAX(id) as idMax');  
    return $qb->getQuery()->getSingleResult();
}

Entity:

public function setUploader(UploadedFile $file, $id)
{
    var_dump($id);
    $url = 'uploads/events';
    $file_name = 'fsdf.'.$id.$file->guessExtension();
    $file->move($url, $file_name);
}

It should work

1stthomas
  • 731
  • 2
  • 15
  • 22
Letsrocks
  • 650
  • 4
  • 11
  • I'm really sorry but sadly I can't use controller on this – vimuth Apr 29 '16 at 12:20
  • 1
    Oh well, look the response of this post http://stackoverflow.com/questions/14684745/get-entitymanager-inside-an-entity. He explains how use em in an entity – Letsrocks Apr 29 '16 at 12:23
  • To be honest I checked out the solution earlier but I couldn't understand. I'm really sorry but I'm little bit new to this... And if you can modify it and add to your answer it would be great help for me and I'll definitely accept it as correct answer :) – vimuth Apr 29 '16 at 12:29
  • 3
    @vimuth If you're new to this, then please trust us when we say you shouldn't do it (having repository [or worse container] access inside the entities). Invest a bit more time and find a solution without it. – Yoshi Apr 29 '16 at 12:30
1

Try this in your Controller:

$blogPost= new BlogPost () ; 
$em = $this->getDoctrine()->getManager();
$blogPost = $form->getData();
$maxId = $em->getRepository('AppBundle:BlogPost')->createQueryBuilder('b')
    ->where("MAX(b.id) as maxId")
    ->getQuery()
    ->getSingleResult();
Imanali Mamadiev
  • 2,604
  • 2
  • 15
  • 23
  • Thanks. This looks like a much cleaner and robust version than writing SQL manually, as other databases might need slightly different implementations or something. – SDwarfs Aug 17 '23 at 15:09
  • Seems the `->where("MAX(b.id) as maxId")` needs to be actually a `->select("MAX(b.id) as maxId")`, as this selects the return value function and is not part of the SQL queries "WHERE" part. – SDwarfs Aug 17 '23 at 15:20
1

I would suggest to hold the EntityManager as a class variable inside your Entity and either instantiate it via the constructor or via a setter-method which you call before you use the setUploader function.

This should be the cleanest and best readable solution.

Nickolaus
  • 4,785
  • 4
  • 38
  • 60
-2

Form another thread I found this and it's working for me.

global $kernel;
if ( 'AppCache' == get_class($kernel) )
{
   $kernel = $kernel->getKernel();
}
$em = $kernel->getContainer()->get( 'doctrine.orm.entity_manager');

I can't use it in controller cause I have an admin class instead of controller on this. Since lot of people suggesting this using entity_manager inside entity is not good practice I'm using the code inside admin class instead of entity.

This is the original thread..
How to use entityManager inside Entity?

vimuth
  • 5,064
  • 33
  • 79
  • 116