I want to sanitize data in cakephp but i am facing a problem. i have a form with a date field . When i tried to sanities all the data the date looses it's mysql format and is stored in the db as a rubbish data(1970-01-01) but if i remove the sanitize it works fine
i tried the following
function beforeSave()
{
$this->data = Sanitize::clean($this->data);
return true;
}
i also tried this and this works but it defeats the purpose
function beforeSave()
{
$date = $this->data['Cabinet']['date_of_inspection'];
$this->data = Sanitize::clean($this->data);
$this->data['Cabinet']['date_of_inspection'] = $date;
return true;
}
what is the way out
From CakePHP Manual :
CakePHP already protects you against
SQL Injection if you use CakePHP's ORM
methods (such as find() and save())
and proper array notation (ie.
array('field' => $value)) instead of
raw SQL. For sanitization against XSS
its generally better to save raw HTML
in database without modification and
sanitize at the time of
output/display.output/display.
$this->data = Sanitize::clean($this->data, array('encode' => false) solved the problem. i agree with what Jamal Aziz/Cakephp says
Related
I am trying to make change password option by using ajax. Here I have tried below code in controller
if ($this->request->is(array('post', 'put'))){
$id=$this->Auth->user('id');
$changePass=$_POST['cpass'];
$cpasss=AuthComponent::password($changePass);
echo $cpasss;
$up=$this->User->updateAll(
array('User.password'=>"$cpasss"),
array('User.id'=>"$id")
);
}
Here hash is working fine,I have seen by firebug but the problem is here password not updating in database.If I remove
$cpasss=AuthComponent::password($changePass);
then password is updating fine but without hash.May anybody help me to solve this problem ?
There is no need to use updateAll() here. Instead just save the data using save() and remember to pass the primary key with the save data:-
if ($this->request->is(array('post', 'put'))) {
$id = $this->Auth->user('id');
$changePass = $this->request->data['User']['cpass'];
$data = array(
'id' => $id,
'password' => AuthComponent::password($changePass)
);
$this->User->save($data);
}
If you do use updateAll() it needs to be used with caution as it does not escape the passed fields. From the docs:-
The $fields array accepts SQL expressions. Literal values should be
quoted manually using DboSource::value().
Update your code to:
if ($this->request->is(array('post', 'put'))){
$id=$this->Auth->user('id');
$changePass= $this->request->data['cpass'];
$cpasss=AuthComponent::password($changePass);
$up=$this->User->updateAll(
array('User.password'=> $cpasss),
array('User.id'=> $id)
);
}
Changes:
$_POST[] is not the proper way of taking form data in cakephp.
No need to include the variables in double quotes(").
Please help, this is my first plugin I'm writing and I'm completely lost. I'm trying to write and update information in a table in a joomla database using my custom giveBadge() function. The functions receives two different variables, the first variable is the $userID and the second one is the digit 300 which I pass at the bottom of the class using giveBadge(300). At the same comparing the $userID in the Joomla database to ensure that the number 300 is given to the current user logged in the Joomla site.
Thanks in advance.
<?php
defined('JPATH_BASE') or die;
class plgUserBadge extends JPlugin
{
public function onUserLogin () {
$user =& JFactory::getUser();
$userID =& user->userID;
return $userID;
}
public function giveBadge ($userID, &$badgeID) {
// Get a db connection.
$db = JFactory::getDbo();
// Create a new query object.
$query = $db->getQuery(true);
// Fields to update.
$fields = array(
'profile_value=\'Updating custom message for user 1001.\'',
'ordering=2');
// Conditions for which records should be updated.
$conditions = array(
'user_id='.$userID,
'profile_key=\'custom.message\'');
$query->update($db->quoteName('#__user_badges'))->set($fields)->where($conditions);
$db->setQuery($query);
try {
$result = $db->query();
} catch (Exception $e) {
// Catch the error.
}es = array(1001, $db->quote('custom.message'), $db->quote('Inserting a record using insert()'), 1);
}
}
giveBadge(300); //attaches to $badgeID
?>
Here is not going well with your code:
You can drop the assign by reference in all your code (&) - you really don't need it, in 99% of the cases.
Use an IDE (for example Eclipse with PDT). At the top of your code you have & user->userID; Any IDE will spot your error and also other things in your code.
Study existing plugins to understand how they work. Here is also the documentation on plugins.
The method onUserLogin() will automatically be called by Joomla when the specific event is triggered (when your plugin is activated). Check with a die("My plugin was called") to see if your plugin is really called
inside onUserLogin() you do all your business logic. You are not supposed to return something, just return true. Right now your method does absolutely nothing. But you can call $this->giveBadge() to move the logic to another method.
I have custom validation rule:
public function customRule($check)
{
}
Inside this rule I would like to access some model data (in database). Of course I can do it like this:
$this->id = 23;
$this->read();
But then all the data in current model will be overidden by read function (I mean $this->data[$this->alias][...] is overridden.
How I can get this data?
Use a regular
$result = $this->find('first', array('conditions' => array($this->alias . '.' . $this->primaryKey => $id));
with the id in the find conditions. And work with the result, it is not overriding the data property.
Just to note that if you want to get the full record of the data that is currently being validated it is always accessible in $this->data inside the validation rule as opposed to $check which contains only the data in the currently validated field.
If you need to validate based on something that is stored in the DB, you can use $this->find() or any of the Model's functions as you are in the Model.
I support #burzum 's answer +1.
I got a few lines of codes in a Model in cakePHP 1.26:
function beforeSave() {
$this->data['User']['pswd'] = md5($raw['User']['pswd']);
return true;
} // this beforeSave() works
The code above has been tested and it is working in my database.
Yet, I am not sure if I can understand it well,
so, I re-wrote the code in other way, and it just failed to work then.
function beforeSave() {
$raw=$this->data;
$raw['User']['pswd'] = md5($raw['User']['pswd']);
return true;
} // this beforeSave() failed to work
Why the second method can not work?
In this line:
$raw=$this->data
You're just assigning $this->data by value to $raw. So when you change $raw's array data, $this->data isn't affected by the change.
Besides, you're totally changing the meaning of your code. What you end up doing is replacing $raw's data with $this->data from your model. I've not worked with CakePHP before, but I assume $raw already contains all the raw data you've received through some kind input, while $this->data in your model contains the older version of your model data (for example, an older password that the user was going to change). Your changed code will just erase all the new data in $raw, which I don't think is what you intend to do judging from your first code example.
To give you a little explanation of this line:
$this->data['User']['pswd'] = md5($raw['User']['pswd']);
It's pretty simple: the pswd item in the User array of $this->data is set as the MD5 checksum of the pswd in the User array of $raw.
if($this->data['Register']['password'] == $this->data['Register']['confirm_password'])
{
return true;
}
else
{
return false;
}
Use this in your model's beforeSave function()
In one of my models, I have a "LONGTEXT" field that has a big dump of a bunch of stuff that I never care to read, and it slows things down, since I'm moving much more data between the DB and the web app.
Is there a way to specify in the model that I want CakePHP to simply ignore that field, and never read it or do anything with it?
I really want to avoid the hassle of creating a separate table and a separate model, only for this field.
Thanks!
Daniel
As #SpawnCxy said, you'll need to use the 'fields' => array(...) option in a find to limit the data you want to retrieve. If you don't want to do this every time you write a find, you can add something like this to your models beforeFind() callback, which will automatically populate the fields options with all fields except the longtext field:
function beforeFind($query) {
if (!isset($query['fields'])) {
foreach ($this->_schema as $field => $foo) {
if ($field == 'longtextfield') {
continue;
}
$query['fields'][] = $this->alias . '.' . $field;
}
}
return $query;
}
Regarding comment:
That's true… The easiest way in this case is probably to unset the field from the schema.
unset($this->Model->_schema['longtextfield']);
I haven't tested it, but this should prevent the field from being included in the query. If you want to make this switchable for each query, you could move it to another variable like $Model->_schemaInactiveFields and move it back when needed. You could even make a Behavior for this.
The parameter fields may help you.It doesn't ignore fields but specifies fields you want:
array(
'conditions' => array('Model.field' => $thisValue), //array of conditions
'fields' => array('Model.field1', 'Model.field2'), //list columns you want
)
You can get more information of retrieving data in the cookbook .
Another idea:
Define your special query in the model:
function myfind($type,$params)
{
$params['fields'] = array('Model.field1','Model.field2',...);
return $this->find($type,$params);
}
Then use it in the controller
$this->Model->myfind($type,$params);
Also try containable behaviour will strip out all unwanted fields and works on model associations as well.
Containable
class Post extends AppModel { <br>
var $actsAs = array('Containable'); <br>
}
where Post is your model?
You can add a beforeFilter function in your Table and add a select to the query
Excample:
public function beforeFind(Event $event, Query $query){
$protected = $this->newEntity()->hidden;
$tableSchema = $event->subject()->schema();
$fields = $tableSchema->columns();
foreach($fields as $key => $name){
if(in_array($name,$protected)){
unset($fields[$key]);
}
}
$query->select($fields);
return $event;
}
In this excample I took the hidden fields from the ModelClass to exclude from result.
Took it from my answer to a simular question here : Hidden fields are still listed from database in cakephp 3