1

Now, I know this question has been asked a lot, but I searched and searched but I just can't figure it out and I've been stuck for hours now. I'm really sorry if it turnes out to be a really dumb mistake (It probably will).

So, I have my Controller which instatiates the editAction() function when a button on my website is pressed. It checks if the request is a _POST request, passes on the data and checks if the input given is valid, all this works fine.

I then try to access a function in my Manager class. And that's where the error is happening and my website spits out:

"Call to a member function updateJob() on null".

Now, PhpStorm is not saying there's an error or a warning, it recognizes the jobManager class and I've checked the namespaces and class names, but all are correct. The variables are also defined correctly, as far as I can see. I'd be really thankful if someone could tell me what I am doing wrong. The code is below.

current state after adding $jobManager to __construct:

class IndexController extends AbstractActionController
{
    /**
     * Entity manager.
     * @var EntityManager
     */
    private $entityManager;

    /**
     * Post manager.
     * @var JobManager
     */
    private $jobManager;

    public function __construct($entityManager, $jobManager)
    {
        $this->entityManager = $entityManager;

        /***
         * Edit from comment advice:
         * I have added this line to my __construct
         * But this does not solve the issue.
         ***/
        $this->jobManager = $jobManager;
    }

    public function indexAction()
    {
        // Get recent jobs
        $jobs = $this->entityManager->getRepository(Jobs::class)
            ->findBy(['status'=>Jobs::STATUS_READY]
            );

        // Render the view template
        return new ViewModel([
            'jobs' => $jobs
        ]);
    }

    public function editAction()
    {
        // Create the form.
        $form = new JobForm();

        // Get post ID.
        $jobId = $this->params()->fromRoute('id', -1);

        // Find existing job in the database.
        $jobs = $this->entityManager->getRepository(Jobs::class)
            ->findOneById($jobId);
        if ($jobs == null) {
            $this->getResponse()->setStatusCode(404);
            return;
        }

        // Check whether this job is a POST request.
        if ($this->getRequest()->isPost()) {

            // Get POST data.
            $data = $this->params()->fromPost();

            // Fill form with data.
            $form->setData($data);
            if ($form->isValid()) {

                // Get validated form data.
                $data = $form->getData();

                // Use job manager service to add new post to database.
                $this->jobManager->updateJob( $jobs, $data);

                // Redirect the user to "backups" page.
                return $this->redirect()->toRoute('backups');
            }
        } else {
            $data = [
                'id' => $jobs->getId(),
                'jobName' => $jobs->getJobName(),
                'status' => $jobs->getStatus(),
                'vmId' => $jobs->getVmId(),
                'targetfolderPrefix' => $jobs->getTargetFolderPrefix(),
                'numberOfBackups' => $jobs->getNumberOfBackups(),
                'lastBackupUsed' => $jobs->getLastBackupUsed(),
                'repeat' => $jobs->getRepeat(),
                'scheduleRunAtMinute' => $jobs->getScheduleRunAtMinute(),
                'scheduleRunAtHour' => $jobs->getScheduleRunAtHour(),
                'scheduleRunAtDOW' => $jobs->getScheduleRunAtDOW(),
                'hostId' => $jobs->getHostId()
            ];

            $form->setData($data);
        }

        // Render the view template.
        return new ViewModel([
            'form' => $form,
            'jobs' => $jobs
        ]);
    }
}
Martin
  • 22,212
  • 11
  • 70
  • 132
Mr. Shield
  • 21
  • 4
  • Don't worry about asking dumb questions. That's how you learn. – Howard P Jan 18 '19 at 12:47
  • Have you checked what's inside of `$data`? – Howard P Jan 18 '19 at 12:49
  • I think so. If I understood right, $data gets it's data from the Post request that is sent and then passes it along. – Mr. Shield Jan 18 '19 at 12:52
  • Yes, but you need to actually check - what you expect to happen and what's really happening are most always different. echo the values inside of `$data` to find out. – Howard P Jan 18 '19 at 12:53
  • 1
    `$this->jobManager->` is null in this function – Masivuye Cokile Jan 18 '19 at 12:53
  • I don't really know how to echo it out, where I can see the output. Because if I put echo($data); in my code, it stilljust gives me the error. – Mr. Shield Jan 18 '19 at 12:56
  • Then comment out the line giving you the error first. Debugging PHP is a valuable skill you should nail down. Looks like @MasivuyeCokile has your answer though. – Howard P Jan 18 '19 at 12:57
  • what is the value of `$jobManager` to me seems null – Masivuye Cokile Jan 18 '19 at 12:59
  • It doesn't echo out anything. Maybe there's the problem then, I'll look at how $data gets its data. if jobManager is null, does that mean there's something wrong with that file? Or is that caused by the $data? – Mr. Shield Jan 18 '19 at 13:01
  • Read your PHP Error log. – Martin Jan 18 '19 at 13:05
  • You have only declared the property with `private $jobManager;`, but this doesn’t get initialized with an actual object instance anywhere. – misorude Jan 18 '19 at 13:08
  • 1
    @Mr.Shield The Entity Manager is injected into your class via dependency injection[1] (I guess.). You forgot to inject the jobManager into your class. Try to add `$this->jobManager = $jobManager` and add `JobManager $jobManager` in the `__construct` function prototype. You might have to configure somewhere what is injected into your class, read that up in the docs of your framework. [1]: https://en.wikipedia.org/wiki/Dependency_injection – Xatenev Jan 18 '19 at 13:09
  • I added the $jobManager to my __construct function, but it's still giving me the same error. I don't quite understand what @misorude means with initializing it with and object instance.. Sorry. – Mr. Shield Jan 18 '19 at 13:15
  • You need to assign an instance of the JobManager class to this property somewhere … otherwise you _have_ nothing here that you could call any updateJob method on. _“I added the $jobManager to my __construct function”_ - please edit the question to reflect the current state of things then. – misorude Jan 18 '19 at 13:20

1 Answers1

2

What is wrong

 $this->jobManager->updateJob( $jobs, $data);

You are telling PHP:

"In $this class, look in the jobManager object and run the method updateJob with these variables.... "

But in $this class you have written:

/**
 * Post manager.
 * @var JobManager
 */
private $jobManager;

But you have nowhere set jobManager to be anything. You have no setter function in the class as well as no other function setting what a jobManager variable actually is... so jobManager can never be anything.

So what you're in effect doing is saying to PHP

"In $this class, look in the jobManager empty null-space and run the method updateJob with these variables..."

This is clearly not going to end well.

How to fix it

You need to set what jobManager is before you can use it, as referenced by Xatenev. Typically when you construct the class or using a Setter method, if preferred.

ONE:

public function __construct(EntityManager $entityManager, JobManager $jobManagerVar)
{
    $this->entityManager = $entityManager;
    $this->jobManager = $jobManagerVar;
}

Alternatively - if ->jobManager method needs to be defined after the object IndexController is created; then you need to use a Setter class (because the jobManager var is *private*.

Thus TWO:

class IndexController extends AbstractActionController
{

...
    public function setJobManager($jobManagerVar){
        $this->jobManager = $jobManagerVar
    }

...
}

And then when you instantiate the IndexController you can do:

// ONE from above:
$theClass = new IndexController($entity,$jobManager);

or

// TWO from above
$theClass = new IndexController($entity);

...

$theClass->setJobManager($jobManger);

There are various other nuances as to methods of setting values in classes, I'm not going to go over them all, it will depend on what's going on in your wider project.

Community
  • 1
  • 1
Martin
  • 22,212
  • 11
  • 70
  • 132