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

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.

Related

Point cakephp 3 model to a different table

For database organisation purposes, I have added pretext for every table.
I would then name models in Cakephp without the pretext, for less writing when calling them.
In Cakephp 2 I would use public $useTable = 'dev_pictures'; to point "Picture" model to "dev_pictures" table, in Cakephp 3, this has no effect. How would i do it in Cakephp 3?
Why not simply reading the migration guide?
It's now Table::table(), the method is a getter and setter. Set the table name in your tables initialize() method.
CakePHP 3.0 doesn't support table_prefix and 3.1 doesn't seem to be addressing that. So, in the meantime I think the simplest solution is doing the following:
class Picture extends AppModel {
public $useTable = 'dev_pictures';
}
(Take in account that CakePHP 2.x prefix support was not really solid).

Unable to access model in plugin

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');

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.

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.

How do I implement a model for an Oracle package in CakePHP?

I have an Oracle package that I need to access in CakePHP. I am trying to determine the best way to implement the code for calling this function. I need to pass for variables from the UI to the procedure being called. I want to be able to use the model for the field validation before submitting to the package. It is a very specific procedure call:
begin SCHEMA.package.function_name(vars); end;
At the same time, there isn't the standard $this->save() or $this->find() to a package.
Does anyone have CakePHP experience with this? Or any suggestions for implementation? Should I just put it in a model by itself?
Well, after no response I did some digging this week, and I think I have a great solution to this. I was actually thinking it was more complicated than what it really is.
Set up a model to point to the package you create. Within the package there may be multiple functions. So the model will contain all of the functions for the package that are required for your application.
Here is what my model looks like:
<?php
class {PACKAGENAME} extends AppModel {
var $name = {PACKAGENAME};
var $useTable = false;
function {PACKAGE_METHOD}() {
return $this->query('begin SCHEMA.PACKAGE.FUNCTION(); end;');
}
}
Replace the {PACKAGENAME} with the name of the Oracle package. The rest should be self explanatory. You can also configure the function to handle variables, of course.

Resources