Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FatalErrorException: Error: Call to a member function has() on a non-object

I have a read a lot of topics on this and I can't seem to find a solution to my problem.

I feel like the problem is obvious and maybe I have just been staring at it too long.

The error is FatalErrorException: Error: Call to a member function has() on a non-object in /vagrant/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php line 198

Looking at the error line, it says.

public function getDoctrine()
    {
        if (!$this->container->has('doctrine')) {
            throw new \LogicException('The DoctrineBundle is not registered in your application.');
        }

        return $this->container->get('doctrine');
    }

Here is my code...

This is the main controller that is calling the DAO Controller

public function clickThroughAction(request $request, $hash)
    {
        if (isset($hash)) {
            $dbController = $this->get('database_controller');
            print_r($dbController->getReferralIdByHash($hash));
            return $this->redirect($this->generateUrl('home'));
        } else {
            return 0;

        }
    }

This is the service that is being used.

services:
    database_controller:
        class:  Fuel\FormBundle\Controller\DatabaseController

This is the dao controller that is calling the database.

public function getReferralIdByHash($hash)
    {
        $em = $this->getDoctrine()->getManager();
        $query = $em->createQuery(
            'Select u From FuelFormBundle:UserReferrals u WHERE u.user_hash = :hash'
        )->setParameter('hash', $hash);

        $referral = $query->getResult();

        if (!$referral) {
            throw $this->createNotFoundException(
                'No product referral found'
            );
            $logger = $this->get('logger');
            $logger->info('I just got the logger');
            $logger->crit('An error occurred, hash for referrals is not recognized. current hash is: ' . $hash . " .");
            return $this->redirect($this->generateUrl('home'));
        }

        $clickThroughCount = $referral[0]->getClickThrough();
        $referral[0]->setClickThrough($clickThroughCount + 1);
        $em->flush();
        return $referral;
    }

I think the problem is that the doctrine container is not present which is why I am having issues. I am not sure how to solve this.

Any help is appreciated. Thanks!

Edit


Ok so here is what I changed.

Main Controller stayed the same.

DAO Controller a couple of things were added.

class DatabaseController extends Controller{
    protected  $entityManager;

    public function __construct($entityManager) {
        $this->entityManager = $entityManager;
    }
public function getReferralIdByHash($hash)
    {
        $em = $this->entityManager;
        $query = $em->createQuery(
            'Select u From FuelFormBundle:UserReferrals u WHERE u.user_hash = :hash'
        )->setParameter('hash', $hash);

        $referral = $query->getResult();

        if (!$referral) {
            throw $this->createNotFoundException(
                'No product referral found'
            );
            $logger = $this->get('logger');
            $logger->info('I just got the logger');
            $logger->crit('An error occurred, hash for referrals is not recognized. current hash is: ' . $hash . " .");
            return $this->redirect($this->generateUrl('home'));
        }

        $clickThroughCount = $referral[0]->getClickThrough();
        $referral[0]->setClickThrough($clickThroughCount + 1);
        $em->flush();
        return $referral;
    }
}

Service ended up looking like this

services:
     database_controller:
          class:  Fuel\FormBundle\Controller\DatabaseController
          arguments: ["@doctrine.orm.entity_manager"]
like image 728
B Rad Avatar asked Oct 09 '13 20:10

B Rad


2 Answers

The problem is the container not being injected into the controller here.

Normally, Symfony does this automatically if you're extending Symfony\Bundle\FrameworkBundle\Controller\Controller, which itself extends Symfony\Component\DependencyInjection\ContainerAware:

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class YourController extends Controller

The container is injected into the controller (if not explicitly defined as a service) using setter injection calling the method setContainer() with the container as an argument.

Now, as you configured your controller as a service you need to add the setContainer call to your service configuration:

services:
    database_controller:
        class:  Fuel\FormBundle\Controller\DatabaseController
        calls:
            - [setContainer, ["@service_container"]]

Clear your cache afterwards.

like image 169
Nicolai Fröhlich Avatar answered Nov 11 '22 10:11

Nicolai Fröhlich


Not sure why you would make a controller a service. For what use case? Normally a service is a Plain Old PHP Object.

About your problem .. since you are using the controller as a service it does not get the container automatically. So you have to inject the entire container, which is kind of heavy if you just need doctrine.

So it's better just to inject the things you really need. To inject doctrine, in your yml below class:

arguments: ["@doctrine.orm.entity_manager"]

Then in your controller constructor:

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

Possible you will need to call the parent constructor (be aware of that).

If you want do inject the complete service container anyway, here is the right section in the manual how you can do that: http://symfony.com/doc/current/cookbook/service_container/scopes.html#passing-the-container-as-a-dependency-of-your-service

like image 1
Flip Avatar answered Nov 11 '22 12:11

Flip