Unable to access model in plugin - cakephp

I have two Plugins in cakephp both contains User model. When I want to access the properties of User model it always call first User model. How can I access second User Model?

Not possible - rename your models
Unfortunately that's not possible. Because of the way models are defined, that means you're wanting to load two different classes with the same name in the same namespace (global) which is not possible with PHP - the only solution is to use different classnames.
A standard practice is to name plugin classes prefixed with the plugin name to avoid collisions:
So for example in the foo plugin:
<?php
//App/Plugin/Foo/Model/FooUser.php
class FooUser extends FooAppModel {
}
And in the bar plugin:
<?php
//App/Plugin/Bar/Model/BarUser.php
class BarUser extends BarAppModel {
}
This does lead to slightly more cumbersome usage, but prevents roadblock-problems when trying to access both classes at the same time.

You have to specify the plugin name when you initialize the model classes. So you could call your first one 'User' and your second one 'PluginUser', ie:
$this->User = ClassRegistry::init('PluginOne.User');
$this->PluginUser = ClassRegistry::init('PluginTwo.User');

Related

CakePHP 1.3: extending class unable to find its parent model PHP file

In the class declaration line of the model (.php) files, I'm trying to extend off of a different class then AppModel. Let's say I have some models, including Model, ModelOrder, and ModelLastShipment, etc. And yes, "Model" is a made up name for the sake of generalization.
Model does not use a table and does not have any table association. It extends AppModel. It has some basic functions that I'd like ModelOrder and ModelLastShipment (and other Model... classes) to inherit. The problem is that while ModelOrder can be extended (i.e. class ModelOrder extends Model {...}), I'm unable to do the same with the following because of a missing file error.
model_last_shipment.php:
class ModelLastShipment extends Model {...}
This returns the error,
Fatal error: Class 'Model' not found in C:\xampp\htdocs\my_app\app\models\model_last_shipment.php on line 3
Including include_once('model.php') before the declaration solves this issue, but why does the extension work for ModelOrder without explicit inlcusion but not for ModelLastShipment?
Please let me know if there is more information needed to resolve this. There are many articles and posts regarding this sort of error, but I've yet to find out why I'm getting this error for one and not for another.
Let's say I have some models, including Model
It's impossible to create a class named "Model"
Model is a core class. If you create a class named Model, it with either not be loaded (because the class Model already exists) or cause fatal behavior - possibly "at random".
The class structure in the question is:
Overloadable (Cake)
Model (Cake)
AppModel (App)
Model (App) <- problem
That cannot work. Class names must be unique and Model is a core class.
Including include_once('model.php') before the declaration solves this issue
Are these model class names made up? As stated above that isn't possible with a class named Model.
Intermediary class models are not automatically loaded
These are the only model classes that are loaded automatically in Cake 1.3:
Model
AppModel
AppModel (when appropriate)
If the class hierarchy of your models is such that there are more intermediary classes - they need to be loaded explicitly:
<?php
App::import('Model', 'SomethingElse');
class NotNamedModel extends SomethingElse {

CakePHP model named 'Model' not working

I have a model named Model. After some frustration with its responses, I came to the conclusion that the class file is not being used.
To test this, I changed the name of the file from model.php to model_x.php and no errors were encountered.
Can someone verify to me if Model is an invalid name for an appModel class?
I am using CakePHP 2.x
Lee
The class Model is already taken
So what you should do is create another name. It's the same when using a controller and model named layout, because the Layout folder in View is already used for the layouts. So you should either come up with a clever solution with routing, or simply give it a different name.

Howto extend a plugin model class in CakePHP with "clean" classnames?

I'm currently learning CakePHP. I use CakePHP 2.2.3. I have succesfully "installed" a user management plugin. This plugin has a model class "User" and uses table "users". Now, I'd like to extend this User model in order to e.g. relate my own models to it, e.g. Posts.
I managed to to this with the following code:
App::import('Model', 'Usermgmt.User');
class MyUser extends User {
var $hasMany = array('Post');
var $useTable = 'users';
}
This works.
However, I don't like the fact that I have to call my Model class something like "MyUser". It makes everything very ugly and, maybe - theoretically - sometime I want to install another plugin that uses classname "MyUser". Is it somehow possible to use "clean" class names and prevent possible name collisions in the future..?
No, that's not possible because CakePHP doesn't yet support namespaces. According to the roadmap support for namespaces is planned for CakePHP 3.

Autoloading model on demand in codeigniter

Can I somehow omit the first line? i.e. $this->load->model('Model_name'); and autoload it when necessary?
To load a model you will use the following function:
$this->load->model('Model_name');
Once loaded, you will access your model functions using an object with the same name as your class:
$this->Model_name->function();
Lazy loading is not supported in Codeiginiter 2.1
There are a couple of options available to you
Use the 'autoload' in the config. This will always make the model available throughout the application. See here for more info
Load the model in the __construct() of your controller (if it is specific to that controller)
You don't understand the logic .
$this->load->model('Model_name') means you load it when it necessary.
or
If you find that you need a particular model globally throughout your application, you can tell CodeIgniter to auto-load it during system initialization. This is done by opening the application/config/autoload.php file and adding the model to the autoload array.

Dynamically passing a model name to a CakePHP Plugin

I'm having trouble wording my problem, so it's been tough to search for an answer. Hopefully you'll know how to help.
I am creating a CakePHP 2.1 Plugin that will interact with a series of its own Models:
- Friend
- Group
- User
Friend and Group are models that are created specifically for the Plugin, and they function within the plugin normally. However, the User model is really just an alias for some other table in the parent app.
So, if "My Awesome Application" decides to use "My Awesome Plugin", it will have to have its own "users" table (though it may called something else). Let's say "My Awesome Application" has a Model called MyUser. "My Awesome Plugin" wants to dynamically tell its internal User model to $useTable = "my_users".
My question is, how do I pass that data to the Plugin? How do I configure "My Awesome Plugin" to understand that User should $useTable "my_users";
As I understand you would like a Model in a PlugIn to use a table that would typically belong to a Model in your Application - by the conventions. Have you tried statically setting:
public $useTable = "my_users";
in the plugin? All plugins usually get initialized when Cake starts up, so all configurations should be loaded then. Why do you need this - it does really restrict you a lot? Will the table being used by the Plugin model change runtime?
The Model class also has some goodies you may find useful:
$this->User->table;
holds the table name for the model - the table that is currently being used that is**.
Also you can set the source table for the Model (inside a Controller) with:
$this->User->setSource('table_name);
** I am not sure if this applies when you use Model::setSource(). It would be interesting to check out what $this->User->table; holds after a Model::setSource() call.
I've figured out a way to accomplish this, but it might not work in all scenarios for all people.
I created a Component in my Plugin, and then I call the Component in my Controller. I pass the name of the users Model through the Component. This way, I can get information about the users Model, and I can set it as the useTable to my Plugin for use in the Plugin.
Of course, this method restricts me to using the Component to utilize the Plugin, but that's probably for the best.
Here's an example of how I did it:
// in the AppController
public $components = array(
'MyPlugin.MyPluginComponent' => array('userModel'=>'UserModelName')
);
// in the Plugin's Component
class MyPluginComponent extends Component {
function initialize($controller) {
//get the base user model
$this->UserModel = ClassRegistry::init($this->settings['userModel']);
//set the useTable for our plugin's user model
$this->PluginUser = ClassRegistry::init('MyPlugin.PluginUser');
//set the useTable value for this model
$this->PleaseUser->setSource($this->UserModel->useTable);
}
That seems to work for me. Hope this helps someone else.

Resources