I'm trying to use a Symfony service in a legacy app.
An extract of the file:
<?php
use AppBundle\Services\HealthCoverageValidation\GenericCancellationRequest;
use AppBundle\Services\HealthCoverageValidation\Transaction;
use Symfony\Component\HttpFoundation\Response;
/**
* #var Composer\Autoload\ClassLoader
*/
$loader = require __DIR__.'/../app/autoload.php';
$kernel = new AppKernel('dev', true);
class Test extends \Symfony\Bundle\FrameworkBundle\Controller\Controller {
public function testAutorizacion() {
global $kernel;
$validator = $kernel->getContainer()->get('nano.services.health_coverage.validator');
But then getContainer() returns null. How can I workaround this?
Related
Why I cannot declare or init session globally in the BaseController.php ?
BaseController.php
<?php
namespace App\Controllers;
use CodeIgniter\Controller;
use CodeIgniter\HTTP\CLIRequest;
use CodeIgniter\HTTP\IncomingRequest;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;
/**
* Class BaseController
*
* BaseController provides a convenient place for loading components
* and performing functions that are needed by all your controllers.
* Extend this class in any new controllers:
* class Home extends BaseController
*
* For security be sure to declare any new methods as protected or private.
*/
abstract class BaseController extends Controller
{
/**
* Instance of the main Request object.
*
* #var CLIRequest|IncomingRequest
*/
protected $request;
/**
* An array of helpers to be loaded automatically upon
* class instantiation. These helpers will be available
* to all other controllers that extend BaseController.
*
* #var array
*/
protected $helpers = ['BotMenu_helper',
'Channel_helper',
'Day_helper',
'Dir_helper',
'File_helper',
'Key_helper',
'Login_helper',
'Notification_helper',
'Response_helper',
'Security_helper',
'Ticker_helper',
'Utility_helper',
'RSS_helper',
'User_helper'];
/**
* Constructor.
*/
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
// Do Not Edit This Line
parent::initController($request, $response, $logger);
// Preload any models, libraries, etc, here.
// E.g.: $this->session = \Config\Services::session();
$this->session = \Config\Services::session();
$this->language = \Config\Services::language();
$this->language->setLocale($this->session->lang);
}
}
When I do post :
$routes->post('ProcessCheckoutApp', 'App\Controllers\Front\AppPayment::ProcessCheckoutApp', ['as' => 'ProcessCheckoutApp']);
I got this error :
message": "CodeIgniter\\Session\\Session and Psr\\Log\\LoggerAwareTrait define the same property ($logger) in the composition of CodeIgniter\\Session\\Session. However, the definition differs and is considered incompatible. Class was composed",
I didn't declare session in any file.
Finally found the problem.
Do not init globally session in the BaseController. Because if you have run a thirdparty autoload.php it will causing the error.
Example that make session error :
public $session;
function __construct()
{
require_once APPPATH . 'ThirdParty/vendor/autoload.php';
$this->session = session();
}
The correct way is init the session above the autoload.php
public $session;
function __construct()
{
$this->session = session();
require_once APPPATH . 'ThirdParty/vendor/autoload.php';
}
I need to run the controller method every 2 hours. I read somewhere that you need to create a command and run this command by using CRON. It is correct?
MY COMMAND:
namespace AppBundle\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Routing\Annotation\Route;
class RunCommand extends Command
{
// the name of the command (the part after "bin/console")
protected static $defaultName = 'app:run';
protected function configure()
{
// ...
}
protected function execute(InputInterface $input, OutputInterface $output)
{
echo 'BEGIN';
$controller = new \AppBundle\Controller\DefaultController();
$controller->storeAction();
echo 'END';
}
}
MY CONTROLLER:
/**
* #Route("/to-db", name="to-db")
*/
public function storeAction()
{
$entityManager = $this->getDoctrine()->getManager();
$data = new Skuska();
$data->setName('Keyboard');
$entityManager->persist($data);
$entityManager->flush();
// die();
}
My error: In ControllerTrait.php line 424: Call to a member function has() on null
Is my code correct? How do I run a method using cron?
I don't want to use another bundle. I want to program it myself
As mentioned in the comments, you should move the logic out of the controller and into a service, and use that service both in the command and in the controller.
With the default service autoloading configuration, you don't even have to care about your service declarations. Your command will automatically be a service, and you can inject other services into it.
https://symfony.com/doc/current/console/commands_as_services.html
For controllers, you don't even need to use a specific constructor.
https://symfony.com/doc/current/controller.html#fetching-services
<?php
// AppBundle/Service/StoreService.php
use AppBundle\Entity\Skuska;
use Doctrine\ORM\EntityManager;
class StoreService
{
/** #var EntityManager */
private $entityManager;
/**
* StoreService constructor.
* #param EntityManager $entityManager
*/
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
public function store()
{
$data = new Skuska();
$data->setName('Keyboard');
$this->entityManager->persist($data);
$this->entityManager->flush();
}
}
<?php
// AppBundle/Controller/StoreController.php
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use AppBundle\Service\StoreService;
class StoreController extends Controller
{
/**
* #Route("/to-db", name="to-db")
* #param StoreService $storeService
* #return Response
*/
// Hinting to you service like this should be enough for autoloading.
// No need for a specific constructor here.
public function storeAction(StoreService $storeService)
{
$storeService->store();
return new Response(
// Return something in you response.
);
}
}
<?php
// AppBundle/Command/RunCommand.php
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use AppBundle\Service\StoreService;
class RunCommand extends Command
{
protected static $defaultName = 'app:run';
/** #var StoreService */
protected $storeService;
/**
* RunCommand constructor.
* #param StoreService $storeService
*/
public function __construct(StoreService $storeService)
{
$this->storeService = $storeService;
parent::__construct();
}
protected function configure()
{
// ...
}
protected function execute(InputInterface $input, OutputInterface $output)
{
echo 'BEGIN';
$this->storeService->store();
echo 'END';
}
}
I have a code in Symfony 3.2, where I am trying to pass repository from Commmand class to my custom class, where I am running the websockets
<?php
namespace MyBundle\Command;
use MyBundle\Server\Notification;
use Ratchet\Http\HttpServer;
use Ratchet\Server\IoServer;
use Ratchet\WebSocket\WsServer;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class ServerCommand extends ContainerAwareCommand
{
/**
* Configure a new Command Line
*/
protected function configure()
{
$this->setName('Project:notification:server')
->setDescription('Start the notification server.');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$em = $this->getApplication()->getKernel()->getContainer()->get('My.repository.car');
$server = IoServer::factory(new HttpServer(
new WsServer(
new Notification($this->getContainer(),$em)
)
), 8080);
$server->run();
}
}
for All my db queries I am using repositories and there is no Entity. I have done this before, and it was working fine.
But now when I run command from terminal I am getting this error
Parse error: parse error in
/Applications/XAMPP/xamppfiles/htdocs/lavtaxi/src/MyBundle/Command/ServerCommand.php
on line 28
on line 28 there is
"$server = IoServer::factory(new HttpServer( " part
this is my services.yml
services:
My.repository.car:
class: MyBundle\Repository\CarRepository
arguments: ["#doctrine.orm.entity_manager"]
and this is Notification.php where I am trying to get data and send via sockets
<?php
namespace MyBundle\Server;
use Doctrine\ORM\EntityManager;
use Ratchet\ConnectionInterface;
use Ratchet\MessageComponentInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
class Notification implements MessageComponentInterface
{
protected $connections = array();
private $users = array();
protected $container;
private $drivers = array();
private $repository = null;
public function __construct(ContainerInterface $container, $em)
{
$this->repository = $em;
$this->container = $container;
$this->users = [];
$this->drivers = [];
}
/**
* A new websocket connection
*
* #param ConnectionInterface $conn
*/
public function onOpen(ConnectionInterface $conn)
{
$this->connections[] = $conn;
$this->users[$conn->resourceId] = $conn;
$this->drivers = $this->repository->getCarsData();
$conn->send('..:: Hello from the Notification Center ::..');
$conn->send(json_encode($this->drivers));
echo "New connection \n";
}
}
Error is disappears when I remove the repository calling part above, so I know that problem is not on IoServer
I using symfony 2 and ratchet and memcache on a websocket chat project ratchet working good with symfony and i tested it on the "hello world" app on the offical web site docs
but the problem is when I run this line
new Chat(new MyApp(), $this->getContainer()),
i get this error
Attempted to load class "MyApp" from namespace
my command line code
<?php
// myapplication/src/sandboxBundle/Command/SocketCommand.php
// Change the namespace according to your bundle
namespace check\roomsBundle\Command;
use Ratchet\Session\SessionProvider;
use Symfony\Component\HttpFoundation\Session\Storage\Handler;
use Doctrine\Common\Cache\MemcacheCache;
use Ratchet\App;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\HttpFoundation\Session\Storage\Handler\MemcacheSessionHandler;
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
// Include ratchet libs
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
// Change the namespace according to your bundle
use check\roomsBundle\Sockets\Chat;
use Doctrine\ORM\EntityManager;
use Symfony\Component\HttpFoundation\Session\Session;
class WsServerCommand extends ContainerAwareCommand
{
protected function configure()
{
$this->setName('sockets:start-chat')
// the short description shown while running "php bin/console list"
->setHelp("Starts the chat socket demo")
// the full command description shown when running the command with
->setDescription('Starts the chat socket demo')
; }
protected function execute(InputInterface $input, OutputInterface $output)
{
$output->writeln([
'Chat socket',// A line
'============',// Another line
'Starting chat, open your browser.',// Empty line
]);
$memcache = new \Memcache;
$memcache->connect('localhost', 11211);
$session = new SessionProvider(
new Chat(new MyApp(), $this->getContainer()),
new Handler\MemcacheSessionHandler($memcache)
);
$server = new App('localhost');
$server->route('/sessDemo', $session);
$server->run();
}
}
the Chat.php code
<?php
namespace check\roomsBundle\Sockets;
use tuto\testBundle\Entity\Users;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Ratchet\WebSocket\WsServerInterface;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Doctrine\ORM\EntityManager;
use Symfony\Component\DependencyInjection\ContainerInterface as Container;
use Symfony\Component\HttpFoundation\Session\Session;
/**
* This component will allow access to user data (FOSUserBundle)
* for each connection in your Ratchet application.
*/
class Chat implements MessageComponentInterface, WsServerInterface
{
/**
* #var \Ratchet\MessageComponentInterface
*/
protected $_app;
/**
* #var \Symfony\Component\DependencyInjection\ContainerInterface
*/
protected $_container;
/**
* #param MessageComponentInterface $app
* #param ContainerInterface $container
*/
public function __construct(MessageComponentInterface $app, ContainerInterface $container)
{
$this->_app = $app;
$this->_container = $container;
}
/**
* {#inheritdoc}
*/
public function onOpen(ConnectionInterface $conn)
{
if (!isset ($conn->Session) || !$conn->Session instanceof Session) {
throw new \RuntimeException('Session is not defined. Make sure that SessionProvider is executed before FOSUserProvider.');
}
try {
$token = unserialize($conn->Session->get('_security_main'));
$user = $token->getUser();
$provider = $this->_container->get('fos_user.user_provider.username');
$conn->User = $provider->refreshUser($user);
} catch (Exception $ex) {
$conn->User = null;
}
return $this->_app->onOpen($conn);
}
There isn't any use MyApp; on the top of your page.
use AppBundle\Classes ?
I'd like to retrieve my module configuration from a controller in Zend Framework 3.
I searched, and it seems that the standard way to do this in ZF2 is to use
$this->getServiceLocator()
to access the configuration in module.config.php.
However, this won't work in ZF3, as there is no getServiceLocator() method.
What is the standard way to achieve this?
Don't know if you found an answer, as there are different solutions as tasmaniski wrote. Just in case, let me share one that would have helped me a lot when I started to play with ZF3:
MyControllerFactory.php
<?php
namespace My\Namespace;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;
use DependencyNamespace\...\ControllerDependencyClass; // this is not a real one of course!
class MyControllerFactory implements FactoryInterface
{
/**
* #param ContainerInterface $container
* #param string $requestedName
* #param null|array $options
* #return AuthAdapter
*/
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
// Get config.
$config = $container->get('configuration');
// Get what I'm interested in config.
$myStuff = $config['the-array-i-am-interested-in']
// Do something with it.
$controllerDepency = dummyFunction($myStuff);
/*...the rest of your code here... */
// Inject dependency.
return $controllerDepency;
}
}
MyController.php
<?php
namespace My\Namespace;
use Zend\Mvc\Controller\AbstractActionController;
use DependencyNamespace\...\DependencyClass;
class MyController extends AbstractActionController
{
private $controllerDepency;
public function __construct(DependencyClass $controllerDepency)
{
$this->controllerDepency = $controllerDepency;
}
/*...the rest of your class here... */
}
You need to inject your dependencies through service manager.
Basicly you need to create 2 class Controller and ControllerFactory that will create Controller with all dependencies.