I would like to extend Query class in order to create function customContain() available in every Table model. How should I do it?
I want to use that BleMethod() in all table models in cakephp. Where I have to add code of that function? Where I have to implements BleMethod?
Unlike Cake2 Cake3 does not feature an application level class like AppModel from where all other classes inherit from. So you have two options:
Trait
Behavior
The behavior can be loaded globally to all models by using the Model.initialize event. And then loading the behavior inside the events callback. Read these pages:
Creating a behavior
Event system
Model / Table callbacks
But that's not what you want
customContain() indicates for me that you want to setup some contains very often. Well, use finders.
Finders can be combined:
$this->Table->find('foo')->find('myContains')->all();
Each custom find will add something to the query object. You can add your custom contains this way.
Read Custom Finder Methods.
Related
I have same name component and model e.g. product. So how can we use the component function and model functions?
E.g.: $this->componentName->function() / $this->modelName->function()
Assuming this is your own code I'd change the name used by your component. The way I tend to deal with this in CakePHP 2 is to use a plural naming convention with components. So in your example you would have the model Product and the component ProductsComponent. Then in your controller you can easily distinguish between the two:-
$this->Product->function(); // Model method
$this->Products->function(); // Component method
Seeing as in Cake's naming convention controllers are plural it makes sense to extend this to components.
call the components from the collection object.
$this->Color->find(); // Model
$this->Component->Color->method(); // Component
I ran into this problem when I had a model and component both named
"Account". Model gets loaded after so I think it overwrites.
However, I am not sure the Component thing will work as I never tried
it. It does work for Behaviors, so its worth a shot.
I'm trying to get to grips with the power behind Joomla (3.x)'s framework.
I've noticed that there are multiple types of model that can be used in a component:
JModelAdmin
Prototype admin model. Acts as a Factory class for application specific objects and provides many supporting API functions.
JModelLegacy
Base class for a Joomla Model
Acts as a Factory class for application specific objects and provides many supporting API functions.
JModelList
Model class for handling lists of items.
Acts as a Factory class for application specific objects and provides many supporting API functions.
JModelForm
Prototype form model.
Acts as a Factory class for application specific objects and provides many supporting API functions.
JModelItem
Prototype item model.
I understand that JModelLegacy seems to be the foundation class. My models have been extending JModelLegacy by default, however, I was wondering if I could be potentially using the benefits from the other classes.
If there was someone who knows about these models, I would appreciate having an explanation about what the differences are between these model classes, and an intended scenario where you would use one over others.
First of all all the classes are available for code study under:
\libraries\legacy\model\
It's also important to understand that these classes should be used (generally speaking) in connection with the corresponding controllers: JControllerLegacy, JControllerForm and JControllerAdmin.
JModelLegacy - is the base class for the Joomla model (model as in MVC). It will basically work as a Factory class by initializing the database driver object and the table object.
You may want to extend this class if you just want to do some basic SQL queries (any work with JDatabase) and write other business logic.
All models will extend JModelLegacy.
JModelList - is a class for handling lists of items. It provides pagination and filtering. Basically everywhere you display a list of items, you can use JModelList. All core components rely on JModelList.
JModelForm and JModelAdmin are generally associated with forms. Forms can be the the User registration form or creating and editing a record. Forms in Joomla are defined in XML files. JModelForm will load this files as JForm objects, will load form data, preprocess the form and validate it.
This is one of the most powerful classes that you can use. They will do the heavy lifting. When you don't like a specific behaviour you can override it by implementing your own code.
JModelAdmin adds some extra admin functionalities to the form:
perform batch operations on records.
will do ACL checks on records.
JModelAdmin will generally be used when editing a record or for batch operations, especially in backend.
JModelItem - very unlikely you will need it. It exposes just a method getStoreId() and two properties. You won't need this class, unless for as a naming thing, instead of using JModelLegacy you want to extend it when doing something basic, such as displaying a record. (my personal understanding of things).
Conclusion: Above is a general introduction to this classes, as I see them. My suggestion is to look into detail how Joomla uses them, what methods are exposed and how to use them. They are very powerful classes, and especially for CRUD operations they will help you do all the heavy lifting. After you understand what they do, you can use them and override them when needed.
I want to have a filter on my site so they only see what they want to see. For example a user enables a location filter and selects that he only wants to see USA profiles. I save the filters in an different database table then userdata and in json.
This sounds quite simple but it isn't :) I want to prevent that I have to paste a long group of code to almost every model function.
Is it for example possible that I create 1 time a function with json_decode and foreaches to generate the right active record (where) codes and insert it in a model function with for example $this->enableFilters(); ? I use multiple models so I actually don't want to add a function to every model.
Is this all possible?
One option is to extend the core model class to include a common function. Look at the Extending Native Libraries part on the manual.
So, for example, you will create a MY_Model to extend CI_Model and all your models can extend MY_Model. Your common functions can be on MY_Model that is available to all child classes.
I do have an module e.g. account. Of course you will find a file called in acount/actions/action.class.php.
The PHP-file action.class.php is getting big. Is it possible to extend it?
for an example:
/account/action/action.class.php
/account/action/action2.class.php
If it is possible, how does the code look like in action.class.php and in action2.class.php? And/or where should I enter something in a config-ymal-file?
Thanks in advance!
Craphunter
Symfony actions can be declare in two flavors:
A big actios.class.php file that inherit from sfActions
Multiple xxxAction.class.php file that inherit from sfAction
The are both basically the same but these cant be mixed (you must decide if you want 123123 files, 1 per action, or one big fat file).
Here its the symfony reference on this matters: Symfony Front Controller - Actions check the Action section.
It sounds like the action class is getting too big because you have too much stuff in it. I would suggest breaking it into multiple modules or moving relevant parts of the logic code into your models.
Adding an include for an action2 file is not how Symfony 1.4 is intended to be used and will likely just lead to all kinds of other headache.
PHP doesn't support 'partial classes' like C#. So you have two options:
Create an inheritance chain, by creating a baseActions class which inherits from sfAction. Then create your MainActions class which inherits from baseActions. You can add different layers of inheritance.
Group functions in seperate classes. Override the execute() function in your actions file, and manually call the function on the class you need.
Also consider if some of the behavior you're implementing in the action (controller) belongs to the model (or the view) instead. If the really belongs to the action just follow guiman's advice and create an action per class inheriting sfAction.
If I have a CRUD module based on a model (as generated by the CLI), and I have to define additional behaviors for that model, I tend to create another module to contain that behaviours. E.g., considering a model Article. I could create an article module for the CRUD behaviors (generated), article_support for additional behaviors like moderation, activation, etc. and perhaps article_ajax for async requests.
I have an index action in my users_controller that get a list of users. For each user i want to calculate the number of projects they have associated (one user => many projects). I was thinking of using a method like getProjectTotal and calling it for each user. Would I put this method in the users_controller and call it like
$this->getProjectTotal($id)
in the view?
Thanks,
Jonesy
Sure. It sounds like this is just a helper method based on the call. I do that all the time. I'll typically set the method visibility to private or at least protected to keep it from being called accidentally in a rendering scenario.
I'm still relatively new to CakePHP, but I've been using the built-in counterCache in Cake 1.2 to track the number of hasMany records for a parent Model in one of my apps. Create a field in your parent Model to store the hasMany count, and enable counterCache in the $belongsTo property for the child Model, and you're good to go. It automatically updates the counterCache count field in the parent model whenever the # of "hasMany" records increases/decreases. I like this method of tracking as it keeps the controller a little cleaner if all you need is the count without any other conditions.
Docs: http://book.cakephp.org/view/816/counterCache-Cache-your-count
Also, I'm still new to MVC, but I think if you're going to gather the count via a private/protected controller method, you'd want to call it in the controller and then send the data to the view, not perform the actual method from the view, in this scenario.
Also - yes you can make a controller method for work that isn't going to render a view - BUT - in your case you should use counterCache / a Model function since you are either fetching / counting / manipulating actual data related to the Project model and it's relationship with the User model and current logged in User specifically.
When building out my controllers I tend to stick to methods that render a view or return data for an element called from requestAction. If the method is computational or setting up variables but doesn't require a template or isn't called from an element I move it to a component / helper / model / behavior. Combined with a docblock with #requestAction in the flags for introspection and I can get a list of regular actions, and data returning actions without worrying that a controller is full of other methods.