Php – Error: Call to a member function get() on a non-object

controllerPHPsymfony

I am trying to send mail with Swift_Message however when I go to send the data it will not send and I get an error of

FatalErrorException: Error: Call to a member function get() on a
non-object in
/vagrant/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php
line 252

Here is the Email Controller that I am using.

use Symfony\Component\Finder\Shell\Command;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\DependencyInjection\ContainerInterface;

class EmailController extends Controller{

    public function createMessage($subject, $from, $from_name, $to, $to_name, $body){
        // Create the message
        $message = \Swift_Message::newInstance()

            // Give the message a subject
            ->setSubject($subject)

            // Set the From address with an associative array
            ->setFrom(array($from => $from_name))

            // Set the To addresses with an associative array
            ->setTo(array($to => $to_name))

            // Give it a body
            ->setBody($body, 'text/html');

        return $message;
    }

    public function sendEmail($message, $urlAlias){

        $this->get('mailer')->send($message);

        return $this->redirect($this->generateUrl($urlAlias));
    }
}

I understand that its unable to access the object which I think is part of the container class but I can seem to get it to pull up. I have tried using $this->container->get(...

but that also does not work. What am I missing. This seems like it should be really straight forward.

I am calling this function from a different bundle using an action to call the current controller. I don't know if that makes a difference.


Ok so when looking in /vagrant/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php

The line it errors on is

   /**
     * Gets a service by id.
     *
     * @param string $id The service id
     *
     * @return object The service
     */
    public function get($id)
    {
        return $this->container->get($id);
    }
}

Which makes me feel like 'mailer; is not a good $id but it is used in Symfony's examples and in a lot of other private examples.

Don't know if this helps or not but figured it was worth mentioning.

Could this be because of the swiftmailer: setting inside of my config.yml file?

routing.yml file

fuel_form_homepage:
    pattern:  /hello/{name}
    defaults: { _controller: FuelFormBundle:Default:index }

referral_form:
    pattern:   /form/referral/{hash}
    defaults: { _controller: FuelFormBundle:Form:referralForm }

referral_result:
    pattern:  /form/referral/result
    defaults: { _controller: FuelFormBundle:Form:referralResult }

user_form:
    pattern:    /form/user
    defaults: { _controller: FuelFormBundle:Form:userForm }

home:
    pattern:    /
    defaults: { _controller: FuelFormBundle:Default:home}

This is the function that calls

public function userFormAction(request $request){
        $user = new User();
        $form = $this->createForm('user', $user);

        $form->handleRequest($request);
        if($form->isValid()){
            $user->setTimeCreated();
            $user->setTimeUpdated();
            $date = $user->getTimeCreated();
            $timestamp = $date->format("U");
            $hash = $user->getFirstName() . $user->getLastName() . $timestamp ;
            $user->setUserHash(md5($hash));
            $em = $this->getDoctrine()->getManager();
            $em->persist($user);
            $em->flush();
            print_r($user);
            //TODO: @Email: @Body: make sure to replace with correct information.

            //Calls a service named email_bundle_controller
            $emailController = $this->get('email_bundle_controller');

            $fullName = $user->getFirstName() . $user->getLastName();
            $body = "please visit the following url to start referring! <a href='http://localhost:8080/app_dev.php/form/referral/" . $user->getUserHash() . "'>Your URL</a>";
            $message = $emailController->createMessage('Welcome to Fuel PRM References', 'bsaverino@gmail.com', 'Brad Saverino', $user->getEmail(), $fullName, $body);
            $emailController->sendEmail($message, 'user_form');

        }

        return $this->render('FuelFormBundle:Default:mainForm.html.twig', array('form' => $form->createView(),));

    }

This is the service that allows me to call on the other bundle.

services:
    fuel_form.form.type.referral:
        class: Fuel\FormBundle\Form\Type\ReferralType
        tags:
            - { name: form.type, alias: referral}

    fuel_form.form.type.user:
        class: Fuel\FormBundle\Form\Type\UserType
        tags:
            - { name: form.type, alias: user}

    email_bundle_controller:
        class: Fuel\EmailBundle\Controller\EmailController

This is the FuelEmailBundle.php

namespace Fuel\EmailBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;
use \Symfony\Component\DependencyInjection\ContainerInterface;

class FuelEmailBundle extends Bundle
{
    private static $containerInstance = null;

    public function setContainer(ContainerInterface $container = null)
    {
        parent::setContainer($container);
        self::$containerInstance = $container;
    }

    public static function getContainer()
    {
        return self::$containerInstance;
    }
}

These are the changes that were made to the sendEmail function

public function sendEmail($message, $urlAlias){

        $container = FuelEmailBundle::getContainer();

        $mailer = $container->get('mailer');

        $mailer->send($message);

        return $this->redirect($this->generateUrl($urlAlias));
    }

Best Answer

As Cerad had mentioned above, you are getting the error as container is not set. One way of fixing this issue would be to pass a container instance to your bundle so that you can call the container from anywhere in your project.

Edit the class corresponding to your bundle(BundleName.php) to include two methods setContainer and getContainer. See the example below.

namespace Venom\CoreBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;
use \Symfony\Component\DependencyInjection\ContainerInterface;

class VenomCoreBundle extends Bundle
{
   private static $containerInstance = null; 

   public function setContainer(ContainerInterface $container = null) 
   { 
    parent::setContainer($container); 
    self::$containerInstance = $container; 
   }

   public static function getContainer() 
   { 
    return self::$containerInstance; 
   }
 }

Use the appropriate namespaces. Then, use the namespace for the bundle in classes where you need the container. You may call the container by

$container = VenomCoreBundle::getContainer();

Then, call the mailer

$mailer = $container->get('mailer');

Related Topic