How to pass data in url using cakephp? - cakephp

I wanted to now if there is a way to pass a simple string inside url and cakephp some how put it inside one of the inputs of my form without any code writing on view side?
I tried calling this->set("bla","bla"); the field name is bla
but nothing changed in view

As I understood the question you want to have something like this:
in the url you have something like:
http://yourserver.com/controller/action?search=string
and you want to put this "string" in the search field, right?
Then let's imagine that your field's name is data[search_field]. (I am skipping the model, because for my example it's not needed, but it's possible the name to be data[Model][search_field]).
Then in your controller's action you have to do following:
$this->data['search_string'] = $this->params['url']['search'];

You can pass values in the url by using html helper. Try:
echo $this->Html->link('View Some Page', array(
'controller' => 'yourController',
'action' => 'view',
1, // id
'?' => array('yourField' => 'valueToPass'))
);

Related

Cakephp 2.5 Postlink hidding the model atribute name at the url

I am using a cakephp 2.5 postlink method inside a view file :
$tableRow['Model.modelatribute'] = $this->Form->postLink(
$data['Vehicle']['plate'],
array('controller'=>'somecontroller',
'action' => 'somemethod',
'Model.modelatribute' => base64_encode($data['Vehicle']['plate'])
),
array('confirm' => 'Look at vehicle '.$data['Vehicle']['plate'])
);
I would like not to show the model atribute name on the url bar. After clicking on the link and being redirected, the url shows :
somemethod/Model.modelatribute:vSpEeTIweQ%3D%3D
Can i hide the model atribute name, using postlink method o cakephp 2.5 ?
ThankĀ“s in advance
If you simply want to pass the value of Model.modelatribute as a parameter, just leave off Model.modelatribute in your routing array. If you want to pass the value without occouring in the url you can use the data option of postLink.
echo $this->Form->postLink(
$data['Vehicle']['plate'],
array(
'controller'=>'somecontroller',
'action' => 'somemethod',
base64_encode($data['Vehicle']['plate']) // Routing array without modelname
),
array(
'confirm' => 'Look at vehicle '.$data['Vehicle']['plate'],
'data' => array(
// Data option of postLink method
'Model.modelatribute' => base64_encode($data['Vehicle']['plate'])
)
)
);
Well, you put in there. If you don't want it to be there simply don't put it in the URL. You can alternatively put it into the body of the POST request.
If you're concerned that people can use the model name for something and you want to hide it for that reason, then it is a very bad approach called security through obscurity. Instead you want to ensure that you validate that only values you want are passed and processed. So check your incoming data, always, from everywhere.

Filtering parameters in CakePHP

In Rails, we can specify the allowed parameters to be used in the controller when saving data. So, with params being the submitted data, I can do this:
params.require(:person).permit(:name, :age)
Which will ensure that the :person key is present and will filter out anything that is not a person's :name or :age.
Is there any way in CakePHP to accomplish this?
EDIT: I know I can write PHP, I want to know if there's a Cake component / plugin that already does this.
Something in this PHP way:
// submited data
$this->request->data['Person'] = array(
'name' => 'Salines',
'age' => '41',
'job' => 'Web Developer'
);
// check if isset and filter out anything that is not a person's name or age
if(isset($this->request->data['Person']))
{
$permit = array('name' => '','age' => '');
$this->request->data['Person'] = array_intersect_key($this->request->data['Person'],$permit);
}
//and return $this->request->data like
array(
'Person' => array(
'name' => 'Salines',
'age' => '41'
)
);
I'm looking for a Cake-provided solution (if there is one)
Well, define "cake-provided", you mean by the framework itself? No, the core doesn't have this functionality but there are two plugins.
For Cake3: Plum Search
For Cake2 & 3: CakeDC Search
For Cake3 I would go for Plum-Search, it is written by the same person as the initial code of the other plugin but a complete rewrite and makes a better use of Cake3.
Next time you ask name your exact Cake version.
Both plugins implement the PRG pattern but don't explicitly allow or deny query parameters. They'll only grab the parameters you specified in your filter declaration and turn them into the request. Validate and save to exclude unwanted fields.
Make a url link like this
echo $this->Html->url(array('controller'=>'users','action'=>'hello','par1'=>23,'par2'=>'sud'));
In hello function in users controller
pr($this->params->named['par1']);
pr($this->params->named['par2']);

Accessing actions with prefixes in cakephp

im still noob with cakephp. I want to access an action with a prefix but im being redirected to my current view. how can i do this? Example:
ihave a function like below:
function admin_getID()
{
some codes here...
}
in my link. i accessed it using this html helper:
$this->Html->url(array('action'=>'getID', 'admin'=>true))
note that currently i dont have any prefix and i want to access the action with a prefix.
the url will be used in jQuery.ajax's URL so in the jquery,
jQuery.ajax({
...
url:"Html->url(array("action"=>"getID", "admin"=>true))?>",
...
});
Thank you!
Since in your file core.php you are using the same prefix, for example:
Configure::write('Routing.prefixes', array('admin'));
You should use:
echo $this->Html->link('link', array('action' => 'getID', 'admin' => true));
This will generate the link /admin/{your_controller}/getID.
For the same Controller, but if you want to display to another controller, you must include the controller parameter in the array.
If you're not using the directive Routing.prefixes as I said above, simply add the admin_getID parameter in action value.
I think you are talking about routing. So for example, if you want to define actions for admin like:
admin_index
admin_edit
admin_view
adn have them accessible by
example.com/admin/index
example.com/admin/edit
example.com/admin/view
This is called routing in CakePHP. You can see how this is done here:
http://book.cakephp.org/1.3/en/view/948/Defining-Routes
Update
You can just do this:
<?php echo $this->Html->link('link', array('controller' => '{CONTROLLER_NAME}', 'action' => 'getID', 'admin' => 'true')); ?>
UPDATE 2
You are not echoing your URL. You need to do this:
jQuery.ajax({ ... url:"<?php echo $this->Html->url(array("action"=>"getID", "admin"=>true)); ?>", ... });
If you are not using PHP to render your jQuery, you cannot use cake to generate your URL, you will have to do it manually:
jQuery.ajax({ ... url:"/admin/CONTROLLER/getID", ... });

CakePhp Router:connect, I don't get the syntax

I am trying to connect the next urls:
1) /food/tips
2) /happiness/tips/best_tips
To the following objects:
1) controller=tips / action=index / passed_parameters=food
2) controller=tips / action=index / passed_parameters=(happiness,best_tips)
--edit--
These routes are not fixed.
Meaning: what I try to do is to route every url that have tips as action, to the tips controller, to any fixed(index is good enough) action, and chaining the rest of the url as it was in the original call.
Something like /any_controller/tips/any_param to /tips/index/any_params
-- end edit --
Hope that now there is some sense.
How should it be done?
(please - also explain)
Thanks
the routing is all done through the call Router::connect('thing to catch', 'where to send it');
so it can be as simple as:
Router::connect('/food/tips', '/tips/index/food');
or the preferred method (using cakes built in url builder)
Router::connect('/food/tips/*', array('controller' => 'tips', 'action' => 'index', 'food');
The first method takes a string argument and passes it to another string which would be a url and you would then have to catch it in your controller, and expect a passed parameter through the url.
The second method uses cakes built in url former which takes an array with keys controller and action (there are other options: http://api.cakephp.org/class/router#method-Routerurl)
The second is preferred due to proper formatting and future flexibility (I believe).
any passed parameters in the second method are just passed as un-named items in the array. named parameters are just passed as keyed elements. So if I wanted to create a URL like this
/posts/index/find:all/page:2
I would write the url like this:
Router::connect('/url_to_catch', array('controller' => 'posts', 'action' => 'index', 'find' => 'all', 'page' => 2);
So just to finish up, I would actually pass your parameter through as named:
Router::connect('/happiness/tips/best_tips', array('controller' => 'tips', 'action' => 'index', 'items' => array('happiness', 'best_tips'));
which would need a function in your tips controller that looks like this:
function tips(){ $this->passedArgs['items']; }
I would recommend reading the chapter on Routing the the book, as it will explain things better than I can and it seems counter productive to paste it here.
http://book.cakephp.org/#!/view/948/Defining-Routes
For the sake of explanation I will try,
Router::connect('/food/tips', array('controller' => 'tips', 'action' => 'index', 'food'));
Router::connect('/happiness/tips/best_tips', array('controller' => 'tips', 'action' => 'index', 'happiness','best_tips'));
This should get things working for you. What you are essentially doing is telling the Cake Routing what url you want it to capture, as it will be doing this using Regex. Then you want to tell it which code you want it to run. So this takes a Controller and Action pair, as a set of things to do.
You also want to pass through your named paremeters afterwards. These will tack onto the function in your controller so that you can do stuff with them.
It's quite easy, just check the Router configuration in the manual. You have to use the connect method from the Router class. This accepts 2 parameters. First your desired routed (e.g. food/tips) and second an array with the actual path it should follow. So for your examples you'd do something like this:
Router::connect('/food/tips', array('controller' => 'tips', 'action' => 'index', 'food');
Router::connect('/happiness/tips/best_tips', array('controller' => 'tips', 'action' => 'index', 'happiness', 'best_tips');
This is equivalent to calling TipsController->index('food') and TipsController('happiness', 'best_tips) respectively.
However, your routes look a bit funny. The Cake convention for routes is /controller/action/param1/param2/etc where the parameters param1 etc. are optional and the index action is assumed when no other action is given.
You're taking a different approach and I would suggest (if you can) change it to the Cake conventional routes, as this will save you a lot of work later on because Cake will automatically connect these routes to the desired methods.
So my suggestion is going for tips/food and tips/happiness/best_tips instead of the routes you suggest. This way, you don't have to do any router configuration.
UPDATE
After you're edit, I think it's best to try something with defining custom routes. I can't test this for you at the moment, so you should do some testing yourself, but in that case it would be something like:
Router::connect('/:section/tips/:param',
array('action' => 'index'),
array(
'section' => '[a-z]*',
'param' => '[a-z]*'
)
);
UPDATE2
Sorry, I've tested the above and it doesn't seem to work.

CakePHP AutoComplete Question

I am working on a book review application and I am using autoComplete to search for titles in when creating a review. The review model has an associated book_id field and the relationship is setup as the review hasOne book and a book hasMany reviews.
I am trying to pass the Book.id (into the book_id field), but I want to display Book.name for the user to select from. With the default setup (accomplished via CakePHP's tutorial), I can only pass Book.name. Is it possible to display the name and pass the id?
Also, I am passing it via the following code in the create() action of the review controller:
$this->data['Review']['book_id'] = $this->data['Book']['id'];
Is that the proper way to do it in CakePHP? I know in Ruby on Rails, it is automatic, but I can't seem to make it work automagically in CakePHP. Finally, I am not using the generator because it is not available in my shared hosting environment... so if this is the wrong way, what do I need other than associates in my models to make it happen automatically?
Thanks for the help and I promise this is my question for awhile...
UPDATE- I tried the following, but it is not working. Any ideas why?
function autoComplete() {
$this->set('books', $this->Book->find('all', array(
'conditions' => array(
'Book.name LIKE' => $this->data['Book']['name'].'%'
),
'fields' => array('id','name')
)));
$this->layout = 'ajax';
}
The problem is that when I use the code above in the controller, the form submits, but it doesn't save the record... No errors are also thrown, which is weird.
UPDATE2:
I have determine that the reason this isn't working is because the array types are different and you can't change the array type with the autoComplete helper. As a workaround, I tried the follow, but it isn't working. Can anyone offer guidance why?
function create() {
if($this->Review->create($this->data) && $this->Review->validates()) {
$this->data['Review']['user_id'] = $this->Session->read('Auth.User.id');
$this->Book->find('first', array('fields' => array('Book.id'), 'conditions' => array('Book.name' => $this->data['Book']['name'])));
$this->data['Review']['book_id'] = $this->Book->id;
$this->Review->save($this->data);
$this->redirect(array('action' => 'index'));
} else {
$errors = $this->Review->invalidFields();
}
}
FINAL UPDATE:
Ok, I found that the helper only takes the find(all) type or array and that the "id" field wasn't passing because it only applied to the autoComplete's LI list being generated. So, I used the observeField to obtain the information and then do a database lookup and tried to create a hidden field on the fly with the ID, but that didn't work. Finally, the observeField would only take the characters that I put in instead of what I clicked, due to an apparent Scriptaculous limitation. So, I ended up going to a dropdown box solution for now and may eventually look into something else. Thanks for all of the help anyway!
First of all, $this->data will only contain ['Book']['id'] if the field exists in the form (even if it's hidden).
To select something by name and return the id, use the list variant of the find method, viz:
$selectList = $this->Book->find('list', array(
'fields' => array(
'id',
'name'
)));
$this->set('selectList', $selectList);
In the view, you can now use $selectList for the options in the select element:
echo $form->input('Book.id', array('type' => 'hidden'));
echo $form->input('template_id', array(
'options' => $selectList,
'type' => 'select'
));

Resources