I'm working on a web application, using the CAKEPHP framework. Herefor i need to request one variable on multiple pages (all pages have different controllers). it is oubvious that i get a error on several pages, since the variable isn't declared in all the different controllers.
Is there a workaround for this? i've already tried the app:: import to import a controller in another controller, but this doens't seem to work (still get a undefined variable error).
Thnx for your cooperation!
Regards,
Simon
Duplicate question, but I think it's phrased a bit better so I'll paste my answer here:
Standing on the shoulders of deceze's comment and DavidYell's answer, I think they've managed to scratch out a decent view of what you're trying to get to. Maybe. So with that loose understanding of what you're seeing and what you have...
By default, the PagesController::display() method generates the homepage view (home.ctp). I suspect that this is what you're talking about. That said, the variable you're setting in a method of your SectionsController won't be available to your homepage which is created by a different method in a different controller. If you want a variable available to all views there are several things you can do:
You can set the variable in your config/core.php file (not generally recommended)
You can set it in config/bootstrap.php if it's a constant. By that, I mean that it's a value you're going to hard code, not something dynamically generated. Whether you create the variable as a constant doesn't matter.
You can set in in your AppController in a beforeFilter() or beforeRender() method. All of your custom controllers (assuming you've followed protocol) inherit from the AppController. If you choose this path, make a copy of cake/libs/controller/app_controller.php and place it in your app/ directory.
Those are the ways that I think will best meet your needs as I understand them.
You can use the Configure.write... more info here
More on configure class
One way to make sure that the variable is available on all pages is to define it on the front controller (normally index.php) or any other always included file (such as global configs), another option might be to use the $_SESSION super global.
You can youse the beforeRender() or beforeFilter() callback methods from your AppController. :)
These'll be called on every page request. :)
If you to access a value from different controllers, you will need to save that value into a database record so it can be accessed by the different controller methods. Each controller call exists in its own context and can only share data that is stored external to the scripts.
In situations like this, I've created a preferences table (with fields like, id, name and value). Then add a $uses value to the app_controller to make it available to all controllers. Finally, just grab it with a find call. (ie. $foo = $this->Preferences->find( 'first', array('conditions'=>array('name'='foo')));
Related
I am attempting to create a controller that can detect if it is called from another controller in the application.
If it called directly via the URL, however, I need to know so I can perform some other actions.
i.e.
cheese/modulename calling potato/modulename is different to someone accessing site/cheese/modulename via URL - and I need to be able to pick up on this and act accordingly.
I am aware of:
$this->router->class
but it will not work as I may have the same named class in another module (HMVC pattern as an FYI) that may want to call this controller (cheese/modulename calling potato/modulename as an example would return 'modulename' - so I can't use that as a check to see if it was called by itself.)
I basically need a check for:
controller was called via another controller = true / false
can anyone tell me how (or if I am being thick!)
I am doing this in the __construct() just in case your solution will have a problem with that (can't see why but you never know!)
EDIT
Thank you to Mohammad Walid for his answer.
For clarity the structure is
CLIENTS
MODELS
CONTROLLERS
- Client
- Api
VIEWS
JOBS
MODELS
CONTROLLERS
- Jobs
- Api
VIEWS
I will be calling the API from Client - but may also call it from another API (possibly) That may be
In another Module
For Example the CLIENTS Api might get called from the JOBS Api Controller (I have no intention of doing this at present but it may be a possibility under different scenarios I haven't forseen and want to make it future-proof so I don't have a massive refactoring job in the future.)
You can try this:
function is_called_via_url($controller_object){
return $this->uri->segment(1) === get_class($controller_object);
}
and in your controller:
if(is_called_via_url($this)){
//do something
}
I'm not quite sure if passing $this as an argument in the constructor will work, but it worth try.
Reference and a hint from MonkeyZeus's comment.
From the comments there seems to be no way to do this without using debug_backtrace($options, $limit)
However the work-around I have ended up doing is to add a 'flag' within the authorisation module (which is called before all controllers)
The flag defaults to false.
If a controller from within my application calls the API page I turn this flag to true (is_application = true - I am currently just manually pasting this into the __construct of any controllers in my application that need to talk to my API)
I can then just do a simple
if(!is_application){
//this was called directly from the URL not from within the application
}
from within the API controller.
Hopefully this will be helpful for others who are attempting this sort of thing and once again thank you to the people who took the time to comment / answer.
I am trying to use a pre_controller hook in Codeigniter to define commonly used variables throughout the stuff I am building. However I am trying to figure out if a controller is my best choice or should I use something else.
What I need is something that can access the DB, Sessions, Etc yet pass this information down to a view. I also need to in various controllers override a common default from these common variables.
Ideas?
Overall I am thinking controller level so I can play with $this->data[] entries. But I don't think it being a precontroller I can override that in another controller.
You can set variables into $this->config object
I am making website, that will be used by 2 different user types. And both types have different controllers. But some things are common for both users, specifically I want to make a class that will contain methods that will be run when either user logs in (it will check some stuff like is email confirmed etc etc..)
Anyway, I tried to create new library, and that worked sort of.. But there are problems because $this is not available, and I need to use $CI, which needs to be redeclared on every method.. so it is a bit of a pain.
Any better way to do it?
Extend the Controller class. Have a look here:
Codeigniter MY_Controller
Currently in my CI project I have a single controller that handles all things account. Such-as register, login, activation, etc.
My routes work as such...
domain.com/account/login/ or domain.com/account/register/
How can I remove account from the route while also being about to remove the controller from other pages.
I basically want the controller to always be removed. One of my reasons for this is SEO, search engine rank the importunateness of a page based on how deep it is in a website.
The only way I have seem to achieve this is to do some thing like route['activate'] = 'account/activate'; for every single page, which would be a huge hassle.
$route['^(?!other|controllers).*'] = “account/$0″;
Try this :
$route['(:any)'] = "account/$1";
The answer to your question is that you DO have to explicitly set the routes.
How is it going to know which controller a given function is in????
You have to tell it.
use mod_rewrite (if the controller is always the same name)
Ok, I can think of one way to do this, but it is probably gonna be more of a pain than just writing out routes for each function.
You need to extend the Router.php with application/core/MY_Router.php and overide the _validate_request() method. Which basically decides if this this is a valid route or not.
it does a check to see if the controller class exists then fails if it doesn't exist.
You need to replace this with some code which assumes no controller segment, then scans thru each of your controllers and checks if it contains the method called (it will be segment 1, since theres no controller).
Now the tricky part, at this point in the CI lifecycle your controller obviously isnt loaded, so you cant examine it using method_exists() yet.
You need to load your controllers one at a time, and then for each one run
method_exists($loaded_class, $method_name)
and if its true, then set then go ahead and call:
$this->set_class('the_name_of_the_scanned_class_which_had_the_method');
Then CI can keep going on as normal and it will load your methods without the user ever know what controller it loaded from.
.. probably not worth the hassle imho. A much easier solution would be to just have one controller and one route to that controller.
I created a page using the MVC structure called 'sections' ( view is located in the app/views/sections folder, model in the model folder and the controller in the controller folder) when i request the variable $test, it works fine without any errors..
When i want to request this variable in my home.ctp, it provides me with an error, saying that the variable is undefined..
Is there any way in cakePHP to request this variable on any page you want it to?
Thnx in advance!
In the MVC stack, you need to set variables with data in your controller, and then pass them out to your view.
So in your example, you'll want to $this->set('myvar',$item); in your SectionsController, then in your view, you will be able to echo $myvar.
Be sure to set this in the home() method of your Sections controller, otherwise it won't be available in your home view.
Standing on the shoulders of deceze's comment and DavidYell's answer, I think they've managed to scratch out a decent view of what you're trying to get to. Maybe. So with that loose understanding of what you're seeing and what you have...
By default, the PagesController::display() method generates the homepage view (home.ctp). I suspect that this is what you're talking about. That said, the variable you're setting in a method of your SectionsController won't be available to your homepage which is created by a different method in a different controller. If you want a variable available to all views there are several things you can do:
You can set the variable in your config/core.php file (not generally recommended)
You can set it in config/bootstrap.php if it's a constant. By that, I mean that it's a value you're going to hard code, not something dynamically generated. Whether you create the variable as a constant doesn't matter.
You can set in in your AppController in a beforeFilter() or beforeRender() method. All of your custom controllers (assuming you've followed protocol) inherit from the AppController. If you choose this path, make a copy of cake/libs/controller/app_controller.php and place it in your app/ directory.
Those are the ways that I think will best meet your needs as I understand them.