Cakephp: Abstracting AppController another level, possible? - model-view-controller

I was wondering if it's somehow possible to add another abstraction controller between AppController and my app's other controllers?
So that my controllers, e.g. UsersController extends SecureController
and SecureController extends AppController.
Also I want to be able to have other controllers extend AppController directly:
SomeNonSecureController extends AppController.
this is because my current AppController has all sorts of Auth and ACL stuff in its beforeFilter, but i also have controllers that don't need that security stuff (before everything needed the security, no new specs have been added)..
but because some many controllers do need it, it doesn't make sense to copy-paste the code to all needy controllers.
I was thinking to but all the beforeFilter security stuff into a SecureController - that way any controllers that need security simpley extend it, while others inherit from AppController directly.
How would you go on about doing something like this?
Thanks in advance,
Ken.

My first thoughts would be to see if I could abstract some of the functionality from the beforeFilter into a component - remember components can use other components too, just include them in your component's $components property, so you can access the AuthComponent and AclComponent etc.
If this was not suitable then I'd go for your route, in order to do it, just include('secure_controller.php'); before your individual controller class declaration in it's file.
I have done something similar by creating a BaseController that I use in all my projects which provides all my admin CRUD actions that are standard. I then have my AppController extend this which contains application specific, controller wide functionality, then individual controllers extend that, and end up being practically empty. All I do is:
// app/base_controller.php
<?php class BaseController extends Controller {} ?>
// app/app_controller.php
<?php
include('base_controller.php');
class AppController extends BaseController {}
?>
// app/controllers/my_controller.php
<?php class MyController extends AppController {} ?>

I've just been attempting this too. It seems it's relatively simple to extend any controller with any other one. In Cake 2.0 you just use the import() statement (include() does a similar thing).
App::import('Controller', 'Security');
class SecureAreaController extends SecurityController {
// extra functionality *not* in base class goes here
}

Related

Yii 1.1: Can I have multiple base controllers?

There is a Controller class in protected/components that starts with the following comment:
/**
* Controller is the customized base controller class.
* All controller classes for this application should extend from this base class.
*/
class Controller extends CController {
...
Can I define an alternative base controller, lets say Controller2:
class Controller2 extends CController {
...
And derive some user controllers from it? Will it violate Yii architecture or introduce some flaws somehow?
Yes, you can have multiple base controllers. Default template represents pretty basic application so some concepts are simplified. In bigger applications having multiple base controllers is pretty common (for example separate modules can have its own base controller), although usually you have some hierarchy and there is one base controller at the top of inheritance tree.
You can have multiple base controllers which extends CController directly, but it may be harder to introduce app-specific behavior - in your case you would need to copy the same code to both Controller and Controller2 classes. So usually it is good practice to create app-level base controller which will be base for all controllers - even if it is empty at the beginning in may save you the trouble of changing each controller at a later stage of the project.
For example you may have separated base controllers for backend and frontend, which extends one app-level base controller:
class FrontendController extends Controller {
// frontend-specific adjustments
}
class BackendController extends Controller {
// backend-specific adjustments
}
class Controller extends CController {
// app-specific adjustments (for backend and frontend)
}

How to extend Laravel core class MessageBags

I need to extend Illuminate\Support\MessageBag because of add some help methods but I cant bind my own class App\Support\MyMessageBag to laravel use my class (that extends App\Support\MyMessageBag) instead of original core class.
Do you have any ideas?

Clarification of Laravel Request Class

I see that laravel controller comes with 2 request class. Are they the same?
use Illuminate\Http\Request;
and
use App\Http\Requests;
Is it optional to choose one over the other?
use Illuminate\Http\Request;
This one is a file located in vendor/laravel/framework/src/Illuminate/Http/Request.php , it's a class with all the methods and properties related to a request, it extends SymfonyRequest.
class Request extends SymfonyRequest implements Arrayable, ArrayAccess
{
// ...
}
use App\Http\Requests;
This one itself is just a namespace, it's like a stub to the requests namespace. I never use it (I use a line for every request).
It could be used in this way:
public function save(Requests\FormRequest $request)
App\Http\Requests\Request extends the Illuminate\Foundation\Http\FormRequest and any class that extends it is going to validate itself when resolved out of the IoC Container.
On the other hand Illuminate\Http\Request is just a plain request that extends directly from SymfonyRequest it's useful to inject in your controller methods if you just need to extract the request parameters or the user from the current request.
Laravel 5 (I hope :p) you can just use at the top:
use Request;
I am not much sure about use Illuminate\Http\Request;
But App\Http\Request is the class which is used to:
Get users' input data.
If user fills form, then we can get data with the help of this class.
2.Make user input validations.
Validations can be done in controller but it is not good practice.
We should use seperate request class that can be made by:
php artisan make:request request-class-name.
This will make a file in App\Http\Requests\ with given name i.e. request-class-name.
In this class we can do validations as well as authorizations.
If you want to learn about authorizations then learn about Gates https://laravel.com/docs/5.4/authorization.

Can a controller use the same instance of command from a controller it extends?

I have multiple SimpleFormController controllers. One controller contains a command object used to filter results in the other controllers. I seem to be missing something simple, but I can't seem to find a way to use the same instance of the command object in the other controllers.
My setup is such that this main controller, let's call it RootController extends SimpleFormController, and the rest of the controllers extend RootController. The idea was that the command object is stored in one place - RootController and the controllers that extend it reuse the same object. However, it doesn't seem to be working that way, other controllers seem to have their own copy of the command object.
Form backing objects are just normal Pojos, so you can inherit it form each other.
public class BaseCommand {
...
}
public class MoreCommand extends BaseComman {
...
}
May you just forget the "update" the commandClass in your Controller Subclasses.
Anyway: notice that SimpleFormController is deprecated in Spring 3.0. Instead the Annotation Style is preferred.
Update: One INSTANCE of an command object, can be handled by only one INSTANCE of an Controller. So you can subclass the Controller (don't miss to call super), but you can not have two instances of the controller and hope that both are invoked.

Where to place the login/authentication related actions in MVC

I've searched around and found that when implementing an authentication module in MVC architecture some people opt to place the login related actions in the User controller while others place it in a controller dedicated to authentication only.
In pseudo-java-like code:
class UserController extends Controller {
public login() {
//...
}
}
Accessed with http://mydomain.com/user/login.
vs.
class AuthController extends Controller {
public login() {
//...
}
}
Accessed with http://mydomain.com/auth/login.
I would like to know which approach is better, and why. That is, if there's really any difference at all.
Thanks in advance.
IMO:
The stuff handling the actual login should be in a controller, like the UserController you suggested.
Persistent authentication (e.g. checking whether a user is logged in) could just be some functions in the UserModel, which you call from any controller.
Depending on the situation, you may want some kind of global function that redirects to the login page if the user is not logged in.
I prefer the first approach, with the simple reasoning that the authentication is an action pertaining to the user. And in general, I prefer my controllers to reflect the real-life entities my logic deals.

Resources