How to paginate existing model functions in CakePHP? - cakephp

I have loads of model functions returning different datasets already.
I would like to be able to paginate these without having to rewrite them all using the paginate method in the controller. Is there a tidy way of doing this?

Wouldn't this do the trick?
$this->set('dataSet', $this->paginate($verySpecialModelDataSet, $paginateOptions));
If you have many controllers, you could possibly make your calls by overriding beforeRender()
[http://book.cakephp.org/view/60/Callbacks] in AppController.

Related

CakePhp pagination and my own function

I have a big function in my model. It returns list of friends with their photos and profiles. There are two 'finds' with loops in body, so it is not easy.
Now I need to show this list with pagination.
Is threre any posibility to create pagination with my method?
There is no posibility to get this data in one find (or paginate) function.
Any ideas?
Yes, it is possible.
You can implement the paginate() and paginateCount() methods on your model, or include them in a behavior attached to your model. Behaviors implementing paginate and/or paginateCount should implement the method signatures defined below with the normal additional first parameter of $model:
Custom Query Pagination will do the same stuff you needed.

Data logic on load using a component - cakePHP

I have a project I'm developing which includes articles that can be commented on (comments stored in separate table of course). I want to perform pre logic on a field from each comment, wherever they are loaded through-out the app. The data logic I want to performed is from a custom written component.
The logical place to me that this could be achieved globally is from the comment model, but I could be wrong.
I'm not even 100% if I can use a component from a model, but I've been trying to do this logic using the afterFind() call-back function:
function afterFind($results) {
foreach ($results as $key => $val) {
if (isset($val['Comment']['created'])) {
$results[$key]['Comment']['created'] = $this->Dateconvert->howLongAgo($val['Comment']['created']);;
}
}
return $results;
}
I have tried echoing from inside this function and it doesn't actually seem to be getting called but searching hasn't revealed any functions that do, but I believe afterFind() is best to illustrate what I'm trying to achieve.
So I am looking for a solution where I can performed the post-load logic on articles comments, whether they are being loaded from other controllers with associations to comments or in the comments controller. Basically a global one hit solution :D
cakephp indicates that components are for controllers and behaviours for models and helpers for view...
knowing that first, you may also know that you can use any part of it wherever you want because cake still php, though is not recomended... if is a library of functions you may want to put it inside the libs folders and access it from there.
how, easy use App::import('component', 'nameComponent'); component can be lib, controller, etc..
Having said that, afterFind is a good place to do after load things, remember that this function is call ONLY when a find is used, if you use, any other like query or save or update it won't be called.
hope this helps you :)

How do I track my parent find function call in beforeFind() for CakePHP

I am currently using CakePHP beforeFind() to filter my search queries based on the current logged in user. It seems great at the moment and everything is working smoothly, the only problem is that I need to know where the find function was initially called so that I can apply different query filters based on the parent find function call; is there anyway to achieve that?
That seems like coupling your models to your controllers/actions, which in general is a bad idea.
Try creating a custom method in your model instead. You can have whatever method signature you need, and just call find from within and return its results as needed.

CakePHP: how to use a model in the app_controller

Iv got a method in a model that I want to be executed everytime a page is requested so I think I need to call it from the app_controller but can't seem to get it to work. The model i want to use is called Blacklist and it has a method in it called check_blacklist() which is what I want to run every time a page is requested. Does anyone know how I should do it?
Thanks
Well, one way to do that would be adding:
var $uses = array('Blacklist');
In your AppController class.
Perhaps a better solution is using a CakePHP built-in method called: loadModel, like this:
$this->loadModel('Blacklist');
If you add Blacklist in the $uses array in your AppController, it will be available in all of your controllers, loadModel just loads the Model for a specific task.
Try to avoid using the $uses array as it adds some overhead to all actions, whether or not the model is used in that action.
As Pawel says, you can use $this->loadModel('Blacklist'); It should be located in the action, say view, just before $this->Blacklist->check_blacklist()
e.g.
function view($id)
{
if($id)
{
$this->loadModel('Blacklist');
$this->Blacklist->check_blacklist();
...
}
}
If this is very widely used, I'd probably write the function on app_model.
Edit:
Use of loadModel is covered here: http://book.cakephp.org/view/845/loadModel
$ModelName = ClassRegistry::init('ModelName');
$ModelName->find();
Unfortunately, due to bug #858, your best bet is to avoid using loadModel() in AppController for now, unless you aren't using any plugins (quite possible). The solution I used to replace $uses was along the lines of:
$this->Blacklist = ClassRegistry::init('Blacklist');
$this->Blacklist->check_blacklist();
Note that you should put this in your beforeFilter() or beforeRender() (see the cookbook) - depending on when you want it executed...
If you'd like to use that same code in other sites, or have it fire earlier in the loading chain, you might consider a Component - putting the same code in your Component initialize() function, or startup() function if the point in the load chain is less critical.

What is the best way to access another CakePHP's Model in a Controller?

Say I got two Controllers like this Table1sController, and Table2sController.
With corresponding models: Table1sModel, Table2sModel.
In the Table1sController, I got this:
$this->Table1sModel->action();
Say I want to access some data in Table2sModel.
How is it possible to do something like this in Table1sController?
I have tried this in Table1sController:
$this->Table2sModel->action();
But I received an error message like this:
Undefined property: Table1sController::$Table2sModel
There are a few ways to go here.
If your models have defined associations (hasMany, etc.), then you can access that model's methods (assuming you're in Model1Controller) with:
$this->Model1->Model2->method();
If there is no model association between the two models, but you want to be able to use the Model2's methods, you can add an entry in the $uses attribute of model1Controller. See http://book.cakephp.org/2.0/en/controllers.html#components-helpers-and-uses
Finally, if it's a transitory connection (you don't want the overhead of loading other models every time, because you're only rarely going to access model2), check out the manual's section on creating / destroying associations on the fly, at http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html
Something is inherently wrong with what you are doing.
In any controller, you can specify $uses = array('Table1sModel', 'Table2sModel', 'LolModel') and use each Model you need in your controller. You are not calling another controller to access a Model. Models are for data access, you access the needed ones directly from any controller.
I understand, that many MVC examples are almost always show you one page of one controller with one model which is horribly wrong as 99% of the cases you have one site from one controller using many different parts of different models.
(If you really need to call an action, use $this-requestAction())

Resources