I am confused about the distinction and treatment of the index() and view() functions inside CakePHP 2.4.
Specifically, I am trying to modify a 3rd party API authored in CakePHP 2.4
Consider this Controller:
class EventsController extends AppController {
<snip>
public function index() {
if ($this->request->params['named']) {
$conditions = $this->request->params['named'];
} else {
$conditions = array();
}
}
This allows me to construct a URL like http://myserver/api/events/index/StartTime >=:12/EndTime <=15.json and the StartTime and EndTime get passed into conditions when I do a find.
That's great.
Now that same Controller has this additional function:
public function view($id) {
}
This function seems to be called when I invoke a url like http://myserver/api/events/1234.json
I am trying to extend view with more parameters, just like index. For example, I'd like to invoke:
http://myserver/api/events/1234/MonitorId =:3.json and MonitorId =:3 gets passed as a parameter to handle in view. I don't want to add these into the function definitions - it can be anything.
If I try and do this, I get a "Controller" not found, but this same approach works in index()
Can someone help me achieve my goal and help explain what is going on?
(IF it helps, the full code of the controller is here)
As I can see, you are using CakePHP RESTful routing routes.php
Here,
index is used for listing all the resources e.g. all blog posts. URL /events/index is getting mapped to index method in controller automagically.
view is used for showing a specific resource which can be identified by some unique identifier like id or uuid e.g. specific blog post. URL /events/<some_identifier> gets mapped to view method
What you need to do is modify view definition to read all query string parameters that you pass in URL and call Model accordingly. By default. routes parses the first string after events in URL to resource ID and passes it as first argument to view method in controller. This is scaffolded code.
You can use named parameters $this->request->params['named'] in your view definition and construct your queries. No hard-coding.
It turns out that I need to explicitly call the view action to pass it more parameters.
So api/events/view/218245/AlarmFrames >=: 80.json works as intended and then I can get the parameters with $conditions = $this->request->params['named'];
Related
I am using cakephp 3.x have put database queries in model in which i want to check the current controller action and based on that i will make my database queries.
I know i can pass controller action from my controller itself to my model function but is there a way i can just check my current controller action inside my model only so that i do not need to pass it in my multiple functions which are inside model only.
My Try -- UsersTable.php
public function initialize(array $config)
{
parent::initialize($config);
$this->table('users');
$this->primaryKey('user_id');
echo '<pre>';
print_r($GLOBALS);
exit;
}
so far if i do this, i got an array in response and in which i found this the best result out of other things in that array
[REQUEST_URI] => /5p_group/users/add
I m also trying to use this
echo '<pre>';
print_r($GLOBALS['_SERVER']['HTTP_REFERER']);
exit;
which gives me this output
http://localhost/5p_group/users/archived
so eventually i am getting the result which i want but i want another proper method which cakephp 3.x uses ..
So is there any other way or more frequent way from that i can get my current controller action ?
Any ideas will be appreciated ..
Thanks
First of all you should use the routing class in your model. So at the top you can call it like below
use Cake\Routing\Router;
And then in your initialize function you can check the params like
debug(Router::getRequest());
Or to be more specific you can use
debug(Router::getRequest()->params['action']);
I think this is the solution using cakephp classes only, though a small hack.
For more function reference you can access the cookbook at Router Class
The question was about a Model, but it shows up on Google.
When inside a view (.ctp file), use
\Cake\Routing\Router::getRequest()->getAttributes();
CakePHP 3
I want to add my save, update, find queries in model and call those functions in controller, rather than adding the queries in controller.
I'm not sure what's you precisely want to acheive, but I first of all hope you know that CakePHP has implemented save, update and find functions for your models. If not, look at the docs, e.g. here: http://book.cakephp.org/2.0/en/models/saving-your-data.html
If you want to add functions with custom queries to your model, you can simply add them as a normal function in your model, e.g.:
MODEL
public function myMethod(){
// Fetch data
return $this->query("SELECT * FROM pictures LIMIT 2;");
}
CONTROLLER
public function index(){
// Get data from model-method
$data = $this->ModelName->myMethod();
// Send data to view
$this->set(compact('data'));
}
In your model classes you don't have to refer to your model in your code:
In your controller: $this->ModelName->function()
In your model: $this->function()
Has the same meaning.
Follow up question to: In CakePHP, where would I put a method that performs a check on the Session User?
Background: In my previous question, I was informed that the correct place to place a method such as levelCheck() which performs a semi-complicated evaluation of a user's level, and is needed in practically all my controllers, is the AppController.
Now, this method is also incredibly useful for the way I design menu layouts and other view devices. For that reason, I would like to create a helper that can make use of that method.
Problem: I recognize that it's generally frowned upon to call a controller method from the view... however there is no viable way for me to pass data to replicate the function of this method, nor do I want to replicate the method in two places (violating DRY methodology).
Question: How then do I call this method from a helper, or is there a better way to provide use of this method in the view/elements?
Put the method in AppController, also - set a variable that will save the result.
In the beforeRender callback, set the result as a viewVar.
some code:
// AppController
class AppController extends Controller
{
$levelCheckResult = null;
function levelCheck(){
$this->levelCheckResult = true/false;
}
function beforeRender(){
$this->set('levelCheckResult', $this->levelCheckResult);
}
}
that's it, now you can access it in the view.
edit
create a public function in the app_controller, and in the beforeRender(), send the app_controller itself, to the view.
class AppController extends Controller
{
function levelCheck(){
....
}
function beforeRender(){
$this->set('TheApp', $this);
}
}
// in the view
$TheApp::levelCheck();
However, please consider again the design. this kind of manipulation is strongly suggest that you should change some stuff there.
In short - the view is still backend execution of the program and not the client side, so in definition - it should and can be controlled, from the controller...
The solution I ended up using was to move the method to a component (CurrentUserComponent).
From there, it was as simple as calling the component in the head of my helper...
App::uses('CurrentUserComponent', 'Controller/Component');
And referencing the component's static method:
CurrentUserComponent::levelCheck(x,y,z);
I don't think this is entirely within the intention of the MVC pattern, but it doesn't pervert it horribly, and allows access to the method from anywhere in the application.
In my controller, I would like to set some values and have them exist (or live) throughout the different views in my app.
I read somewhere that I need to use beforeFilter function, but I am not sure if that is correct and how I go about doing that.
So in my controller I want to have
public function page1() {
$this->Model->setId('123');
}
public function page2() {
$this->Model->getId(); // would able to get the Id that was set from page1 function
$this->Model->setName('Bob');
}
public function page3() {
$this->Model->getId();
$this->Model->getName();
}
Let me know if you have questions.
To have this kind of "persistence" throughout the views, I guess the most simple approach is sessions.
Note that with the code you provided (I know is not a working example), you want the variable to be persistent inside a model, but that same model wont be maintained between actions of the same controller (or other controller for that matter).
You have to set that variable in sessions and retrieve it when you want to use it, or in the database and create methods in the model to get the last inserted id, for example.
So your code would be like
public function page1() {
$this->Session->write('id', '123');
}
public function page2() {
$this->Session->read('id');
$this->Session->write('name', 'Bob');
}
public function page3() {
$this->Session->read('id');
$this->Session->read('name');
}
Have a single model method that returns all your data in an array like
return array('varName' => $value, 'varName2' => $value2);
You can then call this model method from the controllers before filter and simply do
$this->set(ClassRegistry::init('MyModel')->commonViewVars());
If you would describe for what you think you need to do that I could give you a better advice like using requestAction() for example, this might be another option depending on what you're trying to do.
Depending on what data you want to pass to every page you should really consider to cache it. If its a menu for example cache it "forever" and just update the cache when the menu changes.
I have installed a plugin (SignMeUp) for the user registration, and according to the documentation the registration function inside my User Controller has to look something like this:
public function register() {
$this->SignMeUp->register();
}
Looking at the $this->data array inside this function shows that everything is working fine. However, when I use
debug($this->data);
inside the registration() function of the plugin (the one I just directed my function to), the array is empty. Somehow the data doesn't get passed on. What could be the cause?
Resolved! This can be solved by replacing all the $this->data occurences in the SignMeUpComponent with $this->controller->request->data
It's a change from Cake 1.3 to Cake 2.x