I am creating a webapp that has some common functions. So I figured the easiest way to do this would be to make a base controller and just extend that. So in the base controller I have (similar to):
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
class BaseController extends Controller
{
protected function dosomething($data)
{
return $data;
}
}
And then in the default controller:
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
class DefaultController extends BaseController
{
/**
* #Route("/", name="homepage")
*/
public function indexAction()
{
$data = "OK";
$thedata = $this->dosomething($data);
}
}
And then for the Admin Controller:
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
class AdminController extends BaseController
{
/**
* #Route("/", name="homepage")
*/
public function indexAction()
{
$data = "OK";
$thedata = $this->dosomething($data);
}
}
However, I am getting errors like "Compile Error: Access level to AppBundle\Controller\AdminController::dosomething() must be protected (as in class AppBundle\Controller\BaseController) or weaker", not just when I load the admin controller function, but default as well. When I stop the admin controller extending base controller, this error goes (seems to work on default but not admin).
I'm guessing somewhere I have to let Symfony know that the admin controller is safe or something?
It has nothing to do with Symfony, it's PHP.
Obviously, you're trying to redefine dosomething method in your Admin Controller, and trying to make this method private.
It's not allowed. It may be either protected or public.
It's principle of OOP. Because if you would have a class SubAdminController, then instance of it would be also instance of both AdminController and BaseController. And PHP must definitely know if the method dosomething from parent class is accessible from SubAdminController.
Related
I'm using the Fosuserbundle to manager members in my project { SF::3.4.8 },
when trying to override the controller of the registrationController by following the Symfony documentation
<?php
namespace TestUserBundle;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use FOSUserBundle\Controller\RegistrationController as BaseController;
class RegistrationController extends BaseController {
public function registerAction(Request $request)
{
die("Hello");
}
}
but the system ignore that controller and still use The original controller, so if there any way to override my controller by
First, overriding the controller is probably not the best way to process. You should consider to hook into controller. Here is the related documentation: https://symfony.com/doc/master/bundles/FOSUserBundle/controller_events.html
Then if you still want to override the controller, you should act in the dependency injection. The service name of the controller is fos_user.registration.controller.
To replace the service you can simply use:
services:
fos_user.registration.controller:
class: YourController
arguments:
$eventDispatcher: '#event_dispatcher'
$formFactory: '#fos_user.registration.form.factory'
$userManager: '#fos_user.user_manager'
$tokenStorage: 'security.token_storage'
You can also override it in a CompilerPass. Which is probably the best solution for you because you do this inside another bundle.
Here is how it should look:
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class ReplaceRegistrationController extends CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$container
->getDefinition('fos_user.registration.controller')
->setClass(YourController::class)
;
}
}
Don't forget to register it inside your bundle:
$container->addCompilerPass(new ReplaceRegistrationController());
I'm really new with symfony, and I have strange problem.
I have a default controller, which looks like:
Both Controllers located:
src/AppBundle/Controller/
Names:
DefaultController.php
and
CmsController.php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
class DefaultController extends Controller
{
/**
* #Route("/")
*/
public function indexAction(Request $request)
{
die('Homepage');
}
}
And I'm trying to create new one:
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
class CmsController extends Controller
{
/**
* #Route("/cms")
*/
public function cmsAction(Request $request)
{
die('Cms Page');
}
}
Routing file looks like:
app:
resource: "#AppBundle/Controller/"
type: annotation
When I try to go for www.domainname.com - default controller shows "Homepage" - as it should.
When I try to go for www.domainname.com/cms - it gives error 404.
What can be the problem?
Probelm was simply with cache. Clearing it solved the problem.
I've just started using Symfony. I want to echo the $bookid when I call a URL like book/5 , but I stuck somewhere.
Here's my DefaultController.php file
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class DefaultController extends Controller {
/**
* #Route("/book/{id}", name="book")
*/
public function indexAction() {
return $this->render('default/index2.html.php');
}
}
file: /Myproject/app/Resources/views/default/index2.html.php
<?php
echo $id;
?>
When I call the book/6 , I get a blank page. What's missing? Do I need to change somewhere else, too?
You should declare that variable in your action and pass it to your view.
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class DefaultController extends Controller
{
/**
* #Route("/book/{id}", name="book")
*/
public function indexAction($id)
{
return $this->render('default/index2.html.php', array(
'id' => $id
));
}
}
Whenever you have a parameter defined in your URL, you also need to "declare" it in your action function, so symfony maps it. Then, if you want to use it in your view, you have to pass it along.
If you are just starting with Symfony, I strongly recommend reading the Symfony Book and Cookbook. They are full of examples and relatively easy to understand, even for a newbie.
Other than that, the answer from smottt is correct. You add {id} in your route definition and receive it as parameter in your controller action.
Symfony book: Routing
So I'm building a Symfony web app.
I have a simple controller (DefaultController.php) as follows:
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
class DefaultController extends Controller
{
/**
* #Route("/", name="default")
*/
public function defaultAction(){
return $this->render('default/hello.html.twig', array(
'name' => "hello"
));
}
}
Nothing special.
Now, I would like to have a separate .php file called APIController.php that gets called when a user navigates to http://eamorr.com/api/
APIController.php would then handle requests such as:
http://eamorr.com/api/getUser
http://eamorr.com/api/addUser
http://eamorr.com/api/getAllUsers
...
Here's what APIController.php should look like:
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
class APIController extends Controller
{
/**
* #Route("/getUser", name="getUser")
*/
public function getUser(){
//
}
/**
* #Route("/addUser", name="addUser")
*/
public function addUser(){
//
}
/**
* #Route("/getAllUsers", name="getAllUsers")
*/
public function getAllUsers(){
//
}
//etc.
}
From an architectural point of view, am I doing this right? Does anyone have any recommendations as to how to do this in Symfony?
If you define routes like:
/**
* #Route("/getUser", name="getUser")
*/
public function getUser(){
//
}
Then the URL to this action will be http://eamorr.com/getUser. As you can see there's no /api part, and this is because you didn't mention it anywhere.
You have two solutions for this case.
First it to define full routes like
/**
* #Route("/api/getUser", name="getUser")
*/
public function getUser(){
//
}
Second: since you want all APIController actions to have this /api part, you can define a prefix for all routes by defining "base" route for whole class.
/**
* #Route("/api", name="getUser")
*/
class APIController extends Controller
Then you can leave your actions' routes like they are.
More info: http://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/routing.html#route-prefix
You are on the right track. But if you are looking to support multiple request and response formats (eg. JSON, XML) you are better off using FOSRestBundle.
It can handle content negotiation, entity serialization (using JMSSerializerBundle which is used by the FOSRest Bundle) and it let's you build RESTful routes.
I have a model in src\Front\Model\FrontModel.php
I am trying to extend it in my IndexController i have this in my Module.php:
use Front\Model\FrontModel;
But i always get this error:
Fatal error: Class 'Front\Model\FrontModel' not found in
C:\Apache24\htdocs\cartbiz\module\Front\src\Front\Controller\IndexController.php
on line 16
I have this in my IndexController where i am trying to extend my model my Controller resides in src\Front\Controller\IndexController.php
namespace Front\Controller;
use Front\Model\FrontModel;
class IndexController extends FrontModel
{
/* Initialize Controller */
public function initAction()
{
parent::initAction();
}
}
I have this as my model class my model class resides in src\Front\Model\FrontModel.php
namespace Front\Model\FrontModel;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class FrontModel extends AbstractActionController
{
/* Application initializer
** All front application logic
*/
public function __construct ()
{
die('ssss');
$this->_viewManager=new ViewModel;
$this->_viewManager->setTemplate('front/index/index');
return $this->_viewManager;
}
}
Any help is appreciated
You need to add a namespace to the FontModel class.
namespace Front\Model;
use Zend\Mvc\Controller\AbstractActionController;
class FrontModel extends AbstractActionController
{}
Also, it's worth noting that your naming conventions could lead to confusion. I would recommend placing all the controllers in the controller folder, and reading up on the coding standards.
Tested and works
namespace Front\Model;
use Zend\Mvc\Controller\AbstractActionController;
class FrontModel extends AbstractActionController
{
/* Application initializer
** All front application logic
*/
public function __construct ()
{
die('ssss');
$this->_viewManager=new ViewModel;
$this->_viewManager->setTemplate('front/index/index');
return $this->_viewManager;
}
}