CakePHP - centralizing controller logic - cakephp

Using CakePHP, I am finding that I'm duplicating some code between controller actions. I have a dozen or so actions (belonging to various controllers) that all need to run the same query and set() the same 10 variables for the use in a particular layout. They also need to handle any errors in the same way and render an error page.
I know that components are intended to centralize logic used among controllers, but in my case, this logic needs access to the set() and render() methods of the controller. What is the suggested approach to this situation?
Thanks, Brian

Put the logic in your AppController class which your controller should extend from.
Check out the docs: http://book.cakephp.org/view/957/The-App-Controller

Ended up rolling my own sort of business logic layer on this one. Example below. Thoughts/comments welcome.
class MyController extends AppController {
public function my_action() {
// The BLL class is specific for this action and gets the entire
// controller so has access to the set() method as well as components.
$this->Bll = new MyActionLogic($this);
$this->Bll->do_whatever();
}
}

Related

How to call controller within another conroller in cakephp

I am using cakephp v2.6 to develop a web app.
Is it possible to call a controller within another controller in CAKEPHP.
Is it correct way for doing the same
In SecondController.php
App::uses('FirstController','Controller');
class SecondController extends AppController
{
$firstcontrollerobject=$this->FirstController;
}
Thanqs
Short answer is Yes, but you shouldn't.
You should use either a component or a model. Or put your action in AppController if you want it to be used by other controllers.
App::uses('FirstController','Controller');
class SecondController extends AppController
{
public function test() {
$FirstController = new FirstController();
$Firstcontroller->action();
}
}
Put PHP code in the Component, if you want to share between several controllers
Components are packages of logic that are shared between controllers. CakePHP comes with a fantastic set of core components you can use to aid in various common tasks. You can also create your own components. If you find yourself wanting to copy and paste things between controllers, you should consider creating your own component to contain the functionality. Creating components keeps controller code clean and allows you to reuse code between projects.
http://book.cakephp.org/2.0/en/controllers/components.html

CakePHP how to log API requests globally?

I have an API based on CakePHP, controller with name AccessLogController is responsible for saving access log into the database.
Question is:
What is the best practice for global logging in CakePHP?
I thought that I will call AccessLogController method from inherited AppController in before filter callback like this:
public function beforeFilter() {
$accessLogCtrl = new AccessLogsController();
$accessLogCtrl->add($param1, $param2);
}
But i not sure that is it a good way how to do it..
Many Thanks for any advice..
That's not how you should use controllers, never ever, except maybe in your test suite!
That being said, using AppController::beforeFilter() to globally log controller action requests is generally fine, just make sure that you always invoke parent::beforeFilter() in case you are overriding the filter in an extending controller.
However, you should definitely refactor your logging functionality into either a utility class, a component, a model, or even directly into AppController, depending on how it's actually logging things, and if you need to use it in places other than in AppController.

How to work with controllers for Extjs deeply nested components?

I have a large scale application with lots of views, models, stores in it. Till now i am able to manage all the functionality to run from functions, events withing the views itself. I have never used controller to handle the entire application.
Please let me know how to use controllers to handle each and every component in the app. And there are some components that are dynamically being generated. How to add listeners these components on demand.
Please tell me about controllers much!
Thanks in advance :)
Controllers use event selectors to handle events through an event bus, so handling events is built in to the component structure.
A controller typically looks like:
Ext.define('MyApp.controller.Foo', {
init: function() {
this.control({
'some_selector': {
someevent: this.onSomething
}
});
},
onSomething: function() {}
});
The selector is an Ext.ComponentQuery selector, so if a component that matches that selector fires a particular event, it will call your method. There's plenty of information about selectors in the docs.

CakePHP: Layout, variables and question

I got layout, nothing special, three columns, just to learn CakePHP. In documentation I found nothing about this case.
I got some statistics in sidebars, si I send them to layout file (default.ctp) cause they are displayed on every page.
I build (thanks to one user here) a component:
class SidebarComponent extends object {
function startup(&$controller) {
$this->controller = $controller; // Stores reference Controller in the component
}
function count_articles() {
$articles = ClassRegistry::init('Articles')->count_articles();
$this->controller->set(compact('articles'));
}
}
Everything is working perfectly. I got question about my technique. I needed to load component method in controller by putting:
$this->Sidebar->count_articles();
So I decided to make it a bit shorter, cause I will have to put it in every controller. So, I created new component's function:
function sidebars($userid) {
return array(
$this->top_articles(),
$this->random_article()
);
}
And I initialize it in controller that way:
$this->Sidebar->sidebars();
Everything is working correctly, I need only advice/feedback if it's good way I do this :)
Thanks for your time.
you don't need to call it explicitly in every controller. component's startup() method is called automatically before every action in the controller that is using your component.
so you can use startup() to get and set your data for views, and if you need some initialization before (like getting reference to controller), put it in component's initialize() method.
If you have sidebars with the same things in them, also sounds like a case for elements as well

CakePHP: Query in Component?

Got question, maybe even problem while creating CakePHP Component. Basically, I need to implement few quesries that can be accesses everywhere in my layout (sidebar statistics and so).
When I try to query in Component, I got error about calling function on a non-object.
Damn, can anybody explain me this one?
Cheers!
Are you doing something like this?
class MyComponent extends object {
function startup(&$controller) {
$this->controller = $controller; // Stores reference Controller in the component
}
function common() {
$data = ClassRegistry::init('MyModel')->myQuery(); // Call the query on the model
$this->controller->set(compact('data')); // Sets data from myQuery in view
}
}
At the risk of sounding pedantic, you'd be violating MVC pretty egregiously by doing this. If you're okay with that, you can use App::import() to load any model from anywhere in your app (http://book.cakephp.org/view/531/Importing-Controllers-Models-Components-Behaviors-).
If you're interested in attempting to retain the MVC structure, we may be able to help with some more information about the queries you need to run in that generic manner.

Resources