CakePHP a class that can be used anywhere? - cakephp

I have a multi-domain site. Depending on the domain the site needs to behave accordingly.
I created a helper called CompanyInfo it has methods such as name(), phone(), email(), etc.
Depending on what domain you are on it returns the correct information.
So for example if I need to display the phone number for a user to call I would use $this->CompanyInfo->phone() and it will display the correct phone number for the user depending on the domain.
Ok, this is all good, but not really relevant. The real issue is, I need this information in more than just the view. Helpers are just for views though. If I want to access this information from a controller I need to create a component to do it.
I really don't want to have a Helper and a Component doing the same thing. I would rather have one class handle it rather than copy and paste logic.
So whats the best way to have a class with methods that can be accessed from the controller or view or even model?

Is it just this kind of static information (name, phonenumber, email, etc) what you need to display? Why not just add them to your configuration in core.php?
Something like
# in core.php
Configuration::write('Company.name', 'Acme Corp.');
Configuration::write('Company.email', 'joe#acme.com');
You can then get this info anywhere you need using
Configuration::read('Company.name');

You can define this variable in your app_controller and then use these variable easily in any of your controller as set these variables from there only.
Call this function in your construct class.
i think that will solve your problem.

You can access model classes from any place this way :
$companyInfoModel = ClassRegistry::init('CompanyInfo');
$phone = $companyInfoModel->phone();

a) you can use libs in cake1.3 for that
b) static model methods which you can pass the content to and which will return the expected value
echo Model::phone($data)

Related

Proper way to access entity key outside the original class

I'm coding my first GAE web app in Python. I need to collect ~30 properties and instantiate a Client object (I'm using Model.db). I'd like to accomplish this on 4 separate sequential forms. If I use a separate page handler for each form, what is the best way to extract and reference the key or id on each form and put data into the same data entity? How do I avoid a global variable?
Not sure I follow... You may need to explain the issue a little more clearly.
First, do not use a global variable.
You can have 4 forms on the same template, all with the same handler. Give each a separate hidden attribute. Or, depending on your templating package, you should be able to access the form by ID.
In your handler:
entity = MyModel.get_by_key_name('my_key_name')
if request.method == 'POST':
if request.POST['hidden_field'] == 'firstform':
entity['prop_1'] = form.prop_1.data
...
if request.POST['hidden_field'] == 'secondform':
...
...
entity.put()
else:
return <template>
You will need to modify the syntax above to suit your templating pkg.

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.

Grab a variable from the URL and then pass it to a controller CakePHP 2.0

I'm trying to build a sort of Wordpress-esque CMS system to a project I'm building. I want the user to be able to create pages on the fly, and for them to appear in certain areas of the website.
I have made something similar in Symfony2, where the controller grabs a specific variable from the URL (as definded in the route.yml file, usually $id etc) and I then use the variable in the controller to display whatever content it relates to in the database.
However, I'm not used to CakePHP 2.0, and struggling to find what I need. I know it's possible, but I don't know the best way to achieve it. Especially as CakePHP uses a different routes file than Symfony.
How would I grab a variable from the URL and pass it for use inside a controller?
By variable do you mean GET query string parameters, like in /foo?key=value? You can access them in the controller through the request object: $this->request->query['key'].
If you are looking for something more integrated you can use CakePHP's default routes or make your own.
The default routes work with URLs like /controller/action/param1/param2 and pass the parameters to the action by position. For instance /posts/view/521 maps to a call to view(521) in PostsController, and /posts/byMonth/2012/02 maps to a call to byMonth("2012","02").
You can also use named parameters and the URLs look like /controller/action/key1:value1/key2:value2. In controller actions you would read them with $this->params['named']['key1'].
With custom routes you can make your URLs anything you want. You're not forced to the /controller/action pattern; you can make /archives/2012-02 map to PostsController::byMonth(2012,2), or have /512-post-title map to PostsController::view(512).
Typically you would start out with the default routes and add custom routes when you decide you need them. You can read all about the default and custom routes in http://book.cakephp.org/2.0/en/development/routing.html
Short answer: it depends.
If you're looking to pass parameters to a function, you don't need to mess with routes at all; every non-named URL path segment is processed in order and handed to the action as method parameters (so /controller/action/1234 passes "1234" as the first parameter to the action method in the controller controller class).
Named parameters allow you to pass parameters anywhere in the URL string, and to make them optional. The form is just key:value and they're accessed via $this->params['named'] in the controller.
The last option is prefix routing. The best place to get to speed on that is naturally the CakePHP Cookbook, but the general gist is that in a route definition, you can name a path component in the URL by prefixing it with a colon, identically to how the default routes show :controller, :plugin and :action. You can define any name you like, even optionally applying regex pattern requirements and then access it through $this->params['variablename'] in the controller.

How to pass var from controller into a different view with Cakephp

I am new to Cakephp and indeed OOP, so forgive me if i haven't fully grasped the MVC concept yet. I have search a lot but cannot find an answer - perhaps my way of working below is not correct. I hope you can help.
I am building a site which will have many elements relating to their tables and data. I intend to use a view to pick and choose the relevant elements and any parameters needed.
For example, the homepage of my site will have two elements - a latestusers element and a latestscores element. I am trying to use a view not related to either the users or scores models/controllers, stored in 'other/index.ctp'.
I have tried using set() to pass a variable from the users controller (latestusers action) into the other/index.ctp view, but the viewVars remain empty. Could this be due to scope of the variable (i think it is fine for a view in the users folder, i.e. a view specific to the users controller).
I could achieve what i want to do by using global variables, but i think this is missing the point of MVC/OOP. Would be grateful for any suggestions.
I can include code if need be - it is fairly basic at this stage - but i feel my problem lies with how i am going about things, not the code itself.
Cheers,
James
Yes, the issue is with the scope. If you're going to use variables in the element you'll need to pass them in from your view. So the flow would look something like this
Controller $this->set()s the variable into your current view/layout
Your view/layout calls $this->element with the current element path.
Your element uses those variables.
In number 2 you need to pass your variables as an array of data. This section on the cookbook gives more information : http://book.cakephp.org/view/1081/Elements
<?php echo$this->element('helpbox',
array("helptext" => "Oh, this text is very helpful."));?>
Note - I didn't understand part of the question. Just want to make sure you are passing data to the correct view. You should not be calling the view of another controller in your active controller.
Your other/index.ctp should be an element and that element should be called from your layout.

Count number of posts in cakephp

I'm trying to create a menu in cake php where I can also know how many articles are inside the section, should I use a manual query, or does exist some existing method to do it?
My site menu:
- Works (12)
- Photos (35)
- Stuff (7)
- Contacts
My problem is also I didn't get how I can access to data like this for every view, this should be a main menu, so I should use this in every view but If i put it in default.ctp, every model deosn't exist, because I cannot access it from a view.
Does exist some page which talks about this?
Since those are separate models that are not related to each other, you'll need to do a manual count.
$this->Model->find('count');
EDIT
Ok, so looks like you are talking about different models.
If this is used in a menu, that means it will be shown in all pages.
You have two ways of doing this.
You can do it by having an AppController for you application. Basically, you can put this code in the beforeRender method so it runs everytime your a request is rendered
function beforeRender() {
App::import('Model', array('Work', 'Photo', 'Stuff'));
$work = new Work();
$workCount = $work->find('count');
//do the same for the other
$this->set('workCount', $workCount);
}
Have a look at this for more details on callbacks : http://book.cakephp.org/view/977/Controller-Methods#Callbacks-984
Secondly, you can do this via a helper. You can put the same code (that is inside the bforeRender) into a helper, and you can call the helper method.
You can look here for more info on creating a helper : http://book.cakephp.org/view/1097/Creating-Helpers
The CounterCache behavior will help you out:
http://book.cakephp.org/view/1033/counterCache-Cache-your-count

Resources