How do I resolve a "Fatal error" when creating a service? - symfony

I'm following this Drupal 8 module development 101 tutorial. It's between 37:15 to 45:14 on the YouTube video. I kept getting this error:
Fatal error: Class 'Drupal\dino_roar\DinoServices\HelloGenerator' not found in C:\Users\myName\Sites\devdesktop\drupal-8.0.5\modules\dino_roar\src\Controller\RoarController.php on line 11
Folder structure:
HelloGenerator.php
<?php
namespace Drupal\dino_roar\DinoServices;
class HelloGenerator
{
public function getHello($count){
return "Gotten Hello ".$count;
}
}
RoarController.php
<?php
namespace Drupal\dino_roar\Controller;
//use Drupal\dino_roar\DinoServices\HelloGenerator;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class RoarController extends Controller
{
public function roar($count){
//$helloGenerator = new HelloGenerator();
$helloGenerator = $this->get('dino_roar.hello_generator');
$hello = $helloGenerator->getHello($count);
return new Response($hello);
//return new Response("Hello World ".$count);
}
}
dino_roar.info.yml
name: Dino ROAR
type: module
description: "ROAR at you"
package: Custom
core: 8.x
dino_roar.routing.yml
dino_says:
path: /dino/says/{count}
defaults:
_controller: '\Drupal\dino_roar\Controller\RoarController::roar'
requirements:
_permission: 'access content'
dino_roar.services.yml
services:
dino_roar.hello_generator:
class: Drupal\dino_roar\DinoServices\HelloGenerator
The fatal error points to this line of code in the RoarController.php file: $helloGenerator = new HelloGenerator();
This is the Symfony version. I can't find it say 1,2, or 3 in this window.

First of all, your RoarController class needs to extends the Controller class
class RoarController
to
use Symfony\Bundle\FrameworkBundle\Controller\Controller
class RoarController extends Controller
EDIT
Ok now change
public function roar($count){
$helloGenerator = new HelloGenerator();
$hello = $helloGenerator->getHello($count);
return new Response($hello);
//return new Response("Hello World ".$count);
}
to
public function roar($count){
$helloGenerator = $this->get('dino_roar.hello_generator');
$hello = $helloGenerator->getHello($count);
return new Response($hello);
//return new Response("Hello World ".$count);
}
You didn't understand how use services that why I invite you to read this http://symfony.com/doc/current/book/service_container.html#creating-configuring-services-in-the-container

Related

Symfony2 send email from service

I created the next class:
//src/AppBundle/Services/RegisterMail.php
namespace AppBundle\Services;
class RegisterMail{
protected $mailer;
public function __construct($mailer)
{
$this->mailer = $mailer;
}
public function sendPassword(){
$message = \Swift_Message::newInstance()
->setSubject('Otro correo')
->setFrom('fromEmail#fromEmail.com')
->setTo('toEmail#toEmail.com')
->setBody('hola desde el servicio')
;
$envia = $this->mailer->send($message);
}
}
And I declare it as a service in my services.yml
services:
registermail:
class: AppBundle\Services\RegisterMail
arguments: [#mailer]
In my controller call the service:
//src/AppBundle/Controller/DefaultController
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class DefaultController extends Controller
{
/**
* #Route("/")
*/
public function indexAction()
{
//EnvĂ­o el email con el password
$mailer = $this->get('registermail');
$mailer->sendPassword();
return $this->render(':Default:index.html.twig');
}
}
The email are sent, but the page still loading 30 seconds, and I have an alert from developer toolbar: "An error occurred while loading the web debug toolbar (404: not found). Do you want to open the profiler?
If Accept the message symfony profiler don't show any error.
If Cancel the message developer toolbar don't appears.
What am I doing wrong?
Thank you!
#RL83 you are probably sending the message synchronously by not using any kind of spool in swiftmailer and your smtp provider is working slowly.
You should try using an async spool queue, I'd recommend using https://github.com/radutopala/TSSAutomailerBundle, which provides you with a database queue. So basically, you'll not only have a spool queue but also a history of the sent emails, stored in the database layer.
Try to replace your code with this:
//src/AppBundle/Services/RegisterMail.php
namespace AppBundle\Services;
class RegisterMail{
protected $mailer;
protected $transport; // <- Add transport to your service
public function __construct($mailer, $transport)
{
$this->mailer = $mailer;
$this->transport = $transport;
}
public function sendPassword() // <- change the method like this
{
$email = $mailer->createMessage()
->setSubject('Otro correo')
->setFrom('fromEmail#fromEmail.com')
->setTo('toEmail#toEmail.com')
->setCharset("UTF-8")
->setContentType('text/html')
->setBody('hola desde el servicio')
;
$send = $mailer->send($email);
$spool->flushQueue($transport);
}
}
Register your service and add the new dependency - the transport service "#swiftmailer.transport.real"
services:
registermail:
class: AppBundle\Services\RegisterMail
arguments: ["#mailer", "#swiftmailer.transport.real" ]
And your trouble will be resolved
Thank for your answers and sorry for the delay.
#lyberteam when i put your code, i get this error message:
Notice: Undefined variable: mailer
500 Internal Server Error - ContextErrorException
Here: $email = $mailer->createMessage()
Any suggestion?
Thank you

In Symfony2 how can I use a Service within a Factory class?

I am trying to setup a Symfony implementation of this PHP library for Chargify https://github.com/johannez/chargify
I'm getting a bit lost working out the best / proper way to set it all up.
I think I need to setup Guzzle as a service, then create a Chargify factory and have that added as a service.
My problem is that in the factory class, when I try and use the Guzzle service I get a fatal error
Fatal error: Using $this when not in object context in /symfony/src/Acme/ChargifyBundle/Factory/ChargifyFactory.php on line 8
This is my Factory class
<?php
namespace Acme\ChargifyBundle\Factory;
class ChargifyFactory implements ChargifyFactoryInterface
{
public static function build($type)
{
$client = $this->get('chargify.guzzle.client');
$className = 'Chargify\\Controller\\' . ucfirst($type);
if (class_exists($className)) {
return new $className($client);
}
else {
throw new Exception("Invalid controller type given.");
}
}
}
If it's useful to see some config, this is my services.yml for the bundle
services:
chargify.guzzle.client.curl_auth:
class: %guzzle.plugin.curl_auth.class%
arguments:
api_key: %chargify_api_key%
chargify.guzzle.client:
class: %guzzle.client.class%
tags:
- { name: guzzle.client }
calls:
- [setBaseUrl, [%chargify_domain%]]
- [addSubscriber, [#chargify.guzzle.client.curl_auth]]
argument: %chargify_domain%
chargify.factory:
class: Acme\ChargifyBundle\Factory\ChargifyFactory
arguments:
- ["type"]
chargify.customer:
class: Acme\ChargifyBundle\Controller\CustomerController
factory_class: Acme\ChargifyBundle\Factory\ChargifyFactory
factory_method: build
arguments:
type: "customer"
How can I use the guzzle client in the Factory with out using
$client = $this->get('chargify.guzzle.client');
EDIT:
I have changed the code as per #alex's answer, but I'm still getting an error. I think this is because the function is static. I've looked though the documents, but I can't see where I can setup a factory without a static function, and when I get rid of static I get a different error.
Runtime Notice: Non-static method Acme\ChargifyBundle\Factory\ChargifyFactory::build() should not be called statically, assuming $this from incompatible context
That is being thrown from some generated code
protected function getChargify_CustomerService()
{
return $this->services['chargify.customer'] = \Acme\ChargifyBundle\Factory\ChargifyFactory::build('customer');
}

Create a log system in symfony2

I want to create a system of logs in symfony2 and I have a question, so I have in service.yml :
services:
my_logger:
class: Monolog\Logger
arguments: [Debug]
calls:
- [pushHandler, [#my_log_handler]]
my_log_handler:
class: Monolog\Handler\StreamHandler
arguments: [/home/vagrant/Workspace/symfony/app/logs/test.log, 100]
I have a class in Utils/Logs like this :
class Logs {
public static function logInfo($a_log) {
$sc = new ContainerBuilder();
$logguer = $sc->get('my_logger');
$logguer->info($a_log);
}
}
And my controller :
$categories = array();
Logs::logInfo(print_r($categories));
The question is how to modify Utilis/Logs class to be possible to call logInfo method? Help me please...Thx in advance...It's possible to create this?

Symfony Custom Route loader, loading multiple times, getting exception

I'm trying to make custom routeloader according to http://symfony.com/doc/current/cookbook/routing/custom_route_loader.html
my code looks like this
//the routeloader:
//the namespace and use code ....
class FooLoader extends Loader{
private $loaded = false;
private $service;
public function __construct($service){
$this->service = $service;
}
public function load($resource, $type=null){
if (true === $this->loaded)
throw new \RuntimeException('xmlRouteLoader is already loaded');
//process some routes and make $routeCollection
$this->loaded = true;
return $routeCollection;
}
public function getResolver()
{
// needed, but can be blank, unless you want to load other resources
// and if you do, using the Loader base class is easier (see below)
}
public function setResolver(LoaderResolverInterface $resolver)
{
// same as above
}
function supports($resource, $type = null){
return $type === 'xmlmenu';
}
}
//the service definition
foo.xml_router:
class: "%route_loader.class%"
arguments: [#foo.bar_service] //this service and the injection has been tested and works.
tags:
- { name: routing.loader }
//the routing definitions
//routing_dev.yml
_foo:
resource: "#FooBarBundle/Resources/config/routing.yml"
-----------------------------
//FooBarBundle/Resources/config/routing.yml
_xml_routes:
resource: .
type: xmlmenu
and when I try to access any route I get the exception:
RuntimeException: xmlRouteLoader is already loaded
which is the exception I defined if the loader is loaded multiple times.So why does it try to load this loader more than once? and I'm pretty sure I've defined it only there.
Actually the answer was quite simple.it seems like this method only supports one level of imports.I only needed to put the _xml_routes directly under routing_dev.yml, otherwise it somehow winds out in a loop.explanations to why that is are appreciated.

How to include Facebook-SDK

I'm using an example of FOSUserBundle with FOSFacebookBundle. Hereon i have build my application.
The relevant Project Structure is like following:
src\ABC\MainBundle\
src\ABC\UserBundle\
src\ABC\MainBundle\Controller\DefaultController.php
src\ABC\UserBundle\Security\User\Provider\FacebookProvider.php
vendor\facebook\php-sdk\src\base_facebook.php
Part of the FacebookProvider:
use \BaseFacebook;
use \FacebookApiException;
class FacebookProvider implements UserProviderInterface
{
protected $facebook;
public function __construct(BaseFacebook $facebook, $userManager, $validator)
{
$this->facebook = $facebook;
}
public function loadUserByUsername($username)
{
try {
$fbdata = $this->facebook->api('/me');
...
As you can see there is the Facebook-Object already available.
What i want to do now is nearly the same, but in my DefaultController:
use \BaseFacebook;
use \FacebookApiException;
class DefaultController extends BaseController
{
public function indexAction(){
$facebook = new Facebook('key', 'secret');
$fbfriends_obj = $facebook->api('/'.$fbid.'/friends');
...
But there i get the message
Fatal error: Class 'ABC\MainBundle\Controller\Facebook' not found in C:\xampp\htdocs\...\src\ABC\MainBundle\Controller\DefaultController.php on line x
Why is that? How can i access the facebook-class from inside my defaultcontroller? If its already possible for the facebookprovider, why it aint possible for my controller?
any hints will be really appreciated!
The solution to that problem is, that the facebook-class has no namespace and you have to do something like
$facebook = new \Facebook(...)
Problem is here:
use \BaseFacebook;
use \FacebookApiException;
You are importing BaseFacebook class from namespace you should use \Facebook (in Controller and FacebookProvider classes)

Resources