Extending all controller classes from my custom controller class in symfony2 - php

Like in Codeigniter we do have 'core' folder where we can define our own controller like 'MY_Controller' and can be used to extend all the class to extend from this controller is there any possibility to do so in Symfony2.
In symfony I want to create class 'MY_Controller' which extends from the base class 'Controller', and I want all the classes in the controllers to extend from MY_Controller' class.
Thanks in Advance...

Note:
When working with Symfony2 it is strongly recommended you follow the Symfony2 coding style. It's basically the same as PHP-FIG, with one or two deviations. So underscores are a no-no in class names. Other than that: Symfony is pretty easy to work with, and fully OO, so changing the class a controller extends from is as simple as replacing extends Controller with extends AnotherClass.
But now, the symfony2-way of using a custom controller:
What you could do, is create a Core bundle (CoreBundle henceforth). Then, in this CoreBundle, define a controller, that extends from the Symfony Controller component. From the command line, in your project root, use this command:
php app/console generate:bundle --namespace=YourNameSpace/CoreBundle --bundle-name=YourNameSpaceCoreBundle
More options can be found here
After that, you'll find a DefaultController class in the bundle directories. (probably in the folder src/YourNamespace/CoreBundle/Controller). Then, set about generating your Core controller:
php app/console generate:controller --controller=YourNameSpaceCoreBundle:Core
See the documentation for more options on how to generate your core controller.
After you've finished setting up your custom controller, you can use it in any of the other bundles at will:
namespace YourNameSpace\AnotherBundle\Controller;
use YourNameSpace\CoreBundle\Controller\CoreController;
class DefaultController extends CoreController
{//extends from your custom controller
}
And that's it: you're done.

First, don't name the class using underscores as in PSR-0 each underscore char is converted to a directory separator, when used in class name.
Second, put your controllers to <bundledir>/Controller/
Third, name your controller something like BaseController and extend all other controllers from it.
Fourth, think of using dependency injection rather than coupling functionality in a base controller.

Related

Putting Laravel and Lumen controllers inside packages

I'm developing a package which has controllers in it and I want this package to be compatible with (or useable by) both Laravel and Lumen projects. My problem is Laravel controllers extend Illuminate\Routing\Controller and Lumen controllers extend Laravel\Lumen\Routing\Controller. The controller inside my package can't extend them both.
The only solution I've come up with is to have the controllers inside the package extend App\Http\Controllers\Controller.
But I see some problems:
App\Http\Controllers\Controller should exist; which means it wouldn't work if the App namespace is named differently.
The package is now "aware" that it is being included in something.
Testability: I can't test the controller independently because of the reference to App\Http\Controllers\Controller.
Is there a better way of doing this?
Edit 1
I'm finding other classes which are affected in a similar way. For example, the namespace of the trait Authorizable is Illuminate\Foundation\Auth\Access in Laravel while it is Laravel\Lumen\Auth in Lumen. I am using a model which uses that trait. How do I make my model compatible with both Lumen and Laravel?
Well, you could simply have two different files and classes wrapped in if statements and check for the corresponding classes to extend. So:
LaravelClass.php:
if(class_exists(Illuminate\Routing\Controller:class)){
class LaravelClass extends Illuminate\Routing\Controller {
use YourCodeTrait;
// any more code that is not in your trait
}
}
LumenClass.php
if(class_exists(Laravel\Lumen\Routing\Controller:class)){
class LaravelClass extends Laravel\Lumen\Routing\Controller {
use YourCodeTrait;
// any more code that is not in your trait
}
}
Loading both files will only load one of the classes. In the code above I use a trait to load the contents of your controller, assuming the contents is the same, you could use the same trait and not have to repeat yourself.
trait YourCodeTrait{
// whatever would normally go in your controllers
}

CodeIgniter cannot instantiate a model extending abstract base model

I'm trying to make an application in CodeIgniter where every controller extends a base controller called 'Incyte_Controller.php' and where every model extends a base model called 'Incyte_Model.php'.
I used to import these parent classes in every child class using 'require', but want to change that as it is too redundant for me.
So i moved the base files to 'application/core' and changed the base class prefix in Config.php from 'MY_' to 'Incyte_'.
Now, all controllers can extend 'Incyte_Controller' without the use of 'required'.
But, strangely, when the application tries to load a model it says:
Fatal error: Cannot instantiate abstract class Incyte_Model in
/opt/lampp/htdocs/incyte/system/core/Common.php on line 172
This happens even though i try to extend the base model in the exact same way i extended the base controller.
I checked for spelling errors, including capital letters, but found none.
Also, i must mention that both base classes are abstract classes, because they shouldn't operate on themselves(my teachers would most likely prefer that)
Please understand i KNOW abstract classes themselves cannot be instantiated, but classes that extend abstract classes CAN be instantiated, and that is what i'm trying to do. But it doesn't seem to work in one case, while it does work in another very similar case, which is strange.
I hope any of you can help
A better way to do this would be to extend the core model class to something like MY_Incyte_Model and then extend this in your actual models.
So instead of class AwesomeModel extends CI_Model you can have class AwesomeModel extends MY_Incyte_Model.
Read more here
https://ellislab.com/codeigniter/user-guide/general/core_classes.html
Go to /opt/lampp/htdocs/incyte/system/core/Common.php and you will find a line trying to do something like this:
new Incyte_Model();
The Incyte_Model class is abstract (which means that it can't be used directly - it has to be sub-classed).
Look into how PHP handles Object Oriented (OO) code.
In particular, look at class abstractions.

Using Custom Controller to extend module controller in Zend Framework 2

It appears that in Zend Framework 2, every controller seems to extend the AbstractActionController by default.
I was thinking if there's a way for all my controllers to extend a CustomController that in turn extends the AbstractActionController.
The purpose of this CustomController, is to do checks like whether a user is authorized to access my other controllers or not and also may be generate menu navigation.
Is this still a good idea and if so, will doing this work?
**IndexController.php**
class IndexController extends CustomController {
}
**CustomController.php**
class CustomController extends AbstractActionController {
}
Thanks,
Of course you can extend a base class and it will work.
Is it a good idea ? It really depends on your project.
For authentication and permission check, you could also use a module like ZfcRbac or BjyAuthorize
For navigation, there is spiffy-navigation
If you use php 5.4+, Traits can also be an alternative to inheritance

Adding PHP namespaces into an existing ZF1 application

I'm trying to integrate PHP namespaces into an existing Zend Framework project (v1.12). When I add namespacing at the top of a working controller, it doesn't work anymore and the application throws an Invalid controller class error. Here's my controller definition :
namespace MyProject\Controller;
use MyProject\Controller\MyRestController;
class MyFooController extends MyRestController
{
}
and the init method within the Bootstrap.php:
protected function _initAutoload()
{
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->registerNamespace('MyProject');
return $autoloader;
}
Just a guess (have not used ZF for quite some time): Zend will not accept any class as a controller, just those extended from the framework's base controller class. As you don't extend from the frameworks base controller class you see the error.
If that is the reason, take care you initially extended from the base framework controller class or you implemented the needed interface.
namespace MyProject\Controller;
class MyRestController extendes Zend_Framework_Base_Controller_Class_Name_Here
{
...
p.s. the use MyProject\Controller\MyRestController; looks superfluous as that class is in that namespace already. Let's review your code:
namespace MyProject\Controller;
This sets the namespace of the file. That means, non-FQCN will resolve into it. For example:
new MyRestController();
Resolves to the following FQCN:
new MyProject\Controller\MyRestController
Which - oha! - is exactly what you wrote in use:
use MyProject\Controller\MyRestController;
Which means, that this use clause is superfluous, the extend in:
class MyFooController extends MyRestController
Would go to it anyway at first. Because it's the same namespace.
I am facing similar problem now. For me this looks like that Zend cannot properly resolve namespaced controller name. So when I put for example IndexController into namespace \Basic\Controller, it will be not loaded because Zend want to load \IndexController class, which does not exist.
I am thinking about extending standard zend router class, which has method getControllerName.
Then I can set this in bootstrap by:
$router = new \My\Namespaced\Router();
$front = Zend_Controller_Front::getInstance();
$front->setRouter($router);
I didn't tried that code yet but this should work.

Extending the IndexController with a BaseController in Zend

I'm trying to extend my controllers with a global base controller as such:
class BaseController extends Zend_Controller_Action {
// common controller actions
public function listAction() {
// do stuff
}
}
class IndexController extends BaseController {
// index controller specific actions
}
class LoginController extends BaseController {
// login controller specific actions
}
But I get this error:
PHP Fatal error: Class 'BaseController' not found in /var/www/Zend/project/application/controllers/IndexController.php on line 3
Any ideas on how to get Zend to "see" this controller?
Autoloader
Setup the autoloader and register your library which should be besides the Zend library with the autoloader like so (in your bootstrap.php after setting the include path):
//AutoLoad loads classes automatically if they are used
require_once 'Zend/Loader/Autoloader.php';
$loader = Zend_Loader_Autoloader::getInstance();
$loader->registerNamespace('Mylibrary_');
Zend naming conventions
Then you should rename your BaseController as follows
/Zend (folder)
/Mylibrary (folder)
/Controller (folder)
Action.php <-- this is your basecontroller file
which contains:
class Mylibrary_Controller_Action extends Zend_Controller_Action
{
}
and your normal controllers in the controller folder:
class IndexController extends Mylibrary_Controller_Action
{
}
so basically when you want to extend the framework you keep a parallel structure in your own library.
I would separate it into your own library, i.e. create the file library/YourApp/Controller/Action.php, and consequently name it YourApp_Controller_Action extends Zend_Controller_Action. From there you could place controllers where they should be and let them extend YourApp_Controller_Action in favor of Zend_Controller_Action.
To find the file you should rely on the autoloader to look not just inside of library/Zend, but also in library/YourApp. I.e. look for the set_include_path in your bootstrap.
With this technique you should keep in mind that your custom "basecontroller" might get bloated with methods that not all of your controllers needs to inherit.
the quick solution that does not take advantage of the autoloader functionality is to
require_once '/path/to/BaseController.php' in the index-controller file.
If you have set-up autocontroller, then it can not find it, so you should consider checking what's wrong. Try the previous approach and inform on results.
Even more quicker solution (and conceptually more correct) is NOT to create base controllers at all:)
You have common action? Use action helpers. You have some functionality that must be autorun? Use controller plugins.
By design ZF controllers were made as flexible as possible, and limiting yourself by inheritance (and coupling it brings) is just not the best possible strategy.

Categories